~ubuntu-branches/ubuntu/jaunty/xorp/jaunty

« back to all changes in this revision

Viewing changes to fea/data_plane/ifconfig/ifconfig_set.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jose Calhariz, Javier Fernandez-Sanguino, Jose Calhariz
  • Date: 2008-01-23 01:24:37 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123012437-7l2u9r0k8e7op8st
Tags: 1.5~cvs.20080128-1
[ Javier Fernandez-Sanguino ]
* Update to latest CVS contents
* Modify debian/rules to prevent autobuilders from building 
  the binary-independent components: (Closes: #441121)
  - Create a new Build-Depends-Indep with all the TeX
  components used to build documentation
  - Since autobuilders call build, which in turns calls build-indep, hack
    the debian rules file so that the documentation is only built if ps2pdf,
    dvips and pslatex are available. 
* Modify the init.d script:
  - restart action: Do not attempt to stop xorp if not running
  - stop function: fix errors in the script
  - add a try-restart action
  - restructure the init.d script, move the restart code to a function
  - review the use of echo calls and exit values
* Use, as examples, the new boot files at rtrmgr/config/

[ Jose Calhariz ]
* Add depends on ncurses-dev, I don't know why xorp use tigetstr
  function from curses.  This way the depends field change less between
  build environments.
* Removed pushd and popd commands from Makefile and replaced with cd
  commands, was a bashism and FTBFS (closes: #453637)
* debian/control converted to utf-8 (closes: #454026) (closes: #453485)
* init.d/xorp now returns 0 if disabled.
* Added Vcs-Browser and Vcs-Svn fields pointing to the repository of the
  package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
2
2
 
3
 
// Copyright (c) 2001-2007 International Computer Science Institute
 
3
// Copyright (c) 2001-2008 International Computer Science Institute
4
4
//
5
5
// Permission is hereby granted, free of charge, to any person obtaining a
6
6
// copy of this software and associated documentation files (the "Software")
12
12
// notice is a summary of the XORP LICENSE file; the license in that file is
13
13
// legally binding.
14
14
 
15
 
#ident "$XORP: xorp/fea/data_plane/ifconfig/ifconfig_set.cc,v 1.6 2007/07/11 22:18:15 pavlin Exp $"
 
15
#ident "$XORP: xorp/fea/data_plane/ifconfig/ifconfig_set.cc,v 1.19 2008/01/04 03:16:09 pavlin Exp $"
16
16
 
17
17
#include "fea/fea_module.h"
18
18
 
19
19
#include "libxorp/xorp.h"
20
20
#include "libxorp/xlog.h"
21
21
#include "libxorp/debug.h"
22
 
#include "libxorp/ether_compat.h"
23
22
#include "libxorp/ipvx.hh"
24
23
 
25
 
#ifdef HAVE_NET_IF_H
26
 
#include <net/if.h>
27
 
#endif
28
 
 
29
24
#include "fea/ifconfig.hh"
30
25
#include "fea/ifconfig_set.hh"
31
26
 
40
35
// in the class that inherits from IfConfigSet.
41
36
//
42
37
 
43
 
bool
 
38
//
 
39
// Copy some of the interfrace state from the pulled configuration
 
40
//
 
41
static void
 
42
copy_interface_state(const IfTreeInterface* pulled_ifp,
 
43
                     IfTreeInterface& config_iface)
 
44
{
 
45
    if (pulled_ifp == NULL)
 
46
        return;
 
47
 
 
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());
 
55
    }
 
56
    if (config_iface.mac().empty()) {
 
57
        if (config_iface.mac() != pulled_ifp->mac())
 
58
            config_iface.set_mac(pulled_ifp->mac());
 
59
    }
 
60
    if (config_iface.interface_flags() != pulled_ifp->interface_flags())
 
61
        config_iface.set_interface_flags(pulled_ifp->interface_flags());
 
62
}
 
63
 
 
64
//
 
65
// Copy some of the vif state from the pulled configuration
 
66
//
 
67
static void
 
68
copy_vif_state(const IfTreeVif* pulled_vifp, IfTreeVif& config_vif)
 
69
{
 
70
    if (pulled_vifp == NULL)
 
71
        return;
 
72
 
 
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());
 
85
}
 
86
 
 
87
int
44
88
IfConfigSet::push_config(IfTree& iftree)
45
89
{
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();
48
95
 
49
96
    // Clear errors associated with error reporter
50
 
    ifconfig().ifconfig_error_reporter().reset();
 
97
    error_reporter.reset();
51
98
 
52
99
    //
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.
54
105
    //
55
106
    for (ii = iftree.interfaces().begin();
56
107
         ii != iftree.interfaces().end();
57
108
         ++ii) {
58
 
        IfTreeInterface& i = ii->second;
59
 
        //
60
 
        // Skip the ifindex check if the interface has no mapping to
 
109
        IfTreeInterface& config_iface = ii->second;
 
110
 
 
111
        //
 
112
        // Set the "soft" flag for interfaces that are emulated
 
113
        //
 
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);
 
118
        }
 
119
 
 
120
        //
 
121
        // Skip the rest of processing if the interface has no mapping to
61
122
        // an existing interface in the system.
62
123
        //
63
 
        if (i.is_soft() || (i.discard() && is_discard_emulated(i)))
 
124
        if (config_iface.is_soft())
 
125
            continue;
 
126
 
 
127
        //
 
128
        // Skip configuration for default system config interfaces
 
129
        //
 
130
        if (config_iface.default_system_config())
64
131
            continue;
65
132
 
66
133
        //
67
134
        // Check that the interface is recognized by the system
68
135
        //
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
72
139
                continue;
73
140
            }
74
 
            ifconfig().ifconfig_error_reporter().interface_error(
75
 
                i.ifname(),
76
 
                "interface not recognized");
77
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
78
 
            return false;
 
141
            error_reporter.interface_error(config_iface.ifname(),
 
142
                                           "interface not recognized");
 
