summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/debug.c12
-rw-r--r--zebra/if_netlink.c8
-rw-r--r--zebra/rib.h8
-rw-r--r--zebra/rt_netlink.c6
-rw-r--r--zebra/zapi_msg.c22
-rw-r--r--zebra/zebra_dplane.c12
-rw-r--r--zebra/zebra_evpn_mh.c19
-rw-r--r--zebra/zebra_rib.c287
-rw-r--r--zebra/zebra_vxlan.c23
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__,