diff --git a/lib/prefix.h b/lib/prefix.h index a27f46ba0a..823aed30c3 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -315,7 +315,9 @@ extern void prefix_ipv4_free(struct prefix_ipv4 *); extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *); extern void apply_mask_ipv4(struct prefix_ipv4 *); -#define PREFIX_COPY_IPV4(DST, SRC) \ +#define PREFIX_COPY(DST, SRC) \ + *((struct prefix *)(DST)) = *((const struct prefix *)(SRC)) +#define PREFIX_COPY_IPV4(DST, SRC) \ *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC)); extern int prefix_ipv4_any(const struct prefix_ipv4 *); diff --git a/zebra/connected.c b/zebra/connected.c index 7176ce70bd..77a560c6bd 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -54,10 +54,7 @@ static void connected_withdraw(struct connected *ifc) if (ifc->address->family == AF_INET) if_subnet_delete(ifc->ifp, ifc); - if (ifc->address->family == AF_INET) - connected_down_ipv4(ifc->ifp, ifc); - else - connected_down_ipv6(ifc->ifp, ifc); + connected_down(ifc->ifp, ifc); UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL); } @@ -92,10 +89,7 @@ static void connected_announce(struct interface *ifp, struct connected *ifc) zebra_interface_address_add_update(ifp, ifc); if (if_is_operative(ifp)) { - if (ifc->address->family == AF_INET) - connected_up_ipv4(ifp, ifc); - else - connected_up_ipv6(ifp, ifc); + connected_up(ifp, ifc); } } @@ -204,8 +198,9 @@ static void connected_update(struct interface *ifp, struct connected *ifc) } /* Called from if_up(). */ -void connected_up_ipv4(struct interface *ifp, struct connected *ifc) +void connected_up(struct interface *ifp, struct connected *ifc) { + afi_t afi; struct prefix p; struct nexthop nh = { .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, @@ -214,34 +209,59 @@ void connected_up_ipv4(struct interface *ifp, struct connected *ifc) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; - PREFIX_COPY_IPV4((struct prefix_ipv4 *)&p, CONNECTED_PREFIX(ifc)); + PREFIX_COPY(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask(&p); - /* In case of connected address is 0.0.0.0/0 we treat it tunnel - address. */ - if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) + afi = family2afi(p.family); + + switch (afi) { + case AFI_IP: + /* + * In case of connected address is 0.0.0.0/0 we treat it tunnel + * address. + */ + if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) + return; + break; + case AFI_IP6: +#ifndef LINUX + /* XXX: It is already done by rib_bogus_ipv6 within rib_add */ + if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) + return; +#endif + break; + default: + zlog_warn("Received unknown AFI: %s", afi2str(afi)); return; + break; + } - rib_add(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, + rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); - rib_add(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, + rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling RIB processing", - ifp->vrf_id, ifp->name); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s address %s add/up, scheduling RIB processing", + ifp->vrf_id, ifp->name, + prefix2str(&p, buf, sizeof(buf))); + } rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); /* Schedule LSP forwarding entries for processing, if appropriate. */ if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); + if (IS_ZEBRA_DEBUG_MPLS) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s IP %s address add/up, scheduling MPLS processing", + ifp->vrf_id, ifp->name, + prefix2str(&p, buf, sizeof(buf))); + } mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); } } @@ -335,8 +355,9 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, connected_update(ifp, ifc); } -void connected_down_ipv4(struct interface *ifp, struct connected *ifc) +void connected_down(struct interface *ifp, struct connected *ifc) { + afi_t afi; struct prefix p; struct nexthop nh = { .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, @@ -345,37 +366,92 @@ void connected_down_ipv4(struct interface *ifp, struct connected *ifc) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) return; - PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); + PREFIX_COPY(&p, CONNECTED_PREFIX(ifc)); /* Apply mask to the network. */ apply_mask(&p); - /* In case of connected address is 0.0.0.0/0 we treat it tunnel - address. */ - if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) - return; + afi = family2afi(p.family); - /* Same logic as for connected_up_ipv4(): push the changes into the - * head. */ - rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, + switch (afi) { + case AFI_IP: + /* + * In case of connected address is 0.0.0.0/0 we treat it tunnel + * address. + */ + if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) + return; + break; + case AFI_IP6: + if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) + return; + break; + default: + zlog_info("Unknown AFI: %s", afi2str(afi)); + break; + } + + /* + * Same logic as for connected_up(): push the changes into the + * head. + */ + rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, 0, 0); - rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, + rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, 0, 0); - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv4 address down, scheduling RIB processing", - ifp->vrf_id, ifp->name); + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s IP %s address down, scheduling RIB processing", + ifp->vrf_id, ifp->name, + prefix2str(&p, buf, sizeof(buf))); + } rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); /* Schedule LSP forwarding entries for processing, if appropriate. */ if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); + if (IS_ZEBRA_DEBUG_MPLS) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s IP %s address down, scheduling MPLS processing", + ifp->vrf_id, ifp->name, + prefix2str(&p, buf, sizeof(buf))); + } + mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); + } +} + +static void connected_delete_helper(struct connected *ifc, struct prefix *p) +{ + struct interface *ifp; + + if (!ifc) + return; + ifp = ifc->ifp; + + connected_withdraw(ifc); + + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s IP %s address del, scheduling RIB processing", + ifp->vrf_id, ifp->name, + prefix2str(p, buf, sizeof(buf))); + } + rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); + + /* Schedule LSP forwarding entries for processing, if appropriate. */ + if (ifp->vrf_id == VRF_DEFAULT) { + if (IS_ZEBRA_DEBUG_MPLS) { + char buf[PREFIX_STRLEN]; + + zlog_debug("%u: IF %s IP %s address delete, scheduling MPLS processing", + ifp->vrf_id, ifp->name, + prefix2str(p, buf, sizeof(buf))); + } mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); } } @@ -385,86 +461,25 @@ void connected_delete_ipv4(struct interface *ifp, int flags, struct in_addr *addr, u_char prefixlen, struct in_addr *broad) { - struct prefix_ipv4 p, d; + struct prefix p, d; struct connected *ifc; - memset(&p, 0, sizeof(struct prefix_ipv4)); + memset(&p, 0, sizeof(struct prefix)); p.family = AF_INET; - p.prefix = *addr; + p.u.prefix4 = *addr; p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN : prefixlen; if (broad) { - memset(&d, 0, sizeof(struct prefix_ipv4)); + memset(&d, 0, sizeof(struct prefix)); d.family = AF_INET; - d.prefix = *broad; + d.u.prefix4 = *broad; d.prefixlen = prefixlen; - ifc = connected_check_ptp(ifp, (struct prefix *)&p, - (struct prefix *)&d); + ifc = connected_check_ptp(ifp, &p, &d); } else - ifc = connected_check_ptp(ifp, (struct prefix *)&p, NULL); + ifc = connected_check_ptp(ifp, &p, NULL); - if (!ifc) - return; - - connected_withdraw(ifc); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv4 address del, scheduling RIB processing", - ifp->vrf_id, ifp->name); - - rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - - /* Schedule LSP forwarding entries for processing, if appropriate. */ - if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); - mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); - } -} - -void connected_up_ipv6(struct interface *ifp, struct connected *ifc) -{ - struct prefix p; - struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, - }; - - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) - return; - - PREFIX_COPY_IPV6((struct prefix_ipv6 *)&p, CONNECTED_PREFIX(ifc)); - - /* Apply mask to the network. */ - apply_mask(&p); - -#ifndef LINUX - /* XXX: It is already done by rib_bogus_ipv6 within rib_add */ - if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) - return; -#endif - - rib_add(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv6 address down, scheduling RIB processing", - ifp->vrf_id, ifp->name); - - rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - - /* Schedule LSP forwarding entries for processing, if appropriate. */ - if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); - mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); - } + connected_delete_helper(ifc, &p); } /* Add connected IPv6 route to the interface. */ @@ -509,75 +524,20 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, connected_update(ifp, ifc); } -void connected_down_ipv6(struct interface *ifp, struct connected *ifc) -{ - struct prefix p; - struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, - }; - - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) - return; - - PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); - - apply_mask(&p); - - if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) - return; - - rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, &nh, 0, 0); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv6 address down, scheduling RIB processing", - ifp->vrf_id, ifp->name); - - rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - - /* Schedule LSP forwarding entries for processing, if appropriate. */ - if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); - mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); - } -} - void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, u_char prefixlen) { - struct prefix_ipv6 p; + struct prefix p; struct connected *ifc; - memset(&p, 0, sizeof(struct prefix_ipv6)); + memset(&p, 0, sizeof(struct prefix)); p.family = AF_INET6; - memcpy(&p.prefix, address, sizeof(struct in6_addr)); + memcpy(&p.u.prefix6, address, sizeof(struct in6_addr)); p.prefixlen = prefixlen; - ifc = connected_check(ifp, (struct prefix *)&p); - if (!ifc) - return; + ifc = connected_check(ifp, &p); - connected_withdraw(ifc); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - zlog_debug( - "%u: IF %s IPv6 address del, scheduling RIB processing", - ifp->vrf_id, ifp->name); - - rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - - /* Schedule LSP forwarding entries for processing, if appropriate. */ - if (ifp->vrf_id == VRF_DEFAULT) { - if (IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "%u: IF %s IPv4 address add/up, scheduling MPLS processing", - ifp->vrf_id, ifp->name); - mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); - } + connected_delete_helper(ifc, &p); } int connected_is_unnumbered(struct interface *ifp) diff --git a/zebra/connected.h b/zebra/connected.h index c6da36956d..d10a092984 100644 --- a/zebra/connected.h +++ b/zebra/connected.h @@ -38,8 +38,8 @@ extern void connected_delete_ipv4(struct interface *ifp, int flags, extern void connected_delete_ipv4_unnumbered(struct connected *ifc); -extern void connected_up_ipv4(struct interface *, struct connected *); -extern void connected_down_ipv4(struct interface *, struct connected *); +extern void connected_up(struct interface *ifp, struct connected *ifc); +extern void connected_down(struct interface *ifp, struct connected *ifc); extern void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *address, u_char prefixlen, @@ -47,9 +47,6 @@ extern void connected_add_ipv6(struct interface *ifp, int flags, extern void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, u_char prefixlen); -extern void connected_up_ipv6(struct interface *, struct connected *); -extern void connected_down_ipv6(struct interface *ifp, struct connected *); - extern int connected_is_unnumbered(struct interface *); #endif /*_ZEBRA_CONNECTED_H */ diff --git a/zebra/interface.c b/zebra/interface.c index 5668590fdc..5d02259159 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -527,18 +527,13 @@ static void if_install_connected(struct interface *ifp) struct listnode *node; struct listnode *next; struct connected *ifc; - struct prefix *p; if (ifp->connected) { for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) { if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) zebra_interface_address_add_update(ifp, ifc); - p = ifc->address; - if (p->family == AF_INET) - connected_up_ipv4(ifp, ifc); - else if (p->family == AF_INET6) - connected_up_ipv6(ifp, ifc); + connected_up(ifp, ifc); } } } @@ -549,17 +544,11 @@ static void if_uninstall_connected(struct interface *ifp) struct listnode *node; struct listnode *next; struct connected *ifc; - struct prefix *p; if (ifp->connected) { for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) { - p = ifc->address; zebra_interface_address_delete_update(ifp, ifc); - - if (p->family == AF_INET) - connected_down_ipv4(ifp, ifc); - else if (p->family == AF_INET6) - connected_down_ipv6(ifp, ifc); + connected_down(ifp, ifc); } } } @@ -608,7 +597,7 @@ static void if_delete_connected(struct interface *ifp) next = anode->next; ifc = listgetdata(anode); - connected_down_ipv4(ifp, ifc); + connected_down(ifp, ifc); /* XXX: We have to send notifications * here explicitly, because we destroy @@ -642,7 +631,7 @@ static void if_delete_connected(struct interface *ifp) rn->info = NULL; route_unlock_node(rn); } else if (cp.family == AF_INET6) { - connected_down_ipv6(ifp, ifc); + connected_down(ifp, ifc); zebra_interface_address_delete_update(ifp, ifc);