summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_clist.c5
-rw-r--r--bgpd/bgp_community_alias.c40
-rw-r--r--bgpd/bgp_community_alias.h2
-rw-r--r--bgpd/bgp_io.c3
-rw-r--r--bgpd/bgpd.h1
-rw-r--r--ospf6d/ospf6_asbr.c2
-rw-r--r--ospfd/ospf_interface.h116
-rw-r--r--tests/topotests/bgp_community_alias/r1/bgpd.conf2
-rw-r--r--tests/topotests/bgp_community_alias/test_bgp-community-alias.py11
-rw-r--r--tools/etc/frr/support_bundle_commands.conf72
-rw-r--r--zebra/rib.h5
-rw-r--r--zebra/zapi_msg.c17
-rw-r--r--zebra/zebra_rib.c9
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.