143
            break;
79
144
        }
80
145
 
81
146
        //
82
147
        // Check the interface and vif name
83
148
        //
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(),
88
 
                                                               v.vifname(),
89
 
                                                               "bad vif name");
90
 
                XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
91
 
                return false;
92
 
            }
93
 
        }
94
 
    }
95
 
 
96
 
    //
97
 
    // Walk config
98
 
    //
99
 
    push_iftree_begin();
100
 
    for (ii = iftree.interfaces().begin();
101
 
         ii != iftree.interfaces().end();
102
 
         ++ii) {
103
 
        IfTreeInterface& i = ii->second;
104
 
 
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);
108
 
 
109
 
        // Soft interfaces and their child nodes should never be pushed.
110
 
        if (i.is_soft())
111
 
            continue;
112
 
 
113
 
        if (i.discard() && is_discard_emulated(i))
114
 
            continue;
115
 
 
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();
 
151
             ++vi) {
 
152
            IfTreeVif& config_vif = vi->second;
 
153
            if (config_vif.is_vlan())
119
154
                continue;
120
 
        }
121
 
 
122
 
        push_interface_begin(i);
123
 
 
124
 
        for (vi = i.vifs().begin(); vi != i.vifs().end(); ++vi) {
125
 
            IfTreeVif& v = vi->second;
126
 
 
127
 
            // XXX: delete the vif if the interface is deleted
128
 
            if (i.state() == IfTreeItem::DELETED)
129
 
                v.mark(IfTreeItem::DELETED);
130
 
 
131
 
            push_vif_begin(i, v);
132
 
 
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);
141
 
            }
142
 
 
143
 
#ifdef HAVE_IPV6
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);
152
 
            }
153
 
#endif // HAVE_IPV6
154
 
 
155
 
            push_vif_end(i, v);
156
 
        }
157
 
 
158
 
        push_interface_end(i);
159
 
    }
160
 
    push_iftree_end();
161
 
 
162
 
    if (ifconfig().ifconfig_error_reporter().error_count() != 0)
163
 
        return false;
 
155
            if (config_vif.vifname() != config_iface.ifname()) {
 
156
                error_reporter.vif_error(config_iface.ifname(),
 
157
                                         config_vif.vifname(),
 
158
                                         "bad vif name");
 
159
                break;
 
160
            }
 
161
        }
 
162
        if (error_reporter.error_count() > 0)
 
163
            break;
 
164
 
 
165
        //
 
166
        // Propagate the "DELETED" status from interfaces to vifs and addresses
 
167
        //
 
168
        for (vi = config_iface.vifs().begin();
 
169
             vi != config_iface.vifs().end();
 
170
             ++vi) {
 
171
            IfTreeVif& config_vif = vi->second;
 
172
            if (config_iface.state() == IfTreeItem::DELETED)
 
173
                config_vif.mark(IfTreeItem::DELETED);
 
174
 
 
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();
 
179
                 ++a4i) {
 
180
                IfTreeAddr4& config_addr = a4i->second;
 
181
                if (config_vif.state() == IfTreeItem::DELETED)
 
182
                    config_addr.mark(IfTreeItem::DELETED);
 
183
            }
 
184
 
 
185
            // Propagate the "DELETE" status to the IPv6 addresses
 
186
#ifdef HAVE_IPV6
 
187
            IfTreeVif::IPv6Map::iterator a6i;
 
188
            for (a6i = config_vif.ipv6addrs().begin();
 
189
                 a6i != config_vif.ipv6addrs().end();
 
190
                 ++a6i) {
 
191
                IfTreeAddr6& config_addr = a6i->second;
 
192
                if (config_vif.state() == IfTreeItem::DELETED)
 
193
                    config_addr.mark(IfTreeItem::DELETED);
 
194
            }
 
195
#endif // HAVE_IPV6
 
196
        }
 
197
    }
 
198
 
 
199
    if (error_reporter.error_count() > 0) {
 
200
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
201
        return (XORP_ERROR);
 
202
    }
 
203
 
 
204
    //
 
205
    // Push the config:
 
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.
 
210
    //
 
211
    push_iftree_begin(iftree);
 
212
 
 
213
    //
 
214
    // 1. Push the vif creation/deletion (e.g., VLAN).
 
215
    //
 
216
    for (ii = iftree.interfaces().begin();
 
217
         ii != iftree.interfaces().end();
 
218
         ++ii) {
 
219
        IfTreeInterface& config_iface = ii->second;
 
220
        const IfTreeInterface* pulled_ifp = NULL;
 
221
 
 
222
        pulled_ifp = pulled_iftree.find_interface(config_iface.ifname());
 
223
 
 
224
        //
 
225
        // Skip interfaces that should never be pushed:
 
226
        // - Soft interfaces
 
227
        // - Default system config interfaces
 
228
        //
 
229
        if (config_iface.is_soft())
 
230
            continue;
 
231
        if (config_iface.default_system_config())
 
232
            continue;
 
233
 
 
234
        for (vi = config_iface.vifs().begin();
 
235
             vi != config_iface.vifs().end();
 
236
             ++vi) {
 
237
            IfTreeVif& config_vif = vi->second;
 
238
            const IfTreeVif* pulled_vifp = NULL;
 
239
 
 
240
            if (pulled_ifp != NULL)
 
241
                pulled_vifp = pulled_ifp->find_vif(config_vif.vifname());
 
242
 
 
243
            push_vif_creation(pulled_ifp, pulled_vifp, config_iface,
 
244
                              config_vif);
 
245
        }
 
246
    }
 
247
 
 
248
    //
 
249
    // 2. Pull the config from the system (e.g., to obtain information
 
250
    //    such as interface indexes for newly created interfaces/vifs).
 
251
    //
 
252
    ifconfig().pull_config();
 
253
 
 
254
    //
 
255
    // 3. Push the interface/vif/address configuration.
 
256
    //
 
