summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/ptm_adapter.c124
-rw-r--r--bgpd/bgp_nb.c36
-rw-r--r--bgpd/bgp_nb.h24
-rw-r--r--bgpd/bgp_nb_config.c38
-rw-r--r--bgpd/bgp_nht.c2
-rw-r--r--bgpd/bgp_route.c25
-rw-r--r--bgpd/bgpd.c7
-rw-r--r--doc/user/ospf6d.rst14
-rw-r--r--doc/user/zebra.rst13
-rw-r--r--include/linux/rtnetlink.h1
-rw-r--r--lib/bfd.c48
-rw-r--r--lib/zclient.h7
-rw-r--r--ospf6d/ospf6_bfd.c2
-rw-r--r--ospf6d/ospf6_bfd.h1
-rw-r--r--ospf6d/ospf6_interface.c355
-rw-r--r--ospf6d/ospf6_zebra.c68
-rw-r--r--pimd/pim_iface.c2
-rw-r--r--pimd/pim_iface.h11
-rw-r--r--pimd/pim_pim.c8
-rw-r--r--tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py62
-rw-r--r--yang/frr-bgp-common-structure.yang6
-rw-r--r--yang/frr-bgp-common.yang8
-rw-r--r--zebra/connected.c21
-rw-r--r--zebra/main.c15
-rw-r--r--zebra/rt_netlink.c6
-rw-r--r--zebra/zebra_rib.c30
-rw-r--r--zebra/zebra_router.c10
-rw-r--r--zebra/zebra_router.h5
-rw-r--r--zebra/zebra_vty.c47
29 files changed, 702 insertions, 294 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index d3d54c1780..90e2df2367 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -84,10 +84,11 @@ static void bfdd_client_deregister(struct stream *msg);
static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
{
char timers[3][128] = {};
+ char minttl_str[32] = {};
char addr[3][128] = {};
char profile[128] = {};
char cbit_str[32];
- char msgbuf[256];
+ char msgbuf[512];
va_list vl;
/* Avoid debug calculations if it's disabled. */
@@ -120,6 +121,10 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
snprintf(cbit_str, sizeof(cbit_str), " cbit:0x%02x", bpc->bpc_cbit);
+ if (bpc->bpc_has_minimum_ttl)
+ snprintf(minttl_str, sizeof(minttl_str), " minimum-ttl:%d",
+ bpc->bpc_minimum_ttl);
+
if (bpc->bpc_has_profile)
snprintf(profile, sizeof(profile), " profile:%s",
bpc->bpc_profile);
@@ -128,9 +133,10 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...)
vsnprintf(msgbuf, sizeof(msgbuf), fmt, vl);
va_end(vl);
- zlog_debug("%s [mhop:%s %s%s%s%s%s%s%s%s]", msgbuf,
+ zlog_debug("%s [mhop:%s %s%s%s%s%s%s%s%s%s]", msgbuf,
bpc->bpc_mhop ? "yes" : "no", addr[0], addr[1], addr[2],
- timers[0], timers[1], timers[2], cbit_str, profile);
+ timers[0], timers[1], timers[2], cbit_str, minttl_str,
+ profile);
}
static void _ptm_bfd_session_del(struct bfd_session *bs, uint8_t diag)
@@ -307,6 +313,8 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
/*
* Register/Deregister/Update Message format:
+ *
+ * Old format (being used by PTM BFD).
* - header: Command, VRF
* - l: pid
* - w: family
@@ -322,16 +330,37 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
* - multihop:
* - w: family
* - AF_INET:
- * - l: destination ipv4
+ * - l: source IPv4 address
* - AF_INET6:
- * - 16 bytes: destination IPv6
+ * - 16 bytes: source IPv6 address
* - c: ttl
* - no multihop
* - AF_INET6:
* - w: family
- * - 16 bytes: ipv6 address
+ * - 16 bytes: source IPv6 address
* - c: ifname length
* - X bytes: interface name
+ *
+ * New format:
+ * - header: Command, VRF
+ * - l: pid
+ * - w: family
+ * - AF_INET:
+ * - l: destination IPv4 address
+ * - AF_INET6:
+ * - 16 bytes: destination IPv6 address
+ * - l: min_rx
+ * - l: min_tx
+ * - c: detect multiplier
+ * - c: is_multihop?
+ * - w: family
+ * - AF_INET:
+ * - l: source IPv4 address
+ * - AF_INET6:
+ * - 16 bytes: source IPv6 address
+ * - c: ttl
+ * - c: ifname length
+ * - X bytes: interface name
* - c: bfd_cbit
* - c: profile name length.
* - X bytes: profile name.
@@ -355,58 +384,50 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
bpc->bpc_ipv4 = (bpc->bpc_peer.sa_sin.sin_family == AF_INET);
/* Get peer configuration. */
- if (command != ZEBRA_BFD_DEST_DEREGISTER) {
- STREAM_GETL(msg, bpc->bpc_recvinterval);
- bpc->bpc_has_recvinterval =
- (bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
-
- STREAM_GETL(msg, bpc->bpc_txinterval);
- bpc->bpc_has_txinterval =
- (bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
-
- STREAM_GETC(msg, bpc->bpc_detectmultiplier);
- bpc->bpc_has_detectmultiplier =
- (bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
- }
+ STREAM_GETL(msg, bpc->bpc_recvinterval);
+ bpc->bpc_has_recvinterval =
+ (bpc->bpc_recvinterval != BPC_DEF_RECEIVEINTERVAL);
+
+ STREAM_GETL(msg, bpc->bpc_txinterval);
+ bpc->bpc_has_txinterval =
+ (bpc->bpc_txinterval != BPC_DEF_TRANSMITINTERVAL);
+
+ STREAM_GETC(msg, bpc->bpc_detectmultiplier);
+ bpc->bpc_has_detectmultiplier =
+ (bpc->bpc_detectmultiplier != BPC_DEF_DETECTMULTIPLIER);
/* Read (single|multi)hop and its options. */
STREAM_GETC(msg, bpc->bpc_mhop);
- if (bpc->bpc_mhop) {
- /* Read multihop source address and TTL. */
- _ptm_msg_read_address(msg, &bpc->bpc_local);
- STREAM_GETC(msg, bpc->bpc_minimum_ttl);
- if (bpc->bpc_minimum_ttl >= BFD_TTL_VAL
- || bpc->bpc_minimum_ttl == 0) {
- zlog_warn("%s: received invalid TTL configuration %d",
- __func__, bpc->bpc_has_minimum_ttl);
- bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
- bpc->bpc_has_minimum_ttl = false;
- } else {
- bpc->bpc_minimum_ttl =
- (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
- bpc->bpc_has_minimum_ttl = true;
- }
+
+ /* Read multihop source address and TTL. */
+ _ptm_msg_read_address(msg, &bpc->bpc_local);
+
+ /* Read the minimum TTL (0 means unset or invalid). */
+ STREAM_GETC(msg, bpc->bpc_minimum_ttl);
+ if (bpc->bpc_minimum_ttl == 0) {
+ bpc->bpc_minimum_ttl = BFD_DEF_MHOP_TTL;
+ bpc->bpc_has_minimum_ttl = false;
} else {
- /* If target is IPv6, then we must obtain local address. */
- if (bpc->bpc_ipv4 == false)
- _ptm_msg_read_address(msg, &bpc->bpc_local);
+ bpc->bpc_minimum_ttl = (BFD_TTL_VAL + 1) - bpc->bpc_minimum_ttl;
+ bpc->bpc_has_minimum_ttl = true;
+ }
- /*
- * Read interface name and make sure it fits our data
- * structure, otherwise fail.
- */
- STREAM_GETC(msg, ifnamelen);
- if (ifnamelen >= sizeof(bpc->bpc_localif)) {
- zlog_err("ptm-read: interface name is too big");
- return -1;
- }
+ /*
+ * Read interface name and make sure it fits our data
+ * structure, otherwise fail.
+ */
+ STREAM_GETC(msg, ifnamelen);
+ if (ifnamelen >= sizeof(bpc->bpc_localif)) {
+ zlog_err("ptm-read: interface name is too big");
+ return -1;
+ }
- bpc->bpc_has_localif = ifnamelen > 0;
- if (bpc->bpc_has_localif) {
- STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
- bpc->bpc_localif[ifnamelen] = 0;
- }
+ bpc->bpc_has_localif = ifnamelen > 0;
+ if (bpc->bpc_has_localif) {
+ STREAM_GET(bpc->bpc_localif, msg, ifnamelen);
+ bpc->bpc_localif[ifnamelen] = 0;
}
+
if (vrf_id != VRF_DEFAULT) {
struct vrf *vrf;
@@ -424,6 +445,7 @@ static int _ptm_msg_read(struct stream *msg, int command, vrf_id_t vrf_id,
strlcpy(bpc->bpc_vrfname, VRF_DEFAULT_NAME, sizeof(bpc->bpc_vrfname));
}
+ /* Read control plane independant configuration. */
STREAM_GETC(msg, bpc->bpc_cbit);
/* Handle profile names. */
diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c
index 644b03dff0..f098332b29 100644
--- a/bgpd/bgp_nb.c
+++ b/bgpd/bgp_nb.c
@@ -2833,17 +2833,17 @@ const struct frr_yang_module_info frr_bgp_info = {
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import",
.cbs = {
- .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
- .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+ .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify,
+ .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy,
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export",
.cbs = {
- .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
- .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+ .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify,
+ .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy,
}
},
{
@@ -4789,17 +4789,17 @@ const struct frr_yang_module_info frr_bgp_info = {
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import",
.cbs = {
- .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
- .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+ .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify,
+ .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy,
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export",
.cbs = {
- .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
- .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+ .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify,
+ .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy,
}
},
{
@@ -6743,17 +6743,17 @@ const struct frr_yang_module_info frr_bgp_info = {
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import",
.cbs = {
- .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
- .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+ .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify,
+ .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy,
}
},
{
- .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export",
.cbs = {
- .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
- .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+ .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify,
+ .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy,
}
},
{
diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h
index c78c9c34ad..f608d4f8c1 100644
--- a/bgpd/bgp_nb.h
+++ b/bgpd/bgp_nb.h
@@ -1220,13 +1220,13 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path
struct nb_cb_modify_args *args);
int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
struct nb_cb_destroy_args *args);
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args);
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args);
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args);
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args);
int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
struct nb_cb_modify_args *args);
@@ -2064,13 +2064,13 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con
struct nb_cb_modify_args *args);
int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
struct nb_cb_destroy_args *args);
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args);
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args);
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args);
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args);
int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
struct nb_cb_modify_args *args);
@@ -2908,13 +2908,13 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_
struct nb_cb_modify_args *args);
int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
struct nb_cb_destroy_args *args);
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args);
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args);
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args);
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args);
int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
struct nb_cb_modify_args *args);
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
index ee6b13278d..f19fcf0f8c 100644
--- a/bgpd/bgp_nb_config.c
+++ b/bgpd/bgp_nb_config.c
@@ -8844,7 +8844,7 @@ bgp_global_afi_safi_route_flap_validation(struct nb_cb_modify_args *args)
int reuse;
int suppress;
- if (yang_dnode_exists(args->dnode, "../supress-above")
+ if (yang_dnode_exists(args->dnode, "../suppress-above")
&& yang_dnode_exists(args->dnode, "../reuse-above")) {
suppress =
yang_dnode_get_uint16(args->dnode, "../suppress-above");
@@ -15374,9 +15374,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import
*/
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -15391,7 +15391,7 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupre
return NB_OK;
}
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
@@ -15408,9 +15408,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupre
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export
*/
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -15425,7 +15425,7 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupre
return NB_OK;
}
-int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
@@ -23692,9 +23692,9 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import
*/
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -23709,7 +23709,7 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con
return NB_OK;
}
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
@@ -23726,9 +23726,9 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export
*/
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -23743,7 +23743,7 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con
return NB_OK;
}
-int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
@@ -32005,9 +32005,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-import
*/
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -32022,7 +32022,7 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_uns
return NB_OK;
}
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_import_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
@@ -32039,9 +32039,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_uns
/*
* XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsuppress-map-export
*/
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_modify(
struct nb_cb_modify_args *args)
{
switch (args->event) {
@@ -32056,7 +32056,7 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_uns
return NB_OK;
}
-int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsuppress_map_export_destroy(
struct nb_cb_destroy_args *args)
{
switch (args->event) {
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 64b10c0252..5d3667af1a 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -72,7 +72,7 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
if (BGP_DEBUG(nht, NHT)) {
char buf[PREFIX2STR_BUFFER];
- zlog_debug("bgp_unlink_nexthop: freeing bnc %s(%u)(%s)",
+ zlog_debug("%s: freeing bnc %s(%u)(%s)", __func__,
bnc_str(bnc, buf, PREFIX2STR_BUFFER),
bnc->srte_color, bnc->bgp->name_pretty);
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 8d87f2cd04..87e8feb3bf 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1836,8 +1836,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
/* If community is not disabled check the no-export and local. */
if (!transparent && bgp_community_filter(peer, piattr)) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug(
- "subgrpannouncecheck: community filter check fail");
+ zlog_debug("%s: community filter check fail", __func__);
return false;
}
@@ -13915,16 +13914,16 @@ void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
: "");
}
-DEFPY_YANG(bgp_dampening,
- bgp_dampening_cmd,
- "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_supress]]",
- NO_STR
- "BGP Specific commands\n"
- "Enable route-flap dampening\n"
- "Half-life time for the penalty\n"
- "Value to start reusing a route\n"
- "Value to start suppressing a route\n"
- "Maximum duration to suppress a stable route\n")
+DEFPY_YANG(
+ bgp_dampening, bgp_dampening_cmd,
+ "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_suppress]]",
+ NO_STR
+ "BGP Specific commands\n"
+ "Enable route-flap dampening\n"
+ "Half-life time for the penalty\n"
+ "Value to start reusing a route\n"
+ "Value to start suppressing a route\n"
+ "Maximum duration to suppress a stable route\n")
{
afi_t afi;
safi_t safi;
@@ -13943,7 +13942,7 @@ DEFPY_YANG(bgp_dampening,
nb_cli_enqueue_change(vty, "./suppress-above",
NB_OP_MODIFY, suppress_str);
nb_cli_enqueue_change(vty, "./unreach-decay",
- NB_OP_MODIFY, max_supress_str);
+ NB_OP_MODIFY, max_suppress_str);
} if (argc == 3) {
nb_cli_enqueue_change(vty, "./reach-decay",
NB_OP_MODIFY, halflife_str);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index b773c16b57..fd2c431eac 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -6975,8 +6975,8 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
struct listnode *node, *nnode;
int ret;
- zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
- gtsm_hops, peer->host);
+ zlog_debug("%s: set gtsm_hops to %d for %s", __func__, gtsm_hops,
+ peer->host);
/* We cannot configure ttl-security hops when ebgp-multihop is already
set. For non peer-groups, the check is simple. For peer-groups,
@@ -7078,8 +7078,7 @@ int peer_ttl_security_hops_unset(struct peer *peer)
struct listnode *node, *nnode;
int ret = 0;
- zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
- peer->host);
+ zlog_debug("%s: set gtsm_hops to zero for %s", __func__, peer->host);
/* if a peer-group member, then reset to peer-group default rather than
* 0 */
diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst
index dd53d8f8b4..c66774a408 100644
--- a/doc/user/ospf6d.rst
+++ b/doc/user/ospf6d.rst
@@ -174,10 +174,11 @@ Showing OSPF6 information
This command shows LSA database summary. You can specify the type of LSA.
-.. index:: show ipv6 ospf6 interface
-.. clicmd:: show ipv6 ospf6 interface
+.. index:: show ipv6 ospf6 interface [json]
+.. clicmd:: show ipv6 ospf6 interface [json]
- To see OSPF interface configuration like costs.
+ To see OSPF interface configuration like costs. JSON output can be
+ obtained by appending "json" in the end.
.. index:: show ipv6 ospf6 neighbor [json]
.. clicmd:: show ipv6 ospf6 neighbor [json]
@@ -195,10 +196,11 @@ Showing OSPF6 information
This command shows internal routing table.
-.. index:: show ipv6 ospf6 zebra
-.. clicmd:: show ipv6 ospf6 zebra
+.. index:: show ipv6 ospf6 zebra [json]
+.. clicmd:: show ipv6 ospf6 zebra [json]
- Shows state about what is being redistributed between zebra and OSPF6
+ Shows state about what is being redistributed between zebra and OSPF6.
+ JSON output can be obtained by appending "json" at the end.
OSPF6 Configuration Examples
============================
diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst
index 624e3cfe1a..5c7f4ac773 100644
--- a/doc/user/zebra.rst
+++ b/doc/user/zebra.rst
@@ -72,6 +72,19 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
option and we will use Route Replace Semantics instead of delete
than add.
+.. option:: --asic-offload [notify_on_offload|notify_on_ack]
+
+ The linux kernel has the ability to use asic-offload ( see switchdev
+ development ). When the operator knows that FRR will be working in
+ this way, allow them to specify this with FRR. At this point this
+ code only supports asynchronous notification of the offload state.
+ In other words the initial ACK received for linux kernel installation
+ does not give zebra any data about what the state of the offload
+ is. This option takes the optional paramegers notify_on_offload
+ or notify_on_ack. This signals to zebra to notify upper level
+ protocols about route installation/update on ack received from
+ the linux kernel or from offload notification.
+
.. _interface-commands:
Configuration Addresses behaviour
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 9b814c92de..74a0d795ab 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -319,6 +319,7 @@ enum rt_scope_t {
#define RTM_F_FIB_MATCH 0x2000 /* return full fib lookup match */
#define RTM_F_OFFLOAD 0x4000 /* route is offloaded */
#define RTM_F_TRAP 0x8000 /* route is trapping packets */
+#define RTM_F_OFFLOAD_FAILED 0x10000 /* route offload failed */
/* Reserved table identifiers */
diff --git a/lib/bfd.c b/lib/bfd.c
index d1a0ec671e..1a37b348f8 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -104,7 +104,10 @@ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx,
if (((*bfd_info)->required_min_rx != min_rx)
|| ((*bfd_info)->desired_min_tx != min_tx)
|| ((*bfd_info)->detect_mult != detect_mult)
- || (profile && strcmp((*bfd_info)->profile, profile)))
+ || ((*bfd_info)->profile[0] == 0 && profile)
+ || ((*bfd_info)->profile[0] && profile == NULL)
+ || (profile && (*bfd_info)->profile[0]
+ && strcmp((*bfd_info)->profile, profile)))
*command = ZEBRA_BFD_DEST_UPDATE;
}
@@ -468,6 +471,39 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
: sizeof(struct in6_addr);
stream_put(s, &args->dst, addrlen);
+ /*
+ * For more BFD integration protocol details, see function
+ * `_ptm_msg_read` in `bfdd/ptm_adapter.c`.
+ */
+#if HAVE_BFDD > 0
+ /* Session timers. */
+ stream_putl(s, args->min_rx);
+ stream_putl(s, args->min_tx);
+ stream_putc(s, args->detection_multiplier);
+
+ /* Is multi hop? */
+ stream_putc(s, args->mhop != 0);
+
+ /* Source address. */
+ stream_putw(s, args->family);
+ stream_put(s, &args->src, addrlen);
+
+ /* Send the expected TTL. */
+ stream_putc(s, args->ttl);
+
+ /* Send interface name if any. */
+ stream_putc(s, args->ifnamelen);
+ if (args->ifnamelen)
+ stream_put(s, args->ifname, args->ifnamelen);
+
+ /* Send the C bit indicator. */
+ stream_putc(s, args->cbit);
+
+ /* Send profile name if any. */
+ stream_putc(s, args->profilelen);
+ if (args->profilelen)
+ stream_put(s, args->profile, args->profilelen);
+#else /* PTM BFD */
/* Encode timers if this is a registration message. */
if (args->command != ZEBRA_BFD_DEST_DEREGISTER) {
stream_putl(s, args->min_rx);
@@ -500,16 +536,6 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args)
if (args->ifnamelen)
stream_put(s, args->ifname, args->ifnamelen);
}
-
- /* Send the C bit indicator. */
- stream_putc(s, args->cbit);
-
- /* `ptm-bfd` doesn't support profiles yet. */
-#if HAVE_BFDD > 0
- /* Send profile name if any. */
- stream_putc(s, args->profilelen);
- if (args->profilelen)
- stream_put(s, args->profile, args->profilelen);
#endif /* HAVE_BFDD */
/* Finish the message by writing the size. */
diff --git a/lib/zclient.h b/lib/zclient.h
index 231fdad09b..3c80ba7efa 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -514,6 +514,13 @@ struct zapi_route {
* offload situation.
*/
#define ZEBRA_FLAG_OFFLOADED 0x100
+/*
+ * This flag tells everyone that the route has
+ * failed offloading.
+ * This flag makes no sense unless you are in an asic
+ * offload situation.
+ */
+#define ZEBRA_FLAG_OFFLOAD_FAILED 0x200
/* The older XXX_MESSAGE flags live here */
uint32_t message;
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index 523ed7f181..a701583621 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -59,7 +59,7 @@ void ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only,
json_object *json_obj, bool use_json)
{
if (param_only)
- bfd_show_param(vty, bfd_info, 1, 0, 0, NULL);
+ bfd_show_param(vty, bfd_info, 1, 0, use_json, json_obj);
else
bfd_show_info(vty, bfd_info, 0, 1, use_json, json_obj);
}
diff --git a/ospf6d/ospf6_bfd.h b/ospf6d/ospf6_bfd.h
index b4e798e911..ddf624efce 100644
--- a/ospf6d/ospf6_bfd.h
+++ b/ospf6d/ospf6_bfd.h
@@ -22,6 +22,7 @@
#include "lib/json.h"
#ifndef OSPF6_BFD_H
#define OSPF6_BFD_H
+#include "lib/json.h"
extern void ospf6_bfd_init(void);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 2d1b5e7b5a..1351602619 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -43,6 +43,7 @@
#include "ospf6d.h"
#include "ospf6_bfd.h"
#include "ospf6_zebra.h"
+#include "lib/json.h"
DEFINE_MTYPE_STATIC(OSPF6D, CFG_PLIST_NAME, "configured prefix list names")
DEFINE_QOBJ_TYPE(ospf6_interface)
@@ -904,7 +905,8 @@ static const char *ospf6_iftype_str(uint8_t iftype)
}
/* show specified interface structure */
-static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
+static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
+ json_object *json_obj, bool use_json)
{
struct ospf6_interface *oi;
struct connected *c;
@@ -915,116 +917,299 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
struct timeval res, now;
char duration[32];
struct ospf6_lsa *lsa, *lsanext;
+ json_object *json_arr;
+ json_object *json_addr;
default_iftype = ospf6_default_iftype(ifp);
- vty_out(vty, "%s is %s, type %s\n", ifp->name,
- (if_is_operative(ifp) ? "up" : "down"),
- ospf6_iftype_str(default_iftype));
- vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
+ if (use_json) {
+ json_object_string_add(json_obj, "status",
+ (if_is_operative(ifp) ? "up" : "down"));
+ json_object_string_add(json_obj, "type",
+ ospf6_iftype_str(default_iftype));
+ json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
+
+ if (ifp->info == NULL) {
+ json_object_boolean_false_add(json_obj, "ospf6Enabled");
+ return 0;
+ }
+ json_object_boolean_true_add(json_obj, "ospf6Enabled");
- if (ifp->info == NULL) {
- vty_out(vty, " OSPF not enabled on this interface\n");
- return 0;
- } else
oi = (struct ospf6_interface *)ifp->info;
- if (if_is_operative(ifp) && oi->type != default_iftype)
- vty_out(vty, " Operating as type %s\n",
- ospf6_iftype_str(oi->type));
-
- vty_out(vty, " Internet Address:\n");
-
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
- p = c->address;
- switch (p->family) {
- case AF_INET:
- vty_out(vty, " inet : %pFX\n", p);
- break;
- case AF_INET6:
- vty_out(vty, " inet6: %pFX\n", p);
- break;
- default:
- vty_out(vty, " ??? : %pFX\n", p);
- break;
+ if (if_is_operative(ifp) && oi->type != default_iftype)
+ json_object_string_add(json_obj, "operatingAsType",
+ ospf6_iftype_str(oi->type));
+
+ } else {
+ vty_out(vty, "%s is %s, type %s\n", ifp->name,
+ (if_is_operative(ifp) ? "up" : "down"),
+ ospf6_iftype_str(default_iftype));
+ vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
+
+ if (ifp->info == NULL) {
+ vty_out(vty, " OSPF not enabled on this interface\n");
+ return 0;
}
+ oi = (struct ospf6_interface *)ifp->info;
+
+ if (if_is_operative(ifp) && oi->type != default_iftype)
+ vty_out(vty, " Operating as type %s\n",
+ ospf6_iftype_str(oi->type));
}
- if (oi->area) {
- vty_out(vty,
- " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
- oi->instance_id, oi->ifmtu, ifp->mtu6);
- vty_out(vty, " MTU mismatch detection: %s\n",
- oi->mtu_ignore ? "disabled" : "enabled");
- inet_ntop(AF_INET, &oi->area->area_id, strbuf, sizeof(strbuf));
- vty_out(vty, " Area ID %s, Cost %u\n", strbuf, oi->cost);
- } else
- vty_out(vty, " Not Attached to Area\n");
+ if (use_json) {
+ json_arr = json_object_new_array();
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
+ json_addr = json_object_new_object();
+ p = c->address;
+ prefix2str(p, strbuf, sizeof(strbuf));
+ switch (p->family) {
+ case AF_INET:
+ json_object_string_add(json_addr, "type",
+ "inet");
+ json_object_string_add(json_addr, "address",
+ strbuf);
+ json_object_array_add(json_arr, json_addr);
+ break;
+ case AF_INET6:
+ json_object_string_add(json_addr, "type",
+ "inet6");
+ json_object_string_add(json_addr, "address",
+ strbuf);
+ json_object_array_add(json_arr, json_addr);
+ break;
+ default:
+ json_object_string_add(json_addr, "type",
+ "unknown");
+ json_object_string_add(json_addr, "address",
+ strbuf);
+ json_object_array_add(json_arr, json_addr);
+ break;
+ }
+ }
+ json_object_object_add(json_obj, "internetAddress", json_arr);
+ } else {
+ vty_out(vty, " Internet Address:\n");
+
+ for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
+ p = c->address;
+ prefix2str(p, strbuf, sizeof(strbuf));
+ switch (p->family) {
+ case AF_INET:
+ vty_out(vty, " inet : %pFX\n", p);
+ break;
+ case AF_INET6:
+ vty_out(vty, " inet6: %pFX\n", p);
+ break;
+ default:
+ vty_out(vty, " ??? : %pFX\n", p);
+ break;
+ }
+ }
+ }
+
+ if (use_json) {
+ if (oi->area) {
+ json_object_boolean_true_add(json_obj,
+ "attachedToArea");
+ json_object_int_add(json_obj, "instanceId",
+ oi->instance_id);
+ json_object_int_add(json_obj, "interfaceMtu",
+ oi->ifmtu);
+ json_object_int_add(json_obj, "autoDetect", ifp->mtu6);
+ json_object_string_add(json_obj, "mtuMismatchDetection",
+ oi->mtu_ignore ? "disabled"
+ : "enabled");
+ inet_ntop(AF_INET, &oi->area->area_id, strbuf,
+ sizeof(strbuf));
+ json_object_string_add(json_obj, "areaId", strbuf);
+ json_object_int_add(json_obj, "cost", oi->cost);
+ } else
+ json_object_boolean_false_add(json_obj,
+ "attachedToArea");
+
+ } else {
+ if (oi->area) {
+ vty_out(vty,
+ " Instance ID %d, Interface MTU %d (autodetect: %d)\n",
+ oi->instance_id, oi->ifmtu, ifp->mtu6);
+ vty_out(vty, " MTU mismatch detection: %s\n",
+ oi->mtu_ignore ? "disabled" : "enabled");
+ inet_ntop(AF_INET, &oi->area->area_id, strbuf,
+ sizeof(strbuf));
+ vty_out(vty, " Area ID %s, Cost %u\n", strbuf,
+ oi->cost);
+ } else
+ vty_out(vty, " Not Attached to Area\n");
+ }
- vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
- ospf6_interface_state_str[oi->state], oi->transdelay,
- oi->priority);
- vty_out(vty, " Timer intervals configured:\n");
- vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
- oi->hello_interval, oi->dead_interval, oi->rxmt_interval);
+ if (use_json) {
+ json_object_string_add(json_obj, "ospf6InterfaceState",
+ ospf6_interface_state_str[oi->state]);
+ json_object_int_add(json_obj, "transmitDelaySec",
+ oi->transdelay);
+ json_object_int_add(json_obj, "priority", oi->priority);
+ json_object_int_add(json_obj, "timerIntervalsConfigHello",
+ oi->hello_interval);
+ json_object_int_add(json_obj, "timerIntervalsConfigDead",
+ oi->dead_interval);
+ json_object_int_add(json_obj, "timerIntervalsConfigRetransmit",
+ oi->rxmt_interval);
+ } else {
+ vty_out(vty, " State %s, Transmit Delay %d sec, Priority %d\n",
+ ospf6_interface_state_str[oi->state], oi->transdelay,
+ oi->priority);
+ vty_out(vty, " Timer intervals configured:\n");
+ vty_out(vty, " Hello %d, Dead %d, Retransmit %d\n",
+ oi->hello_interval, oi->dead_interval,
+ oi->rxmt_interval);
+ }
inet_ntop(AF_INET, &oi->drouter, drouter, sizeof(drouter));
inet_ntop(AF_INET, &oi->bdrouter, bdrouter, sizeof(bdrouter));
- vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
-
- vty_out(vty, " Number of I/F scoped LSAs is %u\n", oi->lsdb->count);
+ if (use_json) {
+ json_object_string_add(json_obj, "dr", drouter);
+ json_object_string_add(json_obj, "bdr", bdrouter);
+ json_object_int_add(json_obj, "numberOfInterfaceScopedLsa",
+ oi->lsdb->count);
+ } else {
+ vty_out(vty, " DR: %s BDR: %s\n", drouter, bdrouter);
+ vty_out(vty, " Number of I/F scoped LSAs is %u\n",
+ oi->lsdb->count);
+ }
monotime(&now);
- timerclear(&res);
- if (oi->thread_send_lsupdate)
- timersub(&oi->thread_send_lsupdate->u.sands, &now, &res);
- timerstring(&res, duration, sizeof(duration));
- vty_out(vty,
- " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
- oi->lsupdate_list->count, duration,
- (oi->thread_send_lsupdate ? "on" : "off"));
- for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
- vty_out(vty, " %s\n", lsa->name);
-
- timerclear(&res);
- if (oi->thread_send_lsack)
- timersub(&oi->thread_send_lsack->u.sands, &now, &res);
- timerstring(&res, duration, sizeof(duration));
- vty_out(vty, " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
- oi->lsack_list->count, duration,
- (oi->thread_send_lsack ? "on" : "off"));
- for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
- vty_out(vty, " %s\n", lsa->name);
- ospf6_bfd_show_info(vty, oi->bfd_info, 1, NULL, false);
+ if (use_json) {
+ timerclear(&res);
+ if (oi->thread_send_lsupdate)
+ timersub(&oi->thread_send_lsupdate->u.sands, &now,
+ &res);
+ timerstring(&res, duration, sizeof(duration));
+ json_object_int_add(json_obj, "pendingLsaLsUpdateCount",
+ oi->lsupdate_list->count);
+ json_object_string_add(json_obj, "pendingLsaLsUpdateTime",
+ duration);
+ json_object_string_add(
+ json_obj, "lsUpdateSendThread",
+ (oi->thread_send_lsupdate ? "on" : "off"));
+
+ json_arr = json_object_new_array();
+ for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
+ json_object_array_add(
+ json_arr, json_object_new_string(lsa->name));
+ json_object_object_add(json_obj, "pendingLsaLsUpdate",
+ json_arr);
+
+ timerclear(&res);
+ if (oi->thread_send_lsack)
+ timersub(&oi->thread_send_lsack->u.sands, &now, &res);
+ timerstring(&res, duration, sizeof(duration));
+
+ json_object_int_add(json_obj, "pendingLsaLsAckCount",
+ oi->lsack_list->count);
+ json_object_string_add(json_obj, "pendingLsaLsAckTime",
+ duration);
+ json_object_string_add(json_obj, "lsAckSendThread",
+ (oi->thread_send_lsack ? "on" : "off"));
+
+ json_arr = json_object_new_array();
+ for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
+ json_object_array_add(
+ json_arr, json_object_new_string(lsa->name));
+ json_object_object_add(json_obj, "pendingLsaLsAck", json_arr);
+
+ } else {
+ timerclear(&res);
+ if (oi->thread_send_lsupdate)
+ timersub(&oi->thread_send_lsupdate->u.sands, &now,
+ &res);
+ timerstring(&res, duration, sizeof(duration));
+ vty_out(vty,
+ " %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
+ oi->lsupdate_list->count, duration,
+ (oi->thread_send_lsupdate ? "on" : "off"));
+ for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
+ vty_out(vty, " %s\n", lsa->name);
+
+ timerclear(&res);
+ if (oi->thread_send_lsack)
+ timersub(&oi->thread_send_lsack->u.sands, &now, &res);
+ timerstring(&res, duration, sizeof(duration));
+ vty_out(vty,
+ " %d Pending LSAs for LSAck in Time %s [thread %s]\n",
+ oi->lsack_list->count, duration,
+ (oi->thread_send_lsack ? "on" : "off"));
+ for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
+ vty_out(vty, " %s\n", lsa->name);
+ }
+ ospf6_bfd_show_info(vty, oi->bfd_info, 1, json_obj, use_json);
return 0;
}
/* show interface */
-DEFUN (show_ipv6_ospf6_interface,
- show_ipv6_ospf6_interface_ifname_cmd,
- "show ipv6 ospf6 interface [IFNAME]",
- SHOW_STR
- IP6_STR
- OSPF6_STR
- INTERFACE_STR
- IFNAME_STR)
+DEFUN(show_ipv6_ospf6_interface,
+ show_ipv6_ospf6_interface_ifname_cmd,
+ "show ipv6 ospf6 interface [IFNAME] [json]",
+ SHOW_STR
+ IP6_STR
+ OSPF6_STR
+ INTERFACE_STR
+ IFNAME_STR
+ JSON_STR)
{
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
int idx_ifname = 4;
struct interface *ifp;
-
- if (argc == 5) {
- ifp = if_lookup_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
- if (ifp == NULL) {
- vty_out(vty, "No such Interface: %s\n",
- argv[idx_ifname]->arg);
- return CMD_WARNING;
+ json_object *json;
+ json_object *json_int;
+ bool uj = use_json(argc, argv);
+
+ if (uj) {
+ json = json_object_new_object();
+ if (argc == 6) {
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg,
+ VRF_DEFAULT);
+ json_int = json_object_new_object();
+ if (ifp == NULL) {
+ json_object_string_add(json, "noSuchInterface",
+ argv[idx_ifname]->arg);
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ json_object_free(json_int);
+ return CMD_WARNING;
+ }
+ ospf6_interface_show(vty, ifp, json_int, uj);
+ json_object_object_add(json, ifp->name, json_int);
+ } else {
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ json_int = json_object_new_object();
+ ospf6_interface_show(vty, ifp, json_int, uj);
+ json_object_object_add(json, ifp->name,
+ json_int);
+ }
}
- ospf6_interface_show(vty, ifp);
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
} else {
- FOR_ALL_INTERFACES (vrf, ifp)
- ospf6_interface_show(vty, ifp);
+ if (argc == 5) {
+ ifp = if_lookup_by_name(argv[idx_ifname]->arg,
+ VRF_DEFAULT);
+ if (ifp == NULL) {
+ vty_out(vty, "No such Interface: %s\n",
+ argv[idx_ifname]->arg);
+ return CMD_WARNING;
+ }
+ ospf6_interface_show(vty, ifp, NULL, uj);
+ } else {
+ FOR_ALL_INTERFACES (vrf, ifp)
+ ospf6_interface_show(vty, ifp, NULL, uj);
+ }
}
return CMD_SUCCESS;
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index b6c712176a..8d3ee1ad02 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -40,6 +40,7 @@
#include "ospf6_zebra.h"
#include "ospf6d.h"
#include "ospf6_area.h"
+#include "lib/json.h"
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
@@ -219,31 +220,64 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
return 0;
}
-DEFUN (show_zebra,
- show_ospf6_zebra_cmd,
- "show ipv6 ospf6 zebra",
- SHOW_STR
- IPV6_STR
- OSPF6_STR
- ZEBRA_STR)
+DEFUN(show_zebra,
+ show_ospf6_zebra_cmd,
+ "show ipv6 ospf6 zebra [json]",
+ SHOW_STR
+ IPV6_STR
+ OSPF6_STR
+ ZEBRA_STR
+ JSON_STR)
{
int i;
+ bool uj = use_json(argc, argv);
+ json_object *json;
+ json_object *json_zebra;
+ json_object *json_array;
+
if (zclient == NULL) {
vty_out(vty, "Not connected to zebra\n");
return CMD_SUCCESS;
}
- vty_out(vty, "Zebra Information\n");
- vty_out(vty, " fail: %d\n", zclient->fail);
- vty_out(vty, " redistribute default: %d\n",
- vrf_bitmap_check(zclient->default_information[AFI_IP6],
- VRF_DEFAULT));
- vty_out(vty, " redistribute:");
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
- vty_out(vty, " %s", zebra_route_string(i));
+ if (uj) {
+ json = json_object_new_object();
+ json_zebra = json_object_new_object();
+ json_array = json_object_new_array();
+
+ json_object_int_add(json_zebra, "fail", zclient->fail);
+ json_object_int_add(
+ json_zebra, "redistributeDefault",
+ vrf_bitmap_check(zclient->default_information[AFI_IP6],
+ VRF_DEFAULT));
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (vrf_bitmap_check(zclient->redist[AFI_IP6][i],
+ VRF_DEFAULT))
+ json_object_array_add(
+ json_array,
+ json_object_new_string(
+ zebra_route_string(i)));
+ }
+ json_object_object_add(json_zebra, "redistribute", json_array);
+ json_object_object_add(json, "zebraInformation", json_zebra);
+
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ } else {
+ vty_out(vty, "Zebra Infomation\n");
+ vty_out(vty, " fail: %d\n", zclient->fail);
+ vty_out(vty, " redistribute default: %d\n",
+ vrf_bitmap_check(zclient->default_information[AFI_IP6],
+ VRF_DEFAULT));
+ vty_out(vty, " redistribute:");
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (vrf_bitmap_check(zclient->redist[AFI_IP6][i],
+ VRF_DEFAULT))
+ vty_out(vty, " %s", zebra_route_string(i));
+ }
+ vty_out(vty, "\n");
}
- vty_out(vty, "\n");
return CMD_SUCCESS;
}
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index cff237f965..62d19f7619 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1174,7 +1174,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp)
zassert(pim_ifp);
/* join suppression disabled ? */
- if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options))
+ if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options))
return 0;
/* t_suppressed = t_periodic * rand(1.1, 1.4) */
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 8decfef74d..664ab31949 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -35,24 +35,27 @@
#define PIM_IF_MASK_PIM (1 << 0)
#define PIM_IF_MASK_IGMP (1 << 1)
#define PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS (1 << 2)
-#define PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPRESSION (1 << 3)
+#define PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION (1 << 3)
#define PIM_IF_IS_DELETED(ifp) ((ifp)->ifindex == IFINDEX_INTERNAL)
#define PIM_IF_TEST_PIM(options) (PIM_IF_MASK_PIM & (options))
#define PIM_IF_TEST_IGMP(options) (PIM_IF_MASK_IGMP & (options))
#define PIM_IF_TEST_IGMP_LISTEN_ALLROUTERS(options) (PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS & (options))
-#define PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(options) (PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPRESSION & (options))
+#define PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
+ (PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION & (options))
#define PIM_IF_DO_PIM(options) ((options) |= PIM_IF_MASK_PIM)
#define PIM_IF_DO_IGMP(options) ((options) |= PIM_IF_MASK_IGMP)
#define PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(options) ((options) |= PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS)
-#define PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(options) ((options) |= PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPRESSION)
+#define PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
+ ((options) |= PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION)
#define PIM_IF_DONT_PIM(options) ((options) &= ~PIM_IF_MASK_PIM)
#define PIM_IF_DONT_IGMP(options) ((options) &= ~PIM_IF_MASK_IGMP)
#define PIM_IF_DONT_IGMP_LISTEN_ALLROUTERS(options) ((options) &= ~PIM_IF_MASK_IGMP_LISTEN_ALLROUTERS)
-#define PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(options) ((options) &= ~PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPRESSION)
+#define PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPPRESSION(options) \
+ ((options) &= ~PIM_IF_MASK_PIM_CAN_DISABLE_JOIN_SUPPRESSION)
#define PIM_I_am_DR(pim_ifp) (pim_ifp)->pim_dr_addr.s_addr == (pim_ifp)->primary_address.s_addr
#define PIM_I_am_DualActive(pim_ifp) (pim_ifp)->activeactive == true
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index bf31d4e450..2ccff8b84a 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -484,9 +484,9 @@ void pim_sock_reset(struct interface *ifp)
pim_ifp->pim_override_interval_msec =
PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
if (PIM_DEFAULT_CAN_DISABLE_JOIN_SUPPRESSION) {
- PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
+ PIM_IF_DO_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options);
} else {
- PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options);
+ PIM_IF_DONT_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options);
}
/* neighbors without lan_delay */
@@ -652,7 +652,7 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
__func__, dst_str, ifp->name, holdtime,
pim_ifp->pim_propagation_delay_msec,
pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(
+ PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(
pim_ifp->options),
pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
listcount(ifp->connected));
@@ -664,7 +664,7 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
pim_ifp->pim_propagation_delay_msec,
pim_ifp->pim_override_interval_msec,
- PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options));
+ PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPPRESSION(pim_ifp->options));
if (pim_tlv_size < 0) {
return -1;
}
diff --git a/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py b/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py
index 3f3b71dea3..089b1acb1c 100644
--- a/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py
+++ b/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py
@@ -156,7 +156,7 @@ def test_bgp_aggregate_address_matching_med_only():
assert result is None, assertmsg
-def test_bgp_aggregate_address_match_and_supress():
+def test_bgp_aggregate_address_match_and_suppress():
"Test that the command matching-MED-only with suppression works."
tgen = get_topogen()
@@ -206,12 +206,15 @@ def test_bgp_aggregate_address_suppress_map():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- expect_route('r2', {
- "192.168.2.0/24": [{"protocol": "bgp"}],
- "192.168.2.1/32": None,
- "192.168.2.2/32": [{"protocol": "bgp"}],
- "192.168.2.3/32": [{"protocol": "bgp"}],
- })
+ expect_route(
+ "r2",
+ {
+ "192.168.2.0/24": [{"protocol": "bgp"}],
+ "192.168.2.1/32": None,
+ "192.168.2.2/32": [{"protocol": "bgp"}],
+ "192.168.2.3/32": [{"protocol": "bgp"}],
+ },
+ )
# Change route map and test again.
tgen.gears["r1"].vtysh_multicmd(
@@ -224,12 +227,15 @@ aggregate-address 192.168.2.0/24 suppress-map rm-sup-two
"""
)
- expect_route('r2', {
- "192.168.2.0/24": [{"protocol": "bgp"}],
- "192.168.2.1/32": [{"protocol": "bgp"}],
- "192.168.2.2/32": None,
- "192.168.2.3/32": [{"protocol": "bgp"}],
- })
+ expect_route(
+ "r2",
+ {
+ "192.168.2.0/24": [{"protocol": "bgp"}],
+ "192.168.2.1/32": [{"protocol": "bgp"}],
+ "192.168.2.2/32": None,
+ "192.168.2.3/32": [{"protocol": "bgp"}],
+ },
+ )
def test_bgp_aggregate_address_suppress_map_update_route_map():
@@ -248,12 +254,15 @@ aggregate-address 192.168.2.0/24 suppress-map rm-sup-three
"""
)
- expect_route('r2', {
- "192.168.2.0/24": [{"protocol": "bgp"}],
- "192.168.2.1/32": [{"protocol": "bgp"}],
- "192.168.2.2/32": [{"protocol": "bgp"}],
- "192.168.2.3/32": [{"protocol": "bgp"}],
- })
+ expect_route(
+ "r2",
+ {
+ "192.168.2.0/24": [{"protocol": "bgp"}],
+ "192.168.2.1/32": [{"protocol": "bgp"}],
+ "192.168.2.2/32": [{"protocol": "bgp"}],
+ "192.168.2.3/32": [{"protocol": "bgp"}],
+ },
+ )
# Create missing route map and test again.
tgen.gears["r1"].vtysh_multicmd(
@@ -264,12 +273,15 @@ match ip address acl-sup-three
"""
)
- expect_route('r2', {
- "192.168.2.0/24": [{"protocol": "bgp"}],
- "192.168.2.1/32": [{"protocol": "bgp"}],
- "192.168.2.2/32": [{"protocol": "bgp"}],
- "192.168.2.3/32": None,
- })
+ expect_route(
+ "r2",
+ {
+ "192.168.2.0/24": [{"protocol": "bgp"}],
+ "192.168.2.1/32": [{"protocol": "bgp"}],
+ "192.168.2.2/32": [{"protocol": "bgp"}],
+ "192.168.2.3/32": None,
+ },
+ )
def test_memory_leak():
diff --git a/yang/frr-bgp-common-structure.yang b/yang/frr-bgp-common-structure.yang
index 507928f28e..7b987a93cd 100644
--- a/yang/frr-bgp-common-structure.yang
+++ b/yang/frr-bgp-common-structure.yang
@@ -344,7 +344,7 @@ submodule frr-bgp-common-structure {
default "true";
description
"When set to 'true' sending Capability Negotiation in the open
- message is supressed to this peer.";
+ message is suppressed to this peer.";
}
leaf override-capability {
@@ -807,9 +807,9 @@ submodule frr-bgp-common-structure {
uses as-path-filter-list-policy-export;
- uses unsupress-map-policy-import;
+ uses unsuppress-map-policy-import;
- uses unsupress-map-policy-export;
+ uses unsuppress-map-policy-export;
}
}
}
diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang
index de78758dbb..cb1a6a8f56 100644
--- a/yang/frr-bgp-common.yang
+++ b/yang/frr-bgp-common.yang
@@ -87,14 +87,14 @@ submodule frr-bgp-common {
}
}
- grouping unsupress-map-policy-import {
- leaf unsupress-map-import {
+ grouping unsuppress-map-policy-import {
+ leaf unsuppress-map-import {
type frr-route-map:route-map-ref;
}
}
- grouping unsupress-map-policy-export {
- leaf unsupress-map-export {
+ grouping unsuppress-map-policy-export {
+ leaf unsuppress-map-export {
type frr-route-map:route-map-ref;
}
}
diff --git a/zebra/connected.c b/zebra/connected.c
index 6a1efc3e65..70ea2e3805 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -41,6 +41,7 @@
#include "zebra/zebra_mpls.h"
#include "zebra/debug.h"
#include "zebra/zebra_errors.h"
+#include "zebra/zebra_router.h"
/* communicate the withdrawal of a connected address */
static void connected_withdraw(struct connected *ifc)
@@ -207,6 +208,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
};
struct zebra_vrf *zvrf;
uint32_t metric;
+ uint32_t flags = 0;
zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
if (!zvrf) {
@@ -251,11 +253,22 @@ void connected_up(struct interface *ifp, struct connected *ifc)
metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
ifc->metric : ifp->metric;
- rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
- rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
+ /*
+ * Since we are hand creating the connected routes
+ * in our main routing table, *if* we are working
+ * in an offloaded environment then we need to
+ * pretend like the route is offloaded so everything
+ * else will work
+ */
+ if (zrouter.asic_offloaded)
+ flags |= ZEBRA_FLAG_OFFLOADED;
+
+ rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
+ flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
+
+ rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
+ flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0);
/* Schedule LSP forwarding entries for processing, if appropriate. */
if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
diff --git a/zebra/main.c b/zebra/main.c
index ced29e1a25..55fd3244cb 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -83,6 +83,8 @@ uint32_t nl_rcvbufsize = 4194304;
#endif /* HAVE_NETLINK */
#define OPTION_V6_RR_SEMANTICS 2000
+#define OPTION_ASIC_OFFLOAD 2001
+
/* Command line options. */
const struct option longopts[] = {
{"batch", no_argument, NULL, 'b'},
@@ -92,6 +94,7 @@ const struct option longopts[] = {
{"retain", no_argument, NULL, 'r'},
{"vrfdefaultname", required_argument, NULL, 'o'},
{"graceful_restart", required_argument, NULL, 'K'},
+ {"asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD},
#ifdef HAVE_NETLINK
{"vrfwnetns", no_argument, NULL, 'n'},
{"nl-bufsize", required_argument, NULL, 's'},
@@ -281,6 +284,8 @@ int main(int argc, char **argv)
char *vrf_default_name_configured = NULL;
struct sockaddr_storage dummy;
socklen_t dummylen;
+ bool asic_offload = false;
+ bool notify_on_ack = true;
graceful_restart = 0;
vrf_configure_backend(VRF_BACKEND_VRF_LITE);
@@ -301,6 +306,7 @@ int main(int argc, char **argv)
" -r, --retain When program terminates, retain added route by zebra.\n"
" -o, --vrfdefaultname Set default VRF name.\n"
" -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n"
+ " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n"
#ifdef HAVE_NETLINK
" -n, --vrfwnetns Use NetNS as VRF backend\n"
" -s, --nl-bufsize Set netlink receive buffer size\n"
@@ -366,6 +372,13 @@ int main(int argc, char **argv)
case OPTION_V6_RR_SEMANTICS:
v6_rr_semantics = true;
break;
+ case OPTION_ASIC_OFFLOAD:
+ if (!strcmp(optarg, "notify_on_offload"))
+ notify_on_ack = false;
+ if (!strcmp(optarg, "notify_on_ack"))
+ notify_on_ack = true;
+ asic_offload = true;
+ break;
#endif /* HAVE_NETLINK */
default:
frr_help_exit(1);
@@ -376,7 +389,7 @@ int main(int argc, char **argv)
zrouter.master = frr_init();
/* Zebra related initialize. */
- zebra_router_init();
+ zebra_router_init(asic_offload, notify_on_ack);
zserv_init();
rib_init();
zebra_if_init();
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 4dc8c2a6eb..3402edf467 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -642,7 +642,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
selfroute = is_selfroute(rtm->rtm_protocol);
- if (!startup && selfroute && h->nlmsg_type == RTM_NEWROUTE) {
+ if (!startup && selfroute
+ && h->nlmsg_type == RTM_NEWROUTE
+ && !zrouter.asic_offloaded) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("Route type: %d Received that we think we have originated, ignoring",
rtm->rtm_protocol);
@@ -672,6 +674,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
flags |= ZEBRA_FLAG_TRAPPED;
if (rtm->rtm_flags & RTM_F_OFFLOAD)
flags |= ZEBRA_FLAG_OFFLOADED;
+ if (rtm->rtm_flags & RTM_F_OFFLOAD_FAILED)
+ flags |= ZEBRA_FLAG_OFFLOAD_FAILED;
/* Route which inserted by Zebra. */
if (selfroute) {
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index b688704962..569b23573c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1821,8 +1821,12 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
"%s(%u):%pFX Stale dplane result for re %p",
VRF_LOGNAME(vrf),
dplane_ctx_get_vrf(ctx), dest_pfx, re);
- } else
- UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+ } else {
+ if (!zrouter.asic_offloaded ||
+ (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED) ||
+ CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED)))
+ UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+ }
}
if (old_re) {
@@ -1899,8 +1903,23 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
zvrf->installs++;
/* Notify route owner */
- zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
-
+ if (zebra_router_notify_on_ack())
+ zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
+ else {
+ if (re) {
+ if (CHECK_FLAG(re->flags,
+ ZEBRA_FLAG_OFFLOADED))
+ zsend_route_notify_owner_ctx(
+ ctx,
+ ZAPI_ROUTE_INSTALLED);
+ if (CHECK_FLAG(
+ re->flags,
+ ZEBRA_FLAG_OFFLOAD_FAILED))
+ zsend_route_notify_owner_ctx(
+ ctx,
+ ZAPI_ROUTE_FAIL_INSTALL);
+ }
+ }
} else {
if (re) {
SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
@@ -2067,7 +2086,8 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
}
/* Ensure we clear the QUEUED flag */
- UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+ if (!zrouter.asic_offloaded)
+ UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
/* Is this a notification that ... matters? We mostly care about
* the route that is currently selected for installation; we may also
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index fc4390f7f8..249ec38a69 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -257,7 +257,12 @@ void zebra_router_terminate(void)
hash_free(zrouter.iptable_hash);
}
-void zebra_router_init(void)
+bool zebra_router_notify_on_ack(void)
+{
+ return !zrouter.asic_offloaded || zrouter.notify_on_ack;
+}
+
+void zebra_router_init(bool asic_offload, bool notify_on_ack)
{
zrouter.sequence_num = 0;
@@ -291,5 +296,6 @@ void zebra_router_init(void)
hash_create_size(8, zebra_nhg_id_key, zebra_nhg_hash_id_equal,
"Zebra Router Nexthop Groups ID index");
- zrouter.asic_offloaded = false;
+ zrouter.asic_offloaded = asic_offload;
+ zrouter.notify_on_ack = notify_on_ack;
}
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index 8651a01e9f..08c5fcaf8d 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -210,13 +210,14 @@ struct zebra_router {
* Does the underlying system provide an asic offload
*/
bool asic_offloaded;
+ bool notify_on_ack;
};
#define GRACEFUL_RESTART_TIME 60
extern struct zebra_router zrouter;
-extern void zebra_router_init(void);
+extern void zebra_router_init(bool asic_offload, bool notify_on_ack);
extern void zebra_router_cleanup(void);
extern void zebra_router_terminate(void);
@@ -255,6 +256,8 @@ extern void multicast_mode_ipv4_set(enum multicast_mode mode);
extern enum multicast_mode multicast_mode_ipv4_get(void);
+extern bool zebra_router_notify_on_ack(void);
+
/* zebra_northbound.c */
extern const struct frr_yang_module_info frr_zebra_info;
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index ab7d2845e7..ea7baa2565 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -204,12 +204,16 @@ static char re_status_output_char(const struct route_entry *re,
star_p = true;
}
+ if (zrouter.asic_offloaded &&
+ CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
+ return 'q';
+
if (zrouter.asic_offloaded
&& CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED))
return 't';
if (zrouter.asic_offloaded
- && !CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED))
+ && CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
return 'o';
if (star_p)
@@ -870,6 +874,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED))
json_object_boolean_true_add(json_route, "offloaded");
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED))
+ json_object_boolean_false_add(json_route, "offloaded");
+
if (re->tag)
json_object_int_add(json_route, "tag", re->tag);
@@ -2005,6 +2012,8 @@ static void vty_show_ip_route_summary(struct vty *vty,
#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1)
uint32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1];
uint32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1];
+ uint32_t offload_cnt[ZEBRA_ROUTE_TOTAL + 1];
+ uint32_t trap_cnt[ZEBRA_ROUTE_TOTAL + 1];
uint32_t i;
uint32_t is_ibgp;
json_object *json_route_summary = NULL;
@@ -2012,6 +2021,8 @@ static void vty_show_ip_route_summary(struct vty *vty,
memset(&rib_cnt, 0, sizeof(rib_cnt));
memset(&fib_cnt, 0, sizeof(fib_cnt));
+ memset(&offload_cnt, 0, sizeof(offload_cnt));
+ memset(&trap_cnt, 0, sizeof(trap_cnt));
if (use_json) {
json_route_summary = json_object_new_object();
@@ -2039,6 +2050,20 @@ static void vty_show_ip_route_summary(struct vty *vty,
else
fib_cnt[re->type]++;
}
+
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_TRAPPED)) {
+ if (is_ibgp)
+ trap_cnt[ZEBRA_ROUTE_IBGP]++;
+ else
+ trap_cnt[re->type]++;
+ }
+
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) {
+ if (is_ibgp)
+ offload_cnt[ZEBRA_ROUTE_IBGP]++;
+ else
+ offload_cnt[re->type]++;
+ }
}
if (!use_json)
@@ -2062,6 +2087,13 @@ static void vty_show_ip_route_summary(struct vty *vty,
json_object_int_add(
json_route_ebgp, "rib",
rib_cnt[ZEBRA_ROUTE_BGP]);
+ json_object_int_add(
+ json_route_ebgp, "fibOffLoaded",
+ offload_cnt[ZEBRA_ROUTE_BGP]);
+ json_object_int_add(
+ json_route_ebgp, "fibTrapped",
+ trap_cnt[ZEBRA_ROUTE_BGP]);
+
json_object_string_add(json_route_ebgp,
"type", "ebgp");
json_object_array_add(json_route_routes,
@@ -2076,6 +2108,12 @@ static void vty_show_ip_route_summary(struct vty *vty,
json_object_int_add(
json_route_ibgp, "rib",
rib_cnt[ZEBRA_ROUTE_IBGP]);
+ json_object_int_add(
+ json_route_ibgp, "fibOffLoaded",
+ offload_cnt[ZEBRA_ROUTE_IBGP]);
+ json_object_int_add(
+ json_route_ibgp, "fibTrapped",
+ trap_cnt[ZEBRA_ROUTE_IBGP]);
json_object_string_add(json_route_ibgp,
"type", "ibgp");
json_object_array_add(json_route_routes,
@@ -2099,6 +2137,13 @@ static void vty_show_ip_route_summary(struct vty *vty,
"fib", fib_cnt[i]);
json_object_int_add(json_route_type,
"rib", rib_cnt[i]);
+
+ json_object_int_add(json_route_type,
+ "fibOffLoaded",
+ offload_cnt[i]);
+ json_object_int_add(json_route_type,
+ "fibTrapped",
+ trap_cnt[i]);
json_object_string_add(
json_route_type, "type",
zebra_route_string(i));