40
35
// in the class that inherits from IfConfigSet.
39
// Copy some of the interfrace state from the pulled configuration
42
copy_interface_state(const IfTreeInterface* pulled_ifp,
43
IfTreeInterface& config_iface)
45
if (pulled_ifp == NULL)
48
if (config_iface.pif_index() != pulled_ifp->pif_index())
49
config_iface.set_pif_index(pulled_ifp->pif_index());
50
if (config_iface.no_carrier() != pulled_ifp->no_carrier())
51
config_iface.set_no_carrier(pulled_ifp->no_carrier());
52
if (config_iface.mtu() == 0) {
53
if (config_iface.mtu() != pulled_ifp->mtu())
54
config_iface.set_mtu(pulled_ifp->mtu());
56
if (config_iface.mac().empty()) {
57
if (config_iface.mac() != pulled_ifp->mac())
58
config_iface.set_mac(pulled_ifp->mac());
60
if (config_iface.interface_flags() != pulled_ifp->interface_flags())
61
config_iface.set_interface_flags(pulled_ifp->interface_flags());
65
// Copy some of the vif state from the pulled configuration
68
copy_vif_state(const IfTreeVif* pulled_vifp, IfTreeVif& config_vif)
70
if (pulled_vifp == NULL)
73
if (config_vif.pif_index() != pulled_vifp->pif_index())
74
config_vif.set_pif_index(pulled_vifp->pif_index());
75
if (config_vif.broadcast() != pulled_vifp->broadcast())
76
config_vif.set_broadcast(pulled_vifp->broadcast());
77
if (config_vif.loopback() != pulled_vifp->loopback())
78
config_vif.set_loopback(pulled_vifp->loopback());
79
if (config_vif.point_to_point() != pulled_vifp->point_to_point())
80
config_vif.set_point_to_point(pulled_vifp->point_to_point());
81
if (config_vif.multicast() != pulled_vifp->multicast())
82
config_vif.set_multicast(pulled_vifp->multicast());
83
if (config_vif.vif_flags() != pulled_vifp->vif_flags())
84
config_vif.set_vif_flags(pulled_vifp->vif_flags());
44
88
IfConfigSet::push_config(IfTree& iftree)
46
90
IfTree::IfMap::iterator ii;
47
91
IfTreeInterface::VifMap::iterator vi;
92
IfConfigErrorReporterBase& error_reporter =
93
ifconfig().ifconfig_error_reporter();
94
const IfTree& pulled_iftree = ifconfig().pulled_config();
49
96
// Clear errors associated with error reporter
50
ifconfig().ifconfig_error_reporter().reset();
97
error_reporter.reset();
53
// Sanity check config - bail on bad interface and bad vif names
100
// Pre-configuration processing:
101
// - Sanity check config - bail on bad interface and bad vif names.
102
// - Set "soft" flag for interfaces.
103
// - Propagate "DELETED" status from interfaces to vifs.
104
// - Propagate "DELETED" status from vifs to addresses.
55
106
for (ii = iftree.interfaces().begin();
56
107
ii != iftree.interfaces().end();
58
IfTreeInterface& i = ii->second;
60
// Skip the ifindex check if the interface has no mapping to
109
IfTreeInterface& config_iface = ii->second;
112
// Set the "soft" flag for interfaces that are emulated
114
if ((config_iface.discard() && is_discard_emulated(config_iface))
115
|| (config_iface.unreachable()
116
&& is_unreachable_emulated(config_iface))) {
117
config_iface.set_soft(true);
121
// Skip the rest of processing if the interface has no mapping to
61
122
// an existing interface in the system.
63
if (i.is_soft() || (i.discard() && is_discard_emulated(i)))
124
if (config_iface.is_soft())
128
// Skip configuration for default system config interfaces
130
if (config_iface.default_system_config())
67
134
// Check that the interface is recognized by the system
69
if (ifconfig().get_insert_ifindex(i.ifname()) == 0) {
70
if (i.state() == IfTreeItem::DELETED) {
136
if (pulled_iftree.find_interface(config_iface.ifname()) == NULL) {
137
if (config_iface.state() == IfTreeItem::DELETED) {
71
138
// XXX: ignore deleted interfaces that are not recognized
74
ifconfig().ifconfig_error_reporter().interface_error(
76
"interface not recognized");
77
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
141
error_reporter.interface_error(config_iface.ifname(),
142
"interface not recognized");
82
147
// Check the interface and vif name
84
for (vi = i.vifs().begin(); vi != i.vifs().end(); ++vi) {
85
IfTreeVif& v= vi->second;
86
if (v.vifname() != i.ifname()) {
87
ifconfig().ifconfig_error_reporter().vif_error(i.ifname(),
90
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
100
for (ii = iftree.interfaces().begin();
101
ii != iftree.interfaces().end();
103
IfTreeInterface& i = ii->second;
105
// Set the "discard_emulated" flag if the discard interface is emulated
106
if (i.discard() && is_discard_emulated(i))
107
i.set_discard_emulated(true);
109
// Soft interfaces and their child nodes should never be pushed.
113
if (i.discard() && is_discard_emulated(i))
116
if ((ifconfig().get_insert_ifindex(i.ifname()) == 0)
117
&& (i.state() == IfTreeItem::DELETED)) {
118
// XXX: ignore deleted interfaces that are not recognized
149
for (vi = config_iface.vifs().begin();
150
vi != config_iface.vifs().end();
152
IfTreeVif& config_vif = vi->second;
153
if (config_vif.is_vlan())
122
push_interface_begin(i);
124
for (vi = i.vifs().begin(); vi != i.vifs().end(); ++vi) {
125
IfTreeVif& v = vi->second;
127
// XXX: delete the vif if the interface is deleted
128
if (i.state() == IfTreeItem::DELETED)
129
v.mark(IfTreeItem::DELETED);
131
push_vif_begin(i, v);
133
IfTreeVif::IPv4Map::iterator a4i;
134
for (a4i = v.ipv4addrs().begin(); a4i != v.ipv4addrs().end(); ++a4i) {
135
IfTreeAddr4& a = a4i->second;
136
// XXX: delete the address if the vif is deleted
137
if (v.state() == IfTreeItem::DELETED)
138
a.mark(IfTreeItem::DELETED);
139
if (a.state() != IfTreeItem::NO_CHANGE)
140
push_vif_address(i, v, a);
144
IfTreeVif::IPv6Map::iterator a6i;
145
for (a6i = v.ipv6addrs().begin(); a6i != v.ipv6addrs().end(); ++a6i) {
146
IfTreeAddr6& a = a6i->second;
147
// XXX: delete the address if the vif is deleted
148
if (v.state() == IfTreeItem::DELETED)
149
a.mark(IfTreeItem::DELETED);
150
if (a.state() != IfTreeItem::NO_CHANGE)
151
push_vif_address(i, v, a);
158
push_interface_end(i);
162
if (ifconfig().ifconfig_error_reporter().error_count() != 0)
155
if (config_vif.vifname() != config_iface.ifname()) {
156
error_reporter.vif_error(config_iface.ifname(),
157
config_vif.vifname(),
162
if (error_reporter.error_count() > 0)
166
// Propagate the "DELETED" status from interfaces to vifs and addresses
168
for (vi = config_iface.vifs().begin();
169
vi != config_iface.vifs().end();
171
IfTreeVif& config_vif = vi->second;
172
if (config_iface.state() == IfTreeItem::DELETED)
173
config_vif.mark(IfTreeItem::DELETED);
175
// Propagate the "DELETE" status to the IPv4 addresses
176
IfTreeVif::IPv4Map::iterator a4i;
177
for (a4i = config_vif.ipv4addrs().begin();
178
a4i != config_vif.ipv4addrs().end();
180
IfTreeAddr4& config_addr = a4i->second;
181
if (config_vif.state() == IfTreeItem::DELETED)
182
config_addr.mark(IfTreeItem::DELETED);
185
// Propagate the "DELETE" status to the IPv6 addresses
187
IfTreeVif::IPv6Map::iterator a6i;
188
for (a6i = config_vif.ipv6addrs().begin();
189
a6i != config_vif.ipv6addrs().end();
191
IfTreeAddr6& config_addr = a6i->second;
192
if (config_vif.state() == IfTreeItem::DELETED)
193
config_addr.mark(IfTreeItem::DELETED);
199
if (error_reporter.error_count() > 0) {
200
XLOG_ERROR("%s", error_reporter.last_error().c_str());
206
// 1. Push the vif creation/deletion (e.g., VLAN).
207
// 2. Pull the config from the system (e.g., to obtain information
208
// such as interface indexes for newly created interfaces/vifs).
209
// 3. Push the interface/vif/address information.
211
push_iftree_begin(iftree);
214
// 1. Push the vif creation/deletion (e.g., VLAN).
216
for (ii = iftree.interfaces().begin();
217
ii != iftree.interfaces().end();
219
IfTreeInterface& config_iface = ii->second;
220
const IfTreeInterface* pulled_ifp = NULL;
222
pulled_ifp = pulled_iftree.find_interface(config_iface.ifname());
225
// Skip interfaces that should never be pushed:
227
// - Default system config interfaces
229
if (config_iface.is_soft())
231
if (config_iface.default_system_config())
234
for (vi = config_iface.vifs().begin();
235
vi != config_iface.vifs().end();
237
IfTreeVif& config_vif = vi->second;
238
const IfTreeVif* pulled_vifp = NULL;
240
if (pulled_ifp != NULL)
241
pulled_vifp = pulled_ifp->find_vif(config_vif.vifname());
243
push_vif_creation(pulled_ifp, pulled_vifp, config_iface,
249
// 2. Pull the config from the system (e.g., to obtain information
250
// such as interface indexes for newly created interfaces/vifs).
252
ifconfig().pull_config();
255
// 3. Push the interface/vif/address configuration.
257
for (ii = iftree.interfaces().begin();
258
ii != iftree.interfaces().end();
260
IfTreeInterface& config_iface = ii->second;
261
const IfTreeInterface* pulled_ifp = NULL;
263
pulled_ifp = pulled_iftree.find_interface(config_iface.ifname());
266
// Skip interfaces that should never be pushed:
268
// - Default system config interfaces
270
if (config_iface.is_soft())
272
if (config_iface.default_system_config())
275
if ((pulled_ifp == NULL)
276
&& (config_iface.state() == IfTreeItem::DELETED)) {
277
// XXX: ignore deleted interfaces that are not recognized
281
push_interface_begin(pulled_ifp, config_iface);
283
for (vi = config_iface.vifs().begin();
284
vi != config_iface.vifs().end();
286
IfTreeVif& config_vif = vi->second;
287
const IfTreeVif* pulled_vifp = NULL;
289
if (pulled_ifp != NULL)
290
pulled_vifp = pulled_ifp->find_vif(config_vif.vifname());
292
push_vif_begin(pulled_ifp, pulled_vifp, config_iface, config_vif);
295
// Push the IPv4 addresses
297
IfTreeVif::IPv4Map::iterator a4i;
298
for (a4i = config_vif.ipv4addrs().begin();
299
a4i != config_vif.ipv4addrs().end();
301
IfTreeAddr4& config_addr = a4i->second;
302
const IfTreeAddr4* pulled_addrp = NULL;
304
if (pulled_vifp != NULL)
305
pulled_addrp = pulled_vifp->find_addr(config_addr.addr());
307
push_vif_address(pulled_ifp, pulled_vifp, pulled_addrp,
308
config_iface, config_vif, config_addr);
313
// Push the IPv6 addresses
315
IfTreeVif::IPv6Map::iterator a6i;
316
for (a6i = config_vif.ipv6addrs().begin();
317
a6i != config_vif.ipv6addrs().end();
319
IfTreeAddr6& config_addr = a6i->second;
320
const IfTreeAddr6* pulled_addrp = NULL;
322
if (pulled_vifp != NULL)
323
pulled_addrp = pulled_vifp->find_addr(config_addr.addr());
325
push_vif_address(pulled_ifp, pulled_vifp, pulled_addrp,
326
config_iface, config_vif, config_addr);
330
push_vif_end(pulled_ifp, pulled_vifp, config_iface, config_vif);
333
push_interface_end(pulled_ifp, config_iface);
336
push_iftree_end(iftree);
338
if (error_reporter.error_count() != 0)
169
IfConfigSet::push_iftree_begin()
345
IfConfigSet::push_iftree_begin(IfTree& iftree)
171
347
string error_msg;
348
IfConfigErrorReporterBase& error_reporter =
349
ifconfig().ifconfig_error_reporter();
174
354
// Begin the configuration
177
if (config_begin(error_msg) < 0) {
178
error_msg = c_format("Failed to begin configuration: %s",
180
ifconfig().ifconfig_error_reporter().config_error(error_msg);
181
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
356
if (config_begin(error_msg) != XORP_OK) {
357
error_msg = c_format("Failed to begin configuration: %s",
361
if (! error_msg.empty()) {
362
error_reporter.config_error(error_msg);
363
XLOG_ERROR("%s", error_reporter.last_error().c_str());
189
IfConfigSet::push_iftree_end()
369
IfConfigSet::push_iftree_end(IfTree& iftree)
191
371
string error_msg;
372
IfConfigErrorReporterBase& error_reporter =
373
ifconfig().ifconfig_error_reporter();
194
378
// End the configuration
197
if (config_end(error_msg) < 0) {
198
error_msg = c_format("Failed to end configuration: %s",
200
ifconfig().ifconfig_error_reporter().config_error(error_msg);
201
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
209
IfConfigSet::push_interface_begin(const IfTreeInterface& i)
212
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
213
XLOG_ASSERT(if_index > 0);
219
if (add_interface(i.ifname(), if_index, error_msg) < 0) {
220
error_msg = c_format("Failed to add interface: %s",
222
ifconfig().ifconfig_error_reporter().interface_error(i.ifname(),
224
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
232
IfConfigSet::push_interface_end(IfTreeInterface& i)
235
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
236
XLOG_ASSERT(if_index > 0);
237
uint32_t new_flags = 0;
239
bool deleted = false;
245
uint32_t pulled_flags = 0;
246
bool pulled_up, enabled;
247
const IfTreeInterface* ifp;
249
ifp = ifconfig().pulled_config().find_interface(i.ifname());
251
deleted = i.is_marked(IfTreeItem::DELETED);
252
enabled = i.enabled();
254
// Get the flags from the pulled config
256
pulled_flags = ifp->interface_flags();
257
new_flags = pulled_flags;
259
pulled_up = pulled_flags & IFF_UP;
260
if (pulled_up && (deleted || !enabled))
261
new_flags &= ~IFF_UP;
262
if ( (!pulled_up) && enabled)
265
new_up = (new_flags & IFF_UP)? true : false;
267
if ((! is_pulled_config_mirror()) && (new_flags == pulled_flags))
268
break; // XXX: nothing changed
270
if (config_interface(i.ifname(), if_index, new_flags, new_up,
273
error_msg = c_format("Failed to configure interface: %s",
275
ifconfig().ifconfig_error_reporter().interface_error(i.ifname(),
277
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
287
bool was_disabled = false;
288
uint32_t new_mtu = i.mtu();
289
uint32_t pulled_mtu = 0;
290
const IfTreeInterface* ifp;
292
ifp = ifconfig().pulled_config().find_interface(i.ifname());
295
pulled_mtu = ifp->mtu();
297
if (is_pulled_config_mirror() && (new_mtu == 0)) {
298
// Get the MTU from the pulled config
299
new_mtu = pulled_mtu;
303
break; // XXX: ignore the MTU setup
305
if ((! is_pulled_config_mirror()) && (new_mtu == pulled_mtu))
306
break; // Ignore: the MTU hasn't changed
308
if ((ifp != NULL) && new_up) {
310
// XXX: Set the interface DOWN otherwise we may not be able to
311
// set the MTU (limitation imposed by the Linux kernel).
313
config_interface(i.ifname(), if_index, new_flags & ~IFF_UP, false,
318
if (set_interface_mtu(i.ifname(), if_index, new_mtu, error_msg) < 0) {
319
error_msg = c_format("Failed to set MTU to %u bytes: %s",
320
XORP_UINT_CAST(new_mtu),
322
ifconfig().ifconfig_error_reporter().interface_error(i.name(),
324
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
326
config_interface(i.ifname(), if_index, new_flags, true,
333
config_interface(i.ifname(), if_index, new_flags, true,
335
i.set_flipped(true); // XXX: the interface was flipped
342
// Set the MAC address
345
bool was_disabled = false;
346
Mac new_mac = i.mac();
348
const IfTreeInterface* ifp;
350
ifp = ifconfig().pulled_config().find_interface(i.ifname());
353
pulled_mac = ifp->mac();
355
if (is_pulled_config_mirror() && new_mac.empty()) {
356
// Get the MAC from the pulled config
357
new_mac = pulled_mac;
361
break; // XXX: ignore the MAC setup
363
if ((! is_pulled_config_mirror()) && (new_mac == pulled_mac))
364
break; // Ignore: the MAC hasn't changed
366
struct ether_addr ea;
369
em = EtherMac(new_mac);
370
if (em.copy_out(ea) != EtherMac::ADDR_BYTELEN) {
371
error_msg = c_format("Expected Ethernet MAC address, "
373
new_mac.str().c_str());
374
ifconfig().ifconfig_error_reporter().interface_error(i.name(),
376
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
379
} catch (const BadMac& bm) {
380
error_msg = c_format("Invalid MAC address \"%s\"",
381
new_mac.str().c_str());
382
ifconfig().ifconfig_error_reporter().interface_error(i.name(),
384
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
388
if ((ifp != NULL) && new_up) {
390
// XXX: Set the interface DOWN otherwise we may not be able to
391
// set the MAC address (limitation imposed by the Linux kernel).
393
config_interface(i.ifname(), if_index, new_flags & ~IFF_UP, false,
398
if (set_interface_mac_address(i.ifname(), if_index, ea, error_msg)
400
error_msg = c_format("Failed to set the MAC address: %s",
402
ifconfig().ifconfig_error_reporter().interface_error(i.name(),
404
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
406
config_interface(i.ifname(), if_index, new_flags, true,
413
config_interface(i.ifname(), if_index, new_flags, true,
415
i.set_flipped(true); // XXX: the interface was flipped
423
IfConfigSet::push_vif_begin(const IfTreeInterface& i,
427
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
428
XLOG_ASSERT(if_index > 0);
434
if (add_vif(i.ifname(), v.vifname(), if_index, error_msg) < 0) {
435
error_msg = c_format("Failed to add vif: %s", error_msg.c_str());
436
ifconfig().ifconfig_error_reporter().vif_error(i.ifname(),
439
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
447
IfConfigSet::push_vif_end(const IfTreeInterface& i,
451
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
452
XLOG_ASSERT(if_index > 0);
458
uint32_t pulled_flags = 0;
460
bool pulled_up, new_up, deleted, enabled;
461
bool pulled_broadcast = false;
462
bool pulled_loopback = false;
463
bool pulled_point_to_point = false;
464
bool pulled_multicast = false;
465
bool new_broadcast = false;
466
bool new_loopback = false;
467
bool new_point_to_point = false;
468
bool new_multicast = false;
469
const IfTreeInterface* ifp;
471
ifp = ifconfig().pulled_config().find_interface(i.ifname());
473
deleted = (i.is_marked(IfTreeItem::DELETED) |
474
v.is_marked(IfTreeItem::DELETED));
475
enabled = i.enabled() & v.enabled();
477
// Get the flags from the pulled config
479
pulled_flags = ifp->interface_flags();
480
new_flags = pulled_flags;
482
pulled_up = pulled_flags & IFF_UP;
483
if (pulled_up && (deleted || !enabled))
484
new_flags &= ~IFF_UP;
485
if ( (!pulled_up) && enabled)
488
if ((! is_pulled_config_mirror()) && (new_flags == pulled_flags))
489
break; // XXX: nothing changed
493
const IfTreeVif* vifp = ifp->find_vif(v.vifname());
495
pulled_broadcast = vifp->broadcast();
496
pulled_loopback = vifp->loopback();
497
pulled_point_to_point = vifp->point_to_point();
498
pulled_multicast = vifp->multicast();
501
if (is_pulled_config_mirror()) {
502
new_broadcast = pulled_broadcast;
503
new_loopback = pulled_loopback;
504
new_point_to_point = pulled_point_to_point;
505
new_multicast = pulled_multicast;
380
if (config_end(error_msg) != XORP_OK) {
381
error_msg = c_format("Failed to end configuration: %s",
385
if (! error_msg.empty()) {
386
error_reporter.config_error(error_msg);
387
XLOG_ERROR("%s", error_reporter.last_error().c_str());
393
IfConfigSet::push_interface_begin(const IfTreeInterface* pulled_ifp,
394
IfTreeInterface& config_iface)
397
IfConfigErrorReporterBase& error_reporter =
398
ifconfig().ifconfig_error_reporter();
400
// Reset the flip flag for this interface
401
config_iface.set_flipped(false);
403
if ((pulled_ifp == NULL) && config_iface.is_marked(IfTreeItem::DELETED)) {
404
// Nothing to do: the interface has been deleted from the system
408
// Copy some of the state from the pulled configuration
409
copy_interface_state(pulled_ifp, config_iface);
412
// Begin the interface configuration
414
if (config_interface_begin(pulled_ifp, config_iface, error_msg)
416
error_msg = c_format("Failed to begin interface configuration: %s",
420
if (! error_msg.empty()) {
421
error_reporter.interface_error(config_iface.ifname(), error_msg);
422
XLOG_ERROR("%s", error_reporter.last_error().c_str());
428
IfConfigSet::push_interface_end(const IfTreeInterface* pulled_ifp,
429
IfTreeInterface& config_iface)
432
IfConfigErrorReporterBase& error_reporter =
433
ifconfig().ifconfig_error_reporter();
436
// End the interface configuration
438
if (config_interface_end(pulled_ifp, config_iface, error_msg)
440
error_msg = c_format("Failed to end interface configuration: %s",
444
if (! error_msg.empty()) {
445
error_reporter.interface_error(config_iface.ifname(), error_msg);
446
XLOG_ERROR("%s", error_reporter.last_error().c_str());
452
IfConfigSet::push_vif_creation(const IfTreeInterface* pulled_ifp,
453
const IfTreeVif* pulled_vifp,
454
IfTreeInterface& config_iface,
455
IfTreeVif& config_vif)
458
IfConfigErrorReporterBase& error_reporter =
459
ifconfig().ifconfig_error_reporter();
461
if ((pulled_vifp == NULL) && config_vif.is_marked(IfTreeItem::DELETED)) {
462
// Nothing to do: the vif has been deleted from the system
466
// Copy some of the state from the pulled configuration
467
copy_interface_state(pulled_ifp, config_iface);
468
copy_vif_state(pulled_vifp, config_vif);
471
// Configure VLAN vif
473
if (config_vif.is_vlan()) {
474
IfConfigVlanSet* ifconfig_vlan_set;
477
// Get the plugin for VLAN setup
478
ifconfig_vlan_set = fea_data_plane_manager().ifconfig_vlan_set();
479
if (ifconfig_vlan_set == NULL) {
480
error_msg = c_format("Failed to apply VLAN setup to "
481
"interface %s vlan %s : no plugin found",
482
config_iface.ifname().c_str(),
483
config_vif.vifname().c_str());
487
if (config_vif.state() == IfTreeItem::DELETED)
491
// Push the VLAN configuration: either add/update or delete it.
495
// Add/update the VLAN
497
if (ifconfig_vlan_set->config_add_vlan(pulled_ifp,
503
error_msg = c_format("Failed to add VLAN to "
504
"interface %s vlan %s: %s",
505
config_iface.ifname().c_str(),
506
config_vif.vifname().c_str(),
507
new_broadcast = v.broadcast();
508
new_loopback = v.loopback();
509
new_point_to_point = v.point_to_point();
510
new_multicast = v.multicast();
513
if (ifconfig_vlan_set->config_delete_vlan(pulled_ifp,
519
error_msg = c_format("Failed to delete VLAN on "
520
"interface %s vlan %s: %s",
521
config_iface.ifname().c_str(),
522
config_vif.vifname().c_str(),
513
new_up = (new_flags & IFF_UP)? true : false;
514
if (config_vif(i.ifname(), v.vifname(), if_index, new_flags, new_up,
515
deleted, new_broadcast, new_loopback,
516
new_point_to_point, new_multicast, error_msg)
518
error_msg = c_format("Failed to configure vif: %s",
530
if (! error_msg.empty()) {
531
error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
533
XLOG_ERROR("%s", error_reporter.last_error().c_str());
539
IfConfigSet::push_vif_begin(const IfTreeInterface* pulled_ifp,
540
const IfTreeVif* pulled_vifp,
541
IfTreeInterface& config_iface,
542
IfTreeVif& config_vif)
545
IfConfigErrorReporterBase& error_reporter =
546
ifconfig().ifconfig_error_reporter();
548
if ((pulled_vifp == NULL) && config_vif.is_marked(IfTreeItem::DELETED)) {
549
// Nothing to do: the vif has been deleted from the system
553
// Copy some of the state from the pulled configuration
554
copy_interface_state(pulled_ifp, config_iface);
555
copy_vif_state(pulled_vifp, config_vif);
558
// Begin the vif configuration
560
if (config_vif_begin(pulled_ifp, pulled_vifp, config_iface, config_vif,
563
error_msg = c_format("Failed to begin vif configuration: %s",
567
if (! error_msg.empty()) {
568
error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
570
XLOG_ERROR("%s", error_reporter.last_error().c_str());
576
IfConfigSet::push_vif_end(const IfTreeInterface* pulled_ifp,
577
const IfTreeVif* pulled_vifp,
578
IfTreeInterface& config_iface,
579
IfTreeVif& config_vif)
582
IfConfigErrorReporterBase& error_reporter =
583
ifconfig().ifconfig_error_reporter();
586
// End the vif configuration
588
if (config_vif_end(pulled_ifp, pulled_vifp, config_iface, config_vif,
589
error_msg) != XORP_OK) {
590
error_msg = c_format("Failed to end vif configuration: %s",
594
if (! error_msg.empty()) {
595
error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
597
XLOG_ERROR("%s", error_reporter.last_error().c_str());
603
IfConfigSet::push_vif_address(const IfTreeInterface* pulled_ifp,
604
const IfTreeVif* pulled_vifp,
605
const IfTreeAddr4* pulled_addrp,
606
IfTreeInterface& config_iface,
607
IfTreeVif& config_vif,
608
IfTreeAddr4& config_addr)
611
IfConfigErrorReporterBase& error_reporter =
612
ifconfig().ifconfig_error_reporter();
615
if (! fea_data_plane_manager().have_ipv4()) {
616
error_msg = "IPv4 is not supported";
620
if (config_addr.is_marked(IfTreeItem::DELETED)
621
|| (! config_addr.enabled())) {
622
// XXX: Disabling an address is same as deleting it
627
// XXX: If the broadcast address was omitted, recompute and set it here.
628
// Note that we recompute it only if the underlying vif is
629
// broadcast-capable.
631
if ((pulled_vifp != NULL)
632
&& pulled_vifp->broadcast()
633
&& (config_addr.prefix_len() > 0)
634
&& (! (config_addr.broadcast() || config_addr.point_to_point()))) {
635
IPv4 mask = IPv4::make_prefix(config_addr.prefix_len());
636
IPv4 broadcast_addr = config_addr.addr() | ~mask;
637
config_addr.set_bcast(broadcast_addr);
638
config_addr.set_broadcast(true);
642
// Push the address configuration: either add/update or delete it.
646
// Add/update the address
648
if (config_add_address(pulled_ifp, pulled_vifp, pulled_addrp,
649
config_iface, config_vif, config_addr,
652
error_msg = c_format("Failed to add address: %s",
519
653
error_msg.c_str());
520
ifconfig().ifconfig_error_reporter().vif_error(i.ifname(),
523
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
531
IfConfigSet::push_vif_address(const IfTreeInterface& i,
533
const IfTreeAddr4& a)
536
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
537
XLOG_ASSERT(if_index > 0);
539
bool enabled = (i.enabled() & v.enabled() & a.enabled());
541
debug_msg("Pushing %s\n", a.str().c_str());
543
if (a.is_marked(IfTreeItem::CREATED) && enabled == false) {
545
// A created but disabled address will not appear in the live
546
// config that was read from the kernel.
549
vifp = ifconfig().live_config().find_vif(i.ifname(), v.vifname());
550
XLOG_ASSERT(vifp != NULL);
551
vifp->add_addr(a.addr());
552
IfTreeAddr4* ap = vifp->find_addr(a.addr());
553
XLOG_ASSERT(ap != NULL);
558
bool deleted = (i.is_marked(IfTreeItem::DELETED) |
559
v.is_marked(IfTreeItem::DELETED) |
560
a.is_marked(IfTreeItem::DELETED));
562
if (deleted || !enabled) {
563
if (delete_vif_address(i.ifname(), v.vifname(), if_index,
564
IPvX(a.addr()), a.prefix_len(), error_msg)
657
// Delete the address
659
if (pulled_addrp == NULL)
660
return; // XXX: nothing to delete
661
if (config_delete_address(pulled_ifp, pulled_vifp, pulled_addrp,
662
config_iface, config_vif, config_addr,
566
665
error_msg = c_format("Failed to delete address: %s",
567
666
error_msg.c_str());
568
ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
572
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
671
if (! error_msg.empty()) {
672
error_reporter.vifaddr_error(config_iface.ifname(),
673
config_vif.vifname(),
676
XLOG_ERROR("%s", error_reporter.last_error().c_str());
581
IPv4 oaddr(IPv4::ZERO());
584
else if (a.point_to_point())
585
oaddr = a.endpoint();
587
uint32_t prefix_len = a.prefix_len();
589
const IfTreeAddr4* ap = NULL;
590
const IfTreeVif* vifp = ifconfig().pulled_config().find_vif(i.ifname(),
593
ap = vifp->find_addr(a.addr());
595
// Test if a new address
596
bool new_address = true;
598
if (is_pulled_config_mirror())
602
if (ap->addr() != a.addr())
604
if (a.broadcast() && (ap->bcast() != a.bcast()))
606
if (a.point_to_point() && (ap->endpoint() != a.endpoint()))
608
if (ap->prefix_len() != prefix_len)
614
break; // Ignore: the address hasn't changed
617
// XXX: If the broadcast address was omitted, recompute it here.
618
// Note that we recompute it only if the underlying vif is
619
// broadcast-capable.
621
bool is_broadcast = a.broadcast();
623
&& (! (a.broadcast() || a.point_to_point()))
625
&& vifp->broadcast()) {
626
IPv4 mask = IPv4::make_prefix(prefix_len);
627
oaddr = a.addr() | ~mask;
632
// Try to add the address.
633
// If the address exists already (e.g., with different prefix length),
634
// then delete it first.
637
delete_vif_address(i.ifname(), v.vifname(), if_index,
638
IPvX(a.addr()), ap->prefix_len(), error_msg);
640
if (add_vif_address(i.ifname(), v.vifname(), if_index, is_broadcast,
641
a.point_to_point(), IPvX(a.addr()), IPvX(oaddr),
642
prefix_len, error_msg)
644
error_msg = c_format("Failed to configure address: %s",
646
ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
650
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
659
IfConfigSet::push_vif_address(const IfTreeInterface& i,
661
const IfTreeAddr6& a)
683
IfConfigSet::push_vif_address(const IfTreeInterface* pulled_ifp,
684
const IfTreeVif* pulled_vifp,
685
const IfTreeAddr6* pulled_addrp,
686
IfTreeInterface& config_iface,
687
IfTreeVif& config_vif,
688
IfTreeAddr6& config_addr)
663
690
string error_msg;
664
uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
665
XLOG_ASSERT(if_index > 0);
667
bool enabled = (i.enabled() & v.enabled() & a.enabled());
669
debug_msg("Pushing %s\n", a.str().c_str());
671
if (a.is_marked(IfTreeItem::CREATED) && enabled == false) {
673
// A created but disabled address will not appear in the live
674
// config rippled up from the kernel via the routing socket
677
vifp = ifconfig().live_config().find_vif(i.ifname(), v.vifname());
678
XLOG_ASSERT(vifp != NULL);
679
vifp->add_addr(a.addr());
680
IfTreeAddr6* ap = vifp->find_addr(a.addr());
681
XLOG_ASSERT(ap != NULL);
686
bool deleted = (i.is_marked(IfTreeItem::DELETED) |
687
v.is_marked(IfTreeItem::DELETED) |
688
a.is_marked(IfTreeItem::DELETED));
690
if (deleted || !enabled) {
691
if (delete_vif_address(i.ifname(), v.vifname(), if_index,
692
IPvX(a.addr()), a.prefix_len(), error_msg)
691
IfConfigErrorReporterBase& error_reporter =
692
ifconfig().ifconfig_error_reporter();
695
if (! fea_data_plane_manager().have_ipv6()) {
696
error_msg = "IPv6 is not supported";
700
if (config_addr.is_marked(IfTreeItem::DELETED)
701
|| (! config_addr.enabled())) {
702
// XXX: Disabling an address is same as deleting it
707
// XXX: For whatever reason a prefix length of zero does not cut it, so
708
// initialize prefix to 64. This is exactly what ifconfig(8) does.
710
if (config_addr.prefix_len() == 0)
711
config_addr.set_prefix_len(64);
714
// Push the address configuration: either add/update or delete it.
718
// Add/update the address
720
if (config_add_address(pulled_ifp, pulled_vifp, pulled_addrp,
721
config_iface, config_vif, config_addr,
724
error_msg = c_format("Failed to configure address: %s",
729
// Delete the address
731
if (pulled_addrp == NULL)
732
return; // XXX: nothing to delete
733
if (config_delete_address(pulled_ifp, pulled_vifp, pulled_addrp,
734
config_iface, config_vif, config_addr,
694
737
error_msg = c_format("Failed to delete address: %s",
695
738
error_msg.c_str());
696
ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
700
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
743
if (! error_msg.empty()) {
744
error_reporter.vifaddr_error(config_iface.ifname(),
745
config_vif.vifname(),
748
XLOG_ERROR("%s", error_reporter.last_error().c_str());
709
IPv6 oaddr(IPv6::ZERO());
710
if (a.point_to_point())
711
oaddr = a.endpoint();
713
// XXX: for whatever reason a prefix length of zero does not cut it, so
714
// initialize prefix to 64. This is exactly as ifconfig(8) does.
715
uint32_t prefix_len = a.prefix_len();
719
const IfTreeAddr6* ap = ifconfig().pulled_config().find_addr(
720
i.ifname(), v.vifname(), a.addr());
722
// Test if a new address
723
bool new_address = true;
725
if (is_pulled_config_mirror())
729
if (ap->addr() != a.addr())
731
if (a.point_to_point() && (ap->endpoint() != a.endpoint()))
733
if (ap->prefix_len() != prefix_len)
739
break; // Ignore: the address hasn't changed
742
// Try to add the address.
743
// If the address exists already (e.g., with different prefix length),
744
// then delete it first.
747
delete_vif_address(i.ifname(), v.vifname(), if_index,
748
IPvX(a.addr()), ap->prefix_len(), error_msg);
750
if (add_vif_address(i.ifname(), v.vifname(), if_index, false,
751
a.point_to_point(), IPvX(a.addr()), IPvX(oaddr),
752
prefix_len, error_msg)
754
error_msg = c_format("Failed to configure address: %s",
756
ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
760
XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
766
752
#endif // HAVE_IPV6