summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_interface.c7
-rw-r--r--bgpd/bgp_evpn_vty.c69
-rw-r--r--bgpd/bgp_nexthop.c192
-rw-r--r--bgpd/bgp_nexthop.h2
-rw-r--r--bgpd/bgp_route.c142
-rw-r--r--bgpd/bgp_route.h1
-rw-r--r--bgpd/bgp_updgrp_adv.c95
-rw-r--r--bgpd/bgp_vty.c69
-rw-r--r--bgpd/bgpd.c12
-rw-r--r--doc/developer/building-frr-for-alpine.rst4
-rw-r--r--doc/user/bgp.rst4
-rw-r--r--isisd/isis_circuit.c37
-rw-r--r--lib/route_types.txt2
-rw-r--r--ospfd/ospf_abr.c2
-rw-r--r--ospfd/ospf_asbr.c16
-rw-r--r--ospfd/ospf_asbr.h2
-rw-r--r--ospfd/ospf_flood.c2
-rw-r--r--ospfd/ospf_lsa.c2
-rw-r--r--ospfd/ospf_vty.c12
-rw-r--r--ospfd/ospfd.c2
-rw-r--r--staticd/static_nht.c5
-rw-r--r--tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py15
-rw-r--r--tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json70
-rw-r--r--tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py29
-rw-r--r--tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py14
-rw-r--r--tests/topotests/mgmt_oper/oper.py17
-rw-r--r--tests/topotests/mgmt_oper/test_oper.py9
-rwxr-xr-xtools/frr-reload.py8
-rw-r--r--zebra/dpdk/zebra_dplane_dpdk.c120
-rw-r--r--zebra/zebra_evpn_mac.c13
-rw-r--r--zebra/zebra_nb_config.c15
-rw-r--r--zebra/zebra_nhg.c22
-rw-r--r--zebra/zebra_routemap.c9
33 files changed, 635 insertions, 385 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c
index b83c7b1908..f17842366a 100644
--- a/babeld/babel_interface.c
+++ b/babeld/babel_interface.c
@@ -719,6 +719,7 @@ babel_interface_close_all(void)
{
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
struct interface *ifp = NULL;
+ int type;
FOR_ALL_INTERFACES(vrf, ifp) {
if(!if_up(ifp))
@@ -740,8 +741,14 @@ babel_interface_close_all(void)
flushbuf(ifp);
usleep(roughly(10000));
gettime(&babel_now);
+ babel_enable_if_delete(ifp->name);
interface_reset(ifp);
}
+ /* Disable babel redistribution */
+ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+ zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
+ zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
+ }
}
/* return "true" if address is one of our ipv6 addresses */
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index d9dfc4c5eb..dc6e0d33c2 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -3108,6 +3108,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
afi_t afi;
safi_t safi;
uint32_t prefix_cnt, path_cnt;
+ int first = true;
afi = AFI_L2VPN;
safi = SAFI_EVPN;
@@ -3132,8 +3133,15 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
sizeof(rd_str), bgp->asnotation);
- if (json)
+ if (json) {
+ if (first) {
+ vty_out(vty, "\"%s\":", rd_str);
+ first = false;
+ } else {
+ vty_out(vty, ",\"%s\":", rd_str);
+ }
json_rd = json_object_new_object();
+ }
rd_header = 1;
@@ -3247,18 +3255,18 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
}
if (json) {
- if (add_rd_to_json)
- json_object_object_add(json, rd_str, json_rd);
- else {
+ if (add_rd_to_json) {
+ vty_json_no_pretty(vty, json_rd);
+ } else {
+ vty_out(vty, "{}");
json_object_free(json_rd);
- json_rd = NULL;
}
}
}
if (json) {
- json_object_int_add(json, "numPrefix", prefix_cnt);
- json_object_int_add(json, "numPaths", path_cnt);
+ vty_out(vty, ",\"numPrefix\":%u", prefix_cnt);
+ vty_out(vty, ",\"numPaths\":%u", path_cnt);
} else {
if (prefix_cnt == 0) {
vty_out(vty, "No EVPN prefixes %sexist\n",
@@ -3276,20 +3284,18 @@ int bgp_evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
{
json_object *json = NULL;
- if (use_json)
+ if (use_json) {
json = json_object_new_object();
+ vty_out(vty, "{\n");
+ }
evpn_show_all_routes(vty, bgp, type, json, detail, false);
- if (use_json)
- /*
- * We are using no_pretty here because under extremely high
- * settings (lots of routes with many different paths) this can
- * save several minutes of output when FRR is run on older cpu's
- * or more underperforming routers out there. So for route
- * scale, we need to use no_pretty json.
- */
- vty_json_no_pretty(vty, json);
+ if (use_json) {
+ vty_out(vty, "}\n");
+ json_object_free(json);
+ }
+
return CMD_SUCCESS;
}
@@ -4940,8 +4946,10 @@ DEFUN(show_bgp_l2vpn_evpn_route,
if (!bgp)
return CMD_WARNING;
- if (uj)
+ if (uj) {
json = json_object_new_object();
+ vty_out(vty, "{\n");
+ }
if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
return CMD_WARNING;
@@ -4954,13 +4962,10 @@ DEFUN(show_bgp_l2vpn_evpn_route,
evpn_show_all_routes(vty, bgp, type, json, detail, self_orig);
- /*
- * This is an extremely expensive operation at scale
- * and as such we need to save as much time as is
- * possible.
- */
- if (uj)
- vty_json_no_pretty(vty, json);
+ if (uj) {
+ vty_out(vty, "}\n");
+ json_object_free(json);
+ }
return CMD_SUCCESS;
}
@@ -5017,10 +5022,20 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
return CMD_WARNING;
- if (rd_all)
+ if (rd_all) {
+ if (uj)
+ vty_out(vty, "{\n");
+
evpn_show_all_routes(vty, bgp, type, json, 1, false);
- else
+
+ if (uj) {
+ vty_out(vty, "}\n");
+ json_object_free(json);
+ return CMD_SUCCESS;
+ }
+ } else {
evpn_show_route_rd(vty, bgp, &prd, type, json);
+ }
if (uj)
vty_json(vty, json);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 5fda5701f3..ed689c8bac 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -869,6 +869,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
? bnc->ifindex_ipv6_ll
: nexthop->ifindex,
bgp->vrf_id));
+ json_object_int_add(json_gate, "ifindex",
+ bnc->ifindex_ipv6_ll ? bnc->ifindex_ipv6_ll
+ : nexthop->ifindex);
break;
case NEXTHOP_TYPE_IPV4:
json_object_string_addf(json_gate, "ip", "%pI4",
@@ -882,6 +885,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
? bnc->ifindex_ipv6_ll
: nexthop->ifindex,
bgp->vrf_id));
+ json_object_int_add(json_gate, "ifindex",
+ bnc->ifindex_ipv6_ll ? bnc->ifindex_ipv6_ll
+ : nexthop->ifindex);
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
json_object_string_addf(json_gate, "ip", "%pI4",
@@ -893,6 +899,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
? bnc->ifindex_ipv6_ll
: nexthop->ifindex,
bgp->vrf_id));
+ json_object_int_add(json_gate, "ifindex",
+ bnc->ifindex_ipv6_ll ? bnc->ifindex_ipv6_ll
+ : nexthop->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_gate,
@@ -926,13 +935,13 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
vty_out(vty, " gate %pI6", &nexthop->gate.ipv6);
if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX &&
bnc->ifindex_ipv6_ll)
- vty_out(vty, ", if %s\n",
- ifindex2ifname(bnc->ifindex_ipv6_ll,
- bgp->vrf_id));
+ vty_out(vty, ", if %s, ifindex %d\n",
+ ifindex2ifname(bnc->ifindex_ipv6_ll, bgp->vrf_id),
+ bnc->ifindex_ipv6_ll);
else if (nexthop->ifindex)
- vty_out(vty, ", if %s\n",
- ifindex2ifname(nexthop->ifindex,
- bgp->vrf_id));
+ vty_out(vty, ", if %s, ifindex %d\n",
+ ifindex2ifname(nexthop->ifindex, bgp->vrf_id),
+ nexthop->ifindex);
else
vty_out(vty, "\n");
break;
@@ -941,22 +950,22 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
vty_out(vty, " gate %pI4", &nexthop->gate.ipv4);
if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX &&
bnc->ifindex_ipv6_ll)
- vty_out(vty, ", if %s\n",
- ifindex2ifname(bnc->ifindex_ipv6_ll,
- bgp->vrf_id));
+ vty_out(vty, ", if %s, ifindex %d\n",
+ ifindex2ifname(bnc->ifindex_ipv6_ll, bgp->vrf_id),
+ bnc->ifindex_ipv6_ll);
else if (nexthop->ifindex)
- vty_out(vty, ", if %s\n",
- ifindex2ifname(nexthop->ifindex,
- bgp->vrf_id));
+ vty_out(vty, ", if %s, ifindex %d\n",
+ ifindex2ifname(nexthop->ifindex, bgp->vrf_id),
+ nexthop->ifindex);
else
vty_out(vty, "\n");
break;
case NEXTHOP_TYPE_IFINDEX:
- vty_out(vty, " if %s\n",
- ifindex2ifname(bnc->ifindex_ipv6_ll
- ? bnc->ifindex_ipv6_ll
- : nexthop->ifindex,
- bgp->vrf_id));
+ vty_out(vty, " if %s, ifindex %d\n",
+ ifindex2ifname(bnc->ifindex_ipv6_ll ? bnc->ifindex_ipv6_ll
+ : nexthop->ifindex,
+ bgp->vrf_id),
+ bnc->ifindex_ipv6_ll ? bnc->ifindex_ipv6_ll : nexthop->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " blackhole\n");
@@ -970,9 +979,8 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
json_object_object_add(json, "nexthops", json_gates);
}
-static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
- struct bgp_nexthop_cache *bnc, bool specific,
- json_object *json)
+static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp, struct bgp_nexthop_cache *bnc,
+ bool detail, bool uj)
{
char buf[PREFIX2STR_BUFFER];
time_t tbuf;
@@ -983,10 +991,10 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
peer = (struct peer *)bnc->nht_info;
- if (json)
+ if (uj)
json_nexthop = json_object_new_object();
if (bnc->srte_color) {
- if (json)
+ if (uj)
json_object_int_add(json_nexthop, "srteColor",
bnc->srte_color);
else
@@ -994,7 +1002,7 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
}
inet_ntop(bnc->prefix.family, &bnc->prefix.u.prefix, buf, sizeof(buf));
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
- if (json) {
+ if (uj) {
json_object_boolean_true_add(json_nexthop, "valid");
json_object_boolean_true_add(json_nexthop, "complete");
json_object_int_add(json_nexthop, "igpMetric",
@@ -1022,7 +1030,7 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
}
bgp_show_nexthops_detail(vty, bgp, bnc, json_nexthop);
} else if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE)) {
- if (json) {
+ if (uj) {
json_object_boolean_true_add(json_nexthop, "valid");
json_object_boolean_false_add(json_nexthop, "complete");
json_object_int_add(json_nexthop, "igpMetric",
@@ -1042,7 +1050,7 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
}
bgp_show_nexthops_detail(vty, bgp, bnc, json_nexthop);
} else {
- if (json) {
+ if (uj) {
json_object_boolean_false_add(json_nexthop, "valid");
json_object_boolean_false_add(json_nexthop, "complete");
json_object_int_add(json_nexthop, "pathCount",
@@ -1074,8 +1082,8 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
}
}
tbuf = time(NULL) - (monotime(NULL) - bnc->last_update);
- if (json) {
- if (!specific) {
+ if (uj) {
+ if (detail) {
json_last_update = json_object_new_object();
json_object_int_add(json_last_update, "epoch", tbuf);
json_object_string_add(json_last_update, "string",
@@ -1090,22 +1098,25 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
}
/* show paths dependent on nexthop, if needed. */
- if (specific)
+ if (detail)
bgp_show_nexthop_paths(vty, bgp, bnc, json_nexthop);
- if (json)
- json_object_object_add(json, buf, json_nexthop);
+
+ if (uj) {
+ vty_out(vty, "\"%s\":", buf);
+ vty_json_no_pretty(vty, json_nexthop);
+ }
}
-static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
- bool import_table, json_object *json, afi_t afi,
- bool detail)
+static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, bool import_table, bool uj,
+ afi_t afi, bool detail)
{
struct bgp_nexthop_cache *bnc;
struct bgp_nexthop_cache_head(*tree)[AFI_MAX];
- json_object *json_afi = NULL;
bool found = false;
+ bool firstafi = true;
+ bool firstnh = true;
- if (!json) {
+ if (!uj) {
if (import_table)
vty_out(vty, "Current BGP import check cache:\n");
else
@@ -1117,34 +1128,42 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
tree = &bgp->nexthop_cache_table;
if (afi == AFI_IP || afi == AFI_IP6) {
- if (json)
- json_afi = json_object_new_object();
+ if (uj)
+ vty_out(vty, "%s:{", (afi == AFI_IP) ? "\"ipv4\"" : "\"ipv6\"");
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc) {
- bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
+ if (uj)
+ vty_out(vty, "%s", firstnh ? "" : ",");
+ bgp_show_nexthop(vty, bgp, bnc, detail, uj);
found = true;
+ firstnh = false;
}
- if (found && json)
- json_object_object_add(
- json, (afi == AFI_IP) ? "ipv4" : "ipv6",
- json_afi);
+ if (found && uj)
+ vty_out(vty, "}");
return;
}
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- if (json && (afi == AFI_IP || afi == AFI_IP6))
- json_afi = json_object_new_object();
- frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc)
- bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
- if (json && (afi == AFI_IP || afi == AFI_IP6))
- json_object_object_add(
- json, (afi == AFI_IP) ? "ipv4" : "ipv6",
- json_afi);
+ if (afi != AFI_IP && afi != AFI_IP6)
+ continue;
+ if (uj)
+ vty_out(vty, "%s%s:{", firstafi ? "" : ",",
+ (afi == AFI_IP) ? "\"ipv4\"" : "\"ipv6\"");
+ firstafi = false;
+ firstnh = true;
+ frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc) {
+ if (uj)
+ vty_out(vty, "%s", firstnh ? "" : ",");
+ bgp_show_nexthop(vty, bgp, bnc, detail, uj);
+ firstnh = false;
+ }
+
+ if (uj)
+ vty_out(vty, "}");
}
}
-static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
- const char *nhopip_str, bool import_table,
- json_object *json, afi_t afi, bool detail)
+static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name, const char *nhopip_str,
+ bool import_table, bool uj, afi_t afi, bool detail)
{
struct bgp *bgp;
@@ -1153,7 +1172,7 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
else
bgp = bgp_get_default();
if (!bgp) {
- if (!json)
+ if (!uj)
vty_out(vty, "%% No such BGP instance exist\n");
return CMD_WARNING;
}
@@ -1163,61 +1182,57 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
struct bgp_nexthop_cache_head (*tree)[AFI_MAX];
struct bgp_nexthop_cache *bnc;
bool found = false;
- json_object *json_afi = NULL;
if (!str2prefix(nhopip_str, &nhop)) {
- if (!json)
+ if (!uj)
vty_out(vty, "nexthop address is malformed\n");
return CMD_WARNING;
}
tree = import_table ? &bgp->import_check_table
: &bgp->nexthop_cache_table;
- if (json)
- json_afi = json_object_new_object();
+ if (uj)
+ vty_out(vty, "%s:{",
+ (family2afi(nhop.family) == AFI_IP) ? "\"ipv4\"" : "\"ipv6\"");
frr_each (bgp_nexthop_cache, &(*tree)[family2afi(nhop.family)],
bnc) {
if (prefix_cmp(&bnc->prefix, &nhop))
continue;
- bgp_show_nexthop(vty, bgp, bnc, true, json_afi);
+ bgp_show_nexthop(vty, bgp, bnc, true, uj);
found = true;
}
- if (json)
- json_object_object_add(
- json,
- (family2afi(nhop.family) == AFI_IP) ? "ipv4"
- : "ipv6",
- json_afi);
- if (!found && !json)
+ if (!found && !uj)
vty_out(vty, "nexthop %s does not have entry\n",
nhopip_str);
+
+ if (uj)
+ vty_out(vty, "}");
} else
- bgp_show_nexthops(vty, bgp, import_table, json, afi, detail);
+ bgp_show_nexthops(vty, bgp, import_table, uj, afi, detail);
return CMD_SUCCESS;
}
-static void bgp_show_all_instances_nexthops_vty(struct vty *vty,
- json_object *json, afi_t afi,
- bool detail)
+static void bgp_show_all_instances_nexthops_vty(struct vty *vty, bool uj, afi_t afi, bool detail)
{
struct listnode *node, *nnode;
struct bgp *bgp;
const char *inst_name;
- json_object *json_instance = NULL;
+ bool firstinst = true;
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
inst_name = (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
? VRF_DEFAULT_NAME
: bgp->name;
- if (json)
- json_instance = json_object_new_object();
+ if (uj)
+ vty_out(vty, "%s\"%s\":{", firstinst ? "" : ",", inst_name);
+
else
vty_out(vty, "\nInstance %s:\n", inst_name);
- bgp_show_nexthops(vty, bgp, false, json_instance, afi, detail);
-
- if (json)
- json_object_object_add(json, inst_name, json_instance);
+ bgp_show_nexthops(vty, bgp, false, uj, afi, detail);
+ firstinst = false;
+ if (uj)
+ vty_out(vty, "}");
}
}
@@ -1241,20 +1256,18 @@ DEFPY (show_ip_bgp_nexthop,
JSON_STR)
{
int rc = 0;
- json_object *json = NULL;
afi_t afiz = AFI_UNSPEC;
if (uj)
- json = json_object_new_object();
+ vty_out(vty, "{\n");
if (afi)
afiz = bgp_vty_afi_from_str(afi);
- rc = show_ip_bgp_nexthop_table(vty, vrf, nhop_str, false, json, afiz,
- detail);
+ rc = show_ip_bgp_nexthop_table(vty, vrf, nhop_str, false, uj, afiz, detail);
if (uj)
- vty_json(vty, json);
+ vty_out(vty, "}\n");
return rc;
}
@@ -1271,16 +1284,14 @@ DEFPY (show_ip_bgp_import_check,
JSON_STR)
{
int rc = 0;
- json_object *json = NULL;
if (uj)
- json = json_object_new_object();
+ vty_out(vty, "{\n");
- rc = show_ip_bgp_nexthop_table(vty, vrf, NULL, true, json, AFI_UNSPEC,
- detail);
+ rc = show_ip_bgp_nexthop_table(vty, vrf, NULL, true, uj, AFI_UNSPEC, detail);
if (uj)
- vty_json(vty, json);
+ vty_out(vty, "}\n");
return rc;
}
@@ -1298,19 +1309,18 @@ DEFPY (show_ip_bgp_instance_all_nexthop,
"Show detailed information\n"
JSON_STR)
{
- json_object *json = NULL;
afi_t afiz = AFI_UNSPEC;
if (uj)
- json = json_object_new_object();
+ vty_out(vty, "{");
if (afi)
afiz = bgp_vty_afi_from_str(afi);
- bgp_show_all_instances_nexthops_vty(vty, json, afiz, detail);
+ bgp_show_all_instances_nexthops_vty(vty, uj, afiz, detail);
if (uj)
- vty_json(vty, json);
+ vty_out(vty, "}");
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index 6a4a02dcc8..5679c215b1 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -82,7 +82,7 @@ struct bgp_nexthop_cache {
* L3 unreachable | VALID = 0 | VALID = 0
* | INCOMPLETE = 0 | INCOMPLETE = 0
*/
-#define BGP_NEXTHOP_EVPN_INCOMPLETE (1 << 7)
+#define BGP_NEXTHOP_EVPN_INCOMPLETE (1 << 8)
uint32_t srte_color;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index bd2fda56fc..5ac1d26603 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -11975,14 +11975,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa
continue;
}
- if (type == bgp_show_type_rpki) {
- if (dest_p->family == AF_INET
- || dest_p->family == AF_INET6)
- rpki_curr_state = hook_call(
- bgp_rpki_prefix_status,
- pi->peer, pi->attr, dest_p);
- if (rpki_target_state != RPKI_NOT_BEING_USED
- && rpki_curr_state != rpki_target_state)
+ if ((dest_p->family == AF_INET || dest_p->family == AF_INET6) &&
+ (detail_routes || detail_json || type == bgp_show_type_rpki)) {
+ rpki_curr_state = hook_call(bgp_rpki_prefix_status, pi->peer,
+ pi->attr, dest_p);
+ if (type == bgp_show_type_rpki &&
+ rpki_target_state != RPKI_NOT_BEING_USED &&
+ rpki_curr_state != rpki_target_state)
continue;
}
@@ -12213,7 +12212,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa
route_vty_out_detail(vty, bgp, dest, dest_p, pi,
family2afi(dest_p->family), safi,
- RPKI_NOT_BEING_USED, json_paths, NULL);
+ rpki_curr_state, json_paths, NULL);
} else {
route_vty_out(vty, dest_p, pi, display,
safi, json_paths, wide);
@@ -15107,6 +15106,8 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
json_object *json = NULL;
json_object *json_ar = NULL;
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
+ bool first = true;
+ struct update_subgroup *subgrp;
/* Init BGP headers here so they're only displayed once
* even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
@@ -15175,6 +15176,28 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
else
table = bgp->rib[afi][safi];
+ subgrp = peer_subgroup(peer, afi, safi);
+ if (use_json) {
+ if (type == bgp_show_adj_route_advertised || type == bgp_show_adj_route_received) {
+ if (header1) {
+ int version = table ? table->version : 0;
+ vty_out(vty, "\"bgpTableVersion\":%d", version);
+ vty_out(vty, ",\"bgpLocalRouterId\":\"%pI4\"", &bgp->router_id);
+ vty_out(vty, ",\"defaultLocPrf\":%u", bgp->default_local_pref);
+ vty_out(vty, ",\"localAS\":%u", bgp->as);
+ if (type == bgp_show_adj_route_advertised && subgrp &&
+ CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
+ vty_out(vty, ",\"bgpOriginatingDefaultNetwork\":\"%s\"",
+ (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
+ }
+
+ if (type == bgp_show_adj_route_advertised)
+ vty_out(vty, ",\"advertisedRoutes\": ");
+ if (type == bgp_show_adj_route_received)
+ vty_out(vty, ",\"receivedRoutes\": ");
+ }
+ }
+
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
|| (safi == SAFI_EVPN)) {
@@ -15193,6 +15216,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
json_routes = json_object_new_object();
const struct prefix_rd *prd;
+
prd = (const struct prefix_rd *)bgp_dest_get_prefix(
dest);
@@ -15206,34 +15230,56 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
&filtered_count_per_rd);
/* Don't include an empty RD in the output! */
- if (json_routes && (output_count_per_rd > 0))
- json_object_object_add(json_ar, rd_str,
- json_routes);
+ if (json_routes && (output_count_per_rd > 0) && use_json) {
+ if (type == bgp_show_adj_route_advertised ||
+ type == bgp_show_adj_route_received) {
+ if (first) {
+ vty_out(vty, "\"%s\":", rd_str);
+ first = false;
+ } else {
+ vty_out(vty, ",\"%s\":", rd_str);
+ }
+ vty_json_no_pretty(vty, json_routes);
+ } else {
+ json_object_object_add(json_ar, rd_str, json_routes);
+ }
+ }
output_count += output_count_per_rd;
filtered_count += filtered_count_per_rd;
}
- } else
+ } else {
show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
json, json_ar, show_flags, &header1, &header2,
rd_str, match, &output_count, &filtered_count);
+ if (use_json) {
+ if (type == bgp_show_adj_route_advertised ||
+ type == bgp_show_adj_route_received) {
+ vty_json_no_pretty(vty, json_ar);
+ }
+ }
+ }
+
if (use_json) {
- if (type == bgp_show_adj_route_advertised)
- json_object_object_add(json, "advertisedRoutes",
- json_ar);
- else
+ if (type == bgp_show_adj_route_advertised || type == bgp_show_adj_route_received) {
+ vty_out(vty, ",\"totalPrefixCounter\":%lu", output_count);
+ vty_out(vty, ",\"filteredPrefixCounter\":%lu", filtered_count);
+ json_object_free(json);
+ } else {
+ /* for bgp_show_adj_route_filtered & bgp_show_adj_route_bestpath type */
json_object_object_add(json, "receivedRoutes", json_ar);
- json_object_int_add(json, "totalPrefixCounter", output_count);
- json_object_int_add(json, "filteredPrefixCounter",
- filtered_count);
-
- /*
- * This is an extremely expensive operation at scale
- * and non-pretty reduces memory footprint significantly.
- */
- vty_json_no_pretty(vty, json);
- } else if (output_count > 0) {
+ json_object_int_add(json, "totalPrefixCounter", output_count);
+ json_object_int_add(json, "filteredPrefixCounter", filtered_count);
+ }
+
+ /*
+ * This is an extremely expensive operation at scale
+ * and non-pretty reduces memory footprint significantly.
+ */
+ if ((type != bgp_show_adj_route_advertised) && (type != bgp_show_adj_route_received))
+ vty_json_no_pretty(vty, json);
+ } else if (output_count > 0) {
if (!match && filtered_count > 0)
vty_out(vty,
"\nTotal number of prefixes %ld (%ld filtered)\n",
@@ -15336,6 +15382,7 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
uint16_t show_flags = 0;
struct listnode *node;
struct bgp *abgp;
+ int ret;
if (detail || prefix_str)
SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
@@ -15377,9 +15424,22 @@ DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
else if (argv_find(argv, argc, "filtered-routes", &idx))
type = bgp_show_adj_route_filtered;
- if (!all)
- return peer_adj_routes(vty, peer, afi, safi, type, route_map,
- prefix_str ? prefix : NULL, show_flags);
+ if (!all) {
+ if (uj)
+ if (type == bgp_show_adj_route_advertised ||
+ type == bgp_show_adj_route_received)
+ vty_out(vty, "{\n");
+
+ ret = peer_adj_routes(vty, peer, afi, safi, type, route_map,
+ prefix_str ? prefix : NULL, show_flags);
+ if (uj)
+ if (type == bgp_show_adj_route_advertised ||
+ type == bgp_show_adj_route_received)
+ vty_out(vty, "}\n");
+
+ return ret;
+ }
+
if (uj)
vty_out(vty, "{\n");
@@ -15778,6 +15838,28 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
return CMD_SUCCESS;
}
+void bgp_address_family_distance_delete(void)
+{
+ afi_t afi = AFI_UNSPEC;
+ safi_t safi = SAFI_UNSPEC;
+ struct bgp_dest *dest = NULL;
+ struct bgp_distance *bdistance = NULL;
+
+ FOREACH_AFI_SAFI (afi, safi) {
+ for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
+ dest = bgp_route_next(dest)) {
+ if (!bgp_dest_has_bgp_path_info_data(dest))
+ continue;
+ bdistance = bgp_dest_get_bgp_distance_info(dest);
+ XFREE(MTYPE_AS_LIST, bdistance->access_list);
+ bgp_distance_free(bdistance);
+
+ bgp_dest_set_bgp_distance_info(dest, NULL);
+ bgp_dest_unlock_node(dest);
+ }
+ }
+}
+
/* Apply BGP information to distance method. */
uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
afi_t afi, safi_t safi, struct bgp *bgp)
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index bde0580d6c..474e229575 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -831,6 +831,7 @@ extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, unsigned short);
extern void bgp_static_add(struct bgp *);
extern void bgp_static_delete(struct bgp *);
+extern void bgp_address_family_distance_delete(void);
extern void bgp_static_redo_import_check(struct bgp *);
extern void bgp_purge_static_redist_routes(struct bgp *bgp);
extern void bgp_static_update(struct bgp *bgp, const struct prefix *p,
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c
index a1bf9a4c61..8f816eb30d 100644
--- a/bgpd/bgp_updgrp_adv.c
+++ b/bgpd/bgp_updgrp_adv.c
@@ -228,64 +228,67 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
afi2str(afi), safi2str(safi), ctx->dest);
UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
- /* withdraw stale addpath without waiting for the coalesce timer timeout.
- * Otherwise, since adj->addpath_tx_id is overwritten, the code never
- * notice anymore it has to do a withdrawal.
- */
- if (addpath_capable)
- subgrp_withdraw_stale_addpath(ctx, subgrp);
- /*
- * Skip the subgroups that have coalesce timer running. We will
- * walk the entire prefix table for those subgroups when the
- * coalesce timer fires.
- */
- if (!subgrp->t_coalesce) {
-
- /* An update-group that uses addpath */
- if (addpath_capable) {
- subgrp_announce_addpath_best_selected(ctx->dest,
- subgrp);
+ /* An update-group that uses addpath */
+ if (addpath_capable) {
+ /* Send withdrawals without waiting for coalesting timer
+ * to expire.
+ */
+ if (subgrp->t_coalesce) {
+ subgrp_withdraw_stale_addpath(ctx, subgrp);
- /* Process the bestpath last so the "show [ip]
- * bgp neighbor x.x.x.x advertised"
- * output shows the attributes from the bestpath
- */
- if (ctx->pi)
- subgroup_process_announce_selected(
- subgrp, ctx->pi, ctx->dest, afi,
- safi,
- bgp_addpath_id_for_peer(
- peer, afi, safi,
- &ctx->pi->tx_addpath));
+ goto done;
}
- /* An update-group that does not use addpath */
- else {
- if (ctx->pi) {
- subgroup_process_announce_selected(
- subgrp, ctx->pi, ctx->dest, afi,
- safi,
- bgp_addpath_id_for_peer(
- peer, afi, safi,
- &ctx->pi->tx_addpath));
- } else {
- /* Find the addpath_tx_id of the path we
- * had advertised and
- * send a withdraw */
- RB_FOREACH_SAFE (adj, bgp_adj_out_rb,
- &ctx->dest->adj_out,
+
+ subgrp_withdraw_stale_addpath(ctx, subgrp);
+ subgrp_announce_addpath_best_selected(ctx->dest, subgrp);
+
+ /* Process the bestpath last so the
+ * "show [ip] bgp neighbor x.x.x.x advertised" output shows
+ * the attributes from the bestpath.
+ */
+ if (ctx->pi)
+ subgroup_process_announce_selected(
+ subgrp, ctx->pi, ctx->dest, afi, safi,
+ bgp_addpath_id_for_peer(peer, afi, safi,
+ &ctx->pi->tx_addpath));
+ } else {
+ /* Send withdrawals without waiting for coalesting timer
+ * to expire.
+ */
+ if (subgrp->t_coalesce) {
+ if (!ctx->pi || CHECK_FLAG(ctx->pi->flags, BGP_PATH_UNUSEABLE)) {
+ RB_FOREACH_SAFE (adj, bgp_adj_out_rb, &ctx->dest->adj_out,
adj_next) {
if (adj->subgroup == subgrp) {
subgroup_process_announce_selected(
- subgrp, NULL,
- ctx->dest, afi,
- safi,
+ subgrp, NULL, ctx->dest, afi, safi,
adj->addpath_tx_id);
}
}
}
+
+ goto done;
+ }
+
+ if (ctx->pi) {
+ subgroup_process_announce_selected(
+ subgrp, ctx->pi, ctx->dest, afi, safi,
+ bgp_addpath_id_for_peer(peer, afi, safi,
+ &ctx->pi->tx_addpath));
+ } else {
+ RB_FOREACH_SAFE (adj, bgp_adj_out_rb, &ctx->dest->adj_out,
+ adj_next) {
+ if (adj->subgroup == subgrp) {
+ subgroup_process_announce_selected(subgrp, NULL,
+ ctx->dest, afi,
+ safi,
+ adj->addpath_tx_id);
+ }
+ }
}
}
+done:
/* Notify BGP Conditional advertisement */
bgp_notify_conditional_adv_scanner(subgrp);
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 2da77c314d..c6b09481b6 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -11488,6 +11488,72 @@ DEFPY (show_bgp_vrfs,
return CMD_SUCCESS;
}
+DEFPY(show_bgp_router,
+ show_bgp_router_cmd,
+ "show bgp router [json]",
+ SHOW_STR
+ BGP_STR
+ "Overall BGP information\n"
+ JSON_STR)
+{
+ char timebuf[MONOTIME_STRLEN];
+ time_t unix_timestamp;
+ bool uj = use_json(argc, argv);
+ json_object *json = NULL;
+
+ if (uj)
+ json = json_object_new_object();
+
+ time_to_string(bm->start_time, timebuf);
+
+ if (uj) {
+ unix_timestamp = time(NULL) - (monotime(NULL) - bm->start_time);
+ json_object_int_add(json, "bgpStartedAt", unix_timestamp);
+ json_object_boolean_add(json, "bgpStartedGracefully",
+ CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART));
+ }
+
+ if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART)) {
+ if (!uj)
+ vty_out(vty, "BGP started gracefully at %s", timebuf);
+ else
+ json_object_boolean_add(json, "grComplete",
+ CHECK_FLAG(bm->flags, BM_FLAG_GR_COMPLETE));
+
+ if (CHECK_FLAG(bm->flags, BM_FLAG_GR_COMPLETE)) {
+ time_to_string(bm->gr_completion_time, timebuf);
+ if (uj) {
+ unix_timestamp = time(NULL) -
+ (monotime(NULL) - bm->gr_completion_time);
+ json_object_int_add(json, "grCompletedAt", unix_timestamp);
+ } else
+ vty_out(vty, "Graceful restart completed at %s", timebuf);
+ } else {
+ if (!uj)
+ vty_out(vty, "Graceful restart is in progress\n");
+ }
+ } else {
+ if (!uj)
+ vty_out(vty, "BGP started at %s", timebuf);
+ }
+
+ if (uj) {
+ json_object_boolean_add(json, "bgpInMaintenanceMode",
+ (CHECK_FLAG(bm->flags, BM_FLAG_MAINTENANCE_MODE)));
+ json_object_int_add(json, "bgpInstanceCount", listcount(bm->bgp));
+
+ vty_json(vty, json);
+ } else {
+ if (CHECK_FLAG(bm->flags, BM_FLAG_MAINTENANCE_MODE))
+ vty_out(vty, "BGP is in Maintenance mode (BGP GSHUT is in effect)\n");
+
+ vty_out(vty, "Number of BGP instances (including default): %d\n",
+ listcount(bm->bgp));
+ }
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_bgp_mac_hash,
show_bgp_mac_hash_cmd,
"show bgp mac hash",
@@ -21939,6 +22005,9 @@ void bgp_vty_init(void)
/* "show [ip] bgp vrfs" commands. */
install_element(VIEW_NODE, &show_bgp_vrfs_cmd);
+ /* Some overall BGP information */
+ install_element(VIEW_NODE, &show_bgp_router_cmd);
+
/* Community-list. */
community_list_vty();
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index f0b4f6c262..05bc804db4 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4244,6 +4244,14 @@ int bgp_delete(struct bgp *bgp)
}
}
+ /* Clean BGP address family parameters */
+ bgp_mh_info->ead_evi_rx = BGP_EVPN_MH_EAD_EVI_RX_DEF;
+ bgp_evpn_switch_ead_evi_rx();
+ bgp_mh_info->ead_evi_tx = BGP_EVPN_MH_EAD_EVI_TX_DEF;
+ bgp_mh_info->evi_per_es_frag = BGP_EVPN_MAX_EVI_PER_ES_FRAG;
+
+ bgp_address_family_distance_delete();
+
return 0;
}
@@ -6682,7 +6690,7 @@ int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
SET_FLAG(member->af_flags[afi][safi],
PEER_FLAG_ALLOWAS_IN_ORIGIN);
member->allowas_in[afi][safi] = 0;
- peer_on_policy_change(peer, afi, safi, 0);
+ peer_on_policy_change(member, afi, safi, 0);
}
} else {
if (member->allowas_in[afi][safi] != allow_num
@@ -6691,7 +6699,7 @@ int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
UNSET_FLAG(member->af_flags[afi][safi],
PEER_FLAG_ALLOWAS_IN_ORIGIN);
member->allowas_in[afi][safi] = allow_num;
- peer_on_policy_change(peer, afi, safi, 0);
+ peer_on_policy_change(member, afi, safi, 0);
}
}
}
diff --git a/doc/developer/building-frr-for-alpine.rst b/doc/developer/building-frr-for-alpine.rst
index 68e58c9d76..a5ce636ebb 100644
--- a/doc/developer/building-frr-for-alpine.rst
+++ b/doc/developer/building-frr-for-alpine.rst
@@ -47,11 +47,11 @@ Build apk packages
./docker/alpine/build.sh
-This will put the apk packages in:
+This will put the apk packages into the architecture folder in:
::
- ./docker/pkgs/apk/x86_64/
+ ./docker/alpine/pkgs/apk/
Usage
-----
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index dafcac7c84..3642681765 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -4350,6 +4350,10 @@ displays IPv6 routing table.
If ``detail`` option is specified after ``json``, more verbose JSON output
will be displayed.
+.. clicmd:: show bgp router [json]
+
+ This command displays information related BGP router and Graceful Restart.
+
Some other commands provide additional options for filtering the output.
.. clicmd:: show [ip] bgp regexp LINE
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index 9a967bc1e3..9ea2cfd0a1 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -1008,45 +1008,40 @@ void isis_circuit_print_json(struct isis_circuit *circuit,
circuit_t2string(level));
if (circuit->area->newmetric)
json_object_int_add(level_json, "metric",
- circuit->te_metric[0]);
+ circuit->te_metric[level - 1]);
else
json_object_int_add(level_json, "metric",
- circuit->metric[0]);
+ circuit->metric[level - 1]);
if (!circuit->is_passive) {
- json_object_int_add(level_json,
- "active-neighbors",
- circuit->upadjcount[0]);
- json_object_int_add(level_json,
- "hello-interval",
- circuit->hello_interval[0]);
+ json_object_int_add(level_json, "active-neighbors",
+ circuit->upadjcount[level - 1]);
+ json_object_int_add(level_json, "hello-interval",
+ circuit->hello_interval[level - 1]);
hold_json = json_object_new_object();
json_object_object_add(level_json, "holddown",
hold_json);
- json_object_int_add(
- hold_json, "count",
- circuit->hello_multiplier[0]);
+ json_object_int_add(hold_json, "count",
+ circuit->hello_multiplier[level - 1]);
json_object_string_add(
hold_json, "pad",
isis_hello_padding2string(
circuit->pad_hellos));
json_object_int_add(level_json, "cnsp-interval",
- circuit->csnp_interval[0]);
+ circuit->csnp_interval[level - 1]);
json_object_int_add(level_json, "psnp-interval",
- circuit->psnp_interval[0]);
+ circuit->psnp_interval[level - 1]);
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
lan_prio_json =
json_object_new_object();
json_object_object_add(level_json,
"lan",
lan_prio_json);
- json_object_int_add(
- lan_prio_json, "priority",
- circuit->priority[0]);
- json_object_string_add(
- lan_prio_json, "is-dis",
- (circuit->u.bc.is_dr[0]
- ? "yes"
- : "no"));
+ json_object_int_add(lan_prio_json, "priority",
+ circuit->priority[level - 1]);
+ json_object_string_add(lan_prio_json, "is-dis",
+ (circuit->u.bc.is_dr[level - 1]
+ ? "yes"
+ : "no"));
}
}
json_object_array_add(levels_json, level_json);
diff --git a/lib/route_types.txt b/lib/route_types.txt
index 93cbc36e97..b5f8b6fdf3 100644
--- a/lib/route_types.txt
+++ b/lib/route_types.txt
@@ -88,7 +88,7 @@ ZEBRA_ROUTE_VRRP, vrrp, vrrpd, '-', 0, 0, 0, "VRRP", vr
ZEBRA_ROUTE_NHG, zebra, none, '-', 0, 0, 0, "Nexthop Group", none
ZEBRA_ROUTE_SRTE, srte, none, '-', 0, 0, 0, "SR-TE", none
ZEBRA_ROUTE_TABLE_DIRECT, table-direct, zebra, 't', 1, 1, 1, "Table-Direct", zebra
-ZEBRA_ROUTE_ALL, wildcard, none, '-', 0, 0, 0, "-", none
+ZEBRA_ROUTE_ALL, any, none, '-', 0, 0, 0, "-", none
## help strings
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 93779991b5..eed1bfcb30 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -1823,7 +1823,7 @@ static void ospf_abr_nssa_type7_default_create(struct ospf *ospf,
"Announcing Type-7 default route into NSSA area %pI4",
&area->area_id);
- /* Prepare the extrenal_info for aggregator */
+ /* Prepare the external_info for aggregator */
memset(&ei, 0, sizeof(struct external_info));
ei.p.family = AF_INET;
ei.p.prefixlen = 0;
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c
index 738ac6d8cf..aa11467027 100644
--- a/ospfd/ospf_asbr.c
+++ b/ospfd/ospf_asbr.c
@@ -492,7 +492,7 @@ static void ospf_aggr_handle_external_info(void *data)
ei->to_be_processed = true;
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
- zlog_debug("%s: Handle extrenal route(%pI4/%d)", __func__,
+ zlog_debug("%s: Handle external route(%pI4/%d)", __func__,
&ei->p.prefix, ei->p.prefixlen);
assert(ospf);
@@ -571,7 +571,7 @@ static void ospf_external_aggr_delete(struct ospf *ospf, struct route_node *rn)
}
struct ospf_external_aggr_rt *
-ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p)
+ospf_external_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p)
{
struct route_node *rn;
struct ospf_external_aggr_rt *summary_rt = NULL;
@@ -617,7 +617,7 @@ void ospf_unlink_ei_from_aggr(struct ospf *ospf,
{
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
zlog_debug(
- "%s: Unlinking extrenal route(%pI4/%d) from aggregator(%pI4/%d), external route count:%ld",
+ "%s: Unlinking external route(%pI4/%d) from aggregator(%pI4/%d), external route count:%ld",
__func__, &ei->p.prefix, ei->p.prefixlen,
&aggr->p.prefix, aggr->p.prefixlen,
OSPF_EXTERNAL_RT_COUNT(aggr));
@@ -648,7 +648,7 @@ static void ospf_link_ei_to_aggr(struct ospf_external_aggr_rt *aggr,
{
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
zlog_debug(
- "%s: Linking extrenal route(%pI4/%d) to aggregator(%pI4/%d)",
+ "%s: Linking external route(%pI4/%d) to aggregator(%pI4/%d)",
__func__, &ei->p.prefix, ei->p.prefixlen,
&aggr->p.prefix, aggr->p.prefixlen);
(void)hash_get(aggr->match_extnl_hash, ei, hash_alloc_intern);
@@ -703,7 +703,7 @@ struct ospf_lsa *ospf_originate_summary_lsa(struct ospf *ospf,
return NULL;
}
- /* Prepare the extrenal_info for aggregator */
+ /* Prepare the external_info for aggregator */
memset(&ei_aggr, 0, sizeof(ei_aggr));
ei_aggr.p = aggr->p;
ei_aggr.tag = aggr->tag;
@@ -1063,7 +1063,7 @@ static void ospf_handle_external_aggr_update(struct ospf *ospf)
aggr->action = OSPF_ROUTE_AGGR_NONE;
- /* Prepare the extrenal_info for aggregator */
+ /* Prepare the external_info for aggregator */
memset(&ei_aggr, 0, sizeof(ei_aggr));
ei_aggr.p = aggr->p;
ei_aggr.tag = aggr->tag;
@@ -1176,7 +1176,7 @@ int ospf_asbr_external_aggregator_set(struct ospf *ospf, struct prefix_ipv4 *p,
{
struct ospf_external_aggr_rt *aggregator;
- aggregator = ospf_extrenal_aggregator_lookup(ospf, p);
+ aggregator = ospf_external_aggregator_lookup(ospf, p);
if (aggregator) {
if (CHECK_FLAG(aggregator->flags,
@@ -1236,7 +1236,7 @@ int ospf_asbr_external_rt_no_advertise(struct ospf *ospf, struct prefix_ipv4 *p)
struct ospf_external_aggr_rt *aggr;
route_tag_t tag = 0;
- aggr = ospf_extrenal_aggregator_lookup(ospf, p);
+ aggr = ospf_external_aggregator_lookup(ospf, p);
if (aggr) {
if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
return OSPF_SUCCESS;
diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h
index 648a5a11ae..0b3b695f3e 100644
--- a/ospfd/ospf_asbr.h
+++ b/ospfd/ospf_asbr.h
@@ -144,7 +144,7 @@ extern int ospf_external_aggregator_timer_set(struct ospf *ospf,
extern void ospf_external_aggrigator_free(struct ospf_external_aggr_rt *aggr);
extern struct ospf_external_aggr_rt *
-ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p);
+ospf_external_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p);
void ospf_unset_all_aggr_flag(struct ospf *ospf);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index e3398af74b..bcb35315d8 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -325,7 +325,7 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
LSA_REFRESH_FORCE, false);
} else {
aggr = (struct ospf_external_aggr_rt *)
- ospf_extrenal_aggregator_lookup(ospf, &p);
+ ospf_external_aggregator_lookup(ospf, &p);
if (aggr) {
struct external_info ei_aggr;
diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c
index 7354223397..ac53f3a19f 100644
--- a/ospfd/ospf_lsa.c
+++ b/ospfd/ospf_lsa.c
@@ -4064,7 +4064,7 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
ospf, lsa, ei, LSA_REFRESH_FORCE, false);
else {
aggr = (struct ospf_external_aggr_rt *)
- ospf_extrenal_aggregator_lookup(ospf, &p);
+ ospf_external_aggregator_lookup(ospf, &p);
if (aggr) {
struct external_info ei_aggr;
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 27528f6594..95e8b179d8 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -10258,8 +10258,10 @@ DEFUN (ospf_external_route_aggregation,
tag = strtoul(argv[idx + 2]->arg, NULL, 10);
ret = ospf_asbr_external_aggregator_set(ospf, &p, tag);
- if (ret == OSPF_INVALID)
- vty_out(vty, "Invalid configuration!!\n");
+ if (ret == OSPF_FAILURE) {
+ vty_out(vty, "%% Failed to set summary-address!\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
return CMD_SUCCESS;
}
@@ -10611,8 +10613,10 @@ DEFUN (ospf_external_route_aggregation_no_adrvertise,
}
ret = ospf_asbr_external_rt_no_advertise(ospf, &p);
- if (ret == OSPF_INVALID)
- vty_out(vty, "Invalid configuration!!\n");
+ if (ret == OSPF_FAILURE) {
+ vty_out(vty, "%% Failed to set summary-address!\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
return CMD_SUCCESS;
}
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index d72afec1e4..90330d368d 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -843,7 +843,7 @@ static void ospf_finish_final(struct ospf *ospf)
ospf_distance_reset(ospf);
route_table_finish(ospf->distance_table);
- /* Release extrenal Aggregator table */
+ /* Release external Aggregator table */
for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
struct ospf_external_aggr_rt *aggr;
diff --git a/staticd/static_nht.c b/staticd/static_nht.c
index 6be598434d..06d27c6f59 100644
--- a/staticd/static_nht.c
+++ b/staticd/static_nht.c
@@ -21,6 +21,7 @@ static void static_nht_update_path(struct static_path *pn, struct prefix *nhp,
uint32_t nh_num, vrf_id_t nh_vrf_id)
{
struct static_nexthop *nh;
+ bool route_changed = false;
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (nh->nh_vrf_id != nh_vrf_id)
@@ -42,8 +43,10 @@ static void static_nht_update_path(struct static_path *pn, struct prefix *nhp,
nh->nh_valid = !!nh_num;
if (nh->state == STATIC_START)
- static_zebra_route_add(pn, true);
+ route_changed = true;
}
+ if (route_changed)
+ static_zebra_route_add(pn, true);
}
static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
index 5d8338d6eb..7e39b83d8f 100644
--- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
+++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
@@ -187,6 +187,16 @@ def test_bgp_administrative_reset_gr():
"""
)
+ def _bgp_verify_show_bgp_router_json():
+ output = json.loads(r1.vtysh_cmd("show bgp router json"))
+ expected = {
+ "bgpStartedAt": "*",
+ "bgpStartedGracefully": False,
+ "bgpInMaintenanceMode": False,
+ "bgpInstanceCount": 1,
+ }
+ return topotest.json_cmp(output, expected)
+
step("Initial BGP converge")
test_func = functools.partial(_bgp_converge)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
@@ -205,6 +215,11 @@ def test_bgp_administrative_reset_gr():
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to send Administrative Reset notification from R2"
+ step("Check show bgp router json")
+ test_func = functools.partial(_bgp_verify_show_bgp_router_json)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Invalid BGP router details"
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
diff --git a/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json
new file mode 100644
index 0000000000..016c019d10
--- /dev/null
+++ b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json
@@ -0,0 +1,70 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "tableVersion": 3,
+ "routerId": "192.0.2.2",
+ "defaultLocPrf": 100,
+ "localAS": 65002,
+ "routes": {
+ "198.51.100.0/24": [
+ {
+ "origin": "IGP",
+ "metric": 0,
+ "valid": true,
+ "version": 2,
+ "rpkiValidationState": "valid",
+ "bestpath": {
+ "overall": true,
+ "selectionReason": "First path received"
+ },
+ "nexthops": [
+ {
+ "ip": "192.0.2.1",
+ "hostname": "r1",
+ "afi": "ipv4",
+ "metric": 0,
+ "accessible": true,
+ "used": true
+ }
+ ],
+ "peer": {
+ "peerId": "192.0.2.1",
+ "routerId": "192.0.2.1",
+ "hostname": "r1",
+ "type": "external"
+ }
+ }
+ ],
+ "203.0.113.0/24": [
+ {
+ "origin": "IGP",
+ "metric": 0,
+ "valid": true,
+ "version": 3,
+ "rpkiValidationState": "valid",
+ "bestpath": {
+ "overall": true,
+ "selectionReason": "First path received"
+ },
+ "nexthops": [
+ {
+ "ip": "192.0.2.1",
+ "hostname": "r1",
+ "afi": "ipv4",
+ "metric": 0,
+ "accessible": true,
+ "used": true
+ }
+ ],
+ "peer": {
+ "peerId": "192.0.2.1",
+ "routerId": "192.0.2.1",
+ "hostname": "r1",
+ "type": "external"
+ }
+ }
+ ]
+ },
+ "totalRoutes": 3,
+ "totalPaths": 3
+} \ No newline at end of file
diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
index 7b40bbdae8..5b775aa6cb 100644
--- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
+++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
@@ -101,6 +101,16 @@ def show_rpki_prefixes(rname, expected, vrf=None):
return topotest.json_cmp(output, expected)
+def show_rpki_valid(rname, expected, vrf=None):
+ tgen = get_topogen()
+
+ cmd = "show bgp ipv4 detail json"
+
+ output = json.loads(tgen.gears[rname].vtysh_cmd(cmd))
+
+ return topotest.json_cmp(output, expected)
+
+
def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None):
tgen = get_topogen()
@@ -123,6 +133,25 @@ def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None):
return topotest.json_cmp(output, expected)
+def test_show_bgp_rpki_prefixes_valid():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r3"]:
+ logger.info("{}: checking if rtrd is running".format(rname))
+ if rtrd_process[rname].poll() is not None:
+ pytest.skip(tgen.errors)
+
+ rname = "r2"
+ expected = open(os.path.join(CWD, "{}/bgp_rpki_valid.json".format(rname))).read()
+ expected_json = json.loads(expected)
+ test_func = functools.partial(show_rpki_valid, rname, expected_json)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Failed to see RPKI on {}".format(rname)
+
+
def test_show_bgp_rpki_prefixes():
tgen = get_topogen()
diff --git a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py
index 3932c29b98..ee7e00b323 100644
--- a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py
+++ b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py
@@ -232,6 +232,20 @@ def test_local_vs_non_local():
assert False, "Route 60.0.0.0/24 should not have fibPending"
+def test_ip_protocol_any_fib_filter():
+ # "Filtered route of source protocol any should not get installed in fib"
+
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r2 = tgen.gears["r2"]
+ r2.vtysh_cmd("conf\nno ip protocol bgp")
+ r2.vtysh_cmd("conf\nip protocol any route-map LIMIT")
+ test_bgp_route()
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/tests/topotests/mgmt_oper/oper.py b/tests/topotests/mgmt_oper/oper.py
index bca452d011..6e1866382b 100644
--- a/tests/topotests/mgmt_oper/oper.py
+++ b/tests/topotests/mgmt_oper/oper.py
@@ -62,7 +62,7 @@ def disable_debug(router):
router.vtysh_cmd("no debug northbound callbacks configuration")
-@retry(retry_timeout=30, initial_wait=1)
+@retry(retry_timeout=30, initial_wait=0.1)
def _do_oper_test(tgen, qr, seconds_left=None):
r1 = tgen.gears["r1"].net
@@ -113,6 +113,7 @@ def _do_oper_test(tgen, qr, seconds_left=None):
"-------DIFF---------\n%s\n---------DIFF----------",
pprint.pformat(cmpout),
)
+ cmpout = str(cmpout)
else:
cmpout = tt_json_cmp(ojson, ejson, exact=True)
if cmpout and ejson_alt is not None:
@@ -186,6 +187,20 @@ def addrgen(a, count, step=1):
@retry(retry_timeout=30, initial_wait=0.1)
+def check_kernel_net(r1, net, vrf):
+ addr = ipaddress.ip_network(net)
+ vrfstr = f" vrf {vrf}" if vrf else ""
+ if addr.version == 6:
+ kernel = r1.cmd_raises(f"ip -6 route show{vrfstr}")
+ else:
+ kernel = r1.cmd_raises(f"ip -4 route show{vrfstr}")
+
+ nentries = len(re.findall("\n", kernel))
+ logging.info("checking kernel routing table%s: (%s entries)", vrfstr, nentries)
+ assert str(net) in kernel, f"Failed to find '{net}' in {nentries} entries"
+
+
+@retry(retry_timeout=30, initial_wait=0.1)
def check_kernel_32(r1, start_addr, count, vrf, step=1):
start = ipaddress.ip_address(start_addr)
vrfstr = f" vrf {vrf}" if vrf else ""
diff --git a/tests/topotests/mgmt_oper/test_oper.py b/tests/topotests/mgmt_oper/test_oper.py
index 23529bc75e..0d346b5b7c 100644
--- a/tests/topotests/mgmt_oper/test_oper.py
+++ b/tests/topotests/mgmt_oper/test_oper.py
@@ -15,7 +15,7 @@ import math
import pytest
from lib.topogen import Topogen
-from oper import check_kernel_32, do_oper_test
+from oper import check_kernel_32, check_kernel_net, do_oper_test
pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
@@ -85,10 +85,17 @@ def test_oper(tgen):
]
r1 = tgen.gears["r1"].net
+
check_kernel_32(r1, "11.11.11.11", 1, "")
check_kernel_32(r1, "12.12.12.12", 1, "")
check_kernel_32(r1, "13.13.13.13", 1, "red")
check_kernel_32(r1, "14.14.14.14", 1, "red")
+
+ check_kernel_net(r1, "2001:1111::/64", "")
+ check_kernel_net(r1, "2002:2222::/64", "")
+ check_kernel_net(r1, "2003:333::/64", "red")
+ check_kernel_net(r1, "2004:4444::/64", "red")
+
do_oper_test(tgen, query_results)
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 2bb364f32b..dba50b3c53 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -270,7 +270,7 @@ ctx_keywords = {
"mpls ldp": {"address-family ": {"interface ": {}}},
"l2vpn ": {"member pseudowire ": {}},
"key chain ": {"key ": {}},
- "vrf ": {},
+ "vrf ": {"rpki": {}},
"interface ": {"link-params": {}},
"pseudowire ": {},
"segment-routing": {
@@ -279,7 +279,11 @@ ctx_keywords = {
"policy ": {"candidate-path ": {}},
"pcep": {"pcc": {}, "pce ": {}, "pce-config ": {}},
},
- "srv6": {"locators": {"locator ": {}}, "encapsulation": {}},
+ "srv6": {
+ "locators": {"locator ": {}},
+ "encapsulation": {},
+ "formats": {"format": {}},
+ },
},
"nexthop-group ": {},
"route-map ": {},
diff --git a/zebra/dpdk/zebra_dplane_dpdk.c b/zebra/dpdk/zebra_dplane_dpdk.c
index ae1a3743ce..0a898c1923 100644
--- a/zebra/dpdk/zebra_dplane_dpdk.c
+++ b/zebra/dpdk/zebra_dplane_dpdk.c
@@ -330,14 +330,11 @@ static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx)
op = dplane_ctx_get_op(ctx);
- switch (op) {
- case DPLANE_OP_RULE_ADD:
+ if (op == DPLANE_OP_RULE_ADD) {
atomic_fetch_add_explicit(&dpdk_stat->rule_adds, 1,
memory_order_relaxed);
zd_dpdk_rule_add(ctx);
- break;
-
- case DPLANE_OP_RULE_UPDATE:
+ } else if (op == DPLANE_OP_RULE_UPDATE) {
/* delete old rule and install new one */
atomic_fetch_add_explicit(&dpdk_stat->rule_adds, 1,
memory_order_relaxed);
@@ -346,62 +343,12 @@ static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx)
zd_dpdk_rule_del(ctx, dplane_ctx_rule_get_ifname(ctx),
in_ifindex, dp_flow_ptr);
zd_dpdk_rule_add(ctx);
- break;
-
- case DPLANE_OP_RULE_DELETE:
+ } else if (op == DPLANE_OP_RULE_DELETE) {
atomic_fetch_add_explicit(&dpdk_stat->rule_dels, 1,
memory_order_relaxed);
in_ifindex = dplane_ctx_get_ifindex(ctx);
dp_flow_ptr = dplane_ctx_rule_get_dp_flow_ptr(ctx);
- zd_dpdk_rule_del(ctx, dplane_ctx_rule_get_ifname(ctx),
- in_ifindex, dp_flow_ptr);
- break;
-
- case DPLANE_OP_NONE:
- case DPLANE_OP_ROUTE_INSTALL:
- case DPLANE_OP_ROUTE_UPDATE:
- case DPLANE_OP_ROUTE_DELETE:
- case DPLANE_OP_ROUTE_NOTIFY:
- case DPLANE_OP_NH_INSTALL:
- case DPLANE_OP_NH_UPDATE:
- case DPLANE_OP_NH_DELETE:
- case DPLANE_OP_LSP_INSTALL:
- case DPLANE_OP_LSP_UPDATE:
- case DPLANE_OP_LSP_DELETE:
- case DPLANE_OP_LSP_NOTIFY:
- case DPLANE_OP_PW_INSTALL:
- case DPLANE_OP_PW_UNINSTALL:
- case DPLANE_OP_SYS_ROUTE_ADD:
- case DPLANE_OP_SYS_ROUTE_DELETE:
- case DPLANE_OP_ADDR_INSTALL:
- case DPLANE_OP_ADDR_UNINSTALL:
- case DPLANE_OP_MAC_INSTALL:
- case DPLANE_OP_MAC_DELETE:
- case DPLANE_OP_NEIGH_INSTALL:
- case DPLANE_OP_NEIGH_UPDATE:
- case DPLANE_OP_NEIGH_DELETE:
- case DPLANE_OP_VTEP_ADD:
- case DPLANE_OP_VTEP_DELETE:
- case DPLANE_OP_NEIGH_DISCOVER:
- case DPLANE_OP_BR_PORT_UPDATE:
- case DPLANE_OP_IPTABLE_ADD:
- case DPLANE_OP_IPTABLE_DELETE:
- case DPLANE_OP_IPSET_ADD:
- case DPLANE_OP_IPSET_DELETE:
- case DPLANE_OP_IPSET_ENTRY_ADD:
- case DPLANE_OP_IPSET_ENTRY_DELETE:
- case DPLANE_OP_NEIGH_IP_INSTALL:
- case DPLANE_OP_NEIGH_IP_DELETE:
- case DPLANE_OP_NEIGH_TABLE_UPDATE:
- case DPLANE_OP_GRE_SET:
- case DPLANE_OP_INTF_ADDR_ADD:
- case DPLANE_OP_INTF_ADDR_DEL:
- case DPLANE_OP_INTF_NETCONFIG:
- case DPLANE_OP_INTF_INSTALL:
- case DPLANE_OP_INTF_UPDATE:
- case DPLANE_OP_INTF_DELETE:
- case DPLANE_OP_VLAN_INSTALL,
- break;
+ zd_dpdk_rule_del(ctx, dplane_ctx_rule_get_ifname(ctx), in_ifindex, dp_flow_ptr);
}
}
@@ -410,62 +357,13 @@ static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx)
*/
static void zd_dpdk_process_update(struct zebra_dplane_ctx *ctx)
{
- switch (dplane_ctx_get_op(ctx)) {
+ enum dplane_op_e op;
- case DPLANE_OP_RULE_ADD:
- case DPLANE_OP_RULE_UPDATE:
- case DPLANE_OP_RULE_DELETE:
+ op = dplane_ctx_get_op(ctx);
+ if (op == DPLANE_OP_RULE_ADD || op == DPLANE_OP_RULE_UPDATE || op == DPLANE_OP_RULE_DELETE)
zd_dpdk_rule_update(ctx);
- break;
- case DPLANE_OP_NONE:
- case DPLANE_OP_ROUTE_INSTALL:
- case DPLANE_OP_ROUTE_UPDATE:
- case DPLANE_OP_ROUTE_DELETE:
- case DPLANE_OP_ROUTE_NOTIFY:
- case DPLANE_OP_NH_INSTALL:
- case DPLANE_OP_NH_UPDATE:
- case DPLANE_OP_NH_DELETE:
- case DPLANE_OP_LSP_INSTALL:
- case DPLANE_OP_LSP_UPDATE:
- case DPLANE_OP_LSP_DELETE:
- case DPLANE_OP_LSP_NOTIFY:
- case DPLANE_OP_PW_INSTALL:
- case DPLANE_OP_PW_UNINSTALL:
- case DPLANE_OP_SYS_ROUTE_ADD:
- case DPLANE_OP_SYS_ROUTE_DELETE:
- case DPLANE_OP_ADDR_INSTALL:
- case DPLANE_OP_ADDR_UNINSTALL:
- case DPLANE_OP_MAC_INSTALL:
- case DPLANE_OP_MAC_DELETE:
- case DPLANE_OP_NEIGH_INSTALL:
- case DPLANE_OP_NEIGH_UPDATE:
- case DPLANE_OP_NEIGH_DELETE:
- case DPLANE_OP_VTEP_ADD:
- case DPLANE_OP_VTEP_DELETE:
- case DPLANE_OP_NEIGH_DISCOVER:
- case DPLANE_OP_BR_PORT_UPDATE:
- case DPLANE_OP_IPTABLE_ADD:
- case DPLANE_OP_IPTABLE_DELETE:
- case DPLANE_OP_IPSET_ADD:
- case DPLANE_OP_IPSET_DELETE:
- case DPLANE_OP_IPSET_ENTRY_ADD:
- case DPLANE_OP_IPSET_ENTRY_DELETE:
- case DPLANE_OP_NEIGH_IP_INSTALL:
- case DPLANE_OP_NEIGH_IP_DELETE:
- case DPLANE_OP_NEIGH_TABLE_UPDATE:
- case DPLANE_OP_GRE_SET:
- case DPLANE_OP_INTF_ADDR_ADD:
- case DPLANE_OP_INTF_ADDR_DEL:
- case DPLANE_OP_INTF_NETCONFIG:
- case DPLANE_OP_INTF_INSTALL:
- case DPLANE_OP_INTF_UPDATE:
- case DPLANE_OP_INTF_DELETE:
- case DPLANE_OP_VLAN_INSTALL,
- atomic_fetch_add_explicit(&dpdk_stat->ignored_updates, 1,
- memory_order_relaxed);
-
- break;
- }
+ else
+ atomic_fetch_add_explicit(&dpdk_stat->ignored_updates, 1, memory_order_relaxed);
}
diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c
index f9009dabb7..3fd84b5257 100644
--- a/zebra/zebra_evpn_mac.c
+++ b/zebra/zebra_evpn_mac.c
@@ -1323,6 +1323,7 @@ int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
uint32_t flags, bool force)
{
int state = ZEBRA_NEIGH_ACTIVE;
+ struct zebra_vrf *zvrf;
if (!force) {
if (CHECK_FLAG(flags, ZEBRA_MAC_LOCAL_INACTIVE) &&
@@ -1330,12 +1331,14 @@ int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr,
/* the host was not advertised - nothing to delete */
return 0;
- /* MAC is LOCAL and DUP_DETECTED, this local mobility event
- * is not known to bgpd. Upon receiving local delete
- * ask bgp to reinstall the best route (remote entry).
+ /* Duplicate detect action is freeze enabled and
+ * Local MAC is duplicate deteced, this local
+ * mobility event is not known to bgpd.
+ * Upon receiving local delete ask bgp to reinstall
+ * the best route (remote entry).
*/
- if (CHECK_FLAG(flags, ZEBRA_MAC_LOCAL) &&
- CHECK_FLAG(flags, ZEBRA_MAC_DUPLICATE))
+ zvrf = zebra_vrf_get_evpn();
+ if (zvrf && zvrf->dad_freeze && CHECK_FLAG(flags, ZEBRA_MAC_DUPLICATE))
state = ZEBRA_NEIGH_INACTIVE;
}
diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c
index ec151360bd..d99010547f 100644
--- a/zebra/zebra_nb_config.c
+++ b/zebra/zebra_nb_config.c
@@ -3358,10 +3358,7 @@ int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args)
const char *proto = yang_dnode_get_string(args->dnode, "protocol");
int rtype;
- if (strcasecmp(proto, "any") == 0)
- rtype = ZEBRA_ROUTE_MAX;
- else
- rtype = proto_name2num(proto);
+ rtype = proto_name2num(proto);
if (args->event == NB_EV_VALIDATE)
if (rtype < 0) {
@@ -3387,10 +3384,7 @@ int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args)
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
- if (strcasecmp(proto, "any") == 0)
- rtype = ZEBRA_ROUTE_MAX;
- else
- rtype = proto_name2num(proto);
+ rtype = proto_name2num(proto);
/* deleting an existing entry, it can't be invalid */
assert(rtype >= 0);
@@ -3418,10 +3412,7 @@ void lib_vrf_zebra_filter_protocol_apply_finish(
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
- if (strcasecmp(proto, "any") == 0)
- rtype = ZEBRA_ROUTE_MAX;
- else
- rtype = proto_name2num(proto);
+ rtype = proto_name2num(proto);
/* finishing apply for a validated entry, it can't be invalid */
assert(rtype >= 0);
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index e61c158ca9..a32fc2bb14 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -1056,6 +1056,7 @@ static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh, struct nh_g
static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
{
struct nhg_connected *rb_node_dep;
+ bool dependent_valid = valid;
if (valid)
SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID);
@@ -1071,6 +1072,7 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
/* Update validity of nexthops depending on it */
frr_each (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
+ dependent_valid = valid;
if (!valid) {
/*
* Grab the first nexthop from the depending nexthop group
@@ -1080,16 +1082,22 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid)
struct nexthop *nexthop = rb_node_dep->nhe->nhg.nexthop;
while (nexthop) {
- if (nexthop_same(nexthop, nhe->nhg.nexthop))
- break;
-
+ if (nexthop_same(nexthop, nhe->nhg.nexthop)) {
+ /* Invalid Nexthop */
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ } else {
+ /*
+ * If other nexthops in the nexthop
+ * group are valid then we can continue
+ * to use this nexthop group as valid
+ */
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ dependent_valid = true;
+ }
nexthop = nexthop->next;
}
-
- if (nexthop)
- UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
- zebra_nhg_set_valid(rb_node_dep->nhe, valid);
+ zebra_nhg_set_valid(rb_node_dep->nhe, dependent_valid);
}
}
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 29bbf6023d..73ffa09c16 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -114,11 +114,6 @@ static void show_vrf_proto_rm(struct vty *vty, struct zebra_vrf *zvrf,
vty_out(vty, "%-24s : none\n", zebra_route_string(i));
}
- if (PROTO_RM_NAME(zvrf, af_type, i))
- vty_out(vty, "%-24s : %-10s\n", "any",
- PROTO_RM_NAME(zvrf, af_type, i));
- else
- vty_out(vty, "%-24s : none\n", "any");
}
static void show_vrf_nht_rm(struct vty *vty, struct zebra_vrf *zvrf,
@@ -1222,8 +1217,8 @@ route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re,
return RMAP_DENYMATCH;
}
if (!rmap) {
- rm_name = PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_MAX);
- rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX);
+ rm_name = PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_ALL);
+ rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_ALL);
if (rm_name && !rmap)
return RMAP_DENYMATCH;