257
    for (ii = iftree.interfaces().begin();
 
258
         ii != iftree.interfaces().end();
 
259
         ++ii) {
 
260
        IfTreeInterface& config_iface = ii->second;
 
261
        const IfTreeInterface* pulled_ifp = NULL;
 
262
 
 
263
        pulled_ifp = pulled_iftree.find_interface(config_iface.ifname());
 
264
 
 
265
        //
 
266
        // Skip interfaces that should never be pushed:
 
267
        // - Soft interfaces
 
268
        // - Default system config interfaces
 
269
        //
 
270
        if (config_iface.is_soft())
 
271
            continue;
 
272
        if (config_iface.default_system_config())
 
273
            continue;
 
274
 
 
275
        if ((pulled_ifp == NULL)
 
276
            && (config_iface.state() == IfTreeItem::DELETED)) {
 
277
            // XXX: ignore deleted interfaces that are not recognized
 
278
            continue;
 
279
        }
 
280
 
 
281
        push_interface_begin(pulled_ifp, config_iface);
 
282
 
 
283
        for (vi = config_iface.vifs().begin();
 
284
             vi != config_iface.vifs().end();
 
285
             ++vi) {
 
286
            IfTreeVif& config_vif = vi->second;
 
287
            const IfTreeVif* pulled_vifp = NULL;
 
288
 
 
289
            if (pulled_ifp != NULL)
 
290
                pulled_vifp = pulled_ifp->find_vif(config_vif.vifname());
 
291
 
 
292
            push_vif_begin(pulled_ifp, pulled_vifp, config_iface, config_vif);
 
293
 
 
294
            //
 
295
            // Push the IPv4 addresses
 
296
            //
 
297
            IfTreeVif::IPv4Map::iterator a4i;
 
298
            for (a4i = config_vif.ipv4addrs().begin();
 
299
                 a4i != config_vif.ipv4addrs().end();
 
300
                 ++a4i) {
 
301
                IfTreeAddr4& config_addr = a4i->second;
 
302
                const IfTreeAddr4* pulled_addrp = NULL;
 
303
 
 
304
                if (pulled_vifp != NULL)
 
305
                    pulled_addrp = pulled_vifp->find_addr(config_addr.addr());
 
306
 
 
307
                push_vif_address(pulled_ifp, pulled_vifp, pulled_addrp,
 
308
                                 config_iface, config_vif, config_addr);
 
309
            }
 
310
 
 
311
#ifdef HAVE_IPV6
 
312
            //
 
313
            // Push the IPv6 addresses
 
314
            //
 
315
            IfTreeVif::IPv6Map::iterator a6i;
 
316
            for (a6i = config_vif.ipv6addrs().begin();
 
317
                 a6i != config_vif.ipv6addrs().end();
 
318
                 ++a6i) {
 
319
                IfTreeAddr6& config_addr = a6i->second;
 
320
                const IfTreeAddr6* pulled_addrp = NULL;
 
321
 
 
322
                if (pulled_vifp != NULL)
 
323
                    pulled_addrp = pulled_vifp->find_addr(config_addr.addr());
 
324
 
 
325
                push_vif_address(pulled_ifp, pulled_vifp, pulled_addrp,
 
326
                                 config_iface, config_vif, config_addr);
 
327
            }
 
328
#endif // HAVE_IPV6
 
329
 
 
330
            push_vif_end(pulled_ifp, pulled_vifp, config_iface, config_vif);
 
331
        }
 
332
 
 
333
        push_interface_end(pulled_ifp, config_iface);
 
334
    }
 
335
 
 
336
    push_iftree_end(iftree);
 
337
 
 
338
    if (error_reporter.error_count() != 0)
 
339
        return (XORP_ERROR);
164
340
    
165
 
    return true;
 
341
    return (XORP_OK);
166
342
}
167
343
 
168
344
void
169
 
IfConfigSet::push_iftree_begin()
 
345
IfConfigSet::push_iftree_begin(IfTree& iftree)
170
346
{
171
347
    string error_msg;
 
348
    IfConfigErrorReporterBase& error_reporter =
 
349
        ifconfig().ifconfig_error_reporter();
 
350
 
 
351
    UNUSED(iftree);
172
352
 
173
353
    //
174
354
    // Begin the configuration
175
355
    //
176
 
    do {
177
 
        if (config_begin(error_msg) < 0) {
178
 
            error_msg = c_format("Failed to begin configuration: %s",
179
 
                                 error_msg.c_str());
180
 
            ifconfig().ifconfig_error_reporter().config_error(error_msg);
181
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
182
 
            return;
183
 
        }
184
 
        break;
185
 
    } while (false);
 
356
    if (config_begin(error_msg) != XORP_OK) {
 
357
        error_msg = c_format("Failed to begin configuration: %s",
 
358
                             error_msg.c_str());
 
359
    }
 
360
 
 
361
    if (! error_msg.empty()) {
 
362
        error_reporter.config_error(error_msg);
 
363
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
364
        return;
 
365
    }
186
366
}
187
367
 
188
368
void
189
 
IfConfigSet::push_iftree_end()
 
369
IfConfigSet::push_iftree_end(IfTree& iftree)
190
370
{
191
371
    string error_msg;
 
372
    IfConfigErrorReporterBase& error_reporter =
 
373
        ifconfig().ifconfig_error_reporter();
 
374
 
 
375
    UNUSED(iftree);
192
376
 
193
377
    //
194
378
    // End the configuration
195
379
    //
196
 
    do {
197
 
        if (config_end(error_msg) < 0) {
198
 
            error_msg = c_format("Failed to end configuration: %s",
199
 
                                 error_msg.c_str());
200
 
            ifconfig().ifconfig_error_reporter().config_error(error_msg);
201
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
202
 
            return;
203
 
        }
204
 
        break;
205
 
    } while (false);
206
 
}
207
 
 
208
 
void
209
 
