From fd36be7e15ee49d12500a5ec4d9597d1597715a7 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 28 Aug 2017 01:30:16 +0200 Subject: [PATCH] zebra: rib: use nexthop ptr in rib_add/delete This simplifies the API for the following blackhole rework. Signed-off-by: David Lamparter --- lib/nexthop.c | 3 +- lib/nexthop.h | 4 +- zebra/connected.c | 31 ++++++++++----- zebra/kernel_socket.c | 29 +++++++++----- zebra/redistribute.c | 15 ++------ zebra/rib.h | 11 +++--- zebra/rt_netlink.c | 90 +++++++++++++++++++++++++------------------ zebra/rtread_getmsg.c | 11 +++--- zebra/zebra_rib.c | 75 ++++++++++++++---------------------- 9 files changed, 139 insertions(+), 130 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 7180be33dd..2dba412f45 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -36,7 +36,8 @@ DEFINE_MTYPE_STATIC(LIB, NEXTHOP, "Nexthop") DEFINE_MTYPE_STATIC(LIB, NH_LABEL, "Nexthop label") /* check if nexthops are same, non-recursive */ -int nexthop_same_no_recurse(struct nexthop *next1, struct nexthop *next2) +int nexthop_same_no_recurse(const struct nexthop *next1, + const struct nexthop *next2) { if (next1->type != next2->type) return 0; diff --git a/lib/nexthop.h b/lib/nexthop.h index 12a1203a8f..7cfba5c5b6 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -135,8 +135,8 @@ void nexthop_add_labels(struct nexthop *, enum lsp_types_t, u_int8_t, void nexthop_del_labels(struct nexthop *); extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type); -extern int nexthop_same_no_recurse(struct nexthop *next1, - struct nexthop *next2); +extern int nexthop_same_no_recurse(const struct nexthop *next1, + const struct nexthop *next2); extern int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2); extern const char *nexthop2str(struct nexthop *nexthop, char *str, int size); diff --git a/zebra/connected.c b/zebra/connected.c index 701314f246..3f8b80b97b 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -177,6 +177,10 @@ static void connected_update(struct interface *ifp, struct connected *ifc) void connected_up_ipv4(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; @@ -192,12 +196,10 @@ void connected_up_ipv4(struct interface *ifp, struct connected *ifc) return; rib_add(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, - 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, - &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, - 0, 0); + &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( @@ -306,6 +308,10 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, void connected_down_ipv4(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; @@ -323,10 +329,10 @@ void connected_down_ipv4(struct interface *ifp, struct connected *ifc) /* 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, - &p, NULL, NULL, ifp->ifindex, 0, 0); + &p, NULL, &nh, 0, 0); rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, NULL, ifp->ifindex, 0, 0); + 0, &p, NULL, &nh, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( @@ -384,6 +390,10 @@ void connected_delete_ipv4(struct interface *ifp, int flags, 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; @@ -400,8 +410,7 @@ void connected_up_ipv6(struct interface *ifp, struct connected *ifc) #endif rib_add(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, - 0, 0); + &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( @@ -489,6 +498,10 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, 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; @@ -501,7 +514,7 @@ void connected_down_ipv6(struct interface *ifp, struct connected *ifc) return; rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, NULL, ifp->ifindex, 0, 0); + 0, &p, NULL, &nh, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index e2a1deb9ac..ee21e61fe7 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -849,6 +849,7 @@ void rtm_read(struct rt_msghdr *rtm) union sockunion dest, mask, gate; char ifname[INTERFACE_NAMSIZ + 1]; short ifnlen = 0; + struct nexthop nh; zebra_flags = 0; @@ -1015,19 +1016,22 @@ 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, 0); + ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, + NULL, 0, 0); + + memset(&nh, 0, sizeof(nh)); + nh.type = NEXTHOP_TYPE_IPV4; + nh.gate.ipv4 = gate.sin; - union g_addr ggate = {.ipv4 = gate.sin.sin_addr}; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, NULL, 0, 0, 0, 0, 0); + &nh, 0, 0, 0, 0); else rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, 0, 0, 0); + &nh, 0, 0); } if (dest.sa.sa_family == AF_INET6) { /* One day we might have a debug section here like one in the @@ -1057,19 +1061,24 @@ 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, 0); + ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, + NULL, NULL, 0, 0); + + memset(&nh, 0, sizeof(nh)); + nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX + : NEXTHOP_TYPE_IPV6; + nh.gate.ipv6 = gate.sin6; + nh.ifindex = ifindex; - union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr}; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, NULL, ifindex, 0, 0, 0, 0); + &nh, 0, 0, 0, 0); else rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, ifindex, 0, 0); + &nh, 0, 0); } } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 9b21eb4d8c..39083ad3b7 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -496,8 +496,6 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, struct route_entry *newre; struct route_entry *same; struct prefix p; - struct nexthop *nhop; - union g_addr *gate; route_map_result_t ret = RMAP_MATCH; if (rmap_name) @@ -529,17 +527,10 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, if (re->nexthop_num == 1) { - nhop = re->nexthop; - if (nhop->type == NEXTHOP_TYPE_IFINDEX) - gate = NULL; - else - gate = (union g_addr *)&nhop->gate.ipv4; - rib_add(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, 0, &p, - NULL, gate, - (union g_addr *)&nhop->src.ipv4, - nhop->ifindex, zebrad.rtm_table_default, + NULL, re->nexthop, + zebrad.rtm_table_default, re->metric, re->mtu, zebra_import_table_distance[AFI_IP] [re->table]); @@ -580,7 +571,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) p.u.prefix4 = rn->p.u.prefix4; rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, - re->table, re->flags, &p, NULL, NULL, 0, + re->table, re->flags, &p, NULL, NULL, zebrad.rtm_table_default, re->metric); } /* DD: Add IPv6 code */ diff --git a/zebra/rib.h b/zebra/rib.h index 495b731e88..9e456e436f 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -294,18 +294,17 @@ extern int rib_uninstall_kernel(struct route_node *rn, struct route_entry *re); * 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, - struct prefix_ipv6 *src_p, union g_addr *gate, - union g_addr *src, ifindex_t ifindex, u_int32_t table_id, - u_int32_t metric, u_int32_t mtu, u_char distance); + struct prefix_ipv6 *src_p, const struct nexthop *nh, + u_int32_t table_id, u_int32_t metric, u_int32_t mtu, + u_char distance); extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, struct prefix_ipv6 *src_p, struct route_entry *); extern void rib_delete(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, union g_addr *gate, - ifindex_t ifindex, u_int32_t table_id, - u_int32_t metric); + struct prefix_ipv6 *src_p, const struct nexthop *nh, + u_int32_t table_id, u_int32_t metric); extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t, union g_addr *, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index e28fe5630a..ec19c53b73 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -365,11 +365,31 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, afi = AFI_IP6; if (h->nlmsg_type == RTM_NEWROUTE) { - if (!tb[RTA_MULTIPATH]) + if (!tb[RTA_MULTIPATH]) { + struct nexthop nh; + size_t sz = (afi == AFI_IP) ? 4 : 16; + + memset(&nh, 0, sizeof(nh)); + if (index && !gate) + nh.type = NEXTHOP_TYPE_IFINDEX; + else if (index && gate) + nh.type = (afi == AFI_IP) + ? NEXTHOP_TYPE_IPV4_IFINDEX + : NEXTHOP_TYPE_IPV6_IFINDEX; + else if (!index && gate) + nh.type = (afi == AFI_IP) + ? NEXTHOP_TYPE_IPV4 + : NEXTHOP_TYPE_IPV6; + else + nh.type = NEXTHOP_TYPE_BLACKHOLE; + nh.ifindex = index; + if (prefsrc) + memcpy(&nh.src, prefsrc, sz); + if (gate) + memcpy(&nh.gate, gate, sz); rib_add(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, - 0, flags, &p, NULL, gate, prefsrc, index, table, - metric, mtu, 0); - else { + 0, flags, &p, NULL, &nh, table, metric, mtu, 0); + } else { /* This is a multipath route */ struct route_entry *re; @@ -444,41 +464,35 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, NULL, re); } } else { - if (!tb[RTA_MULTIPATH]) + if (!tb[RTA_MULTIPATH]) { + struct nexthop nh; + size_t sz = (afi == AFI_IP) ? 4 : 16; + + memset(&nh, 0, sizeof(nh)); + if (index && !gate) + nh.type = NEXTHOP_TYPE_IFINDEX; + else if (index && gate) + nh.type = (afi == AFI_IP) + ? NEXTHOP_TYPE_IPV4_IFINDEX + : NEXTHOP_TYPE_IPV6_IFINDEX; + else if (!index && gate) + nh.type = (afi == AFI_IP) + ? NEXTHOP_TYPE_IPV4 + : NEXTHOP_TYPE_IPV6; + else + nh.type = NEXTHOP_TYPE_BLACKHOLE; + nh.ifindex = index; + if (gate) + memcpy(&nh.gate, gate, sz); rib_delete(afi, SAFI_UNICAST, vrf_id, - ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate, - index, table, metric); - else { - struct rtnexthop *rtnh = - (struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); - - len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); - - for (;;) { - if (len < (int)sizeof(*rtnh) - || rtnh->rtnh_len > len) - break; - - gate = NULL; - if (rtnh->rtnh_len > sizeof(*rtnh)) { - memset(tb, 0, sizeof(tb)); - netlink_parse_rtattr( - tb, RTA_MAX, RTNH_DATA(rtnh), - rtnh->rtnh_len - sizeof(*rtnh)); - if (tb[RTA_GATEWAY]) - gate = RTA_DATA( - tb[RTA_GATEWAY]); - } - - if (gate) - rib_delete(afi, SAFI_UNICAST, vrf_id, - ZEBRA_ROUTE_KERNEL, 0, flags, - &p, NULL, gate, index, - table, metric); - - len -= NLMSG_ALIGN(rtnh->rtnh_len); - rtnh = RTNH_NEXT(rtnh); - } + ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, &nh, + table, metric); + } else { + /* XXX: need to compare the entire list of nexthops + * here for NLM_F_APPEND stupidity */ + rib_delete(afi, SAFI_UNICAST, vrf_id, + ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, + NULL, table, metric); } } diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 1bba003a0a..62f3224b6e 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -75,8 +75,8 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) { struct prefix prefix; - struct in_addr tmpaddr, gateway; - union g_addr *ggateway; + struct in_addr tmpaddr; + struct nexthop nh; u_char zebra_flags = 0; if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE) @@ -93,11 +93,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) tmpaddr.s_addr = routeEntry->ipRouteMask; prefix.prefixlen = ip_masklen(tmpaddr); - gateway.s_addr = routeEntry->ipRouteNextHop; - ggateway = (union g_addr *)&gateway; + memset(&nh, 0, sizeof(nh)); + 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, ggateway, NULL, 0, 0, 0, 0, 0); + zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0); } void route_read(struct zebra_ns *zns) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index dc61ea5e40..644f48793a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2273,16 +2273,15 @@ 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, u_short instance, int flags, struct prefix *p, - struct prefix_ipv6 *src_p, union g_addr *gate, - ifindex_t ifindex, u_int32_t table_id, - u_int32_t metric) + struct prefix_ipv6 *src_p, const struct nexthop *nh, + u_int32_t table_id, u_int32_t metric) { struct route_table *table; struct route_node *rn; struct route_entry *re; struct route_entry *fib = NULL; struct route_entry *same = NULL; - struct nexthop *nexthop; + struct nexthop *rtnh; char buf2[INET6_ADDRSTRLEN]; assert(!src_p || afi == AFI_IP6); @@ -2332,9 +2331,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric) continue; - if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop) - && nexthop->type == NEXTHOP_TYPE_IFINDEX) { - if (nexthop->ifindex != ifindex) + if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->nexthop) + && rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) { + if (rtnh->ifindex != nh->ifindex) continue; if (re->refcnt) { re->refcnt--; @@ -2347,14 +2346,12 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } /* Make sure that the route found has the same gateway. */ else { - if (gate == NULL) { + if (nh == NULL) { same = re; break; } - for (ALL_NEXTHOPS(re->nexthop, nexthop)) - if (IPV4_ADDR_SAME(&nexthop->gate.ipv4, &gate->ipv4) - || IPV6_ADDR_SAME(&nexthop->gate.ipv6, - gate)) { + for (ALL_NEXTHOPS(re->nexthop, rtnh)) + if (nexthop_same_no_recurse(rtnh, nh)) { same = re; break; } @@ -2375,9 +2372,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } if (allow_delete) { /* Unset flags. */ - for (nexthop = fib->nexthop; nexthop; - nexthop = nexthop->next) - UNSET_FLAG(nexthop->flags, + for (rtnh = fib->nexthop; rtnh; + rtnh = rtnh->next) + UNSET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB); UNSET_FLAG(fib->status, @@ -2391,22 +2388,22 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } } else { if (IS_ZEBRA_DEBUG_RIB) { - if (gate) + if (nh) rnode_debug( rn, vrf_id, "via %s ifindex %d type %d " "doesn't exist in rib", inet_ntop( - family2afi(afi), gate, + family2afi(afi), &nh->gate, buf2, INET_ADDRSTRLEN), /* FIXME */ - ifindex, type); + nh->ifindex, type); else rnode_debug( rn, vrf_id, - "ifindex %d type %d doesn't exist in rib", - ifindex, type); + "type %d doesn't exist in rib", + type); } route_unlock_node(rn); return; @@ -2423,15 +2420,14 @@ 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, - union g_addr *gate, union g_addr *src, ifindex_t ifindex, - u_int32_t table_id, u_int32_t metric, u_int32_t mtu, - u_char distance) + const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, + u_int32_t mtu, u_char distance) { struct route_entry *re; struct route_entry *same = NULL; struct route_table *table; struct route_node *rn; - struct nexthop *nexthop; + struct nexthop *rtnh; assert(!src_p || afi == AFI_IP6); @@ -2480,9 +2476,9 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, break; } /* Duplicate system route comes in. */ - else if ((nexthop = re->nexthop) - && nexthop->type == NEXTHOP_TYPE_IFINDEX - && nexthop->ifindex == ifindex + else if ((rtnh = re->nexthop) + && rtnh->type == NEXTHOP_TYPE_IFINDEX + && rtnh->ifindex == nh->ifindex && !CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) { re->refcnt++; return 0; @@ -2503,29 +2499,14 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, re->nexthop_num = 0; re->uptime = time(NULL); - /* Nexthop settings. */ - if (gate) { - if (afi == AFI_IP6) { - if (ifindex) - route_entry_nexthop_ipv6_ifindex_add( - re, &gate->ipv6, ifindex); - else - route_entry_nexthop_ipv6_add(re, &gate->ipv6); - } else { - if (ifindex) - route_entry_nexthop_ipv4_ifindex_add( - re, &gate->ipv4, &src->ipv4, ifindex); - else - route_entry_nexthop_ipv4_add(re, &gate->ipv4, - &src->ipv4); - } - } else - route_entry_nexthop_ifindex_add(re, ifindex); + rtnh = nexthop_new(); + *rtnh = *nh; + route_entry_nexthop_add(re, rtnh); /* If this route is kernel route, set FIB flag to the route. */ if (RIB_SYSTEM_ROUTE(re)) - for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + for (rtnh = re->nexthop; rtnh; rtnh = rtnh->next) + SET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB); /* Link new rib to node.*/ if (IS_ZEBRA_DEBUG_RIB) { -- 2.39.5