diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/debug.c | 12 | ||||
| -rw-r--r-- | zebra/if_netlink.c | 8 | ||||
| -rw-r--r-- | zebra/rib.h | 8 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 6 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 22 | ||||
| -rw-r--r-- | zebra/zebra_dplane.c | 12 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mh.c | 19 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 287 | ||||
| -rw-r--r-- | zebra/zebra_vxlan.c | 23 |
9 files changed, 145 insertions, 252 deletions
diff --git a/zebra/debug.c b/zebra/debug.c index 88a3d98815..525180d4ee 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -244,6 +244,7 @@ DEFUN (debug_zebra_kernel, return CMD_SUCCESS; } +#if defined(HAVE_NETLINK) DEFUN (debug_zebra_kernel_msgdump, debug_zebra_kernel_msgdump_cmd, "debug zebra kernel msgdump [<recv|send>]", @@ -267,6 +268,7 @@ DEFUN (debug_zebra_kernel_msgdump, return CMD_SUCCESS; } +#endif DEFUN (debug_zebra_rib, debug_zebra_rib_cmd, @@ -465,6 +467,7 @@ DEFUN (no_debug_zebra_kernel, return CMD_SUCCESS; } +#if defined(HAVE_NETLINK) DEFUN (no_debug_zebra_kernel_msgdump, no_debug_zebra_kernel_msgdump_cmd, "no debug zebra kernel msgdump [<recv|send>]", @@ -489,6 +492,7 @@ DEFUN (no_debug_zebra_kernel_msgdump, return CMD_SUCCESS; } +#endif DEFUN (no_debug_zebra_rib, no_debug_zebra_rib_cmd, @@ -721,7 +725,9 @@ void zebra_debug_init(void) install_element(ENABLE_NODE, &debug_zebra_pw_cmd); install_element(ENABLE_NODE, &debug_zebra_packet_cmd); install_element(ENABLE_NODE, &debug_zebra_kernel_cmd); +#if defined(HAVE_NETLINK) install_element(ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd); +#endif install_element(ENABLE_NODE, &debug_zebra_rib_cmd); install_element(ENABLE_NODE, &debug_zebra_fpm_cmd); install_element(ENABLE_NODE, &debug_zebra_dplane_cmd); @@ -734,7 +740,9 @@ void zebra_debug_init(void) install_element(ENABLE_NODE, &no_debug_zebra_vxlan_cmd); install_element(ENABLE_NODE, &no_debug_zebra_packet_cmd); install_element(ENABLE_NODE, &no_debug_zebra_kernel_cmd); +#if defined(HAVE_NETLINK) install_element(ENABLE_NODE, &no_debug_zebra_kernel_msgdump_cmd); +#endif install_element(ENABLE_NODE, &no_debug_zebra_rib_cmd); install_element(ENABLE_NODE, &no_debug_zebra_fpm_cmd); install_element(ENABLE_NODE, &no_debug_zebra_dplane_cmd); @@ -748,7 +756,9 @@ void zebra_debug_init(void) install_element(CONFIG_NODE, &debug_zebra_pw_cmd); install_element(CONFIG_NODE, &debug_zebra_packet_cmd); install_element(CONFIG_NODE, &debug_zebra_kernel_cmd); +#if defined(HAVE_NETLINK) install_element(CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd); +#endif install_element(CONFIG_NODE, &debug_zebra_rib_cmd); install_element(CONFIG_NODE, &debug_zebra_fpm_cmd); install_element(CONFIG_NODE, &debug_zebra_dplane_cmd); @@ -761,7 +771,9 @@ void zebra_debug_init(void) install_element(CONFIG_NODE, &no_debug_zebra_vxlan_cmd); install_element(CONFIG_NODE, &no_debug_zebra_packet_cmd); install_element(CONFIG_NODE, &no_debug_zebra_kernel_cmd); +#if defined(HAVE_NETLINK) install_element(CONFIG_NODE, &no_debug_zebra_kernel_msgdump_cmd); +#endif install_element(CONFIG_NODE, &no_debug_zebra_rib_cmd); install_element(CONFIG_NODE, &no_debug_zebra_fpm_cmd); install_element(CONFIG_NODE, &no_debug_zebra_dplane_cmd); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index a51e0b82cb..2a9fff2666 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1527,6 +1527,14 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) return -1; name = (char *)RTA_DATA(tb[IFLA_IFNAME]); + /* Must be valid string. */ + len = RTA_PAYLOAD(tb[IFLA_IFNAME]); + if (len < 2 || name[len - 1] != '\0') { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: invalid intf name", __func__); + return -1; + } + if (tb[IFLA_LINKINFO]) { netlink_parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); diff --git a/zebra/rib.h b/zebra/rib.h index 31d9dfd265..8887053a4c 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -371,9 +371,6 @@ extern void _route_entry_dump(const char *func, union prefixconstptr pp, union prefixconstptr src_pp, const struct route_entry *re); -extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id); -extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id); - #define ZEBRA_RIB_LOOKUP_ERROR -1 #define ZEBRA_RIB_FOUND_EXACT 0 #define ZEBRA_RIB_FOUND_NOGATE 1 @@ -403,6 +400,11 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, struct nexthop_group *ng); +/* + * -1 -> some sort of error + * 0 -> an add + * 1 -> an update + */ extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index a64ec52dda..48ccf91ec7 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -861,6 +861,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, } memcpy(&src_p.prefix, src, 16); src_p.prefixlen = rtm->rtm_src_len; + } else { + /* We only handle the AFs we handle... */ + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: unknown address-family %u", __func__, + rtm->rtm_family); + return 0; } /* diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 27fb5d7c22..66208bfd80 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1937,6 +1937,11 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS) flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED, "%s: Nexthop Group Creation failed", __func__); + + /* Free any local allocations */ + nexthop_group_delete(&nhg); + zebra_nhg_backup_free(&bnhg); + return; } @@ -2110,6 +2115,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) ret = rib_add_multipath_nhe(afi, api.safi, &api.prefix, src_p, re, &nhe); + /* + * rib_add_multipath_nhe only fails in a couple spots + * and in those spots we have not freed memory + */ + if (ret == -1) { + client->error_cnt++; + XFREE(MTYPE_RE, re); + } + /* At this point, these allocations are not needed: 're' has been * retained or freed, and if 're' still exists, it is using * a reference to a shared group object. @@ -2121,15 +2135,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) /* Stats */ switch (api.prefix.family) { case AF_INET: - if (ret > 0) + if (ret == 0) client->v4_route_add_cnt++; - else if (ret < 0) + else if (ret == 1) client->v4_route_upd8_cnt++; break; case AF_INET6: - if (ret > 0) + if (ret == 0) client->v6_route_add_cnt++; - else if (ret < 0) + else if (ret == 1) client->v6_route_upd8_cnt++; break; } diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 0760b2ebb3..a547a97c24 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3495,18 +3495,6 @@ enum zebra_dplane_result dplane_intf_addr_set(const struct interface *ifp, return ZEBRA_DPLANE_REQUEST_FAILURE; } - - /* Ensure that no existing installed v4 route conflicts with - * the new interface prefix. This check must be done in the - * zebra pthread context, and any route delete (if needed) - * is enqueued before the interface address programming attempt. - */ - if (ifc->address->family == AF_INET) { - struct prefix_ipv4 *p; - - p = (struct prefix_ipv4 *)ifc->address; - rib_lookup_and_pushup(p, ifp->vrf_id); - } #endif return intf_addr_update_internal(ifp, ifc, DPLANE_OP_ADDR_INSTALL); diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index f44b19b781..c0cc57fc69 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -3920,8 +3920,18 @@ void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS) struct ipaddr nh; struct ethaddr rmac; struct prefix_evpn dummy_prefix; + size_t min_len = 4 + sizeof(nh); s = msg; + + /* + * Ensure that the stream sent to us is long enough + */ + if (hdr->command == ZEBRA_EVPN_REMOTE_NH_ADD) + min_len += sizeof(rmac); + if (hdr->length < min_len) + return; + vrf_id = stream_getl(s); stream_get(&nh, s, sizeof(nh)); @@ -3929,17 +3939,20 @@ void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS) dummy_prefix.family = AF_EVPN; dummy_prefix.prefixlen = (sizeof(struct evpn_addr) * 8); dummy_prefix.prefix.route_type = 1; /* XXX - fixup to type-1 def */ + dummy_prefix.prefix.ead_addr.ip.ipa_type = nh.ipa_type; if (hdr->command == ZEBRA_EVPN_REMOTE_NH_ADD) { stream_get(&rmac, s, sizeof(rmac)); if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("evpn remote nh %d %pIA rmac %pEA add", - vrf_id, &nh, &rmac); + zlog_debug( + "evpn remote nh %d %pIA rmac %pEA add pfx %pFX", + vrf_id, &nh, &rmac, &dummy_prefix); zebra_rib_queue_evpn_route_add(vrf_id, &rmac, &nh, (struct prefix *)&dummy_prefix); } else { if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("evpn remote nh %d %pIA del", vrf_id, &nh); + zlog_debug("evpn remote nh %d %pIA del pfx %pFX", + vrf_id, &nh, &dummy_prefix); zebra_rib_queue_evpn_route_del(vrf_id, &nh, (struct prefix *)&dummy_prefix); } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index c51dd759a6..1fb4e5e6fc 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -605,12 +605,9 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re, break; case ZEBRA_DPLANE_REQUEST_FAILURE: { - char str[SRCDEST2STR_BUFFER]; - - srcdest_rnode2str(rn, str, sizeof(str)); flog_err(EC_ZEBRA_DP_INSTALL_FAIL, - "%u:%u:%s: Failed to enqueue dataplane install", - re->vrf_id, re->table, str); + "%u:%u:%pRN: Failed to enqueue dataplane install", + re->vrf_id, re->table, rn); break; } case ZEBRA_DPLANE_REQUEST_SUCCESS: @@ -648,15 +645,10 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) zvrf->removals_queued++; break; case ZEBRA_DPLANE_REQUEST_FAILURE: - { - char str[SRCDEST2STR_BUFFER]; - - srcdest_rnode2str(rn, str, sizeof(str)); flog_err(EC_ZEBRA_DP_INSTALL_FAIL, - "%u:%s: Failed to enqueue dataplane uninstall", - re->vrf_id, str); + "%u:%pRN: Failed to enqueue dataplane uninstall", + re->vrf_id, rn); break; - } case ZEBRA_DPLANE_REQUEST_SUCCESS: if (zvrf) zvrf->removals++; @@ -666,46 +658,6 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re) return; } -/* Uninstall the route from kernel. */ -static void rib_uninstall(struct route_node *rn, struct route_entry *re) -{ - struct rib_table_info *info = srcdest_rnode_table_info(rn); - rib_dest_t *dest = rib_dest_from_rnode(rn); - struct nexthop *nexthop; - - if (dest && dest->selected_fib == re) { - if (info->safi == SAFI_UNICAST) - hook_call(rib_update, rn, "rib_uninstall"); - - /* If labeled-unicast route, uninstall transit LSP. */ - if (zebra_rib_labeled_unicast(re)) - zebra_mpls_lsp_uninstall(info->zvrf, rn, re); - - rib_uninstall_kernel(rn, re); - - dest->selected_fib = NULL; - - /* Free FIB nexthop group, if present */ - if (re->fib_ng.nexthop) { - nexthops_free(re->fib_ng.nexthop); - re->fib_ng.nexthop = NULL; - } - UNSET_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG); - - for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); - } - - if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) { - const struct prefix *p, *src_p; - - srcdest_rnode_prefixes(rn, &p, &src_p); - - redistribute_delete(p, src_p, re, NULL); - UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED); - } -} - /* * rib_can_delete_dest * @@ -753,15 +705,12 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) * would match a more specific route */ while (rn) { - if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_NHT_DETAILED) zlog_debug( - "%s: %s Being examined for Nexthop Tracking Count: %zd", - __func__, - srcdest_rnode2str(rn, buf, sizeof(buf)), + "%s: %pRN Being examined for Nexthop Tracking Count: %zd", + __func__, rn, dest ? rnh_list_count(&dest->nht) : 0); - } + if (!dest) { rn = rn->parent; if (rn) @@ -779,17 +728,12 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq) zebra_vrf_lookup_by_id(rnh->vrf_id); struct prefix *p = &rnh->node->p; - if (IS_ZEBRA_DEBUG_NHT_DETAILED) { - char buf1[PREFIX_STRLEN]; - + if (IS_ZEBRA_DEBUG_NHT_DETAILED) zlog_debug( - "%s(%u):%s has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u", + "%s(%u):%pRN has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u", zvrf_name(zvrf), zvrf_id(zvrf), - srcdest_rnode2str(rn, buf1, - sizeof(buf1)), - p, rnh_type2str(rnh->type), seq, + rn, p, rnh_type2str(rnh->type), seq, rnh->seqno); - } /* * If we have evaluated this node on this pass @@ -890,13 +834,10 @@ static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, return; } - if (IS_ZEBRA_DEBUG_RIB) { - char buf[SRCDEST2STR_BUFFER]; - srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug("%s(%u:%u):%s: Adding route rn %p, re %p (%s)", - zvrf_name(zvrf), zvrf_id(zvrf), new->table, buf, rn, + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s(%u:%u):%pRN: Adding route rn %p, re %p (%s)", + zvrf_name(zvrf), zvrf_id(zvrf), new->table, rn, rn, new, zebra_route_string(new->type)); - } /* If labeled-unicast route, install transit LSP. */ if (zebra_rib_labeled_unicast(new)) @@ -913,13 +854,10 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, hook_call(rib_update, rn, "removing existing route"); /* Uninstall from kernel. */ - if (IS_ZEBRA_DEBUG_RIB) { - char buf[SRCDEST2STR_BUFFER]; - srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug("%s(%u:%u):%s: Deleting route rn %p, re %p (%s)", - zvrf_name(zvrf), zvrf_id(zvrf), old->table, buf, rn, + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s)", + zvrf_name(zvrf), zvrf_id(zvrf), old->table, rn, rn, old, zebra_route_string(old->type)); - } /* If labeled-unicast route, uninstall transit LSP. */ if (zebra_rib_labeled_unicast(old)) @@ -965,22 +903,19 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, */ if (nh_active) { if (IS_ZEBRA_DEBUG_RIB) { - char buf[SRCDEST2STR_BUFFER]; - - srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) zlog_debug( - "%s(%u:%u):%s: Updating route rn %p, re %p (%s) old %p (%s)", + "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s) old %p (%s)", zvrf_name(zvrf), zvrf_id(zvrf), - new->table, buf, rn, new, + new->table, rn, rn, new, zebra_route_string(new->type), old, zebra_route_string(old->type)); else zlog_debug( - "%s(%u:%u):%s: Updating route rn %p, re %p (%s)", + "%s(%u:%u):%pRN: Updating route rn %p, re %p (%s)", zvrf_name(zvrf), zvrf_id(zvrf), - new->table, buf, rn, new, + new->table, rn, rn, new, zebra_route_string(new->type)); } @@ -1006,21 +941,19 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf, */ if (!nh_active) { if (IS_ZEBRA_DEBUG_RIB) { - char buf[SRCDEST2STR_BUFFER]; - srcdest_rnode2str(rn, buf, sizeof(buf)); if (new != old) zlog_debug( - "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive", + "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) old %p (%s) - nexthop inactive", zvrf_name(zvrf), zvrf_id(zvrf), - new->table, buf, rn, new, + new->table, rn, rn, new, zebra_route_string(new->type), old, zebra_route_string(old->type)); else zlog_debug( - "%s(%u:%u):%s: Deleting route rn %p, re %p (%s) - nexthop inactive", + "%s(%u:%u):%pRN: Deleting route rn %p, re %p (%s) - nexthop inactive", zvrf_name(zvrf), zvrf_id(zvrf), - new->table, buf, rn, new, + new->table, rn, rn, new, zebra_route_string(new->type)); } @@ -1137,7 +1070,6 @@ static void rib_process(struct route_node *rn) struct route_entry *old_fib = NULL; struct route_entry *new_fib = NULL; struct route_entry *best = NULL; - char buf[SRCDEST2STR_BUFFER]; rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; struct vrf *vrf; @@ -1149,15 +1081,17 @@ static void rib_process(struct route_node *rn) assert(rn); dest = rib_dest_from_rnode(rn); - if (dest) { - zvrf = rib_dest_vrf(dest); - vrf_id = zvrf_id(zvrf); - } + /* + * We have an enqueued node with nothing to process here + * let's just finish up and return; + */ + if (!dest) + return; - vrf = vrf_lookup_by_id(vrf_id); + zvrf = rib_dest_vrf(dest); + vrf_id = zvrf_id(zvrf); - if (IS_ZEBRA_DEBUG_RIB) - srcdest_rnode2str(rn, buf, sizeof(buf)); + vrf = vrf_lookup_by_id(vrf_id); /* * we can have rn's that have a NULL info pointer @@ -1165,26 +1099,24 @@ static void rib_process(struct route_node *rn) * additionally we know RNODE_FOREACH_RE_SAFE * will not iterate so we are ok. */ - if (dest) { - if (IS_ZEBRA_DEBUG_RIB_DETAILED) { - struct route_entry *re = re_list_first(&dest->routes); - - zlog_debug("%s(%u:%u):%s: Processing rn %p", - VRF_LOGNAME(vrf), vrf_id, re->table, buf, - rn); - } + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + struct route_entry *re = re_list_first(&dest->routes); - old_fib = dest->selected_fib; + zlog_debug("%s(%u:%u):%pRN: Processing rn %p", + VRF_LOGNAME(vrf), vrf_id, re->table, rn, + rn); } + old_fib = dest->selected_fib; + RNODE_FOREACH_RE_SAFE (rn, re, next) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char flags_buf[128]; char status_buf[128]; zlog_debug( - "%s(%u:%u):%s: Examine re %p (%s) status: %sflags: %sdist %d metric %d", - VRF_LOGNAME(vrf), vrf_id, re->table, buf, re, + "%s(%u:%u):%pRN: Examine re %p (%s) status: %sflags: %sdist %d metric %d", + VRF_LOGNAME(vrf), vrf_id, re->table, rn, re, zebra_route_string(re->type), _dump_re_status(re, status_buf, sizeof(status_buf)), @@ -1234,11 +1166,11 @@ static void rib_process(struct route_node *rn) if (re != old_selected) { if (IS_ZEBRA_DEBUG_RIB) zlog_debug( - "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map", + "%s: %s(%u):%pRN: imported via import-table but denied by the ip protocol table route-map", __func__, VRF_LOGNAME( vrf), - vrf_id, buf); + vrf_id, rn); rib_unlink(rn, re); } else SET_FLAG(re->status, @@ -1313,8 +1245,8 @@ static void rib_process(struct route_node *rn) : new_fib ? new_fib : NULL; zlog_debug( - "%s(%u:%u):%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", - VRF_LOGNAME(vrf), vrf_id, entry ? entry->table : 0, buf, + "%s(%u:%u):%pRN: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", + VRF_LOGNAME(vrf), vrf_id, entry ? entry->table : 0, rn, (void *)old_selected, (void *)new_selected, (void *)old_fib, (void *)new_fib); } @@ -2469,7 +2401,6 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) if (IS_ZEBRA_DEBUG_RIB_DETAILED) { struct route_entry *re = NULL; - char buf[SRCDEST2STR_BUFFER]; /* * rib_process may have freed the dest @@ -2480,10 +2411,9 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex) if (dest) re = re_list_first(&dest->routes); - srcdest_rnode2str(rnode, buf, sizeof(buf)); - zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u", + zlog_debug("%s(%u:%u):%pRN rn %p dequeued from sub-queue %u", zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, - buf, rnode, qindex); + rnode, rnode, qindex); } if (rnode->info) @@ -3190,13 +3120,10 @@ void rib_delnode(struct route_node *rn, struct route_entry *re) zebra_del_import_table_entry(zvrf, rn, re); /* Just clean up if non main table */ - if (IS_ZEBRA_DEBUG_RIB) { - char buf[SRCDEST2STR_BUFFER]; - srcdest_rnode2str(rn, buf, sizeof(buf)); - zlog_debug("%s(%u):%s: Freeing route rn %p, re %p (%s)", - vrf_id_to_name(re->vrf_id), re->vrf_id, buf, + if (IS_ZEBRA_DEBUG_RIB) + zlog_debug("%s(%u):%pRN: Freeing route rn %p, re %p (%s)", + vrf_id_to_name(re->vrf_id), re->vrf_id, rn, rn, re, zebra_route_string(re->type)); - } rib_unlink(rn, re); } else { @@ -3347,112 +3274,15 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, } /* - * This is an exported helper to rtm_read() to dump the strange - * RE entry found by rib_lookup_ipv4_route() - */ -void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) -{ - struct route_table *table; - struct route_node *rn; - struct route_entry *re; - struct vrf *vrf; - - vrf = vrf_lookup_by_id(vrf_id); - - /* Lookup table. */ - table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); - if (!table) { - flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED, - "%s:%s(%u) zebra_vrf_table() returned NULL", __func__, - VRF_LOGNAME(vrf), vrf_id); - return; - } - - /* Scan the RIB table for exactly matching RE entry. */ - rn = route_node_lookup(table, (struct prefix *)p); - - /* No route for this prefix. */ - if (!rn) { - zlog_debug("%s:%s(%u) lookup failed for %pFX", __func__, - VRF_LOGNAME(vrf), vrf_id, (struct prefix *)p); - return; - } - - /* Unlock node. */ - route_unlock_node(rn); - - /* let's go */ - RNODE_FOREACH_RE (rn, re) { - zlog_debug("%s:%s(%u) rn %p, re %p: %s, %s", __func__, - VRF_LOGNAME(vrf), vrf_id, (void *)rn, (void *)re, - (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED) - ? "removed" - : "NOT removed"), - (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED) - ? "selected" - : "NOT selected")); - route_entry_dump(p, NULL, re); - } -} - -/* Check if requested address assignment will fail due to another - * route being installed by zebra in FIB already. Take necessary - * actions, if needed: remove such a route from FIB and deSELECT - * corresponding RE entry. Then put affected RN into RIBQ head. - */ -void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) -{ - struct route_table *table; - struct route_node *rn; - rib_dest_t *dest; - - if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) { - struct vrf *vrf = vrf_lookup_by_id(vrf_id); - - flog_err(EC_ZEBRA_TABLE_LOOKUP_FAILED, - "%s:%s(%u) zebra_vrf_table() returned NULL", __func__, - VRF_LOGNAME(vrf), vrf_id); - return; - } - - /* No matches would be the simplest case. */ - if (NULL == (rn = route_node_lookup(table, (struct prefix *)p))) - return; - - /* Unlock node. */ - route_unlock_node(rn); - - dest = rib_dest_from_rnode(rn); - /* Check all RE entries. In case any changes have to be done, requeue - * the RN into RIBQ head. If the routing message about the new connected - * route (generated by the IP address we are going to assign very soon) - * comes before the RIBQ is processed, the new RE entry will join - * RIBQ record already on head. This is necessary for proper - * revalidation - * of the rest of the RE. - */ - if (dest->selected_fib) { - if (IS_ZEBRA_DEBUG_RIB) { - struct vrf *vrf = - vrf_lookup_by_id(dest->selected_fib->vrf_id); - - zlog_debug( - "%s(%u):%pFX: freeing way for connected prefix", - VRF_LOGNAME(vrf), dest->selected_fib->vrf_id, - &rn->p); - route_entry_dump(&rn->p, NULL, dest->selected_fib); - } - rib_uninstall(rn, dest->selected_fib); - rib_queue_add(rn); - } -} - -/* * Internal route-add implementation; there are a couple of different public * signatures. Callers in this path are responsible for the memory they * allocate: if they allocate a nexthop_group or backup nexthop info, they * must free those objects. If this returns < 0, an error has occurred and the * route_entry 're' has not been captured; the caller should free that also. + * + * -1 -> error + * 0 -> Add + * 1 -> update */ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, @@ -3567,11 +3397,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, SET_FLAG(re->status, ROUTE_ENTRY_CHANGED); rib_addnode(rn, re, 1); - ret = 1; /* Free implicit route.*/ - if (same) + if (same) { + ret = 1; rib_delnode(rn, same); + } /* See if we can remove some RE entries that are queued for * removal, but won't be considered in rib processing. diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1660792221..2fcaefdfbf 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -150,9 +150,28 @@ static int host_rb_entry_compare(const struct host_rb_entry *hle1, return memcmp(&hle1->p.u.prefix6, &hle2->p.u.prefix6, IPV6_MAX_BYTELEN); } else if (hle1->p.family == AF_EVPN) { - /* a single dummy prefix of route_type BGP_EVPN_AD_ROUTE is - * used for all nexthops associated with a non-zero ESI + uint8_t family1; + uint8_t family2; + + /* two (v4/v6) dummy prefixes of route_type BGP_EVPN_AD_ROUTE + * are used for all nexthops associated with a non-zero ESI */ + family1 = is_evpn_prefix_ipaddr_v4( + (const struct prefix_evpn *)&hle1->p) + ? AF_INET + : AF_INET6; + family2 = is_evpn_prefix_ipaddr_v4( + (const struct prefix_evpn *)&hle2->p) + ? AF_INET + : AF_INET6; + + + if (family1 < family2) + return -1; + + if (family1 > family2) + return 1; + return 0; } else { zlog_debug("%s: Unexpected family type: %d", __func__, |