IfConfigSet::push_interface_begin(const IfTreeInterface& i)
210
 
{
211
 
    string error_msg;
212
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
213
 
    XLOG_ASSERT(if_index > 0);
214
 
 
215
 
    //
216
 
    // Add the interface
217
 
    //
218
 
    do {
219
 
        if (add_interface(i.ifname(), if_index, error_msg) < 0) {
220
 
            error_msg = c_format("Failed to add interface: %s",
221
 
                                 error_msg.c_str());
222
 
            ifconfig().ifconfig_error_reporter().interface_error(i.ifname(),
223
 
                                                                 error_msg);
224
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
225
 
            return;
226
 
        }
227
 
        break;
228
 
    } while (false);
229
 
}
230
 
 
231
 
void
232
 
IfConfigSet::push_interface_end(IfTreeInterface& i)
233
 
{
234
 
    string error_msg;
235
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
236
 
    XLOG_ASSERT(if_index > 0);
237
 
    uint32_t new_flags = 0;
238
 
    bool new_up = false;
239
 
    bool deleted = false;
240
 
 
241
 
    //
242
 
    // Set the flags
243
 
    //
244
 
    do {
245
 
        uint32_t pulled_flags = 0;
246
 
        bool pulled_up, enabled;
247
 
        const IfTreeInterface* ifp;
248
 
 
249
 
        ifp = ifconfig().pulled_config().find_interface(i.ifname());
250
 
 
251
 
        deleted = i.is_marked(IfTreeItem::DELETED);
252
 
        enabled = i.enabled();
253
 
 
254
 
        // Get the flags from the pulled config
255
 
        if (ifp != NULL)
256
 
            pulled_flags = ifp->interface_flags();
257
 
        new_flags = pulled_flags;
258
 
 
259
 
        pulled_up = pulled_flags & IFF_UP;
260
 
        if (pulled_up && (deleted || !enabled))
261
 
            new_flags &= ~IFF_UP;
262
 
        if ( (!pulled_up) && enabled)
263
 
            new_flags |= IFF_UP;
264
 
 
265
 
        new_up = (new_flags & IFF_UP)? true : false;
266
 
 
267
 
        if ((! is_pulled_config_mirror()) && (new_flags == pulled_flags))
268
 
            break;              // XXX: nothing changed
269
 
 
270
 
        if (config_interface(i.ifname(), if_index, new_flags, new_up,
271
 
                             deleted, error_msg)
272
 
            < 0) {
273
 
            error_msg = c_format("Failed to configure interface: %s",
274
 
                                 error_msg.c_str());
275
 
            ifconfig().ifconfig_error_reporter().interface_error(i.ifname(),
276
 
                                                                 error_msg);
277
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
278
 
            return;
279
 
        }
280
 
        break;
281
 
    } while (false);
282
 
 
283
 
    //
284
 
    // Set the MTU
285
 
    //
286
 
    do {
287
 
        bool was_disabled = false;
288
 
        uint32_t new_mtu = i.mtu();
289
 
        uint32_t pulled_mtu = 0;
290
 
        const IfTreeInterface* ifp;
291
 
 
292
 
        ifp = ifconfig().pulled_config().find_interface(i.ifname());
293
 
 
294
 
        if (ifp != NULL)
295
 
            pulled_mtu = ifp->mtu();
296
 
 
297
 
        if (is_pulled_config_mirror() && (new_mtu == 0)) {
298
 
            // Get the MTU from the pulled config
299
 
            new_mtu = pulled_mtu;
300
 
        }
301
 
 
302
 
        if (new_mtu == 0)
303
 
            break;              // XXX: ignore the MTU setup
304
 
 
305
 
        if ((! is_pulled_config_mirror()) && (new_mtu == pulled_mtu))
306
 
            break;              // Ignore: the MTU hasn't changed
307
 
 
308
 
        if ((ifp != NULL) && new_up) {
309
 
            //
310
 
            // XXX: Set the interface DOWN otherwise we may not be able to
311
 
            // set the MTU (limitation imposed by the Linux kernel).
312
 
            //
313
 
            config_interface(i.ifname(), if_index, new_flags & ~IFF_UP, false,
314
 
                             deleted, error_msg);
315
 
            was_disabled = true;
316
 
        }
317
 
 
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),
321
 
                                 error_msg.c_str());
322
 
            ifconfig().ifconfig_error_reporter().interface_error(i.name(),
323
 
                                                                 error_msg);
324
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
325
 
            if (was_disabled) {
326
 
                config_interface(i.ifname(), if_index, new_flags, true,
327
 
                                 deleted, error_msg);
328
 
            }
329
 
            return;
330
 
        }
331
 
 
332
 
        if (was_disabled) {
333
 
            config_interface(i.ifname(), if_index, new_flags, true,
334
 
                             deleted, error_msg);
335
 
            i.set_flipped(true);        // XXX: the interface was flipped
336
 
        }
337
 
 
338
 
        break;
339
 
    } while (false);
340
 
 
341
 
    //
342
 
    // Set the MAC address
343
 
    //
344
 
    do {
345
 
        bool was_disabled = false;
346
 
        Mac new_mac = i.mac();
347
 
        Mac pulled_mac;
348
 
        const IfTreeInterface* ifp;
349
 
 
350
 
        ifp = ifconfig().pulled_config().find_interface(i.ifname());
351
 
 
352
 
        if (ifp != NULL)
353
 
            pulled_mac = ifp->mac();
354
 
 
355
 
        if (is_pulled_config_mirror() && new_mac.empty()) {
356
 
            // Get the MAC from the pulled config
357
 
            new_mac = pulled_mac;
358
 
        }
359
 
 
360
 
        if (new_mac.empty())
361
 
            break;              // XXX: ignore the MAC setup
362
 
 
363
 
        if ((! is_pulled_config_mirror()) && (new_mac == pulled_mac))
364
 
            break;              // Ignore: the MAC hasn't changed
365
 
 
366
 
        struct ether_addr ea;
367
 
        try {
368
 
            EtherMac em;
369
 
            em = EtherMac(new_mac);
370
 
            if (em.copy_out(ea) != EtherMac::ADDR_BYTELEN) {
371
 
                error_msg = c_format("Expected Ethernet MAC address, "
372
 
                                     "got \"%s\"",
373
 
                                     new_mac.str().c_str());
374
 
                ifconfig().ifconfig_error_reporter().interface_error(i.name(),
375
 
                                                                     error_msg);
376
 
                XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
377
 
                return;
378
 
            }
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(),
383
 
                                                                 error_msg);
384
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
385
 
            return;
386
 
        }
