diff options
| -rw-r--r-- | bgpd/bgp_clist.c | 5 | ||||
| -rw-r--r-- | bgpd/bgp_community_alias.c | 40 | ||||
| -rw-r--r-- | bgpd/bgp_community_alias.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_io.c | 3 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 1 | ||||
| -rw-r--r-- | ospf6d/ospf6_asbr.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 116 | ||||
| -rw-r--r-- | tests/topotests/bgp_community_alias/r1/bgpd.conf | 2 | ||||
| -rw-r--r-- | tests/topotests/bgp_community_alias/test_bgp-community-alias.py | 11 | ||||
| -rw-r--r-- | tools/etc/frr/support_bundle_commands.conf | 72 | ||||
| -rw-r--r-- | zebra/rib.h | 5 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 17 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 9 |
13 files changed, 216 insertions, 69 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 50122ad7da..fd8f51fed3 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -33,6 +33,7 @@ #include "bgpd/bgp_community.h" #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_lcommunity.h" +#include "bgpd/bgp_community_alias.h" #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_regex.h" #include "bgpd/bgp_clist.h" @@ -557,7 +558,7 @@ static bool community_regexp_match(struct community *com, regex_t *reg) str = community_str(com, false); /* Regular expression match. */ - if (regexec(reg, str, 0, NULL, 0) == 0) + if (regexec(reg, bgp_alias2community_str(str), 0, NULL, 0) == 0) return true; /* No match. */ @@ -627,7 +628,7 @@ static bool lcommunity_regexp_match(struct lcommunity *com, regex_t *reg) str = lcommunity_str(com, false); /* Regular expression match. */ - if (regexec(reg, str, 0, NULL, 0) == 0) + if (regexec(reg, bgp_alias2community_str(str), 0, NULL, 0) == 0) return true; /* No match. */ diff --git a/bgpd/bgp_community_alias.c b/bgpd/bgp_community_alias.c index f770ebdd5d..5f45e19a3b 100644 --- a/bgpd/bgp_community_alias.c +++ b/bgpd/bgp_community_alias.c @@ -20,6 +20,7 @@ #include "memory.h" #include "lib/jhash.h" +#include "frrstr.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_community_alias.h" @@ -153,6 +154,45 @@ const char *bgp_community2alias(char *community) return community; } +const char *bgp_alias2community(char *alias) +{ + struct community_alias ca; + struct community_alias *find; + + memset(&ca, 0, sizeof(ca)); + strlcpy(ca.alias, alias, sizeof(ca.alias)); + + find = bgp_ca_alias_lookup(&ca); + if (find) + return find->community; + + return alias; +} + +/* Communities structs have `->str` which is used + * for vty outputs and extended BGP community lists + * with regexp. + * This is a helper to convert already aliased version + * of communities into numerical-only format. + */ +const char *bgp_alias2community_str(const char *str) +{ + char **aliases; + int num; + + frrstr_split(str, " ", &aliases, &num); + const char *communities[num + 1]; + + for (int i = 0; i < num; i++) { + communities[i] = + XSTRDUP(MTYPE_TMP, bgp_alias2community(aliases[i])); + XFREE(MTYPE_TMP, aliases[i]); + } + XFREE(MTYPE_TMP, aliases); + + return frrstr_join(communities, num, " "); +} + static int bgp_community_alias_vector_walker(struct hash_bucket *bucket, void *data) { diff --git a/bgpd/bgp_community_alias.h b/bgpd/bgp_community_alias.h index ab8ed06ee6..fc9eb9f9e4 100644 --- a/bgpd/bgp_community_alias.h +++ b/bgpd/bgp_community_alias.h @@ -42,6 +42,8 @@ extern void bgp_ca_community_delete(struct community_alias *ca); extern void bgp_ca_alias_delete(struct community_alias *ca); extern int bgp_community_alias_write(struct vty *vty); extern const char *bgp_community2alias(char *community); +extern const char *bgp_alias2community(char *alias); +extern const char *bgp_alias2community_str(const char *str); extern void bgp_community_alias_command_completion_setup(void); #endif /* FRR_BGP_COMMUNITY_ALIAS_H */ diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index e9b0f9e46a..9b5a31f289 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -111,6 +111,7 @@ void bgp_reads_off(struct peer *peer) thread_cancel_async(fpt->master, &peer->t_read, NULL); THREAD_OFF(peer->t_process_packet); + THREAD_OFF(peer->t_process_packet_error); UNSET_FLAG(peer->thread_flags, PEER_THREAD_READS_ON); } @@ -208,7 +209,7 @@ static int bgp_process_reads(struct thread *thread) * specific state change from 'bgp_read'. */ thread_add_event(bm->master, bgp_packet_process_error, - peer, code, NULL); + peer, code, &peer->t_process_packet_error); } while (more) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 867062a88b..d39743a152 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1415,6 +1415,7 @@ struct peer { struct thread *t_gr_stale; struct thread *t_generate_updgrp_packets; struct thread *t_process_packet; + struct thread *t_process_packet_error; struct thread *t_refresh_stalepath; /* Thread flags. */ diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 165e409eed..b7cbc13b72 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -811,7 +811,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, /* Compare LSA cost with current * route info. */ - if (!asbr_entry + if (asbr_entry && (o_path->cost != route_to_del->path.cost || o_path->u.cost_e2 != route_to_del->path.u diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 7ba6a2b6d7..e441016406 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -273,74 +273,78 @@ struct ospf_interface { DECLARE_QOBJ_TYPE(ospf_interface); /* Prototypes. */ -extern char *ospf_if_name(struct ospf_interface *); -extern struct ospf_interface *ospf_if_new(struct ospf *, struct interface *, - struct prefix *); -extern void ospf_if_cleanup(struct ospf_interface *); -extern void ospf_if_free(struct ospf_interface *); -extern int ospf_if_up(struct ospf_interface *); -extern int ospf_if_down(struct ospf_interface *); - -extern int ospf_if_is_up(struct ospf_interface *); -extern struct ospf_interface *ospf_if_exists(struct ospf_interface *); -extern struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *, - int); +extern char *ospf_if_name(struct ospf_interface *oi); extern struct ospf_interface * -ospf_if_lookup_by_local_addr(struct ospf *, struct interface *, struct in_addr); -extern struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *, - struct prefix_ipv4 *); -extern struct ospf_interface *ospf_if_table_lookup(struct interface *, - struct prefix *); -extern struct ospf_interface *ospf_if_addr_local(struct in_addr); +ospf_if_new(struct ospf *ospf, struct interface *ifp, struct prefix *p); +extern void ospf_if_cleanup(struct ospf_interface *oi); +extern void ospf_if_free(struct ospf_interface *oi); +extern int ospf_if_up(struct ospf_interface *oi); +extern int ospf_if_down(struct ospf_interface *oi); + +extern int ospf_if_is_up(struct ospf_interface *oi); +extern struct ospf_interface *ospf_if_exists(struct ospf_interface *oi); +extern struct ospf_interface *ospf_if_lookup_by_lsa_pos(struct ospf_area *area, + int lsa_pos); extern struct ospf_interface * -ospf_if_lookup_recv_if(struct ospf *, struct in_addr, struct interface *); -extern struct ospf_interface *ospf_if_is_configured(struct ospf *, - struct in_addr *); - -extern struct ospf_if_params *ospf_lookup_if_params(struct interface *, - struct in_addr); -extern struct ospf_if_params *ospf_get_if_params(struct interface *, - struct in_addr); -extern void ospf_free_if_params(struct interface *, struct in_addr); -extern void ospf_if_update_params(struct interface *, struct in_addr); - -extern int ospf_if_new_hook(struct interface *); +ospf_if_lookup_by_local_addr(struct ospf *ospf, struct interface *ifp, + struct in_addr addr); +extern struct ospf_interface *ospf_if_lookup_by_prefix(struct ospf *ospf, + struct prefix_ipv4 *p); +extern struct ospf_interface *ospf_if_table_lookup(struct interface *ifp, + struct prefix *p); +extern struct ospf_interface *ospf_if_addr_local(struct in_addr addr); +extern struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf, + struct in_addr addr, + struct interface *ifp); +extern struct ospf_interface *ospf_if_is_configured(struct ospf *ospf, + struct in_addr *addr); + +extern struct ospf_if_params *ospf_lookup_if_params(struct interface *ifp, + struct in_addr addr); +extern struct ospf_if_params *ospf_get_if_params(struct interface *ifp, + struct in_addr addr); +extern void ospf_free_if_params(struct interface *ifp, struct in_addr addr); +extern void ospf_if_update_params(struct interface *ifp, struct in_addr addr); + +extern int ospf_if_new_hook(struct interface *ifp); extern void ospf_if_init(void); -extern void ospf_if_stream_unset(struct ospf_interface *); -extern void ospf_if_reset_variables(struct ospf_interface *); -extern int ospf_if_is_enable(struct ospf_interface *); -extern int ospf_if_get_output_cost(struct ospf_interface *); -extern void ospf_if_recalculate_output_cost(struct interface *); +extern void ospf_if_stream_unset(struct ospf_interface *oi); +extern void ospf_if_reset_variables(struct ospf_interface *oi); +extern int ospf_if_is_enable(struct ospf_interface *oi); +extern int ospf_if_get_output_cost(struct ospf_interface *oi); +extern void ospf_if_recalculate_output_cost(struct interface *ifp); /* Simulate down/up on the interface. */ -extern void ospf_if_reset(struct interface *); - -extern struct ospf_interface *ospf_vl_new(struct ospf *, struct ospf_vl_data *); -extern struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *, - struct in_addr); -extern struct ospf_vl_data *ospf_vl_lookup(struct ospf *, struct ospf_area *, - struct in_addr); +extern void ospf_if_reset(struct interface *ifp); + +extern struct ospf_interface *ospf_vl_new(struct ospf *ospf, + struct ospf_vl_data *vl_data); +extern struct ospf_vl_data *ospf_vl_data_new(struct ospf_area *area, + struct in_addr addr); +extern struct ospf_vl_data * +ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area, struct in_addr addr); extern int ospf_vl_count(struct ospf *ospf, struct ospf_area *area); -extern void ospf_vl_data_free(struct ospf_vl_data *); -extern void ospf_vl_add(struct ospf *, struct ospf_vl_data *); -extern void ospf_vl_delete(struct ospf *, struct ospf_vl_data *); -extern void ospf_vl_up_check(struct ospf_area *, struct in_addr, - struct vertex *); -extern void ospf_vl_unapprove(struct ospf *); -extern void ospf_vl_shut_unapproved(struct ospf *); -extern int ospf_full_virtual_nbrs(struct ospf_area *); -extern int ospf_vls_in_area(struct ospf_area *); - -extern struct crypt_key *ospf_crypt_key_lookup(struct list *, uint8_t); +extern void ospf_vl_data_free(struct ospf_vl_data *vl_data); +extern void ospf_vl_add(struct ospf *ospf, struct ospf_vl_data *vl_data); +extern void ospf_vl_delete(struct ospf *ospf, struct ospf_vl_data *vl_data); +extern void ospf_vl_up_check(struct ospf_area *area, struct in_addr addr, + struct vertex *vertex); +extern void ospf_vl_unapprove(struct ospf *ospf); +extern void ospf_vl_shut_unapproved(struct ospf *ospf); +extern int ospf_full_virtual_nbrs(struct ospf_area *area); +extern int ospf_vls_in_area(struct ospf_area *area); + +extern struct crypt_key *ospf_crypt_key_lookup(struct list *list, + uint8_t key_id); extern struct crypt_key *ospf_crypt_key_new(void); -extern void ospf_crypt_key_add(struct list *, struct crypt_key *); -extern int ospf_crypt_key_delete(struct list *, uint8_t); +extern void ospf_crypt_key_add(struct list *list, struct crypt_key *key); +extern int ospf_crypt_key_delete(struct list *list, uint8_t key_id); extern uint8_t ospf_default_iftype(struct interface *ifp); extern int ospf_interface_neighbor_count(struct ospf_interface *oi); /* Set all multicast memberships appropriately based on the type and state of the interface. */ -extern void ospf_if_set_multicast(struct ospf_interface *); +extern void ospf_if_set_multicast(struct ospf_interface *oi); extern void ospf_if_interface(struct interface *ifp); diff --git a/tests/topotests/bgp_community_alias/r1/bgpd.conf b/tests/topotests/bgp_community_alias/r1/bgpd.conf index a6366204e8..13b57ad243 100644 --- a/tests/topotests/bgp_community_alias/r1/bgpd.conf +++ b/tests/topotests/bgp_community_alias/r1/bgpd.conf @@ -3,6 +3,8 @@ bgp community alias 65001:1 community-r2-1 bgp community alias 65002:2 community-r2-2 bgp community alias 65001:1:1 large-community-r2-1 ! +bgp large-community-list expanded r2 seq 5 permit _65001:1:1_ +! router bgp 65001 no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as external diff --git a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py index 6aadff1cfa..26933a7992 100644 --- a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py +++ b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py @@ -138,6 +138,17 @@ def test_bgp_community_alias(): success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Cannot see BGP prefixes by community alias at r1" + def _bgp_show_prefixes_by_large_community_list(router): + output = json.loads( + router.vtysh_cmd("show bgp ipv4 unicast large-community-list r2 json") + ) + expected = {"routes": {"172.16.16.1/32": [{"valid": True}]}} + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_show_prefixes_by_large_community_list, router) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Cannot see BGP prefixes by large community list at r1" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tools/etc/frr/support_bundle_commands.conf b/tools/etc/frr/support_bundle_commands.conf index 732470f828..750fa6b39f 100644 --- a/tools/etc/frr/support_bundle_commands.conf +++ b/tools/etc/frr/support_bundle_commands.conf @@ -83,9 +83,35 @@ show version CMD_LIST_END # OSPF Support Bundle Command List -# PROC_NAME:ospf -# CMD_LIST_START -# CMD_LIST_END +PROC_NAME:ospf +CMD_LIST_START +show ip ospf +show ip ospf vrfs +show ip ospf vrf all +show ip ospf vrf all interface +show ip ospf vrf all neighbor +show ip ospf vrf all neighbor detail +show ip ospf vrf all database +show ip ospf vrf all database router +show ip ospf vrf all database network +show ip ospf vrf all database summary +show ip ospf vrf all database asbr-summary +show ip ospf vrf all database external +show ip ospf vrf all database opaque-area +show ip ospf vrf all database opaque-as +show ip ospf vrf all database opaque-link +show ip ospf vrf all database nssa-external +show ip ospf vrf all database max-age +show ip ospf vrf all database self-originate +show ip ospf vrf all route +show ip ospf vrf all mpls-te interface +show ip ospf vrf all interface traffic +show ip ospf mpls-te router +show ip ospf router-info +show ip ospf router-info pce +show ip ospf database segment-routing +show debugging +CMD_LIST_END # RIP Support Bundle Command List # PROC_NAME:rip @@ -130,3 +156,43 @@ show ip pim state show ip pim statistics show ip pim rpf CMD_LIST_END + +# OSPFv3 Support Bundle Command List +PROC_NAME:ospf6 +CMD_LIST_START +show ipv6 ospf6 vrf all +show ipv6 ospf6 vrfs +show ipv6 ospf6 vrf all border-routers +show ipv6 ospf6 vrf all border-routers detail +show ipv6 ospf6 vrf all database +show ipv6 ospf6 vrf all database detail +show ipv6 ospf6 vrf all database dump +show ipv6 ospf6 vrf all database internal +show ipv6 ospf6 vrf all database router detail +show ipv6 ospf6 vrf all database network detail +show ipv6 ospf6 vrf all database inter-prefix detail +show ipv6 ospf6 vrf all database inter-router detail +show ipv6 ospf6 vrf all database intra-prefix detail +show ipv6 ospf6 vrf all database link detail +show ipv6 ospf6 vrf all database as-external detail +show ipv6 ospf6 vrf all database self-originate detail +show ipv6 ospf6 vrf all database type-7 detail +show ipv6 ospf6 vrf all interface +show ipv6 ospf6 vrf all interface prefix +show ipv6 ospf6 vrf all interface traffic +show ipv6 ospf6 vrf all linkstate detail +show ipv6 ospf6 vrf all neighbor +show ipv6 ospf6 vrf all neighbor drchoice +show ipv6 ospf6 vrf all neighbor detail +show ipv6 ospf6 vrf all redistribute +show ipv6 ospf6 vrf all route +show ipv6 ospf6 vrf all route external-1 +show ipv6 ospf6 vrf all route external-2 +show ipv6 ospf6 vrf all route inter-area +show ipv6 ospf6 vrf all route intra-area +show ipv6 ospf6 vrf all route detail +show ipv6 ospf6 vrf all route summary +show ipv6 ospf6 vrf all spf tree +show ipv6 ospf6 vrf all summary-address detail +show ipv6 ospf6 zebra +CMD_LIST_END diff --git a/zebra/rib.h b/zebra/rib.h index 31d9dfd265..a663575e10 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -403,6 +403,11 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, struct nexthop_group *ng); +/* + * -1 -> some sort of error + * 0 -> an add + * 1 -> an update + */ extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 27fb5d7c22..f297bafaf0 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2110,6 +2110,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) ret = rib_add_multipath_nhe(afi, api.safi, &api.prefix, src_p, re, &nhe); + /* + * rib_add_multipath_nhe only fails in a couple spots + * and in those spots we have not freed memory + */ + if (ret == -1) { + client->error_cnt++; + XFREE(MTYPE_RE, re); + } + /* At this point, these allocations are not needed: 're' has been * retained or freed, and if 're' still exists, it is using * a reference to a shared group object. @@ -2121,15 +2130,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) /* Stats */ switch (api.prefix.family) { case AF_INET: - if (ret > 0) + if (ret == 0) client->v4_route_add_cnt++; - else if (ret < 0) + else if (ret == 1) client->v4_route_upd8_cnt++; break; case AF_INET6: - if (ret > 0) + if (ret == 0) client->v6_route_add_cnt++; - else if (ret < 0) + else if (ret == 1) client->v6_route_upd8_cnt++; break; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index c51dd759a6..2ed025857d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -3453,6 +3453,10 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) * allocate: if they allocate a nexthop_group or backup nexthop info, they * must free those objects. If this returns < 0, an error has occurred and the * route_entry 're' has not been captured; the caller should free that also. + * + * -1 -> error + * 0 -> Add + * 1 -> update */ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct prefix_ipv6 *src_p, struct route_entry *re, @@ -3567,11 +3571,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, SET_FLAG(re->status, ROUTE_ENTRY_CHANGED); rib_addnode(rn, re, 1); - ret = 1; /* Free implicit route.*/ - if (same) + if (same) { + ret = 1; rib_delnode(rn, same); + } /* See if we can remove some RE entries that are queued for * removal, but won't be considered in rib processing. |
