diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/ChangeLog | 3 | ||||
-rw-r--r-- | zebra/interface.c | 35 |
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. */ |