387
 
 
388
 
        if ((ifp != NULL) && new_up) {
389
 
            //
390
 
            // XXX: Set the interface DOWN otherwise we may not be able to
391
 
            // set the MAC address (limitation imposed by the Linux kernel).
392
 
            //
393
 
            config_interface(i.ifname(), if_index, new_flags & ~IFF_UP, false,
394
 
                             deleted, error_msg);
395
 
            was_disabled = true;
396
 
        }
397
 
 
398
 
        if (set_interface_mac_address(i.ifname(), if_index, ea, error_msg)
399
 
            < 0) {
400
 
            error_msg = c_format("Failed to set the MAC address: %s",
401
 
                                 error_msg.c_str());
402
 
            ifconfig().ifconfig_error_reporter().interface_error(i.name(),
403
 
                                                                 error_msg);
404
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
405
 
            if (was_disabled) {
406
 
                config_interface(i.ifname(), if_index, new_flags, true,
407
 
                                 deleted, error_msg);
408
 
            }
409
 
            return;
410
 
        }
411
 
 
412
 
        if (was_disabled) {
413
 
            config_interface(i.ifname(), if_index, new_flags, true,
414
 
                             deleted, error_msg);
415
 
            i.set_flipped(true);        // XXX: the interface was flipped
416
 
        }
417
 
 
418
 
        break;
419
 
    } while(false);
420
 
}
421
 
 
422
 
void
423
 
IfConfigSet::push_vif_begin(const IfTreeInterface&      i,
424
 
                          const IfTreeVif&              v)
425
 
{
426
 
    string error_msg;
427
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
428
 
    XLOG_ASSERT(if_index > 0);
429
 
 
430
 
    //
431
 
    // Add the vif
432
 
    //
433
 
    do {
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(),
437
 
                                                           v.vifname(),
438
 
                                                           error_msg);
439
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
440
 
            return;
441
 
        }
442
 
        break;
443
 
    } while (false);
444
 
}
445
 
 
446
 
void
447
 
IfConfigSet::push_vif_end(const IfTreeInterface&        i,
448
 
                          const IfTreeVif&              v)
449
 
{
450
 
    string error_msg;
451
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
452
 
    XLOG_ASSERT(if_index > 0);
453
 
 
454
 
    //
455
 
    // Set the flags
456
 
    //
457
 
    do {
458
 
        uint32_t pulled_flags = 0;
459
 
        uint32_t new_flags;
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;
470
 
 
471
 
        ifp = ifconfig().pulled_config().find_interface(i.ifname());
472
 
 
473
 
        deleted = (i.is_marked(IfTreeItem::DELETED) |
474
 
                   v.is_marked(IfTreeItem::DELETED));
475
 
        enabled = i.enabled() & v.enabled();
476
 
 
477
 
        // Get the flags from the pulled config
478
 
        if (ifp != NULL)
479
 
            pulled_flags = ifp->interface_flags();
480
 
        new_flags = pulled_flags;
481
 
 
482
 
        pulled_up = pulled_flags & IFF_UP;
483
 
        if (pulled_up && (deleted || !enabled))
484
 
            new_flags &= ~IFF_UP;
485
 
        if ( (!pulled_up) && enabled)
486
 
            new_flags |= IFF_UP;
487
 
 
488
 
        if ((! is_pulled_config_mirror()) && (new_flags == pulled_flags))
489
 
            break;              // XXX: nothing changed
490
 
 
491
 
        // Set the vif flags
492
 
        if (ifp != NULL) {
493
 
            const IfTreeVif* vifp = ifp->find_vif(v.vifname());
494
 
            if (vifp != NULL) {
495
 
                pulled_broadcast = vifp->broadcast();
496
 
                pulled_loopback = vifp->loopback();
497
 
                pulled_point_to_point = vifp->point_to_point();
498
 
                pulled_multicast = vifp->multicast();
499
 
            }
500
 
        }
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",
 
382
                             error_msg.c_str());
 
383
    }
 
384
 
 
385
    if (! error_msg.empty()) {
 
386
        error_reporter.config_error(error_msg);
 
387
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
388
        return;
 
389
    }
 
390
}
 
391
 
 
392
void
 
393
IfConfigSet::push_interface_begin(const IfTreeInterface*        pulled_ifp,
 
394
                                  IfTreeInterface&              config_iface)
 
395
{
 
396
    string error_msg;
 
397
    IfConfigErrorReporterBase& error_reporter =
 
398
        ifconfig().ifconfig_error_reporter();
 
399
 
 
400
    // Reset the flip flag for this interface
 
401
    config_iface.set_flipped(false);
 
402
 
 
403
    if ((pulled_ifp == NULL) && config_iface.is_marked(IfTreeItem::DELETED)) {
 
404
        // Nothing to do: the interface has been deleted from the system
 
405
        return;
 
406
    }
 
407
 
 
408
    // Copy some of the state from the pulled configuration
 
409
    copy_interface_state(pulled_ifp, config_iface);
 
410
 
 
411
    //
 
412
    // Begin the interface configuration
 
413
    //
 
414
    if (config_interface_begin(pulled_ifp, config_iface, error_msg)
 
415
        != XORP_OK) {
 
416
        error_msg = c_format("Failed to begin interface configuration: %s",
 
417
                             error_msg.c_str());
 
418
    }
 
419
 
 
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());
 
