diff options
53 files changed, 687 insertions, 692 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 490bc30d7..9e7ed114e 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -756,20 +756,6 @@ static int bfd_ifp_destroy(struct interface *ifp) return 0; } -static int bfdd_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t nvrfid; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, &nvrfid); - if (ifp == NULL) - return 0; - - if_update_to_new_vrf(ifp, nvrfid); - - return 0; -} - static void bfdd_sessions_enable_address(struct connected *ifc) { struct bfd_session_observer *bso; @@ -833,9 +819,6 @@ static zclient_handler *const bfd_handlers[] = { */ [ZEBRA_BFD_DEST_REPLAY] = bfdd_replay, - /* Learn about interface VRF. */ - [ZEBRA_INTERFACE_VRF_UPDATE] = bfdd_interface_vrf_update, - /* Learn about new addresses being registered. */ [ZEBRA_INTERFACE_ADDRESS_ADD] = bfdd_interface_address_update, [ZEBRA_INTERFACE_ADDRESS_DELETE] = bfdd_interface_address_update, diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 3fd246397..e52230713 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -735,6 +735,27 @@ bool community_list_exact_match(struct community *com, return false; } +bool community_list_any_match(struct community *com, struct community_list *list) +{ + struct community_entry *entry; + uint32_t val; + int i; + + for (i = 0; i < com->size; i++) { + val = community_val_get(com, i); + + for (entry = list->head; entry; entry = entry->next) { + if (entry->style == COMMUNITY_LIST_STANDARD && + community_include(entry->u.com, val)) + return entry->direct == COMMUNITY_PERMIT; + if ((entry->style == COMMUNITY_LIST_EXPANDED) && + community_regexp_include(entry->reg, com, i)) + return entry->direct == COMMUNITY_PERMIT; + } + } + return false; +} + /* Delete all permitted communities in the list from com. */ struct community *community_list_match_delete(struct community *com, struct community_list *list) @@ -922,6 +943,28 @@ int community_list_unset(struct community_list_handler *ch, const char *name, return 0; } +bool lcommunity_list_any_match(struct lcommunity *lcom, + struct community_list *list) +{ + struct community_entry *entry; + uint8_t *ptr; + int i; + + for (i = 0; i < lcom->size; i++) { + ptr = lcom->val + (i * LCOMMUNITY_SIZE); + + for (entry = list->head; entry; entry = entry->next) { + if ((entry->style == LARGE_COMMUNITY_LIST_STANDARD) && + lcommunity_include(entry->u.lcom, ptr)) + return entry->direct == COMMUNITY_PERMIT; + if ((entry->style == LARGE_COMMUNITY_LIST_EXPANDED) && + lcommunity_regexp_include(entry->reg, lcom, i)) + return entry->direct == COMMUNITY_PERMIT; + } + } + return false; +} + /* Delete all permitted large communities in the list from com. */ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom, struct community_list *list) diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h index 251169876..a435b92ce 100644 --- a/bgpd/bgp_clist.h +++ b/bgpd/bgp_clist.h @@ -158,8 +158,12 @@ extern bool community_list_exact_match(struct community *com, struct community_list *list); extern bool lcommunity_list_exact_match(struct lcommunity *lcom, struct community_list *list); +extern bool community_list_any_match(struct community *com, + struct community_list *list); extern struct community * community_list_match_delete(struct community *com, struct community_list *list); +extern bool lcommunity_list_any_match(struct lcommunity *lcom, + struct community_list *list); extern struct lcommunity * lcommunity_list_match_delete(struct lcommunity *lcom, struct community_list *list); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index d47324593..5d7441ed6 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3064,6 +3064,40 @@ static void bgp_dynamic_capability_graceful_restart(uint8_t *pnt, int action, } } +static void bgp_dynamic_capability_software_version(uint8_t *pnt, int action, + struct capability_header *hdr, + struct peer *peer) +{ + uint8_t *data = pnt + 3; + uint8_t *end = data + hdr->length; + uint8_t len = *data; + char soft_version[BGP_MAX_SOFT_VERSION + 1] = {}; + + if (action == CAPABILITY_ACTION_SET) { + if (data + len > end) { + zlog_err("%pBP: Received invalid Software Version capability length %d", + peer, len); + return; + } + data++; + + if (len > BGP_MAX_SOFT_VERSION) + len = BGP_MAX_SOFT_VERSION; + + memcpy(&soft_version, data, len); + soft_version[len] = '\0'; + + XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version); + peer->soft_version = XSTRDUP(MTYPE_BGP_SOFT_VERSION, + soft_version); + + SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV); + } else { + UNSET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV); + XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version); + } +} + /** * Parse BGP CAPABILITY message for peer. * @@ -3082,7 +3116,6 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, afi_t afi; iana_safi_t pkt_safi; safi_t safi; - char soft_version[BGP_MAX_SOFT_VERSION + 1] = {}; const char *capability; end = pnt + length; @@ -3129,22 +3162,8 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, switch (hdr->code) { case CAPABILITY_CODE_SOFT_VERSION: - if (action == CAPABILITY_ACTION_SET) { - SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV); - - memcpy(&soft_version, pnt + 3, hdr->length); - soft_version[hdr->length] = '\0'; - - XFREE(MTYPE_BGP_SOFT_VERSION, - peer->soft_version); - peer->soft_version = - XSTRDUP(MTYPE_BGP_SOFT_VERSION, - soft_version); - } else { - UNSET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV); - XFREE(MTYPE_BGP_SOFT_VERSION, - peer->soft_version); - } + bgp_dynamic_capability_software_version(pnt, action, + hdr, peer); break; case CAPABILITY_CODE_MP: if (hdr->length < sizeof(struct capability_mp_data)) { diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 274df5197..e0db43f67 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1528,7 +1528,8 @@ static const struct route_map_rule_cmd route_match_aspath_cmd = { struct rmap_community { char *name; uint32_t name_hash; - int exact; + bool exact; + bool any; }; /* Match function for community match. */ @@ -1551,6 +1552,12 @@ route_match_community(void *rule, const struct prefix *prefix, void *object) if (community_list_exact_match( bgp_attr_get_community(path->attr), list)) return RMAP_MATCH; + } else if (rcom->any) { + if (!bgp_attr_get_community(path->attr)) + return RMAP_OKAY; + if (community_list_any_match(bgp_attr_get_community(path->attr), + list)) + return RMAP_MATCH; } else { if (community_list_match(bgp_attr_get_community(path->attr), list)) @@ -1574,10 +1581,15 @@ static void *route_match_community_compile(const char *arg) len = p - arg; rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1); memcpy(rcom->name, arg, len); - rcom->exact = 1; + p++; + if (*p == 'e') + rcom->exact = true; + else + rcom->any = true; } else { rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); - rcom->exact = 0; + rcom->exact = false; + rcom->any = false; } rcom->name_hash = bgp_clist_hash_key(rcom->name); @@ -1637,6 +1649,12 @@ route_match_lcommunity(void *rule, const struct prefix *prefix, void *object) if (lcommunity_list_exact_match( bgp_attr_get_lcommunity(path->attr), list)) return RMAP_MATCH; + } else if (rcom->any) { + if (!bgp_attr_get_lcommunity(path->attr)) + return RMAP_OKAY; + if (lcommunity_list_any_match(bgp_attr_get_lcommunity(path->attr), + list)) + return RMAP_MATCH; } else { if (lcommunity_list_match(bgp_attr_get_lcommunity(path->attr), list)) @@ -1660,10 +1678,15 @@ static void *route_match_lcommunity_compile(const char *arg) len = p - arg; rcom->name = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1); memcpy(rcom->name, arg, len); - rcom->exact = 1; + p++; + if (*p == 'e') + rcom->exact = true; + else + rcom->any = true; } else { rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); - rcom->exact = 0; + rcom->exact = false; + rcom->any = false; } rcom->name_hash = bgp_clist_hash_key(rcom->name); @@ -5493,15 +5516,15 @@ DEFUN_YANG(no_match_alias, no_match_alias_cmd, "no match alias [ALIAS_NAME]", return nb_cli_apply_changes(vty, NULL); } -DEFPY_YANG (match_community, - match_community_cmd, - "match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]", - MATCH_STR - "Match BGP community list\n" - "Community-list number (standard)\n" - "Community-list number (expanded)\n" - "Community-list name\n" - "Do exact matching of communities\n") +DEFPY_YANG( + match_community, match_community_cmd, + "match community <(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]", + MATCH_STR "Match BGP community list\n" + "Community-list number (standard)\n" + "Community-list number (expanded)\n" + "Community-list name\n" + "Do exact matching of communities\n" + "Do matching of any community\n") { const char *xpath = "./match-condition[condition='frr-bgp-route-map:match-community']"; @@ -5517,35 +5540,35 @@ DEFPY_YANG (match_community, xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg); - if (argc == 4) { - snprintf( - xpath_match, sizeof(xpath_match), - "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", - xpath); + snprintf(xpath_match, sizeof(xpath_match), + "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", + xpath); + if (exact) nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true"); - } else { - snprintf( - xpath_match, sizeof(xpath_match), - "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", - xpath); - nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, - "false"); - } + else + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false"); + + snprintf(xpath_match, sizeof(xpath_match), + "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any", + xpath); + if (any) + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false"); return nb_cli_apply_changes(vty, NULL); } -DEFUN_YANG (no_match_community, - no_match_community_cmd, - "no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [exact-match]]", - NO_STR - MATCH_STR - "Match BGP community list\n" - "Community-list number (standard)\n" - "Community-list number (expanded)\n" - "Community-list name\n" - "Do exact matching of communities\n") +DEFUN_YANG( + no_match_community, no_match_community_cmd, + "no match community [<(1-99)|(100-500)|COMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]]", + NO_STR MATCH_STR "Match BGP community list\n" + "Community-list number (standard)\n" + "Community-list number (expanded)\n" + "Community-list name\n" + "Do exact matching of communities\n" + "Do matching of any community\n") { const char *xpath = "./match-condition[condition='frr-bgp-route-map:match-community']"; @@ -5554,15 +5577,15 @@ DEFUN_YANG (no_match_community, return nb_cli_apply_changes(vty, NULL); } -DEFPY_YANG (match_lcommunity, - match_lcommunity_cmd, - "match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]", - MATCH_STR - "Match BGP large community list\n" - "Large Community-list number (standard)\n" - "Large Community-list number (expanded)\n" - "Large Community-list name\n" - "Do exact matching of communities\n") +DEFPY_YANG( + match_lcommunity, match_lcommunity_cmd, + "match large-community <(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match$exact|any$any>]", + MATCH_STR "Match BGP large community list\n" + "Large Community-list number (standard)\n" + "Large Community-list number (expanded)\n" + "Large Community-list name\n" + "Do exact matching of communities\n" + "Do matching of any community\n") { const char *xpath = "./match-condition[condition='frr-bgp-route-map:match-large-community']"; @@ -5578,35 +5601,35 @@ DEFPY_YANG (match_lcommunity, xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_lcomm_list]->arg); - if (argc == 4) { - snprintf( - xpath_match, sizeof(xpath_match), - "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", - xpath); + snprintf(xpath_match, sizeof(xpath_match), + "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", + xpath); + if (exact) nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true"); - } else { - snprintf( - xpath_match, sizeof(xpath_match), - "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match", - xpath); - nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, - "false"); - } + else + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false"); + + snprintf(xpath_match, sizeof(xpath_match), + "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any", + xpath); + if (any) + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "true"); + else + nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY, "false"); return nb_cli_apply_changes(vty, NULL); } -DEFUN_YANG (no_match_lcommunity, - no_match_lcommunity_cmd, - "no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [exact-match]]", - NO_STR - MATCH_STR - "Match BGP large community list\n" - "Large Community-list number (standard)\n" - "Large Community-list number (expanded)\n" - "Large Community-list name\n" - "Do exact matching of communities\n") +DEFUN_YANG( + no_match_lcommunity, no_match_lcommunity_cmd, + "no match large-community [<(1-99)|(100-500)|LCOMMUNITY_LIST_NAME> [<exact-match|any>]]", + NO_STR MATCH_STR "Match BGP large community list\n" + "Large Community-list number (standard)\n" + "Large Community-list number (expanded)\n" + "Large Community-list name\n" + "Do exact matching of communities\n" + "Do matching of any community\n") { const char *xpath = "./match-condition[condition='frr-bgp-route-map:match-large-community']"; diff --git a/bgpd/bgp_routemap_nb.c b/bgpd/bgp_routemap_nb.c index ae695a6f8..abebfe515 100644 --- a/bgpd/bgp_routemap_nb.c +++ b/bgpd/bgp_routemap_nb.c @@ -165,6 +165,13 @@ const struct frr_yang_module_info frr_bgp_route_map_info = { } }, { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any", + .cbs = { + .modify = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_modify, + .destroy = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_destroy, + } + }, + { .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv4-address", .cbs = { .modify = lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify, diff --git a/bgpd/bgp_routemap_nb.h b/bgpd/bgp_routemap_nb.h index 3ff58f71a..28e418802 100644 --- a/bgpd/bgp_routemap_nb.h +++ b/bgpd/bgp_routemap_nb.h @@ -65,6 +65,10 @@ int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_destroy(struct nb_cb_destroy_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_modify(struct nb_cb_modify_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy(struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_destroy( + struct nb_cb_destroy_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify(struct nb_cb_modify_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_destroy(struct nb_cb_destroy_args *args); int lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_modify(struct nb_cb_modify_args *args); diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c index 9ef9031e5..370295b6c 100644 --- a/bgpd/bgp_routemap_nb_config.c +++ b/bgpd/bgp_routemap_nb_config.c @@ -1127,6 +1127,7 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish( struct routemap_hook_context *rhc; const char *value; bool exact_match = false; + bool any = false; char *argstr; const char *condition; route_map_event_t event; @@ -1140,12 +1141,21 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish( exact_match = yang_dnode_get_bool( args->dnode, "./comm-list-name-exact-match"); + if (yang_dnode_exists(args->dnode, "./comm-list-name-any")) + any = yang_dnode_get_bool(args->dnode, "./comm-list-name-any"); + if (exact_match) { argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, strlen(value) + strlen("exact-match") + 2); snprintf(argstr, (strlen(value) + strlen("exact-match") + 2), "%s exact-match", value); + } else if (any) { + argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, + strlen(value) + strlen("any") + 2); + + snprintf(argstr, (strlen(value) + strlen("any") + 2), "%s any", + value); } else argstr = (char *)value; @@ -1218,6 +1228,39 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_nam } /* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any + */ +int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + break; + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_any_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return lib_route_map_entry_match_destroy(args); + } + + return NB_OK; +} + +/* * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match */ int diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 741542f9b..a04d54fa9 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -477,66 +477,6 @@ static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS) return 0; } -/* VRF update for an interface. */ -static int bgp_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t new_vrf_id; - struct connected *c; - struct nbr_connected *nc; - struct listnode *node, *nnode; - struct bgp *bgp; - struct peer *peer; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - if (!ifp) - return 0; - - if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx Intf VRF change VRF %u IF %s NewVRF %u", vrf_id, - ifp->name, new_vrf_id); - - bgp = bgp_lookup_by_vrf_id(vrf_id); - - if (bgp) { - for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) - bgp_connected_delete(bgp, c); - - for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc)) - bgp_nbr_connected_delete(bgp, nc, 1); - - /* Fast external-failover */ - if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) { - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if ((peer->ttl != BGP_DEFAULT_TTL) - && (peer->gtsm_hops - != BGP_GTSM_HOPS_CONNECTED)) - continue; - - if (ifp == peer->nexthop.ifp) - BGP_EVENT_ADD(peer->connection, - BGP_Stop); - } - } - } - - if_update_to_new_vrf(ifp, new_vrf_id); - - bgp = bgp_lookup_by_vrf_id(new_vrf_id); - if (!bgp) - return 0; - - for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, c)) - bgp_connected_add(bgp, c); - - for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, nc)) - bgp_nbr_connected_add(bgp, nc); - - hook_call(bgp_vrf_status_changed, bgp, ifp); - return 0; -} - /* Zebra route add and delete treatment. */ static int zebra_read_route(ZAPI_CALLBACK_ARGS) { @@ -3401,7 +3341,6 @@ static zclient_handler *const bgp_handlers[] = { [ZEBRA_INTERFACE_ADDRESS_DELETE] = bgp_interface_address_delete, [ZEBRA_INTERFACE_NBR_ADDRESS_ADD] = bgp_interface_nbr_address_add, [ZEBRA_INTERFACE_NBR_ADDRESS_DELETE] = bgp_interface_nbr_address_delete, - [ZEBRA_INTERFACE_VRF_UPDATE] = bgp_interface_vrf_update, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = zebra_read_route, [ZEBRA_NEXTHOP_UPDATE] = bgp_read_nexthop_update, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index dbbc1fa82..e760d4158 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7837,8 +7837,9 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) struct listnode *node, *nnode; int ret; - zlog_debug("%s: set gtsm_hops to %d for %s", __func__, gtsm_hops, - peer->host); + if (bgp_debug_neighbor_events(peer)) + 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, @@ -7947,7 +7948,9 @@ int peer_ttl_security_hops_unset(struct peer *peer) struct listnode *node, *nnode; int ret = 0; - zlog_debug("%s: set gtsm_hops to zero for %s", __func__, peer->host); + if (bgp_debug_neighbor_events(peer)) + 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/developer/zebra.rst b/doc/developer/zebra.rst index 5f039758a..be2952e71 100644 --- a/doc/developer/zebra.rst +++ b/doc/developer/zebra.rst @@ -159,229 +159,7 @@ Past Versions Zebra Protocol Commands ----------------------- -+------------------------------------+-------+ -| Command | Value | -+====================================+=======+ -| ZEBRA_INTERFACE_ADD | 0 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_DELETE | 1 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_ADDRESS_ADD | 2 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_ADDRESS_DELETE | 3 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_UP | 4 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_DOWN | 5 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_SET_MASTER | 6 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_SET_PROTODOWN | 7 | -+------------------------------------+-------+ -| ZEBRA_ROUTE_ADD | 8 | -+------------------------------------+-------+ -| ZEBRA_ROUTE_DELETE | 9 | -+------------------------------------+-------+ -| ZEBRA_ROUTE_NOTIFY_OWNER | 10 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_ADD | 11 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_DELETE | 12 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_DEFAULT_ADD | 13 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_DEFAULT_DELETE | 14 | -+------------------------------------+-------+ -| ZEBRA_ROUTER_ID_ADD | 15 | -+------------------------------------+-------+ -| ZEBRA_ROUTER_ID_DELETE | 16 | -+------------------------------------+-------+ -| ZEBRA_ROUTER_ID_UPDATE | 17 | -+------------------------------------+-------+ -| ZEBRA_HELLO | 18 | -+------------------------------------+-------+ -| ZEBRA_CAPABILITIES | 19 | -+------------------------------------+-------+ -| ZEBRA_NEXTHOP_REGISTER | 20 | -+------------------------------------+-------+ -| ZEBRA_NEXTHOP_UNREGISTER | 21 | -+------------------------------------+-------+ -| ZEBRA_NEXTHOP_UPDATE | 22 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_NBR_ADDRESS_ADD | 23 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_NBR_ADDRESS_DELETE | 24 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_BFD_DEST_UPDATE | 25 | -+------------------------------------+-------+ -| ZEBRA_IMPORT_ROUTE_REGISTER | 26 | -+------------------------------------+-------+ -| ZEBRA_IMPORT_ROUTE_UNREGISTER | 27 | -+------------------------------------+-------+ -| ZEBRA_BFD_DEST_REGISTER | 29 | -+------------------------------------+-------+ -| ZEBRA_BFD_DEST_DEREGISTER | 30 | -+------------------------------------+-------+ -| ZEBRA_BFD_DEST_UPDATE | 31 | -+------------------------------------+-------+ -| ZEBRA_BFD_DEST_REPLAY | 32 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_ROUTE_ADD | 33 | -+------------------------------------+-------+ -| ZEBRA_REDISTRIBUTE_ROUTE_DEL | 34 | -+------------------------------------+-------+ -| ZEBRA_VRF_UNREGISTER | 35 | -+------------------------------------+-------+ -| ZEBRA_VRF_ADD | 36 | -+------------------------------------+-------+ -| ZEBRA_VRF_DELETE | 37 | -+------------------------------------+-------+ -| ZEBRA_VRF_LABEL | 38 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_VRF_UPDATE | 39 | -+------------------------------------+-------+ -| ZEBRA_BFD_CLIENT_REGISTER | 40 | -+------------------------------------+-------+ -| ZEBRA_BFD_CLIENT_DEREGISTER | 41 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_ENABLE_RADV | 42 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_DISABLE_RADV | 43 | -+------------------------------------+-------+ -| ZEBRA_NEXTHOP_LOOKUP_MRIB | 44 | -+------------------------------------+-------+ -| ZEBRA_INTERFACE_LINK_PARAMS | 45 | -+------------------------------------+-------+ -| ZEBRA_MPLS_LABELS_ADD | 46 | -+------------------------------------+-------+ -| ZEBRA_MPLS_LABELS_DELETE | 47 | -+------------------------------------+-------+ -| ZEBRA_MPLS_LABELS_REPLACE | 48 | -+------------------------------------+-------+ -| ZEBRA_IPMR_ROUTE_STATS | 49 | -+------------------------------------+-------+ -| ZEBRA_LABEL_MANAGER_CONNECT | 50 | -+------------------------------------+-------+ -| ZEBRA_LABEL_MANAGER_CONNECT_ASYNC | 51 | -+------------------------------------+-------+ -| ZEBRA_GET_LABEL_CHUNK | 52 | -+------------------------------------+-------+ -| ZEBRA_RELEASE_LABEL_CHUNK | 53 | -+------------------------------------+-------+ -| ZEBRA_FEC_REGISTER | 54 | -+------------------------------------+-------+ -| ZEBRA_FEC_UNREGISTER | 55 | -+------------------------------------+-------+ -| ZEBRA_FEC_UPDATE | 56 | -+------------------------------------+-------+ -| ZEBRA_ADVERTISE_DEFAULT_GW | 57 | -+------------------------------------+-------+ -| ZEBRA_ADVERTISE_SVI_MACIP | 58 | -+------------------------------------+-------+ -| ZEBRA_ADVERTISE_SUBNET | 59 | -+------------------------------------+-------+ -| ZEBRA_ADVERTISE_ALL_VNI | 60 | -+------------------------------------+-------+ -| ZEBRA_LOCAL_ES_ADD | 61 | -+------------------------------------+-------+ -| ZEBRA_LOCAL_ES_DEL | 62 | -+------------------------------------+-------+ -| ZEBRA_VNI_ADD | 63 | -+------------------------------------+-------+ -| ZEBRA_VNI_DEL | 64 | -+------------------------------------+-------+ -| ZEBRA_L3VNI_ADD | 65 | -+------------------------------------+-------+ -| ZEBRA_L3VNI_DEL | 66 | -+------------------------------------+-------+ -| ZEBRA_REMOTE_VTEP_ADD | 67 | -+------------------------------------+-------+ -| ZEBRA_REMOTE_VTEP_DEL | 68 | -+------------------------------------+-------+ -| ZEBRA_MACIP_ADD | 69 | -+------------------------------------+-------+ -| ZEBRA_MACIP_DEL | 70 | -+------------------------------------+-------+ -| ZEBRA_IP_PREFIX_ROUTE_ADD | 71 | -+------------------------------------+-------+ -| ZEBRA_IP_PREFIX_ROUTE_DEL | 72 | -+------------------------------------+-------+ -| ZEBRA_REMOTE_MACIP_ADD | 73 | -+------------------------------------+-------+ -| ZEBRA_REMOTE_MACIP_DEL | 74 | -+------------------------------------+-------+ -| ZEBRA_DUPLICATE_ADDR_DETECTION | 75 | -+------------------------------------+-------+ -| ZEBRA_PW_ADD | 76 | -+------------------------------------+-------+ -| ZEBRA_PW_DELETE | 77 | -+------------------------------------+-------+ -| ZEBRA_PW_SET | 78 | -+------------------------------------+-------+ -| ZEBRA_PW_UNSET | 79 | -+------------------------------------+-------+ -| ZEBRA_PW_STATUS_UPDATE | 80 | -+------------------------------------+-------+ -| ZEBRA_RULE_ADD | 81 | -+------------------------------------+-------+ -| ZEBRA_RULE_DELETE | 82 | -+------------------------------------+-------+ -| ZEBRA_RULE_NOTIFY_OWNER | 83 | -+------------------------------------+-------+ -| ZEBRA_TABLE_MANAGER_CONNECT | 84 | -+------------------------------------+-------+ -| ZEBRA_GET_TABLE_CHUNK | 85 | -+------------------------------------+-------+ -| ZEBRA_RELEASE_TABLE_CHUNK | 86 | -+------------------------------------+-------+ -| ZEBRA_IPSET_CREATE | 87 | -+------------------------------------+-------+ -| ZEBRA_IPSET_DESTROY | 88 | -+------------------------------------+-------+ -| ZEBRA_IPSET_ENTRY_ADD | 89 | -+------------------------------------+-------+ -| ZEBRA_IPSET_ENTRY_DELETE | 90 | -+------------------------------------+-------+ -| ZEBRA_IPSET_NOTIFY_OWNER | 91 | -+------------------------------------+-------+ -| ZEBRA_IPSET_ENTRY_NOTIFY_OWNER | 92 | -+------------------------------------+-------+ -| ZEBRA_IPTABLE_ADD | 93 | -+------------------------------------+-------+ -| ZEBRA_IPTABLE_DELETE | 94 | -+------------------------------------+-------+ -| ZEBRA_IPTABLE_NOTIFY_OWNER | 95 | -+------------------------------------+-------+ -| ZEBRA_VXLAN_FLOOD_CONTROL | 96 | -+------------------------------------+-------+ -| ZEBRA_VXLAN_SG_ADD | 97 | -+------------------------------------+-------+ -| ZEBRA_VXLAN_SG_DEL | 98 | -+------------------------------------+-------+ -| ZEBRA_VXLAN_SG_REPLAY | 99 | -+------------------------------------+-------+ -| ZEBRA_MLAG_PROCESS_UP | 100 | -+------------------------------------+-------+ -| ZEBRA_MLAG_PROCESS_DOWN | 101 | -+------------------------------------+-------+ -| ZEBRA_MLAG_CLIENT_REGISTER | 102 | -+------------------------------------+-------+ -| ZEBRA_MLAG_CLIENT_UNREGISTER | 103 | -+------------------------------------+-------+ -| ZEBRA_MLAG_FORWARD_MSG | 104 | -+------------------------------------+-------+ -| ZEBRA_ERROR | 105 | -+------------------------------------+-------+ -| ZEBRA_CLIENT_CAPABILITIES | 106 | -+------------------------------------+-------+ -| ZEBRA_OPAQUE_MESSAGE | 107 | -+------------------------------------+-------+ -| ZEBRA_OPAQUE_REGISTER | 108 | -+------------------------------------+-------+ -| ZEBRA_OPAQUE_UNREGISTER | 109 | -+------------------------------------+-------+ -| ZEBRA_NEIGH_DISCOVER | 110 | -+------------------------------------+-------+ +The definitions of zebra protocol commands can be found at ``lib/zclient.h``. Dataplane batching ================== diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 186ebfc72..16cafa2ff 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -879,28 +879,24 @@ const struct frr_yang_module_info frr_isisd_info = { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-segs-left", .cbs = { .modify = isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_modify, - .destroy = isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_destroy, }, }, { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-pop", .cbs = { .modify = isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_modify, - .destroy = isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_destroy, }, }, { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-h-encaps", .cbs = { .modify = isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_modify, - .destroy = isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_destroy, }, }, { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-d", .cbs = { .modify = isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_modify, - .destroy = isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_destroy, }, }, { diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index be89fd2ac..c04a006a2 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -334,20 +334,12 @@ void cli_show_isis_srv6_locator(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); int isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_modify( struct nb_cb_modify_args *args); -int isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_destroy( - struct nb_cb_destroy_args *args); int isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_modify( struct nb_cb_modify_args *args); -int isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_destroy( - struct nb_cb_destroy_args *args); int isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_modify( struct nb_cb_modify_args *args); -int isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_destroy( - struct nb_cb_destroy_args *args); int isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_modify( struct nb_cb_modify_args *args); -int isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_destroy( - struct nb_cb_destroy_args *args); void cli_show_isis_srv6_node_msd(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); int isis_instance_segment_routing_srv6_interface_modify( diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 5d0089d6f..b6ee073fd 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -3583,24 +3583,6 @@ int isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_modify( return NB_OK; } -int isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_destroy( - struct nb_cb_destroy_args *args) -{ - struct isis_area *area; - - if (args->event != NB_EV_APPLY) - return NB_OK; - - area = nb_running_get_entry(args->dnode, NULL, true); - area->srv6db.config.max_seg_left_msd = - yang_get_default_uint8("./msd/node-msd/max-segs-left"); - - /* Update and regenerate LSP */ - lsp_regenerate_schedule(area, area->is_type, 0); - - return NB_OK; -} - /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-pop */ @@ -3622,24 +3604,6 @@ int isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_modify( return NB_OK; } -int isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_destroy( - struct nb_cb_destroy_args *args) -{ - struct isis_area *area; - - if (args->event != NB_EV_APPLY) - return NB_OK; - - area = nb_running_get_entry(args->dnode, NULL, true); - area->srv6db.config.max_end_pop_msd = - yang_get_default_uint8("./msd/node-msd/max-end-pop"); - - /* Update and regenerate LSP */ - lsp_regenerate_schedule(area, area->is_type, 0); - - return NB_OK; -} - /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-h-encaps */ @@ -3661,24 +3625,6 @@ int isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_modify( return NB_OK; } -int isis_instance_segment_routing_srv6_msd_node_msd_max_h_encaps_destroy( - struct nb_cb_destroy_args *args) -{ - struct isis_area *area; - - if (args->event != NB_EV_APPLY) - return NB_OK; - - area = nb_running_get_entry(args->dnode, NULL, true); - area->srv6db.config.max_h_encaps_msd = - yang_get_default_uint8("./msd/node-msd/max-h-encaps"); - - /* Update and regenerate LSP */ - lsp_regenerate_schedule(area, area->is_type, 0); - - return NB_OK; -} - /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-d */ @@ -3700,24 +3646,6 @@ int isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_modify( return NB_OK; } -int isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_destroy( - struct nb_cb_destroy_args *args) -{ - struct isis_area *area; - - if (args->event != NB_EV_APPLY) - return NB_OK; - - area = nb_running_get_entry(args->dnode, NULL, true); - area->srv6db.config.max_end_d_msd = - yang_get_default_uint8("./msd/node-msd/max-end-d"); - - /* Update and regenerate LSP */ - lsp_regenerate_schedule(area, area->is_type, 0); - - return NB_OK; -} - /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/interface */ diff --git a/lib/darr.c b/lib/darr.c index f0ef5c90b..bef51b8fc 100644 --- a/lib/darr.c +++ b/lib/darr.c @@ -7,8 +7,9 @@ */ #include <zebra.h> #include "darr.h" +#include "memory.h" -void __dar_resize(void **a, uint count, size_t esize); +DEFINE_MTYPE_STATIC(LIB, DARR, "Dynamic Array"); static uint _msb(uint count) { @@ -56,15 +57,12 @@ void *__darr_resize(void *a, uint count, size_t esize) uint ncount = darr_next_count(count, esize); size_t osz = (a == NULL) ? 0 : darr_size(darr_cap(a), esize); size_t sz = darr_size(ncount, esize); - struct darr_metadata *dm = realloc(a ? _darr_meta(a) : NULL, sz); - /* do *not* use a */ + struct darr_metadata *dm = XREALLOC(MTYPE_DARR, + a ? _darr_meta(a) : NULL, sz); - assert(dm); if (sz > osz) memset((char *)dm + osz, 0, sz - osz); - dm->cap = ncount; - return (void *)(dm + 1); } @@ -351,7 +351,6 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_VRF_ADD), DESC_ENTRY(ZEBRA_VRF_DELETE), DESC_ENTRY(ZEBRA_VRF_LABEL), - DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE), DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER), DESC_ENTRY(ZEBRA_BFD_CLIENT_DEREGISTER), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), diff --git a/lib/plist.c b/lib/plist.c index d8ce83d21..2f5827cf4 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -336,22 +336,6 @@ prefix_list_entry_lookup(struct prefix_list *plist, struct prefix *prefix, return NULL; } -static bool -prefix_list_entry_lookup_prefix(struct prefix_list *plist, - struct prefix_list_entry *plist_entry) -{ - struct prefix_list_entry *pentry = NULL; - - for (pentry = plist->head; pentry; pentry = pentry->next) { - if (pentry == plist_entry) - continue; - if (prefix_same(&pentry->prefix, &plist_entry->prefix)) - return true; - } - - return false; -} - static void trie_walk_affected(size_t validbits, struct pltrie_table *table, uint8_t byte, struct prefix_list_entry *object, void (*fn)(struct prefix_list_entry *object, @@ -418,17 +402,54 @@ static void prefix_list_trie_del(struct prefix_list *plist, } } +/** + * Find duplicated prefix entry (same prefix but different entry) in prefix + * list. + */ +static bool prefix_list_entry_is_duplicated(struct prefix_list *list, + struct prefix_list_entry *entry) +{ + size_t depth, maxdepth = list->master->trie_depth; + uint8_t byte, *bytes = entry->prefix.u.val; + size_t validbits = entry->prefix.prefixlen; + struct pltrie_table *table = list->trie; + struct prefix_list_entry *pentry; + + for (depth = 0; validbits > PLC_BITS && depth < maxdepth - 1; depth++) { + byte = bytes[depth]; + if (!table->entries[byte].next_table) + return NULL; + + table = table->entries[byte].next_table; + validbits -= PLC_BITS; + } + + byte = bytes[depth]; + if (validbits > PLC_BITS) + pentry = table->entries[byte].final_chain; + else + pentry = table->entries[byte].up_chain; + + for (; pentry; pentry = pentry->next_best) { + if (pentry == entry) + continue; + if (prefix_same(&pentry->prefix, &entry->prefix)) + return true; + } + + return false; +} void prefix_list_entry_delete(struct prefix_list *plist, - struct prefix_list_entry *pentry, int update_list) + struct prefix_list_entry *pentry, + int update_list) { - bool duplicate = false; + bool duplicate; if (plist == NULL || pentry == NULL) return; - if (prefix_list_entry_lookup_prefix(plist, pentry)) - duplicate = true; + duplicate = prefix_list_entry_is_duplicated(plist, pentry); prefix_list_trie_del(plist, pentry); @@ -579,14 +600,13 @@ static void prefix_list_entry_add(struct prefix_list *plist, void prefix_list_entry_update_start(struct prefix_list_entry *ple) { struct prefix_list *pl = ple->pl; - bool duplicate = false; + bool duplicate; /* Not installed, nothing to do. */ if (!ple->installed) return; - if (prefix_list_entry_lookup_prefix(pl, ple)) - duplicate = true; + duplicate = prefix_list_entry_is_duplicated(pl, ple); prefix_list_trie_del(pl, ple); diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index a5e66880a..20a157e95 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -729,6 +729,10 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode, dnode, "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match")) vty_out(vty, " exact-match"); + if (yang_dnode_get_bool( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any")) + vty_out(vty, " any"); vty_out(vty, "\n"); } else if (IS_MATCH_LCOMMUNITY(condition)) { vty_out(vty, " match large-community %s", @@ -739,6 +743,10 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode, dnode, "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match")) vty_out(vty, " exact-match"); + if (yang_dnode_get_bool( + dnode, + "./rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-any")) + vty_out(vty, " any"); vty_out(vty, "\n"); } else if (IS_MATCH_EXTCOMMUNITY(condition)) { vty_out(vty, " match extcommunity %s\n", diff --git a/lib/zclient.h b/lib/zclient.h index 2a3ce4e48..f18fc056f 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -127,7 +127,6 @@ typedef enum { ZEBRA_VRF_ADD, ZEBRA_VRF_DELETE, ZEBRA_VRF_LABEL, - ZEBRA_INTERFACE_VRF_UPDATE, ZEBRA_BFD_CLIENT_REGISTER, ZEBRA_BFD_CLIENT_DEREGISTER, ZEBRA_INTERFACE_ENABLE_RADV, diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index abc580b13..1af703d88 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -162,29 +162,6 @@ static int ospf_interface_link_params(ZAPI_CALLBACK_ARGS) return 0; } -/* VRF update for an interface. */ -static int ospf_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp = NULL; - vrf_id_t new_vrf_id; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - if (!ifp) - return 0; - - if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u", - __func__, ifp->name, vrf_id, - ospf_vrf_id_to_name(new_vrf_id), new_vrf_id); - - /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/ - if_update_to_new_vrf(ifp, new_vrf_id); - - return 0; -} - /* Nexthop, ifindex, distance and metric information. */ static void ospf_zebra_add_nexthop(struct ospf *ospf, struct ospf_path *path, struct zapi_route *api) @@ -2203,7 +2180,6 @@ static zclient_handler *const ospf_handlers[] = { [ZEBRA_INTERFACE_ADDRESS_ADD] = ospf_interface_address_add, [ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf_interface_address_delete, [ZEBRA_INTERFACE_LINK_PARAMS] = ospf_interface_link_params, - [ZEBRA_INTERFACE_VRF_UPDATE] = ospf_interface_vrf_update, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route, diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index e8a49b317..876f9e19e 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -129,29 +129,6 @@ int pbr_ifp_down(struct interface *ifp) return 0; } -static int interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t new_vrf_id; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - - if (!ifp) { - DEBUGD(&pbr_dbg_zebra, "%s: VRF change interface not found", - __func__); - - return 0; - } - - DEBUGD(&pbr_dbg_zebra, "%s: %s VRF change %u -> %u", __func__, - ifp->name, vrf_id, new_vrf_id); - - if_update_to_new_vrf(ifp, new_vrf_id); - - return 0; -} - static int route_notify_owner(ZAPI_CALLBACK_ARGS) { struct prefix p; @@ -436,7 +413,6 @@ extern struct zebra_privs_t pbr_privs; static zclient_handler *const pbr_handlers[] = { [ZEBRA_INTERFACE_ADDRESS_ADD] = interface_address_add, [ZEBRA_INTERFACE_ADDRESS_DELETE] = interface_address_delete, - [ZEBRA_INTERFACE_VRF_UPDATE] = interface_vrf_update, [ZEBRA_ROUTE_NOTIFY_OWNER] = route_notify_owner, [ZEBRA_RULE_NOTIFY_OWNER] = rule_notify_owner, [ZEBRA_NEXTHOP_UPDATE] = pbr_zebra_nexthop_update, diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index b1b6958fe..623c14bb0 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -374,6 +374,8 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, pim_sgaddr *sg, struct in_addr rp) { struct pim_msdp_sa *sa; + struct rp_info *rp_info; + struct prefix grp; sa = pim_msdp_sa_add(pim, sg, rp); if (!sa) { @@ -406,6 +408,14 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, sa->sg_str); } /* send an immediate SA update to peers */ + pim_addr_to_prefix(&grp, sa->sg.grp); + rp_info = pim_rp_find_match_group(pim, &grp); + if (rp_info) { + sa->rp = rp_info->rp.rpf_addr; + } else + { + sa->rp = pim->msdp.originator_id; + } sa->rp = pim->msdp.originator_id; pim_msdp_pkt_sa_tx_one(sa); } diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index a414736cc..4324a96be 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -14,7 +14,9 @@ #include "pimd.h" #include "pim_instance.h" +#include "pim_rp.h" #include "pim_str.h" +#include "pim_util.h" #include "pim_errors.h" #include "pim_msdp.h" @@ -387,6 +389,9 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, { struct listnode *sanode; struct pim_msdp_sa *sa; + struct rp_info *rp_info; + struct prefix group_all; + struct in_addr rp; int sa_count; int local_cnt = pim->msdp.local_cnt; @@ -395,8 +400,15 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, zlog_debug(" sa gen %d", local_cnt); } - local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt, - pim->msdp.originator_id); + rp = pim->msdp.originator_id; + if (pim_get_all_mcast_group(&group_all)) { + rp_info = pim_rp_find_match_group(pim, &group_all); + if (rp_info) { + rp = rp_info->rp.rpf_addr; + } + } + + local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt, rp); for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) { if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) { @@ -418,7 +430,7 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, local_cnt); } local_cnt = pim_msdp_pkt_sa_fill_hdr( - pim, local_cnt, pim->msdp.originator_id); + pim, local_cnt, rp); } } diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 92dcbf9d1..62f00dbf8 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -51,39 +51,6 @@ static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS) return 0; } -static int pim_zebra_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t new_vrf_id; - struct pim_instance *pim; - struct pim_interface *pim_ifp; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - if (!ifp) - return 0; - - if (PIM_DEBUG_ZEBRA) - zlog_debug("%s: %s updating from %u to %u", __func__, ifp->name, - vrf_id, new_vrf_id); - - pim = pim_get_pim_instance(new_vrf_id); - if (!pim) - return 0; - - if_update_to_new_vrf(ifp, new_vrf_id); - - pim_ifp = ifp->info; - if (!pim_ifp) - return 0; - - pim_ifp->pim->mcast_if_count--; - pim_ifp->pim = pim; - pim_ifp->pim->mcast_if_count++; - - return 0; -} - #ifdef PIM_DEBUG_IFADDR_DUMP static void dump_if_address(struct interface *ifp) { @@ -463,7 +430,6 @@ static zclient_handler *const pim_handlers[] = { [ZEBRA_NEXTHOP_UPDATE] = pim_parse_nexthop_update, [ZEBRA_ROUTER_ID_UPDATE] = pim_router_id_update_zebra, - [ZEBRA_INTERFACE_VRF_UPDATE] = pim_zebra_interface_vrf_update, #if PIM_IPV == 4 [ZEBRA_VXLAN_SG_ADD] = pim_zebra_vxlan_sg_proc, diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index b58015a67..505290ed3 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -383,31 +383,6 @@ static int rip_ifp_destroy(struct interface *ifp) return 0; } -/* VRF update for an interface. */ -int rip_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t new_vrf_id; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - if (!ifp) - return 0; - - if (IS_RIP_DEBUG_ZEBRA) { - struct vrf *nvrf = vrf_lookup_by_id(new_vrf_id); - - zlog_debug("interface %s VRF change vrf %s(%u) new vrf %s(%u)", - ifp->name, ifp->vrf->name, vrf_id, VRF_LOGNAME(nvrf), - new_vrf_id); - } - - if_update_to_new_vrf(ifp, new_vrf_id); - rip_interface_sync(ifp); - - return 0; -} - static void rip_interface_clean(struct rip_interface *ri) { ri->enable_network = 0; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 5bf51c2f1..36b58cb20 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -222,7 +222,6 @@ static void rip_zebra_connected(struct zclient *zclient) zclient_handler *const rip_handlers[] = { [ZEBRA_INTERFACE_ADDRESS_ADD] = rip_interface_address_add, [ZEBRA_INTERFACE_ADDRESS_DELETE] = rip_interface_address_delete, - [ZEBRA_INTERFACE_VRF_UPDATE] = rip_interface_vrf_update, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = rip_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = rip_zebra_read_route, }; diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index a37cb7d09..4cb4bb5ef 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -264,31 +264,6 @@ static int ripng_ifp_destroy(struct interface *ifp) return 0; } -/* VRF update for an interface. */ -int ripng_interface_vrf_update(ZAPI_CALLBACK_ARGS) -{ - struct interface *ifp; - vrf_id_t new_vrf_id; - - ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, - &new_vrf_id); - if (!ifp) - return 0; - - if (IS_RIPNG_DEBUG_ZEBRA) { - struct vrf *nvrf = vrf_lookup_by_id(new_vrf_id); - - zlog_debug("interface %s VRF change vrf %s(%u) new vrf %s(%u)", - ifp->name, ifp->vrf->name, vrf_id, VRF_LOGNAME(nvrf), - new_vrf_id); - } - - if_update_to_new_vrf(ifp, new_vrf_id); - ripng_interface_sync(ifp); - - return 0; -} - void ripng_interface_clean(struct ripng *ripng) { struct interface *ifp; diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 49b8a197a..bb5a880c0 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -222,7 +222,6 @@ static void ripng_zebra_connected(struct zclient *zclient) static zclient_handler *const ripng_handlers[] = { [ZEBRA_INTERFACE_ADDRESS_ADD] = ripng_interface_address_add, [ZEBRA_INTERFACE_ADDRESS_DELETE] = ripng_interface_address_delete, - [ZEBRA_INTERFACE_VRF_UPDATE] = ripng_interface_vrf_update, [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ripng_zebra_read_route, [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ripng_zebra_read_route, }; diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index c7468b631..3a2bc0c9d 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -413,7 +413,6 @@ extern int ripng_interface_add(ZAPI_CALLBACK_ARGS); extern int ripng_interface_delete(ZAPI_CALLBACK_ARGS); extern int ripng_interface_address_add(ZAPI_CALLBACK_ARGS); extern int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS); -extern int ripng_interface_vrf_update(ZAPI_CALLBACK_ARGS); extern void ripng_interface_sync(struct interface *ifp); extern struct ripng *ripng_lookup_by_vrf_id(vrf_id_t vrf_id); diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 4afc25049..3c60cd731 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -83,7 +83,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) char buf_tag[PREFIX_STRLEN]; uint8_t label_stack_id = 0; uint8_t segs_stack_id = 0; - + char *orig_label = NULL, *orig_seg = NULL; const char *buf_gate_str; uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT; route_tag_t tag = 0; @@ -330,7 +330,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY, NULL); - ostr = XSTRDUP(MTYPE_TMP, args->label); + orig_label = ostr = XSTRDUP(MTYPE_TMP, args->label); while ((nump = strsep(&ostr, "/")) != NULL) { snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_ROUTE_NHLB_KEY_XPATH, @@ -343,7 +343,6 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) NB_OP_MODIFY, nump); label_stack_id++; } - XFREE(MTYPE_TMP, ostr); } else { strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls)); strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH, @@ -364,7 +363,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) nb_cli_enqueue_change(vty, xpath_segs, NB_OP_DESTROY, NULL); - ostr = XSTRDUP(MTYPE_TMP, args->segs); + orig_seg = ostr = XSTRDUP(MTYPE_TMP, args->segs); while ((nump = strsep(&ostr, "/")) != NULL) { snprintf(ab_xpath, sizeof(ab_xpath), FRR_STATIC_ROUTE_NH_SRV6_KEY_SEG_XPATH, @@ -376,7 +375,6 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) NB_OP_MODIFY, nump); segs_stack_id++; } - XFREE(MTYPE_TMP, ostr); } else { strlcpy(xpath_segs, xpath_nexthop, sizeof(xpath_segs)); strlcat(xpath_segs, FRR_STATIC_ROUTE_NH_SRV6_SEGS_XPATH, @@ -419,6 +417,11 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) } ret = nb_cli_apply_changes(vty, "%s", xpath_prefix); + + if (orig_label) + XFREE(MTYPE_TMP, orig_label); + if (orig_seg) + XFREE(MTYPE_TMP, orig_seg); } else { if (args->source) { if (args->distance) diff --git a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py index 4b7c4de80..c319477c8 100644 --- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py +++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py @@ -38,6 +38,9 @@ from lib.common_config import ( required_linux_kernel_version, ) +from lib.topolog import logger +import json + fatal_error = "" @@ -1611,10 +1614,21 @@ def test_resilient_nexthop_group(): ) output = net["r1"].cmd('vtysh -c "show nexthop-group rib sharp"') - output = re.findall(r"Buckets", output) + buckets = re.findall(r"Buckets", output) + + output = net["r1"].cmd('vtysh -c "show nexthop-group rib sharp json"') + + joutput = json.loads(output) + + # Use the json output and collect the nhg id from it + + for nhgid in joutput: + n = joutput[nhgid] + if "buckets" in n: + break - verify_nexthop_group(185483878) - assert len(output) == 1, "Resilient NHG not created in zebra" + verify_nexthop_group(int(nhgid)) + assert len(buckets) == 1, "Resilient NHG not created in zebra" def test_shutdown_check_stderr(): diff --git a/tests/topotests/bgp_comm_list_match/r1/bgpd.conf b/tests/topotests/bgp_comm_list_match/r1/bgpd.conf index 89c9f7728..bac841208 100644 --- a/tests/topotests/bgp_comm_list_match/r1/bgpd.conf +++ b/tests/topotests/bgp_comm_list_match/r1/bgpd.conf @@ -11,6 +11,7 @@ router bgp 65001 ! ip prefix-list p1 seq 5 permit 172.16.255.1/32 ip prefix-list p3 seq 5 permit 172.16.255.3/32 +ip prefix-list p4 seq 5 permit 172.16.255.4/32 ! route-map r2 permit 10 match ip address prefix-list p1 @@ -19,5 +20,9 @@ route-map r2 permit 20 match ip address prefix-list p3 set community 65001:3 route-map r2 permit 30 + match ip address prefix-list p4 + set community 65001:10 65001:12 65001:13 +exit +route-map r2 permit 40 exit ! diff --git a/tests/topotests/bgp_comm_list_match/r1/zebra.conf b/tests/topotests/bgp_comm_list_match/r1/zebra.conf index 17d0eccea..4219a7ca3 100644 --- a/tests/topotests/bgp_comm_list_match/r1/zebra.conf +++ b/tests/topotests/bgp_comm_list_match/r1/zebra.conf @@ -3,6 +3,7 @@ interface lo ip address 172.16.255.1/32 ip address 172.16.255.2/32 ip address 172.16.255.3/32 + ip address 172.16.255.4/32 ! interface r1-eth0 ip address 192.168.0.1/24 diff --git a/tests/topotests/bgp_comm_list_match/r2/bgpd.conf b/tests/topotests/bgp_comm_list_match/r2/bgpd.conf index 98a978068..cb2f89e5c 100644 --- a/tests/topotests/bgp_comm_list_match/r2/bgpd.conf +++ b/tests/topotests/bgp_comm_list_match/r2/bgpd.conf @@ -6,6 +6,9 @@ router bgp 65002 neighbor 192.168.0.1 remote-as external neighbor 192.168.0.1 timers 1 3 neighbor 192.168.0.1 timers connect 1 + neighbor 192.168.1.3 remote-as external + neighbor 192.168.1.3 timers 1 3 + neighbor 192.168.1.3 timers connect 1 address-family ipv4 neighbor 192.168.0.1 route-map r1 in neighbor 192.168.0.1 soft-reconfiguration inbound diff --git a/tests/topotests/bgp_comm_list_match/r2/zebra.conf b/tests/topotests/bgp_comm_list_match/r2/zebra.conf index a69c62235..7fe82bac8 100644 --- a/tests/topotests/bgp_comm_list_match/r2/zebra.conf +++ b/tests/topotests/bgp_comm_list_match/r2/zebra.conf @@ -2,5 +2,8 @@ interface r2-eth0 ip address 192.168.0.2/24 ! +interface r2-eth1 + ip address 192.168.1.2/24 +! ip forwarding ! diff --git a/tests/topotests/bgp_comm_list_match/r3/bgpd.conf b/tests/topotests/bgp_comm_list_match/r3/bgpd.conf new file mode 100644 index 000000000..e68a3e44e --- /dev/null +++ b/tests/topotests/bgp_comm_list_match/r3/bgpd.conf @@ -0,0 +1,21 @@ +! +!debug bgp updates +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + address-family ipv4 + neighbor 192.168.1.2 route-map r1 in + neighbor 192.168.1.2 soft-reconfiguration inbound + exit-address-family +! +bgp community-list 2 seq 10 permit 65001:12 +! +route-map r1 deny 10 + match community 2 any +exit +route-map r1 permit 20 +exit +! diff --git a/tests/topotests/bgp_comm_list_match/r3/zebra.conf b/tests/topotests/bgp_comm_list_match/r3/zebra.conf new file mode 100644 index 000000000..755dd18bf --- /dev/null +++ b/tests/topotests/bgp_comm_list_match/r3/zebra.conf @@ -0,0 +1,6 @@ +! +interface r3-eth0 + ip address 192.168.1.3/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py b/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py index 03fa8da9d..de69ea938 100644 --- a/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py +++ b/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py @@ -39,12 +39,15 @@ pytestmark = [pytest.mark.bgpd] def build_topo(tgen): - for routern in range(1, 3): + for routern in range(1, 4): tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r2"]) def setup_module(mod): @@ -95,12 +98,41 @@ def test_bgp_comm_list_match(): } return topotest.json_cmp(output, expected) - step("Initial BGP converge") + step("Initial BGP converge between R1 and R2") test_func = functools.partial(_bgp_converge) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to filter BGP UPDATES with community-list on R2" +def test_bgp_comm_list_match_any(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r3"] + + def _bgp_converge(): + output = json.loads( + router.vtysh_cmd( + "show bgp ipv4 unicast neighbors 192.168.1.2 filtered-routes json" + ) + ) + expected = { + "receivedRoutes": { + "172.16.255.4/32": { + "path": "65002 65001", + }, + } + } + return topotest.json_cmp(output, expected) + + step("Initial BGP converge between R3 and R2") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to filter BGP UPDATES with community-list on R3" + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py index d1069a876..a653da465 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py @@ -111,7 +111,7 @@ def test_bgp_dynamic_capability_software_version(): if not adv and not rcv: return "" - pattern = "FRRouting/\\d.+" + pattern = "^FRRouting/\\d.+" if re.search(pattern, adv) and re.search(pattern, rcv): return adv, rcv except: diff --git a/tests/topotests/bgp_large_comm_list_match/__init__.py b/tests/topotests/bgp_large_comm_list_match/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/__init__.py diff --git a/tests/topotests/bgp_large_comm_list_match/r1/bgpd.conf b/tests/topotests/bgp_large_comm_list_match/r1/bgpd.conf new file mode 100644 index 000000000..1a91f0f5c --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r1/bgpd.conf @@ -0,0 +1,28 @@ +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.0.2 remote-as external + neighbor 192.168.0.2 timers 1 3 + neighbor 192.168.0.2 timers connect 1 + address-family ipv4 + redistribute connected + neighbor 192.168.0.2 route-map r2 out + exit-address-family +! +ip prefix-list p1 seq 5 permit 172.16.255.1/32 +ip prefix-list p3 seq 5 permit 172.16.255.3/32 +ip prefix-list p4 seq 5 permit 172.16.255.4/32 +! +route-map r2 permit 10 + match ip address prefix-list p1 + set large-community 65001:1:1 65001:2:1 +route-map r2 permit 20 + match ip address prefix-list p3 + set large-community 65001:3:1 +route-map r2 permit 30 + match ip address prefix-list p4 + set large-community 65001:10:1 65001:12:1 65001:13:1 +exit +route-map r2 permit 40 +exit +! diff --git a/tests/topotests/bgp_large_comm_list_match/r1/zebra.conf b/tests/topotests/bgp_large_comm_list_match/r1/zebra.conf new file mode 100644 index 000000000..4219a7ca3 --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r1/zebra.conf @@ -0,0 +1,12 @@ +! +interface lo + ip address 172.16.255.1/32 + ip address 172.16.255.2/32 + ip address 172.16.255.3/32 + ip address 172.16.255.4/32 +! +interface r1-eth0 + ip address 192.168.0.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_large_comm_list_match/r2/bgpd.conf b/tests/topotests/bgp_large_comm_list_match/r2/bgpd.conf new file mode 100644 index 000000000..779b705b5 --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r2/bgpd.conf @@ -0,0 +1,24 @@ +! +!debug bgp updates +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.0.1 remote-as external + neighbor 192.168.0.1 timers 1 3 + neighbor 192.168.0.1 timers connect 1 + neighbor 192.168.1.3 remote-as external + neighbor 192.168.1.3 timers 1 3 + neighbor 192.168.1.3 timers connect 1 + address-family ipv4 + neighbor 192.168.0.1 route-map r1 in + neighbor 192.168.0.1 soft-reconfiguration inbound + exit-address-family +! +bgp large-community-list 1 seq 5 permit 65001:1:1 65001:2:1 +bgp large-community-list 1 seq 10 permit 65001:3:1 +! +route-map r1 deny 10 + match large-community 1 +route-map r1 permit 20 +exit +! diff --git a/tests/topotests/bgp_large_comm_list_match/r2/zebra.conf b/tests/topotests/bgp_large_comm_list_match/r2/zebra.conf new file mode 100644 index 000000000..7fe82bac8 --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r2/zebra.conf @@ -0,0 +1,9 @@ +! +interface r2-eth0 + ip address 192.168.0.2/24 +! +interface r2-eth1 + ip address 192.168.1.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_large_comm_list_match/r3/bgpd.conf b/tests/topotests/bgp_large_comm_list_match/r3/bgpd.conf new file mode 100644 index 000000000..e7cb76a43 --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r3/bgpd.conf @@ -0,0 +1,21 @@ +! +!debug bgp updates +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + address-family ipv4 + neighbor 192.168.1.2 route-map r1 in + neighbor 192.168.1.2 soft-reconfiguration inbound + exit-address-family +! +bgp large-community-list 2 seq 10 permit 65001:12:1 +! +route-map r1 deny 10 + match large-community 2 any +exit +route-map r1 permit 20 +exit +! diff --git a/tests/topotests/bgp_large_comm_list_match/r3/zebra.conf b/tests/topotests/bgp_large_comm_list_match/r3/zebra.conf new file mode 100644 index 000000000..755dd18bf --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/r3/zebra.conf @@ -0,0 +1,6 @@ +! +interface r3-eth0 + ip address 192.168.1.3/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py b/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py new file mode 100644 index 000000000..483c048d2 --- /dev/null +++ b/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright 2023 by 6WIND S.A. +# + +""" +Check if BGP large-community-list works +when used as match rule in incoming route-maps. + +- case 1 should deny incoming updates with large-community-list 1 +bgp large-community-list 1 seq 5 permit 65001:1:1 65001:2:1 +bgp large-community-list 1 seq 10 permit 65001:3:1 +! +route-map r1 deny 10 + match large-community 1 + +route-map test deny 10 + match community 1 + +- case 2 should deny incoming updates with any large-community-list 1 +bgp large-community-list 2 seq 10 permit 65001:12:1 +! +route-map r1 deny 10 + match large-community 2 any +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 4): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_large_comm_list_match(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r2"] + + def _bgp_converge(): + output = json.loads( + router.vtysh_cmd( + "show bgp ipv4 unicast neighbors 192.168.0.1 filtered-routes json" + ) + ) + expected = { + "receivedRoutes": { + "172.16.255.1/32": { + "path": "65001", + }, + "172.16.255.3/32": { + "path": "65001", + }, + } + } + return topotest.json_cmp(output, expected) + + step("BGP filtering check with large-community-list on R2") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert ( + result is None + ), "Failed to filter BGP UPDATES with large-community-list on R2" + + +def test_bgp_large_comm_list_match_any(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears["r3"] + + def _bgp_converge(): + output = json.loads( + router.vtysh_cmd( + "show bgp ipv4 unicast neighbors 192.168.1.2 filtered-routes json" + ) + ) + expected = { + "receivedRoutes": { + "172.16.255.4/32": { + "path": "65002 65001", + }, + } + } + return topotest.json_cmp(output, expected) + + step("BGP filtering check with large-community-list on R3") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to filter BGP UPDATES with large-community-list on R3" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang index 05fe57c7d..c50c51389 100644 --- a/yang/frr-bgp-route-map.yang +++ b/yang/frr-bgp-route-map.yang @@ -777,6 +777,13 @@ identity set-extcommunity-color { description "Do exact matching of communities"; } + + leaf comm-list-name-any { + type boolean; + description + "Do matching of any community"; + } + } } diff --git a/zebra/interface.c b/zebra/interface.c index 92ae8a9dc..919cd11bc 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -853,7 +853,7 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id) if_down_del_nbr_connected(ifp); /* Send out notification on interface VRF change. */ - /* This is to issue an UPDATE or a DELETE, as appropriate. */ + /* This is to issue a DELETE, as appropriate. */ zebra_interface_vrf_update_del(ifp, vrf_id); if (if_is_vrf(ifp)) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 7aa254b1c..463c903da 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -592,9 +592,8 @@ void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u", - ifp->name, ifp->vrf->vrf_id, new_vrf_id); + zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s VRF Id %u -> %u", + ifp->name, ifp->vrf->vrf_id, new_vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { /* Do not send unsolicited messages to synchronous clients. */ @@ -606,7 +605,6 @@ void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id) zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); client->ifdel_cnt++; zsend_interface_delete(client, ifp); - zsend_interface_vrf_update(client, ifp, new_vrf_id); } } @@ -619,9 +617,8 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) struct zserv *client; if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug( - "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u", - ifp->name, old_vrf_id, ifp->vrf->vrf_id); + zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s VRF Id %u -> %u", + ifp->name, old_vrf_id, ifp->vrf->vrf_id); for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { /* Do not send unsolicited messages to synchronous clients. */ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index e59c49f15..b73511f02 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -435,27 +435,6 @@ int zsend_interface_addresses(struct zserv *client, struct interface *ifp) return 0; } -/* Notify client about interface moving from one VRF to another. - * Whether client is interested in old and new VRF is checked by caller. - */ -int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp, - vrf_id_t vrf_id) -{ - struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); - - zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf->vrf_id); - - /* Fill in the name of the interface and its new VRF (id) */ - stream_put(s, ifp->name, INTERFACE_NAMSIZ); - stream_putl(s, vrf_id); - - /* Write packet size. */ - stream_putw_at(s, 0, stream_get_endp(s)); - - client->if_vrfchg_cnt++; - return zserv_send_message(client, s); -} - /* Add new nbr connected IPv6 address */ void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address) { diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index ce8e15446..a01cbf675 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -57,8 +57,6 @@ extern int zsend_redistribute_route(int cmd, struct zserv *zclient, extern int zsend_router_id_update(struct zserv *zclient, afi_t afi, struct prefix *p, vrf_id_t vrf_id); -extern int zsend_interface_vrf_update(struct zserv *zclient, - struct interface *ifp, vrf_id_t vrf_id); extern int zsend_interface_link_params(struct zserv *zclient, struct interface *ifp); extern int zsend_pw_update(struct zserv *client, struct zebra_pw *pw); diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 5124768a7..c04c5f558 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -172,10 +172,13 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg) key = jhash_3words(rule->rule.filter.pcp, rule->rule.filter.vlan_id, rule->rule.filter.vlan_flags, key); - return jhash_3words(rule->rule.filter.src_port, - rule->rule.filter.dst_port, - prefix_hash_key(&rule->rule.filter.dst_ip), - jhash_1word(rule->rule.unique, key)); + key = jhash_3words(rule->rule.filter.src_port, + rule->rule.filter.dst_port, + prefix_hash_key(&rule->rule.filter.dst_ip), key); + + key = jhash_2words(rule->rule.unique, rule->sock, key); + + return key; } bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2) @@ -191,6 +194,9 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2) if (r1->rule.priority != r2->rule.priority) return false; + if (r1->sock != r2->sock) + return false; + if (r1->rule.unique != r2->rule.unique) return false; @@ -226,6 +232,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2) struct pbr_rule_unique_lookup { struct zebra_pbr_rule *rule; + int sock; uint32_t unique; char ifname[INTERFACE_NAMSIZ + 1]; vrf_id_t vrf_id; @@ -236,9 +243,9 @@ static int pbr_rule_lookup_unique_walker(struct hash_bucket *b, void *data) struct pbr_rule_unique_lookup *pul = data; struct zebra_pbr_rule *rule = b->data; - if (pul->unique == rule->rule.unique - && strncmp(pul->ifname, rule->rule.ifname, INTERFACE_NAMSIZ) == 0 - && pul->vrf_id == rule->vrf_id) { + if (pul->sock == rule->sock && pul->unique == rule->rule.unique && + strmatch(pul->ifname, rule->rule.ifname) && + pul->vrf_id == rule->vrf_id) { pul->rule = rule; return HASHWALK_ABORT; } @@ -255,6 +262,7 @@ pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule) strlcpy(pul.ifname, zrule->rule.ifname, INTERFACE_NAMSIZ); pul.rule = NULL; pul.vrf_id = zrule->vrf_id; + pul.sock = zrule->sock; hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul); return pul.rule; |