From 8f43b4d8868b340a7c61e55372b01f070abfb491 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 12 Jan 2018 09:20:30 -0500 Subject: zebra: Add nh_vrf_id to 'struct route_entry` With VRF route-leaking we need to know what vrf the nexthops are in compared to this vrf. This code adds the nh_vrf_id to the route entry and sets it up correctly for the non-route-leaking case. The assumption here is that future commits will make the nh_vrf_id *different* than the vrf_id. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 41e14459b1..8caa39427b 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2514,6 +2514,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, re->mtu = mtu; re->table = table_id; re->vrf_id = vrf_id; + re->nh_vrf_id = vrf_id; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; -- cgit v1.2.3 From 99b9d9609f57d283d79c72c89848d7ac5f000f0b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 8 Jan 2018 09:56:08 -0500 Subject: zebra: Use the correct vrf id to lookup the ifp pointer Use the nexthop vrf_id to properly lookup the ifp pointer for display purposes. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 3 ++- zebra/zebra_vty.c | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 8caa39427b..6f9b855908 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -911,7 +911,8 @@ static unsigned nexthop_active_check(struct route_node *rn, zlog_debug( "%u:%s: Filtering out with NH out %s due to route map", re->vrf_id, buf, - ifindex2ifname(nexthop->ifindex, re->vrf_id)); + ifindex2ifname(nexthop->ifindex, + re->nh_vrf_id)); } UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 82b0157ad3..a0d2930c89 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -539,7 +539,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", via %s", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -549,12 +549,12 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", via %s", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " directly connected, %s", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); @@ -715,7 +715,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add( json_nexthop, "interfaceName", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); } break; case NEXTHOP_TYPE_IPV6: @@ -734,7 +734,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add( json_nexthop, "interfaceName", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); } break; @@ -747,7 +747,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add( json_nexthop, "interfaceName", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: json_object_boolean_true_add(json_nexthop, @@ -881,7 +881,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -891,12 +891,13 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->vrf_id)); + re->nh_vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " is directly connected, %s", - ifindex2ifname(nexthop->ifindex, re->vrf_id)); + ifindex2ifname(nexthop->ifindex, + re->nh_vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); -- cgit v1.2.3 From 8795f90448e45e674ea60da83c2ad571ff2f9fec Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 8 Jan 2018 10:21:09 -0500 Subject: zebra: Add nh_vrf_id to rib_add Add to the rib_add function the ability to pass in the nexthops vrf. Additionally when we decode the netlink message from the linux kernel, properly figure out the nexthops vrf_id. Signed-off-by: Donald Sharp --- zebra/connected.c | 6 ++++-- zebra/kernel_socket.c | 4 ++-- zebra/rib.h | 4 ++-- zebra/rt_netlink.c | 24 +++++++++++++++++++++++- zebra/rtread_getmsg.c | 5 +++-- zebra/zebra_rib.c | 9 +++++---- 6 files changed, 39 insertions(+), 13 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/connected.c b/zebra/connected.c index 7b949c5041..d34fd9021a 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -238,10 +238,12 @@ void connected_up(struct interface *ifp, struct connected *ifc) break; } - rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, + rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ifp->vrf_id, + ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); - rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, + rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ifp->vrf_id, + ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 9fd7bb1c24..ba028ed09c 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1048,7 +1048,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else @@ -1096,7 +1096,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, + rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else diff --git a/zebra/rib.h b/zebra/rib.h index c92f540771..6e3a85c1d1 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -294,8 +294,8 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re); /* NOTE: * All rib_add function will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ -extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - u_short instance, int flags, struct prefix *p, +extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, + int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index cb3f598eb9..384656a573 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -403,6 +403,9 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, afi = AFI_IP6; if (h->nlmsg_type == RTM_NEWROUTE) { + struct interface *ifp; + vrf_id_t nh_vrf_id = vrf_id; + if (!tb[RTA_MULTIPATH]) { struct nexthop nh; size_t sz = (afi == AFI_IP) ? 4 : 16; @@ -434,7 +437,14 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (gate) memcpy(&nh.gate, gate, sz); - rib_add(afi, SAFI_UNICAST, vrf_id, proto, + if (index) { + ifp = if_lookup_by_index(index, + VRF_UNKNOWN); + if (ifp) + nh_vrf_id = ifp->vrf_id; + } + + rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto, 0, flags, &p, NULL, &nh, table, metric, mtu, distance, tag); } else { @@ -465,6 +475,18 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, break; index = rtnh->rtnh_ifindex; + if (index) { + /* + * Yes we are looking this up + * for every nexthop and just + * using the last one looked + * up right now + */ + ifp = if_lookup_by_index(index, + VRF_UNKNOWN); + if (ifp) + re->nh_vrf_id = ifp->vrf_id; + } gate = 0; if (rtnh->rtnh_len > sizeof(*rtnh)) { memset(tb, 0, sizeof(tb)); diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 69e45f9a6c..ba45f54ad2 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -97,8 +97,9 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) nh.type = NEXTHOP_TYPE_IPV4; nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop; - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, - zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0); + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, + ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix, NULL, + &nh, 0, 0, 0, 0, 0); } void route_read(struct zebra_ns *zns) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 6f9b855908..b1f0f70093 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2497,9 +2497,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } -int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, - int flags, struct prefix *p, struct prefix_ipv6 *src_p, - const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, +int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, + int type, u_short instance, int flags, struct prefix *p, + struct prefix_ipv6 *src_p, const struct nexthop *nh, + u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag) { struct route_entry *re; @@ -2515,7 +2516,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, re->mtu = mtu; re->table = table_id; re->vrf_id = vrf_id; - re->nh_vrf_id = vrf_id; + re->nh_vrf_id = nh_vrf_id; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; -- cgit v1.2.3 From 007dbee65cef24561da54cfbf5c4d24052db002a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 8 Jan 2018 10:34:48 -0500 Subject: zebra: When handling nexthops use the correct vrf When we are handling nexthops in zebra, use the appropriate vrf to figure out if the nexthops are active or not. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b1f0f70093..fd1b273c8e 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -256,7 +256,7 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, if (src) nexthop->src.ipv4 = *src; nexthop->ifindex = ifindex; - ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); /*Pending: need to think if null ifp here is ok during bootup? There was a crash because ifp here was coming to be NULL */ if (ifp) @@ -416,7 +416,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, * address in the routing table. */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { - ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); if (ifp && connected_is_unnumbered(ifp)) { if (if_is_operative(ifp)) return 1; @@ -444,7 +444,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, break; } /* Lookup table. */ - table = zebra_vrf_table(afi, SAFI_UNICAST, re->vrf_id); + table = zebra_vrf_table(afi, SAFI_UNICAST, re->nh_vrf_id); if (!table) return 0; @@ -832,7 +832,7 @@ static unsigned nexthop_active_check(struct route_node *rn, family = 0; switch (nexthop->type) { case NEXTHOP_TYPE_IFINDEX: - ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -860,7 +860,8 @@ static unsigned nexthop_active_check(struct route_node *rn, if (rn->p.family != AF_INET) family = AFI_IP6; if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { - ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, + re->nh_vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else -- cgit v1.2.3 From 5bdd34db693867fbfd80d2fe3fc4bc056cc02b0f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 11 Jan 2018 11:51:46 -0500 Subject: zebra: Allow static non interface based routes to leak Allow this to work: vrf DONNA ip route 4.3.2.1/32 192.168.1.5 nexthop-vrf EVA The static route code was not properly telling the nexthop resolution code what vrf to use. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 4 ++-- zebra/zebra_routemap.c | 2 +- zebra/zebra_static.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index fd1b273c8e..16dafa6b89 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -397,7 +397,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, if (set) { UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops(re->vrf_id, + zebra_deregister_rnh_static_nexthops(re->nh_vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; @@ -904,7 +904,7 @@ static unsigned nexthop_active_check(struct route_node *rn, memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re->type, p, nexthop, re->vrf_id, + ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 61af60b5da..89cb2fc488 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1329,7 +1329,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto, struct nh_rmap_obj nh_obj; nh_obj.nexthop = nexthop; - nh_obj.vrf_id = re->vrf_id; + nh_obj.vrf_id = re->nh_vrf_id; nh_obj.source_protocol = re->type; nh_obj.metric = re->metric; nh_obj.tag = re->tag; diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 3423518bba..fa5f0d9c48 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -91,7 +91,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; - zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); + zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn); break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( @@ -111,7 +111,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; - zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); + zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn); break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( @@ -141,7 +141,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, */ if (si->type == STATIC_IPV4_GATEWAY || si->type == STATIC_IPV6_GATEWAY) - zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, + zebra_evaluate_rnh(si->nh_vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); else rib_queue_add(rn); @@ -170,7 +170,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; - zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); + zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn); break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( @@ -190,7 +190,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; - zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); + zebra_register_rnh_static_nh(si->nh_vrf_id, &nh_p, rn); break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( @@ -222,7 +222,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, if (si->type == STATIC_IPV4_GATEWAY || si->type == STATIC_IPV6_GATEWAY) { rib_addnode(rn, re, 0); - zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, + zebra_evaluate_rnh(si->nh_vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); } else rib_addnode(rn, re, 1); -- cgit v1.2.3 From f674dfe234515156eca7618bf2fc647ccfd34787 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Wed, 20 Sep 2017 00:05:25 -0300 Subject: zebra: implement recursive MPLS labels When a nexthop is resolved via a label based nexthop, copy the labels into the newly created recursive nexthop. Please note that this does not fix the case where we have a label based nexthop that is recursively resolved through *another* nexthop that is also label based. In this case we need to create a new label stack for those routes. Signed-off-by: Renato Westphal --- zebra/zebra_rib.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 41e14459b1..f7f05ba68a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -372,6 +372,12 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, break; } + /* Copy labels of the resolved route */ + if (newhop->nh_label) + nexthop_add_labels(resolved_hop, newhop->nh_label_type, + newhop->nh_label->num_labels, + &newhop->nh_label->label[0]); + resolved_hop->rparent = nexthop; nexthop_add(&nexthop->resolved, resolved_hop); } -- cgit v1.2.3 From 7d974ba3b72ce8c4e46201a3c8b60e1680406883 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 24 Jan 2018 08:22:57 -0500 Subject: zebra: Modify southbound interface to pass `struct route_node` The route_node that we are working on is going to be interesting to the kernel_route_rib_pass_fail. So I am setting up the code to allow me to pass it. This will be done in a subsuquent commit. Signed-off-by: Donald Sharp --- zebra/rt.h | 8 +++++--- zebra/rt_netlink.c | 9 +++++---- zebra/rt_socket.c | 9 +++++---- zebra/zebra_rib.c | 7 ++++--- 4 files changed, 19 insertions(+), 14 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/rt.h b/zebra/rt.h index bb4ff5bee8..54d45b889a 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -60,15 +60,17 @@ enum southbound_results { * semantics so we will end up with a delete than * a re-add. */ -extern void kernel_route_rib(struct prefix *p, struct prefix *src_p, - struct route_entry *old, struct route_entry *new); +extern void kernel_route_rib(struct route_node *rn, struct prefix *p, + struct prefix *src_p, struct route_entry *old, + struct route_entry *new); /* * So route install/failure may not be immediately known * so let's separate it out and allow the result to * be passed back up. */ -extern void kernel_route_rib_pass_fail(struct prefix *p, +extern void kernel_route_rib_pass_fail(struct route_node *rn, + struct prefix *p, struct route_entry *re, enum southbound_results res); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 0221162a30..20cc292e11 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1642,8 +1642,9 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in) return suc; } -void kernel_route_rib(struct prefix *p, struct prefix *src_p, - struct route_entry *old, struct route_entry *new) +void kernel_route_rib(struct route_node *rn, struct prefix *p, + struct prefix *src_p, struct route_entry *old, + struct route_entry *new) { int ret = 0; @@ -1672,7 +1673,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p, ret = netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0); } - kernel_route_rib_pass_fail(p, new, + kernel_route_rib_pass_fail(rn, p, new, (!ret) ? SOUTHBOUND_INSTALL_SUCCESS : SOUTHBOUND_INSTALL_FAILURE); @@ -1682,7 +1683,7 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p, if (old) { ret = netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0); - kernel_route_rib_pass_fail(p, old, + kernel_route_rib_pass_fail(rn, p, old, (!ret) ? SOUTHBOUND_DELETE_SUCCESS : SOUTHBOUND_DELETE_FAILURE); diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 09fdf0b2d3..6d4af1203c 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -387,8 +387,9 @@ static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re) return 0; } -void kernel_route_rib(struct prefix *p, struct prefix *src_p, - struct route_entry *old, struct route_entry *new) +void kernel_route_rib(struct route_node *rn, struct prefix *p, + struct prefix *src_p, struct route_entry *old, + struct route_entry *new) { int route = 0; @@ -410,12 +411,12 @@ void kernel_route_rib(struct prefix *p, struct prefix *src_p, zlog_err("Can't lower privileges"); if (new) { - kernel_route_rib_pass_fail(p, new, + kernel_route_rib_pass_fail(rn, p, new, (!route) ? SOUTHBOUND_INSTALL_SUCCESS : SOUTHBOUND_INSTALL_FAILURE); } else { - kernel_route_rib_pass_fail(p, old, + kernel_route_rib_pass_fail(rn, p, old, (!route) ? SOUTHBOUND_DELETE_SUCCESS : SOUTHBOUND_DELETE_FAILURE); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 78077a4b3d..83eff7bdcf 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -998,7 +998,8 @@ int zebra_rib_labeled_unicast(struct route_entry *re) return 1; } -void kernel_route_rib_pass_fail(struct prefix *p, struct route_entry *re, +void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p, + struct route_entry *re, enum southbound_results res) { struct nexthop *nexthop; @@ -1083,7 +1084,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, * the kernel. */ hook_call(rib_update, rn, "installing in kernel"); - kernel_route_rib(p, src_p, old, re); + kernel_route_rib(rn, p, src_p, old, re); zvrf->installs++; return; @@ -1110,7 +1111,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) * the kernel. */ hook_call(rib_update, rn, "uninstalling from kernel"); - kernel_route_rib(p, src_p, re, NULL); + kernel_route_rib(rn, p, src_p, re, NULL); zvrf->removals++; return; -- cgit v1.2.3 From ed216282b6ce3da844e254506d390807fcc0ad36 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 24 Jan 2018 09:16:39 -0500 Subject: zebra: Move selected_fib assignment The dest->selected_fib assignment needs to happen after the install and should be controlled by the southbound api return of success or failure. Signed-off-by: Donald Sharp --- zebra/zebra_rib.c | 78 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 16 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 83eff7bdcf..c200e2dbb3 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1004,9 +1004,13 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p, { struct nexthop *nexthop; char buf[PREFIX_STRLEN]; + rib_dest_t *dest; + + dest = rib_dest_from_rnode(rn); switch (res) { case SOUTHBOUND_INSTALL_SUCCESS: + dest->selected_fib = re; for (ALL_NEXTHOPS(re->nexthop, nexthop)) { if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) continue; @@ -1020,16 +1024,37 @@ void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p, p, ZAPI_ROUTE_INSTALLED); break; case SOUTHBOUND_INSTALL_FAILURE: + /* + * I am not sure this is the right thing to do here + * but the code always set selected_fib before + * this assignment was moved here. + */ + dest->selected_fib = re; + zsend_route_notify_owner(re->type, re->instance, re->vrf_id, p, ZAPI_ROUTE_FAIL_INSTALL); zlog_warn("%u:%s: Route install failed", re->vrf_id, prefix2str(p, buf, sizeof(buf))); break; case SOUTHBOUND_DELETE_SUCCESS: + /* + * The case where selected_fib is not re is + * when we have received a system route + * that is overriding our installed route + * as such we should leave the selected_fib + * pointer alone + */ + if (dest->selected_fib == re) + dest->selected_fib = NULL; for (ALL_NEXTHOPS(re->nexthop, nexthop)) UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); break; case SOUTHBOUND_DELETE_FAILURE: + /* + * Should we set this to NULL if the + * delete fails? + */ + dest->selected_fib = NULL; zlog_warn("%u:%s: Route Deletion failure", re->vrf_id, prefix2str(p, buf, sizeof(buf))); break; @@ -1133,8 +1158,6 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re) /* If labeled-unicast route, uninstall transit LSP. */ if (zebra_rib_labeled_unicast(re)) zebra_mpls_lsp_uninstall(info->zvrf, rn, re); - - dest->selected_fib = NULL; } if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) { @@ -1219,7 +1242,6 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, return; } - dest->selected_fib = new; if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; srcdest_rnode2str(rn, buf, sizeof(buf)); @@ -1233,6 +1255,8 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, if (!RIB_SYSTEM_ROUTE(new)) rib_install_kernel(rn, new, NULL); + else + dest->selected_fib = new; UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED); } @@ -1257,8 +1281,17 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, if (!RIB_SYSTEM_ROUTE(old)) rib_uninstall_kernel(rn, old); - - dest->selected_fib = NULL; + else { + /* + * We are setting this to NULL here + * because that is what we traditionally + * have been doing. I am not positive + * that this is the right thing to do + * but let's leave the code alone + * for the RIB_SYSTEM_ROUTE case + */ + dest->selected_fib = NULL; + } /* Update nexthop for route, reset changed flag. */ nexthop_active_update(rn, old, 1); @@ -1272,7 +1305,6 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, { struct nexthop *nexthop = NULL; int nh_active = 0; - int installed = 1; rib_dest_t *dest = rib_dest_from_rnode(rn); /* @@ -1322,11 +1354,23 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, zebra_mpls_lsp_install(zvrf, rn, new); rib_install_kernel(rn, new, old); + } else { + /* + * We do not need to install the + * selected route because it + * is already isntalled by + * the system( ie not us ) + * so just mark it as winning + * we do need to ensure that + * if we uninstall a route + * from ourselves we don't + * over write this pointer + */ + dest->selected_fib = NULL; } - /* If install succeeded or system route, cleanup flags * for prior route. */ - if (installed && new != old) { + if (new != old) { if (RIB_SYSTEM_ROUTE(new)) { if (!RIB_SYSTEM_ROUTE(old)) rib_uninstall_kernel(rn, old); @@ -1337,10 +1381,6 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, NEXTHOP_FLAG_FIB); } } - - /* Update for redistribution. */ - if (installed) - dest->selected_fib = new; } /* @@ -1348,7 +1388,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, * failed, we * may need to uninstall and delete for redistribution. */ - if (!nh_active || !installed) { + if (!nh_active) { if (IS_ZEBRA_DEBUG_RIB) { char buf[SRCDEST2STR_BUFFER]; srcdest_rnode2str(rn, buf, sizeof(buf)); @@ -1375,7 +1415,8 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, if (!RIB_SYSTEM_ROUTE(old)) rib_uninstall_kernel(rn, old); - dest->selected_fib = NULL; + else + dest->selected_fib = NULL; } } else { /* @@ -1388,12 +1429,12 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, * to add routes. */ if (!RIB_SYSTEM_ROUTE(new)) { - int in_fib = 0; + bool in_fib = false; for (ALL_NEXTHOPS(new->nexthop, nexthop)) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { - in_fib = 1; + in_fib = true; break; } if (!in_fib) @@ -2440,6 +2481,11 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, UNSET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB); + /* + * This is a non FRR route + * as such we should mark + * it as deleted + */ dest->selected_fib = NULL; } else { /* This means someone else, other than Zebra, -- cgit v1.2.3