423
        return;
 
424
    }
 
425
}
 
426
 
 
427
void
 
428
IfConfigSet::push_interface_end(const IfTreeInterface*  pulled_ifp,
 
429
                                IfTreeInterface&        config_iface)
 
430
{
 
431
    string error_msg;
 
432
    IfConfigErrorReporterBase& error_reporter =
 
433
        ifconfig().ifconfig_error_reporter();
 
434
 
 
435
    //
 
436
    // End the interface configuration
 
437
    //
 
438
    if (config_interface_end(pulled_ifp, config_iface, error_msg)
 
439
        != XORP_OK) {
 
440
        error_msg = c_format("Failed to end interface configuration: %s",
 
441
                             error_msg.c_str());
 
442
    }
 
443
 
 
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());
 
447
        return;
 
448
    }
 
449
}
 
450
 
 
451
void
 
452
IfConfigSet::push_vif_creation(const IfTreeInterface*   pulled_ifp,
 
453
                               const IfTreeVif*         pulled_vifp,
 
454
                               IfTreeInterface&         config_iface,
 
455
                               IfTreeVif&               config_vif)
 
456
{
 
457
    string error_msg;
 
458
    IfConfigErrorReporterBase& error_reporter =
 
459
        ifconfig().ifconfig_error_reporter();
 
460
 
 
461
    if ((pulled_vifp == NULL) && config_vif.is_marked(IfTreeItem::DELETED)) {
 
462
        // Nothing to do: the vif has been deleted from the system
 
463
        return;
 
464
    }
 
465
 
 
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);
 
469
 
 
470
    //
 
471
    // Configure VLAN vif
 
472
    //
 
473
    if (config_vif.is_vlan()) {
 
474
        IfConfigVlanSet* ifconfig_vlan_set;
 
475
        bool is_add = true;
 
476
 
 
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());
 
484
            goto done;
 
485
        }
 
486
 
 
487
        if (config_vif.state() == IfTreeItem::DELETED)
 
488
            is_add = false;
 
489
 
 
490
        //
 
491
        // Push the VLAN configuration: either add/update or delete it.
 
492
        //
 
493
        if (is_add) {
 
494
            //
 
495
            // Add/update the VLAN
 
496
            //
 
497
            if (ifconfig_vlan_set->config_add_vlan(pulled_ifp,
 
498
                                                   pulled_vifp,
 
499
                                                   config_iface,
 
500
                                                   config_vif,
 
501
                                                   error_msg)
 
502
                != XORP_OK) {
 
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
                                     error_msg.c_str());
 
508
            }
506
509
        } else {
507
 
            new_broadcast = v.broadcast();
508
 
            new_loopback = v.loopback();
509
 
            new_point_to_point = v.point_to_point();
510
 
            new_multicast = v.multicast();
 
510
            //
 
511
            // Delete the VLAN
 
512
            //
 
513
            if (ifconfig_vlan_set->config_delete_vlan(pulled_ifp,
 
514
                                                      pulled_vifp,
 
515
                                                      config_iface,
 
516
                                                      config_vif,
 
517
                                                      error_msg)
 
518
                != XORP_OK) {
 
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(),
 
523
                                     error_msg.c_str());
 
524
            }
511
525
        }
512
 
 
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)
517
 
            < 0) {
518
 
            error_msg = c_format("Failed to configure vif: %s",
 
526
        goto done;
 
527
    }
 
528
 
 
529
done:
 
530
    if (! error_msg.empty()) {
 
531
        error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
 
532
                                 error_msg);
 
533
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
534
        return;
 
535
    }
 
536
}
 
537
 
 
538
void
 
539
IfConfigSet::push_vif_begin(const IfTreeInterface*      pulled_ifp,
 
540
                            const IfTreeVif*            pulled_vifp,
 
541
                            IfTreeInterface&            config_iface,
 
542
                            IfTreeVif&                  config_vif)
 
543
{
 
544
    string error_msg;
 
545
    IfConfigErrorReporterBase& error_reporter =
 
546
        ifconfig().ifconfig_error_reporter();
 
547
 
 
548
    if ((pulled_vifp == NULL) && config_vif.is_marked(IfTreeItem::DELETED)) {
 
549
        // Nothing to do: the vif has been deleted from the system
 
550
        return;
 
551
    }
 
552
 
 
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);
 
556
 
 
557
    //
 
558
    // Begin the vif configuration
 
559
    //
 
560
    if (config_vif_begin(pulled_ifp, pulled_vifp, config_iface, config_vif,
 
561
                         error_msg)
 
562
        != XORP_OK) {
 
563
        error_msg = c_format("Failed to begin vif configuration: %s",
 
564
                             error_msg.c_str());
 
565
    }
 
566
 
 
567
    if (! error_msg.empty()) {
 
568
        error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
 
569
                                 error_msg);
 
570
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
571
        return;
 
572
    }
 
573
}
 
574
 
 
575
void
 
576
IfConfigSet::push_vif_end(const IfTreeInterface*        pulled_ifp,
 
577
                          const IfTreeVif*              pulled_vifp,
 
578
                          IfTreeInterface&              config_iface,
 
579
                          IfTreeVif&                    config_vif)
 
580
{
 
581
    string error_msg;
 
582
    IfConfigErrorReporterBase& error_reporter =
 
583
        ifconfig().ifconfig_error_reporter();
 
584
 
 
585
    //
 
586
    // End the vif configuration
 
587
    //
 
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",
 
591
                             error_msg.c_str());
 
592
    }
 
593
 
 
594
    if (! error_msg.empty()) {
 
595
        error_reporter.vif_error(config_iface.ifname(), config_vif.vifname(),
 
596
                                 error_msg);
 
597
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
 
598
        return;
 
599
    }
 
600
}
 
601
 
 
602
void
 
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)
 
