diff options
| -rw-r--r-- | bfdd/ptm_adapter.c | 124 | ||||
| -rw-r--r-- | bgpd/bgp_nb.c | 36 | ||||
| -rw-r--r-- | bgpd/bgp_nb.h | 24 | ||||
| -rw-r--r-- | bgpd/bgp_nb_config.c | 38 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 25 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 7 | ||||
| -rw-r--r-- | doc/user/ospf6d.rst | 14 | ||||
| -rw-r--r-- | doc/user/zebra.rst | 13 | ||||
| -rw-r--r-- | include/linux/rtnetlink.h | 1 | ||||
| -rw-r--r-- | lib/bfd.c | 48 | ||||
| -rw-r--r-- | lib/zclient.h | 7 | ||||
| -rw-r--r-- | ospf6d/ospf6_bfd.c | 2 | ||||
| -rw-r--r-- | ospf6d/ospf6_bfd.h | 1 | ||||
| -rw-r--r-- | ospf6d/ospf6_interface.c | 355 | ||||
| -rw-r--r-- | ospf6d/ospf6_zebra.c | 68 | ||||
| -rw-r--r-- | pimd/pim_iface.c | 2 | ||||
| -rw-r--r-- | pimd/pim_iface.h | 11 | ||||
| -rw-r--r-- | pimd/pim_pim.c | 8 | ||||
| -rw-r--r-- | tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py | 62 | ||||
| -rw-r--r-- | yang/frr-bgp-common-structure.yang | 6 | ||||
| -rw-r--r-- | yang/frr-bgp-common.yang | 8 | ||||
| -rw-r--r-- | zebra/connected.c | 21 | ||||
| -rw-r--r-- | zebra/main.c | 15 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 6 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 30 | ||||
| -rw-r--r-- | zebra/zebra_router.c | 10 | ||||
| -rw-r--r-- | zebra/zebra_router.h | 5 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 47 |
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 */ @@ -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)); |
