diff options
author | Paul Jakma <paul.jakma@sun.com> | 2007-04-10 19:30:20 +0000 |
---|---|---|
committer | Paul Jakma <paul.jakma@sun.com> | 2007-04-10 19:30:20 +0000 |
commit | d9a18f1113b915dd0d2a4883a9149f06dd61352e (patch) | |
tree | 0d81d8b3d83b9023ccf396bb1e80085c1dbcdf55 /zebra/interface.c | |
parent | d9d00a689ea636af58f89cb62291245bb2a1bc7d (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.
Diffstat (limited to 'zebra/interface.c')
-rw-r--r-- | zebra/interface.c | 35 |
1 files changed, 21 insertions, 14 deletions
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. */ |