609
{
 
610
    string error_msg;
 
611
    IfConfigErrorReporterBase& error_reporter =
 
612
        ifconfig().ifconfig_error_reporter();
 
613
    bool is_add = true;
 
614
 
 
615
    if (! fea_data_plane_manager().have_ipv4()) {
 
616
        error_msg = "IPv4 is not supported";
 
617
        goto done;
 
618
    }
 
619
 
 
620
    if (config_addr.is_marked(IfTreeItem::DELETED)
 
621
        || (! config_addr.enabled())) {
 
622
        // XXX: Disabling an address is same as deleting it
 
623
        is_add = false;
 
624
    }
 
625
 
 
626
    //
 
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.
 
630
    //
 
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);
 
639
    }
 
640
 
 
641
    //
 
642
    // Push the address configuration: either add/update or delete it.
 
643
    //
 
644
    if (is_add) {
 
645
        //
 
646
        // Add/update the address
 
647
        //
 
648
        if (config_add_address(pulled_ifp, pulled_vifp, pulled_addrp,
 
649
                               config_iface, config_vif, config_addr,
 
650
                               error_msg)
 
651
            != XORP_OK) {
 
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(),
521
 
                                                           v.vifname(),
522
 
                                                           error_msg);
523
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
524
 
            return;
525
654
        }
526
 
        break;
527
 
    } while (false);
528
 
}
529
 
 
530
 
void
531
 
IfConfigSet::push_vif_address(const IfTreeInterface&    i,
532
 
                              const IfTreeVif&          v,
533
 
                              const IfTreeAddr4&        a)
534
 
{
535
 
    string error_msg;
536
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
537
 
    XLOG_ASSERT(if_index > 0);
538
 
 
539
 
    bool enabled = (i.enabled() & v.enabled() & a.enabled());
540
 
 
541
 
    debug_msg("Pushing %s\n", a.str().c_str());
542
 
 
543
 
    if (a.is_marked(IfTreeItem::CREATED) && enabled == false) {
544
 
        //
545
 
        // A created but disabled address will not appear in the live
546
 
        // config that was read from the kernel.
547
 
        //
548
 
        IfTreeVif* vifp;
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);
554
 
        *ap = a;
555
 
        return;
556
 
    }
557
 
 
558
 
    bool deleted = (i.is_marked(IfTreeItem::DELETED) |
559
 
                    v.is_marked(IfTreeItem::DELETED) |
560
 
                    a.is_marked(IfTreeItem::DELETED));
561
 
 
562
 
    if (deleted || !enabled) {
563
 
        if (delete_vif_address(i.ifname(), v.vifname(), if_index,
564
 
                               IPvX(a.addr()), a.prefix_len(), error_msg)
565
 
            < 0) {
 
655
    } else {
 
656
        //
 
657
        // Delete the address
 
658
        //
 
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,
 
663
                                  error_msg)
 
664
            != XORP_OK) {
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(),
569
 
                                                               v.vifname(),
570
 
                                                               a.addr(),
571
 
                                                               error_msg);
572
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
573
667
        }
 
668
    }
 
669
 
 
670
 done:
 
671
    if (! error_msg.empty()) {
 
672
        error_reporter.vifaddr_error(config_iface.ifname(),
 
673
                                     config_vif.vifname(),
 
674
                                     config_addr.addr(),
 
675
                                     error_msg);
 
676
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
574
677
        return;
575
678
    }
576
 
 
577
 
    //
578
 
    // Set the address
579
 
    //
580
 
    do {
581
 
        IPv4 oaddr(IPv4::ZERO());
582
 
        if (a.broadcast())
583
 
            oaddr = a.bcast();
584
 
        else if (a.point_to_point())
585
 
            oaddr = a.endpoint();
586
 
        
587
 
        uint32_t prefix_len = a.prefix_len();
588
 
 
589
 
        const IfTreeAddr4* ap = NULL;
590
 
        const IfTreeVif* vifp = ifconfig().pulled_config().find_vif(i.ifname(),
591
 
                                                                    v.vifname());
592
 
        if (vifp != NULL)
593
 
            ap = vifp->find_addr(a.addr());
594
 
 
595
 
        // Test if a new address
596
 
        bool new_address = true;
597
 
        do {
598
 
            if (is_pulled_config_mirror())
599
 
                break;
600
 
            if (ap == NULL)
601
 
                break;
602
 
            if (ap->addr() != a.addr())
603
 
                break;
604
 
            if (a.broadcast() && (ap->bcast() != a.bcast()))
605
 
                break;
606
 
            if (a.point_to_point() && (ap->endpoint() != a.endpoint()))
607
 
                break;
608
 
            if (ap->prefix_len() != prefix_len)
609
 
                break;
610
 
            new_address = false;
611
 
            break;
612
 
        } while (false);
613
 
        if (! new_address)
614
 
            break;              // Ignore: the address hasn't changed
615
 
 
616
 
        //
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.
620
 
        //
621
 
        bool is_broadcast = a.broadcast();
622
 
        if ((vifp != NULL)
623
 
            && (! (a.broadcast() || a.point_to_point()))
624
 
            && (prefix_len > 0)
625
 
            && vifp->broadcast()) {
626
 
            IPv4 mask = IPv4::make_prefix(prefix_len);
627
 
            oaddr = a.addr() | ~mask;
628
 
            is_broadcast = true;
629
 
        }
630
 
 
631
 
        //
632
 
        // Try to add the address.
633
 
        // If the address exists already (e.g., with different prefix length),
634
 
        // then delete it first.
635
 
        //
636
 
        if (ap != NULL) {
637
 
            delete_vif_address(i.ifname(), v.vifname(), if_index,
638
 
                               IPvX(a.addr()), ap->prefix_len(), error_msg);
639
 
        }
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)
643
 
            < 0) {
644
 
            error_msg = c_format("Failed to configure address: %s",
645
 
                                 error_msg.c_str());
646
 
            ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
647
 
                                                               v.vifname(),
648
 
                                                               a.addr(),
649
 
                                                               error_msg);
