From: Donald Sharp Date: Fri, 22 Jun 2018 01:49:03 +0000 (-0400) Subject: lib, zebra: Allow protocols to use Distance as part of RR semantics X-Git-Tag: frr-6.1-dev~86^2~5 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=40ecd8e46da41b5032707bd4fcbb8cc8890ded61;p=matthieu%2Ffrr.git lib, zebra: Allow protocols to use Distance as part of RR semantics Allow protocols to specify to zebra that they would like zebra to use the distance passed down as part of determine sameness for Route Replace semantics. This will be used by the static daemon to allow it to have backup static routes with greater distances. Signed-off-by: Donald Sharp --- diff --git a/lib/zebra.h b/lib/zebra.h index 98428eaab2..edae75207f 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -414,6 +414,7 @@ extern const char *zserv_command_string(unsigned int command); #define ZEBRA_FLAG_SCOPE_LINK 0x100 #define ZEBRA_FLAG_FIB_OVERRIDE 0x200 #define ZEBRA_FLAG_EVPN_ROUTE 0x400 +#define ZEBRA_FLAG_RR_USE_DISTANCE 0x800 /* ZEBRA_FLAG_BLACKHOLE was 0x04 */ /* ZEBRA_FLAG_REJECT was 0x80 */ diff --git a/zebra/connected.c b/zebra/connected.c index 8869d34fd6..57bfcc4d16 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -403,10 +403,10 @@ void connected_down(struct interface *ifp, struct connected *ifc) * head. */ rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, 0, 0, false); + &p, NULL, &nh, 0, 0, 0, false); rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, 0, 0, false); + &p, NULL, &nh, 0, 0, 0, false); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char buf[PREFIX_STRLEN]; diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index b85c4748c4..71d709e72d 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1043,7 +1043,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0, true); + NULL, 0, 0, 0, true); if (!nh.type) { nh.type = NEXTHOP_TYPE_IPV4; @@ -1058,7 +1058,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, true); + &nh, 0, 0, 0, true); } if (dest.sa.sa_family == AF_INET6) { /* One day we might have a debug section here like one in the @@ -1089,7 +1089,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0, true); + NULL, 0, 0, 0, true); if (!nh.type) { nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX @@ -1106,7 +1106,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, true); + &nh, 0, 0, 0, true); } } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 69c0ebb7ec..e3101fbe72 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -597,7 +597,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, re->ng.nexthop, - zebrad.rtm_table_default, re->metric, false); + zebrad.rtm_table_default, re->metric, re->distance, false); return 0; } diff --git a/zebra/rib.h b/zebra/rib.h index 439327aa48..a37b2bf221 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -311,7 +311,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, unsigned short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, - uint32_t table_id, uint32_t metric, bool fromkernel); + uint32_t table_id, uint32_t metric, uint8_t distance, + bool fromkernel); extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id, union g_addr *addr, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5facfa5faa..918152aa6e 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -644,12 +644,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, if (gate) memcpy(&nh.gate, gate, sz); rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, - &p, &src_p, &nh, table, metric, true); + &p, &src_p, &nh, table, metric, distance, true); } else { /* XXX: need to compare the entire list of nexthops * here for NLM_F_APPEND stupidity */ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, - &p, &src_p, NULL, table, metric, true); + &p, &src_p, NULL, table, metric, distance, true); } } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index b41cb812cb..ad574d7e8b 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1565,7 +1565,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS) rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance, api.flags, &api.prefix, src_p, NULL, table_id, api.metric, - false); + api.distance, false); /* Stats */ switch (api.prefix.family) { @@ -1767,7 +1767,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS) table_id = zvrf->table_id; rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, NULL, NULL, table_id, 0, false); + api.flags, &p, NULL, NULL, table_id, 0, 0, false); client->v4_route_del_cnt++; stream_failure: @@ -2191,7 +2191,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS) src_pp = NULL; rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, src_pp, NULL, client->rtm_table, 0, false); + api.flags, &p, src_pp, NULL, client->rtm_table, 0, 0, false); client->v6_route_del_cnt++; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 33eebfe99e..18bd6b6cbe 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2321,7 +2321,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, { struct route_table *table; struct route_node *rn; - struct route_entry *same; + struct route_entry *same = NULL; struct nexthop *nexthop; int ret = 0; @@ -2355,8 +2355,13 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, /* Lookup route node.*/ rn = srcdest_rnode_get(table, p, src_p); - /* If same type of route are installed, treat it as a implicit - withdraw. */ + zlog_debug("Distance: %d", re->distance); + /* + * If same type of route are installed, treat it as a implicit + * withdraw. + * If the user has specified the No route replace semantics + * for the install don't do a route replace. + */ RNODE_FOREACH_RE (rn, same) { if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) continue; @@ -2368,14 +2373,21 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, if (same->type == ZEBRA_ROUTE_KERNEL && same->metric != re->metric) continue; + + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) && + same->distance != re->distance) + continue; + /* - * We should allow duplicate connected routes because of - * IPv6 link-local routes and unnumbered interfaces on Linux. + * We should allow duplicate connected routes + * because of IPv6 link-local routes and unnumbered + * interfaces on Linux. */ if (same->type != ZEBRA_ROUTE_CONNECT) break; } + zlog_debug("same: %p distance: %d", same, same ? same->distance : -1); /* If this route is kernel route, set FIB flag to the route. */ if (RIB_SYSTEM_ROUTE(re)) for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) @@ -2407,7 +2419,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, unsigned short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, - uint32_t table_id, uint32_t metric, bool fromkernel) + uint32_t table_id, uint32_t metric, uint8_t distance, + bool fromkernel) { struct route_table *table; struct route_node *rn; @@ -2461,6 +2474,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, continue; if (re->instance != instance) continue; + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) && + distance != re->distance) + continue; + if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric) continue; if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng.nexthop)