summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jakma <paul.jakma@sun.com>2007-04-10 19:30:20 +0000
committerPaul Jakma <paul.jakma@sun.com>2007-04-10 19:30:20 +0000
commitd9a18f1113b915dd0d2a4883a9149f06dd61352e (patch)
tree0d81d8b3d83b9023ccf396bb1e80085c1dbcdf55
parentd9d00a689ea636af58f89cb62291245bb2a1bc7d (diff)
[zebra] Retain configured IPv4 address upon removal by kernel
2007-04-08 Paul Jakma <paul.jakma@sun.com> * interface.c: (if_delete_update) Address removal triggered by kernel shouldn't remove configured IPv4 address from connected list.
-rw-r--r--zebra/ChangeLog3
-rw-r--r--zebra/interface.c35
2 files changed, 24 insertions, 14 deletions
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 3cd30bd5..54550467 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -3,6 +3,9 @@
* {ioctl,kernel}_null.c: Install of IP address should
reflect back to zebra via kernel_address_add..., makes
testzebra more useful.
+ * interface.c: (if_delete_update) Address removal triggered
+ by kernel shouldn't remove configured IPv4 address from connected
+ list.
2007-04-07 Paul Jakma <paul.jakma@sun.com>
diff --git a/zebra/interface.c b/zebra/interface.c
index ceee0e2b..1c8d3a48 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -372,15 +372,10 @@ if_add_update (struct interface *ifp)
void
if_delete_update (struct interface *ifp)
{
- struct listnode *node;
- struct listnode *next;
- struct listnode *first;
- struct listnode *last;
struct connected *ifc;
struct prefix *p;
struct route_node *rn;
struct zebra_if *zebra_if;
- struct list *addr_list;
zebra_if = ifp->info;
@@ -401,7 +396,9 @@ if_delete_update (struct interface *ifp)
/* Delete connected routes from the kernel. */
if (ifp->connected)
{
- last = NULL;
+ struct listnode *node;
+ struct listnode *last = NULL;
+
while ((node = (last ? last->next : listhead (ifp->connected))))
{
ifc = listgetdata (node);
@@ -410,21 +407,26 @@ if_delete_update (struct interface *ifp)
if (p->family == AF_INET
&& (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
{
+ struct listnode *anode;
+ struct listnode *next;
+ struct listnode *first;
+ struct list *addr_list;
+
route_unlock_node (rn);
addr_list = (struct list *) rn->info;
/* Remove addresses, secondaries first. */
first = listhead (addr_list);
- for (node = first->next; node || first; node = next)
+ for (anode = first->next; anode || first; anode = next)
{
- if (! node)
+ if (!anode)
{
- node = first;
+ anode = first;
first = NULL;
}
- next = node->next;
+ next = anode->next;
- ifc = listgetdata (node);
+ ifc = listgetdata (anode);
p = ifc->address;
connected_down_ipv4 (ifp, ifc);
@@ -434,12 +436,17 @@ if_delete_update (struct interface *ifp)
UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
/* Remove from subnet chain. */
- list_delete_node (addr_list, node);
+ list_delete_node (addr_list, anode);
route_unlock_node (rn);
/* Remove from interface address list (unconditionally). */
- listnode_delete (ifp->connected, ifc);
- connected_free (ifc);
+ if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
+ {
+ listnode_delete (ifp->connected, ifc);
+ connected_free (ifc);
+ }
+ else
+ last = node;
}
/* Free chain list and respective route node. */