650
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
651
 
        }
652
 
        
653
 
        break;
654
 
    } while (false);
655
679
}
656
680
 
657
681
#ifdef HAVE_IPV6
658
682
void
659
 
IfConfigSet::push_vif_address(const IfTreeInterface&    i,
660
 
                              const IfTreeVif&          v,
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)
662
689
{
663
690
    string error_msg;
664
 
    uint32_t if_index = ifconfig().get_insert_ifindex(i.ifname());
665
 
    XLOG_ASSERT(if_index > 0);
666
 
 
667
 
    bool enabled = (i.enabled() & v.enabled() & a.enabled());
668
 
 
669
 
    debug_msg("Pushing %s\n", a.str().c_str());
670
 
 
671
 
    if (a.is_marked(IfTreeItem::CREATED) && enabled == false) {
672
 
        //
673
 
        // A created but disabled address will not appear in the live
674
 
        // config rippled up from the kernel via the routing socket
675
 
        //
676
 
        IfTreeVif* vifp;
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);
682
 
        *ap = a;
683
 
        return;
684
 
    }
685
 
 
686
 
    bool deleted = (i.is_marked(IfTreeItem::DELETED) |
687
 
                    v.is_marked(IfTreeItem::DELETED) |
688
 
                    a.is_marked(IfTreeItem::DELETED));
689
 
 
690
 
    if (deleted || !enabled) {
691
 
        if (delete_vif_address(i.ifname(), v.vifname(), if_index,
692
 
                               IPvX(a.addr()), a.prefix_len(), error_msg)
693
 
            < 0) {
 
691
    IfConfigErrorReporterBase& error_reporter =
 
692
        ifconfig().ifconfig_error_reporter();
 
693
    bool is_add = true;
 
694
 
 
695
    if (! fea_data_plane_manager().have_ipv6()) {
 
696
        error_msg = "IPv6 is not supported";
 
697
        goto done;
 
698
    }
 
699
 
 
700
    if (config_addr.is_marked(IfTreeItem::DELETED)
 
701
        || (! config_addr.enabled())) {
 
702
        // XXX: Disabling an address is same as deleting it
 
703
        is_add = false;
 
704
    }
 
705
 
 
706
    //
 
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.
 
709
    //
 
710
    if (config_addr.prefix_len() == 0)
 
711
        config_addr.set_prefix_len(64);
 
712
 
 
713
    //
 
714
    // Push the address configuration: either add/update or delete it.
 
715
    //
 
716
    if (is_add) {
 
717
        //
 
718
        // Add/update the address
 
719
        //
 
720
        if (config_add_address(pulled_ifp, pulled_vifp, pulled_addrp,
 
721
                               config_iface, config_vif, config_addr,
 
722
                               error_msg)
 
723
            != XORP_OK) {
 
724
            error_msg = c_format("Failed to configure address: %s",
 
725
                                 error_msg.c_str());
 
726
        }
 
727
    } else {
 
728
        //
 
729
        // Delete the address
 
730
        //
 
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,
 
735
                                  error_msg)
 
736
            != XORP_OK) {
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(),
697
 
                                                               v.vifname(),
698
 
                                                               a.addr(),
699
 
                                                               error_msg);
700
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
701
739
        }
 
740
    }
 
741
 
 
742
 done:
 
743
    if (! error_msg.empty()) {
 
744
        error_reporter.vifaddr_error(config_iface.ifname(),
 
745
                                     config_vif.vifname(),
 
746
                                     config_addr.addr(),
 
747
                                     error_msg);
 
748
        XLOG_ERROR("%s", error_reporter.last_error().c_str());
702
749
        return;
703
750
    }
704
 
 
705
 
    //
706
 
    // Set the address
707
 
    //
708
 
    do {
709
 
        IPv6 oaddr(IPv6::ZERO());
710
 
        if (a.point_to_point())
711
 
            oaddr = a.endpoint();
712
 
        
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();
716
 
        if (prefix_len == 0)
717
 
            prefix_len = 64;
718
 
 
719
 
        const IfTreeAddr6* ap = ifconfig().pulled_config().find_addr(
720
 
            i.ifname(), v.vifname(), a.addr());
721
 
 
722
 
        // Test if a new address
723
 
        bool new_address = true;
724
 
        do {
725
 
            if (is_pulled_config_mirror())
726
 
                break;
727
 
            if (ap == NULL)
728
 
                break;
729
 
            if (ap->addr() != a.addr())
730
 
                break;
731
 
            if (a.point_to_point() && (ap->endpoint() != a.endpoint()))
732
 
                break;
733
 
            if (ap->prefix_len() != prefix_len)
734
 
                break;
735
 
            new_address = false;
736
 
            break;
737
 
        } while (false);
738
 
        if (! new_address)
739
 
            break;              // Ignore: the address hasn't changed
740
 
 
741
 
        //
742
 
        // Try to add the address.
743
 
        // If the address exists already (e.g., with different prefix length),
744
 
        // then delete it first.
745
 
        //
746
 
        if (ap != NULL) {
747
 
            delete_vif_address(i.ifname(), v.vifname(), if_index,
748
 
                               IPvX(a.addr()), ap->prefix_len(), error_msg);
749
 
        }
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)
753
 
            < 0) {
754
 
            error_msg = c_format("Failed to configure address: %s",
755
 
                                 error_msg.c_str());
756
 
            ifconfig().ifconfig_error_reporter().vifaddr_error(i.ifname(),
757
 
                                                               v.vifname(),
758
 
                                                               a.addr(),
759
 
                                                               error_msg);
760
 
            XLOG_ERROR("%s", ifconfig().ifconfig_error_reporter().last_error().c_str());
761
 
        }
762
 
        
763
 
        break;
764
 
    } while (false);
765
751
}
766
752
#endif // HAVE_IPV6