/* Handle changes to addresses and send the neccesary announcements * to clients. */ static void connected_update(struct interface *ifp, struct connected *ifc) { struct connected *current; /* Check same connected route. */ if ((current = connected_check(ifp, (struct prefix *)ifc->address))) { if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* Avoid spurious withdraws, this might be just the kernel 'reflecting' * back an address we have already added. */ if (connected_same(current, ifc)) { /* nothing to do */ connected_free(ifc); return; } /* Clear the configured flag on the old ifc, so it will be freed by * connected withdraw. */ UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); connected_withdraw(current); /* implicit withdraw - freebsd does this */ } /* If the connected is new or has changed, announce it, if it is usable */ if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) connected_announce(ifp, ifc); }
/* Handle implicit withdrawals of addresses, where a system ADDs an address * to an interface which already has the same address configured. * * Returns the struct connected which must be announced to clients, * or NULL if nothing to do. */ static struct connected * connected_implicit_withdraw (struct interface *ifp, struct connected *ifc) { struct connected *current; /* Check same connected route. */ if ((current = connected_check (ifp, (struct prefix *) ifc->address))) { if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* Avoid spurious withdraws, this might be just the kernel 'reflecting' * back an address we have already added. */ if (connected_same (current, ifc) && CHECK_FLAG(current->conf, ZEBRA_IFC_REAL)) { /* nothing to do */ connected_free (ifc); return NULL; } UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); if(CHECK_FLAG (current->flags, ZEBRA_IFA_EXPIRES)) { SET_FLAG (ifc->flags, ZEBRA_IFA_EXPIRES); } ifc->expires = current->expires; // HSA - need to copy over address expiration info if we are to explicitly withdraw a route connected_withdraw (current); /* implicit withdraw - freebsd does this */ } return ifc; }
/* Handle implicit withdrawals of addresses, where a system ADDs an address * to an interface which already has the same address configured. * * Returns the struct connected which must be announced to clients, * or NULL if nothing to do. */ static struct connected * connected_implicit_withdraw (struct interface *ifp, struct connected *ifc) { struct connected *current; /* Check same connected route. */ if ((current = connected_check (ifp, (struct prefix *) ifc->address))) { if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); if (CHECK_FLAG (current->ipv6_config, RTMD_IPV6_ADDR_CONFIG)) SET_FLAG (ifc->ipv6_config, RTMD_IPV6_ADDR_CONFIG); /* Avoid spurious withdraws, this might be just the kernel 'reflecting' * back an address we have already added. */ if (connected_same (current, ifc)) { /* nothing to do */ connected_free (ifc); return NULL; } UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); UNSET_FLAG(current->ipv6_config, RTMD_IPV6_ADDR_CONFIG); connected_withdraw (current); /* implicit withdraw - freebsd does this */ } return ifc; }
void connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, u_char prefixlen, struct in6_addr *broad) { struct prefix_ipv6 p; struct connected *ifc; memset (&p, 0, sizeof (struct prefix_ipv6)); p.family = AF_INET6; memcpy (&p.prefix, address, sizeof (struct in6_addr)); p.prefixlen = prefixlen; ifc = connected_check (ifp, (struct prefix *) &p); if (! ifc) return; connected_withdraw (ifc); }
/* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad) { struct prefix_ipv4 p; struct connected *ifc; memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefix = *addr; p.prefixlen = prefixlen; ifc = connected_check (ifp, (struct prefix *) &p); if (! ifc) return; connected_withdraw (ifc); }