summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfd.c17
-rw-r--r--bfdd/bfd.h10
-rw-r--r--bfdd/bfd_packet.c46
-rw-r--r--bfdd/bfdd_vty.c41
-rw-r--r--bgpd/bgp_conditional_adv.c22
-rw-r--r--bgpd/bgp_evpn_vty.c3
-rw-r--r--bgpd/bgp_packet.c28
-rw-r--r--bgpd/bgp_route.c26
-rw-r--r--bgpd/bgp_routemap.c11
-rw-r--r--bgpd/bgp_updgrp.c10
-rw-r--r--bgpd/bgp_updgrp.h4
-rw-r--r--bgpd/bgpd.c122
-rw-r--r--bgpd/bgpd.h33
-rw-r--r--doc/user/bfd.rst4
-rw-r--r--doc/user/bgp.rst2
-rw-r--r--doc/user/overview.rst2
-rw-r--r--doc/user/pim.rst2
-rw-r--r--doc/user/pimv6.rst8
-rw-r--r--lib/link_state.c5
-rw-r--r--nhrpd/nhrp_peer.c3
-rw-r--r--ospf6d/ospf6_interface.c14
-rw-r--r--ospf6d/ospf6_message.c6
-rw-r--r--ospfd/ospf_abr.c2
-rw-r--r--ospfd/ospf_flood.c38
-rw-r--r--ospfd/ospf_interface.c47
-rw-r--r--ospfd/ospf_interface.h2
-rw-r--r--ospfd/ospf_nsm.c33
-rw-r--r--ospfd/ospf_packet.c200
-rw-r--r--ospfd/ospf_sr.c15
-rw-r--r--ospfd/ospf_vty.c169
-rw-r--r--pathd/path_pcep_pcc.c2
-rw-r--r--pbrd/pbr_vty.c54
-rw-r--r--pimd/pim6_cmd.c35
-rw-r--r--pimd/pim6_cmd.h1
-rw-r--r--pimd/pim_addr.h2
-rw-r--r--pimd/pim_cmd.c3
-rw-r--r--pimd/pim_cmd_common.c123
-rw-r--r--pimd/pim_ifchannel.c52
-rw-r--r--pimd/pim_upstream.c16
-rw-r--r--pimd/pim_vty.c4
-rw-r--r--redhat/frr.spec.in3
-rw-r--r--staticd/static_nb_config.c26
-rw-r--r--tests/topotests/bgp_orf/__init__.py0
-rw-r--r--tests/topotests/bgp_orf/r1/bgpd.conf9
-rw-r--r--tests/topotests/bgp_orf/r1/zebra.conf8
-rw-r--r--tests/topotests/bgp_orf/r2/bgpd.conf9
-rw-r--r--tests/topotests/bgp_orf/r2/zebra.conf4
-rw-r--r--tests/topotests/bgp_orf/test_bgp_orf.py159
-rw-r--r--tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py7
-rw-r--r--vtysh/vtysh_main.c82
-rw-r--r--watchfrr/watchfrr.c2
-rw-r--r--zebra/interface.c4
-rw-r--r--zebra/rib.h4
-rw-r--r--zebra/zapi_msg.c16
-rw-r--r--zebra/zebra_dplane.c6
-rw-r--r--zebra/zebra_mpls.c20
-rw-r--r--zebra/zebra_mpls.h10
-rw-r--r--zebra/zebra_pw.c7
-rw-r--r--zebra/zebra_rib.c292
-rw-r--r--zebra/zebra_router.c2
-rw-r--r--zebra/zebra_vrf.c4
-rw-r--r--zebra/zebra_vxlan.c2
62 files changed, 1212 insertions, 681 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index a161926358..a1fb67d357 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -381,6 +381,9 @@ int bfd_session_enable(struct bfd_session *bs)
ptm_bfd_start_xmt_timer(bs, false);
}
+ /* initialize RTT */
+ bfd_rtt_init(bs);
+
return 0;
}
@@ -574,6 +577,9 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag)
memset(bfd->peer_hw_addr, 0, sizeof(bfd->peer_hw_addr));
/* reset local address ,it might has been be changed after bfd is up*/
memset(&bfd->local_address, 0, sizeof(bfd->local_address));
+
+ /* reset RTT */
+ bfd_rtt_init(bfd);
}
static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
@@ -2063,3 +2069,14 @@ unsigned long bfd_get_session_count(void)
{
return bfd_key_hash->count;
}
+
+void bfd_rtt_init(struct bfd_session *bfd)
+{
+ uint8_t i;
+
+ /* initialize RTT */
+ bfd->rtt_valid = 0;
+ bfd->rtt_index = 0;
+ for (i = 0; i < BFD_RTT_SAMPLE; i++)
+ bfd->rtt[i] = 0;
+}
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 48a1e0bc31..a5881cddb0 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -86,7 +86,8 @@ struct bfd_echo_pkt {
};
};
uint32_t my_discr;
- uint8_t pad[16];
+ uint64_t time_sent_sec;
+ uint64_t time_sent_usec;
};
@@ -249,6 +250,8 @@ struct bfd_config_timers {
uint32_t required_min_echo_rx;
};
+#define BFD_RTT_SAMPLE 8
+
/*
* Session state information
*/
@@ -311,6 +314,10 @@ struct bfd_session {
struct bfd_timers remote_timers;
uint64_t refcount; /* number of pointers referencing this. */
+
+ uint8_t rtt_valid; /* number of valid samples */
+ uint8_t rtt_index; /* last index added */
+ uint64_t rtt[BFD_RTT_SAMPLE]; /* RRT in usec for echo to be looped */
};
struct peer_label {
@@ -635,6 +642,7 @@ const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
bool mhop);
void bfd_sessions_remove_manual(void);
void bfd_profiles_remove(void);
+void bfd_rtt_init(struct bfd_session *bfd);
/**
* Set the BFD session echo state.
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index e2a44bce76..98411a8732 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -55,8 +55,8 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
struct sockaddr_any *peer);
int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen,
struct sockaddr *to, socklen_t tolen);
-int bp_bfd_echo_in(struct bfd_vrf_global *bvrf, int sd,
- uint8_t *ttl, uint32_t *my_discr);
+int bp_bfd_echo_in(struct bfd_vrf_global *bvrf, int sd, uint8_t *ttl,
+ uint32_t *my_discr, uint64_t *my_rtt);
#ifdef BFD_LINUX
ssize_t bfd_recv_ipv4_fp(int sd, uint8_t *msgbuf, size_t msgbuflen,
uint8_t *ttl, ifindex_t *ifindex,
@@ -207,6 +207,7 @@ void ptm_bfd_echo_fp_snd(struct bfd_session *bfd)
struct iphdr *iph;
struct bfd_echo_pkt *beph;
static char sendbuff[100];
+ struct timeval time_sent;
if (!bvrf)
return;
@@ -259,6 +260,11 @@ void ptm_bfd_echo_fp_snd(struct bfd_session *bfd)
beph->len = BFD_ECHO_PKT_LEN;
beph->my_discr = htonl(bfd->discrs.my_discr);
+ /* RTT calculation: add starting time in packet */
+ monotime(&time_sent);
+ beph->time_sent_sec = htobe64(time_sent.tv_sec);
+ beph->time_sent_usec = htobe64(time_sent.tv_usec);
+
total_len += sizeof(struct bfd_echo_pkt);
uh->len =
htons(total_len - sizeof(struct iphdr) - sizeof(struct ethhdr));
@@ -338,10 +344,11 @@ static int ptm_bfd_process_echo_pkt(struct bfd_vrf_global *bvrf, int s)
{
struct bfd_session *bfd;
uint32_t my_discr = 0;
+ uint64_t my_rtt = 0;
uint8_t ttl = 0;
/* Receive and parse echo packet. */
- if (bp_bfd_echo_in(bvrf, s, &ttl, &my_discr) == -1)
+ if (bp_bfd_echo_in(bvrf, s, &ttl, &my_discr, &my_rtt) == -1)
return 0;
/* Your discriminator not zero - use it to find session */
@@ -360,6 +367,16 @@ static int ptm_bfd_process_echo_pkt(struct bfd_vrf_global *bvrf, int s)
return -1;
}
+ /* RTT Calculation: add current RTT to samples */
+ if (my_rtt != 0) {
+ bfd->rtt[bfd->rtt_index] = my_rtt;
+ bfd->rtt_index++;
+ if (bfd->rtt_index >= BFD_RTT_SAMPLE)
+ bfd->rtt_index = 0;
+ if (bfd->rtt_valid < BFD_RTT_SAMPLE)
+ bfd->rtt_valid++;
+ }
+
bfd->stats.rx_echo_pkt++;
/* Compute detect time */
@@ -1003,8 +1020,8 @@ void bfd_recv_cb(struct thread *t)
*
* Returns -1 on error or loopback or 0 on success.
*/
-int bp_bfd_echo_in(struct bfd_vrf_global *bvrf, int sd,
- uint8_t *ttl, uint32_t *my_discr)
+int bp_bfd_echo_in(struct bfd_vrf_global *bvrf, int sd, uint8_t *ttl,
+ uint32_t *my_discr, uint64_t *my_rtt)
{
struct bfd_echo_pkt *bep;
ssize_t rlen;
@@ -1062,6 +1079,17 @@ int bp_bfd_echo_in(struct bfd_vrf_global *bvrf, int sd,
return -1;
}
+#ifdef BFD_LINUX
+ /* RTT Calculation: determine RTT time of IPv4 echo pkt */
+ if (sd == bvrf->bg_echo) {
+ struct timeval time_sent = {0, 0};
+
+ time_sent.tv_sec = be64toh(bep->time_sent_sec);
+ time_sent.tv_usec = be64toh(bep->time_sent_usec);
+ *my_rtt = monotime_since(&time_sent, NULL);
+ }
+#endif
+
return 0;
}
@@ -1074,11 +1102,10 @@ int bp_udp_send_fp(int sd, uint8_t *data, size_t datalen,
struct bfd_session *bfd)
{
ssize_t wlen;
- struct msghdr msg;
+ struct msghdr msg = {0};
struct iovec iov[1];
uint8_t msgctl[255];
- struct sockaddr_ll sadr_ll;
-
+ struct sockaddr_ll sadr_ll = {0};
sadr_ll.sll_ifindex = bfd->ifp->ifindex;
sadr_ll.sll_halen = ETH_ALEN;
@@ -1089,7 +1116,6 @@ int bp_udp_send_fp(int sd, uint8_t *data, size_t datalen,
iov[0].iov_base = data;
iov[0].iov_len = datalen;
- memset(&msg, 0, sizeof(msg));
memset(msgctl, 0, sizeof(msgctl));
msg.msg_name = &sadr_ll;
msg.msg_namelen = sizeof(sadr_ll);
@@ -1605,7 +1631,7 @@ int bp_echo_socket(const struct vrf *vrf)
zlog_fatal("echo-socket: socket: %s", strerror(errno));
struct sock_fprog pf;
- struct sockaddr_ll sll;
+ struct sockaddr_ll sll = {0};
/* adjust filter for socket to only receive ECHO packets */
pf.filter = my_filterudp;
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index a9fc716177..21429f06cf 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -66,6 +66,9 @@ static void _display_peer_counters_json(struct vty *vty, struct bfd_session *bs)
static void _display_peer_counter_iter(struct hash_bucket *hb, void *arg);
static void _display_peer_counter_json_iter(struct hash_bucket *hb, void *arg);
static void _display_peers_counter(struct vty *vty, char *vrfname, bool use_json);
+static void _display_rtt(uint32_t *min, uint32_t *avg, uint32_t *max,
+ struct bfd_session *bs);
+
static struct bfd_session *
_find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv,
const char *label, const char *peer_str,
@@ -106,6 +109,9 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs)
{
char buf[256];
time_t now;
+ uint32_t min = 0;
+ uint32_t avg = 0;
+ uint32_t max = 0;
_display_peer_header(vty, bs);
@@ -150,6 +156,8 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs)
vty_out(vty, "\t\tRemote diagnostics: %s\n", diag2str(bs->remote_diag));
vty_out(vty, "\t\tPeer Type: %s\n",
CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) ? "configured" : "dynamic");
+ _display_rtt(&min, &avg, &max, bs);
+ vty_out(vty, "\t\tRTT min/avg/max: %u/%u/%u usec\n", min, avg, max);
vty_out(vty, "\t\tLocal timers:\n");
vty_out(vty, "\t\t\tDetect-multiplier: %u\n",
@@ -217,6 +225,9 @@ static struct json_object *_peer_json_header(struct bfd_session *bs)
static struct json_object *__display_peer_json(struct bfd_session *bs)
{
struct json_object *jo = _peer_json_header(bs);
+ uint32_t min = 0;
+ uint32_t avg = 0;
+ uint32_t max = 0;
json_object_int_add(jo, "id", bs->discrs.my_discr);
json_object_int_add(jo, "remote-id", bs->discrs.remote_discr);
@@ -275,6 +286,11 @@ static struct json_object *__display_peer_json(struct bfd_session *bs)
json_object_int_add(jo, "remote-detect-multiplier",
bs->remote_detect_mult);
+ _display_rtt(&min, &avg, &max, bs);
+ json_object_int_add(jo, "rtt-min", min);
+ json_object_int_add(jo, "rtt-avg", avg);
+ json_object_int_add(jo, "rtt-max", max);
+
return jo;
}
@@ -608,6 +624,31 @@ _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv,
return bs;
}
+void _display_rtt(uint32_t *min, uint32_t *avg, uint32_t *max,
+ struct bfd_session *bs)
+{
+#ifdef BFD_LINUX
+ uint8_t i;
+ uint32_t average = 0;
+
+ if (bs->rtt_valid == 0)
+ return;
+
+ *max = bs->rtt[0];
+ *min = 1000;
+ *avg = 0;
+
+ for (i = 0; i < bs->rtt_valid; i++) {
+ if (bs->rtt[i] < *min)
+ *min = bs->rtt[i];
+ if (bs->rtt[i] > *max)
+ *max = bs->rtt[i];
+ average += bs->rtt[i];
+ }
+ *avg = average / bs->rtt_valid;
+
+#endif
+}
/*
* Show commands.
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c
index 9c2826fa13..fc44e86cbc 100644
--- a/bgpd/bgp_conditional_adv.c
+++ b/bgpd/bgp_conditional_adv.c
@@ -258,6 +258,25 @@ static void bgp_conditional_adv_timer(struct thread *t)
? UPDATE_TYPE_WITHDRAW
: UPDATE_TYPE_ADVERTISE;
+ /*
+ * Update condadv update type so
+ * subgroup_announce_check() can properly apply
+ * outbound policy according to advertisement state
+ */
+ paf = peer_af_find(peer, afi, safi);
+ if (paf && (SUBGRP_PEER(PAF_SUBGRP(paf))
+ ->filter[afi][safi]
+ .advmap.update_type !=
+ filter->advmap.update_type)) {
+ /* Handle change to peer advmap */
+ if (BGP_DEBUG(update, UPDATE_OUT))
+ zlog_debug(
+ "%s: advmap.update_type changed for peer %s, adjusting update_group.",
+ __func__, peer->host);
+
+ update_group_adjust_peer(paf);
+ }
+
/* Send regular update as per the existing policy.
* There is a change in route-map, match-rule, ACLs,
* or route-map filter configuration on the same peer.
@@ -270,11 +289,10 @@ static void bgp_conditional_adv_timer(struct thread *t)
__func__, peer->host,
get_afi_safi_str(afi, safi,
false));
-
- paf = peer_af_find(peer, afi, safi);
if (paf) {
update_subgroup_split_peer(paf, NULL);
subgrp = paf->subgroup;
+
if (subgrp && subgrp->update_group)
subgroup_announce_table(
paf->subgroup, NULL);
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 797075563b..6ba516c39c 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -4036,6 +4036,9 @@ DEFUN (no_bgp_evpn_advertise_type5,
afi_t afi = 0;
safi_t safi = 0;
+ if (!bgp_vrf)
+ return CMD_WARNING;
+
argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 0bbf6f8a21..fe1887565e 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2283,17 +2283,26 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
peer, orf_type, orf_len);
}
+ /* ORF prefix-list name */
+ snprintf(name, sizeof(name), "%s.%d.%d",
+ peer->host, afi, safi);
+
/* we're going to read at least 1 byte of common
* ORF header,
* and 7 bytes of ORF Address-filter entry from
* the stream
*/
- if (orf_len < 7)
+ if (*p_pnt & ORF_COMMON_PART_REMOVE_ALL) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%pBP rcvd Remove-All pfxlist ORF request",
+ peer);
+ prefix_bgp_orf_remove_all(afi, name);
break;
+ }
- /* ORF prefix-list name */
- snprintf(name, sizeof(name), "%s.%d.%d",
- peer->host, afi, safi);
+ if (orf_len < 7)
+ break;
while (p_pnt < p_end) {
/* If the ORF entry is malformed, want
@@ -2306,17 +2315,6 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size)
memset(&orfp, 0, sizeof(orfp));
common = *p_pnt++;
/* after ++: p_pnt <= p_end */
- if (common
- & ORF_COMMON_PART_REMOVE_ALL) {
- if (bgp_debug_neighbor_events(
- peer))
- zlog_debug(
- "%pBP rcvd Remove-All pfxlist ORF request",
- peer);
- prefix_bgp_orf_remove_all(afi,
- name);
- break;
- }
ok = ((uint32_t)(p_end - p_pnt)
>= sizeof(uint32_t));
if (ok) {
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 2e7dbaaf66..a8cf9ca3c0 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2212,6 +2212,32 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
bgp_peer_as_override(bgp, afi, safi, peer, attr);
+ if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
+ filter->advmap.aname &&
+ route_map_lookup_by_name(filter->advmap.aname)) {
+ struct bgp_path_info rmap_path = {0};
+ struct bgp_path_info_extra dummy_rmap_path_extra = {0};
+ struct attr dummy_attr = *attr;
+
+ /* Fill temp path_info */
+ prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
+ pi, peer, &dummy_attr);
+
+ struct route_map *amap =
+ route_map_lookup_by_name(filter->advmap.aname);
+
+ ret = route_map_apply(amap, p, &rmap_path);
+
+ bgp_attr_flush(&dummy_attr);
+
+ /*
+ * The conditional advertisement mode is Withdraw and this
+ * prefix is a conditional prefix. Don't advertise it
+ */
+ if (ret == RMAP_PERMITMATCH)
+ return false;
+ }
+
/* Route map & unsuppress-map apply. */
if (!post_attr &&
(ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index e94b633b3b..33f68c9e88 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -3867,7 +3867,7 @@ static void bgp_route_map_update_peer_group(const char *rmap_name,
* network statements, etc looking to see if they use this route-map.
*/
static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
- int route_update)
+ bool route_update)
{
int i;
bool matched;
@@ -4080,7 +4080,7 @@ static void bgp_route_map_process_update_cb(char *rmap_name)
struct bgp *bgp;
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
- bgp_route_map_process_update(bgp, rmap_name, 1);
+ bgp_route_map_process_update(bgp, rmap_name, true);
#ifdef ENABLE_BGP_VNC
vnc_routemap_update(bgp, __func__);
@@ -4116,12 +4116,11 @@ static void bgp_route_map_mark_update(const char *rmap_name)
/* Signal the groups that a route-map update event has
* started */
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
- update_group_policy_update(bgp,
- BGP_POLICY_ROUTE_MAP,
- rmap_name, 1, 1);
+ update_group_policy_update(bgp, BGP_POLICY_ROUTE_MAP,
+ rmap_name, true, 1);
} else {
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
- bgp_route_map_process_update(bgp, rmap_name, 0);
+ bgp_route_map_process_update(bgp, rmap_name, false);
#ifdef ENABLE_BGP_VNC
vnc_routemap_update(bgp, __func__);
#endif
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 405dd8f6ec..f1173941a0 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -218,6 +218,8 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi,
MTYPE_BGP_FILTER_NAME, CONDITION_MAP_NAME(srcfilter));
CONDITION_MAP(dstfilter) = CONDITION_MAP(srcfilter);
}
+
+ dstfilter->advmap.update_type = srcfilter->advmap.update_type;
}
/**
@@ -389,6 +391,9 @@ static unsigned int updgrp_hash_key_make(const void *p)
strlen(filter->advmap.aname), SEED1),
key);
+ if (filter->advmap.update_type)
+ key = jhash_1word(filter->advmap.update_type, key);
+
if (peer->default_rmap[afi][safi].name)
key = jhash_1word(
jhash(peer->default_rmap[afi][safi].name,
@@ -588,6 +593,9 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2)
&& strcmp(fl1->advmap.aname, fl2->advmap.aname)))
return false;
+ if (fl1->advmap.update_type != fl2->advmap.update_type)
+ return false;
+
if ((pe1->default_rmap[afi][safi].name
&& !pe2->default_rmap[afi][safi].name)
|| (!pe1->default_rmap[afi][safi].name
@@ -1547,7 +1555,7 @@ static int update_group_periodic_merge_walkcb(struct update_group *updgrp,
* update groups.
*/
void update_group_policy_update(struct bgp *bgp, enum bgp_policy_type ptype,
- const char *pname, int route_update,
+ const char *pname, bool route_update,
int start_event)
{
struct updwalk_context ctx;
diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h
index 473017c809..56289d399d 100644
--- a/bgpd/bgp_updgrp.h
+++ b/bgpd/bgp_updgrp.h
@@ -298,7 +298,7 @@ struct updwalk_context {
enum bgp_policy_type policy_type;
const char *policy_name;
int policy_event_start_flag;
- int policy_route_update;
+ bool policy_route_update;
updgrp_walkcb cb;
void *context;
uint8_t flags;
@@ -377,7 +377,7 @@ extern bool update_subgroup_trigger_merge_check(struct update_subgroup *,
int force);
extern void update_group_policy_update(struct bgp *bgp,
enum bgp_policy_type ptype,
- const char *pname, int route_update,
+ const char *pname, bool route_update,
int start_event);
extern void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
updgrp_walkcb cb, void *ctx);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index bd3e61377a..c17bd76ad7 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -482,14 +482,14 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set)
}
/* BGP's cluster-id control. */
-int bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
+void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
{
struct peer *peer;
struct listnode *node, *nnode;
if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID)
&& IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id))
- return 0;
+ return;
IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id);
bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID);
@@ -505,16 +505,15 @@ int bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
}
- return 0;
}
-int bgp_cluster_id_unset(struct bgp *bgp)
+void bgp_cluster_id_unset(struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *nnode;
if (!bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID))
- return 0;
+ return;
bgp->cluster_id.s_addr = 0;
bgp_config_unset(bgp, BGP_CONFIG_CLUSTER_ID);
@@ -530,7 +529,6 @@ int bgp_cluster_id_unset(struct bgp *bgp)
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
}
- return 0;
}
/* time_t value that is monotonicly increasing
@@ -623,7 +621,7 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as)
return;
}
-int bgp_confederation_id_unset(struct bgp *bgp)
+void bgp_confederation_id_unset(struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *nnode;
@@ -645,7 +643,6 @@ int bgp_confederation_id_unset(struct bgp *bgp)
bgp_session_reset_safe(peer, &nnode);
}
}
- return 0;
}
/* Is an AS part of the confed or not? */
@@ -664,16 +661,16 @@ bool bgp_confederation_peers_check(struct bgp *bgp, as_t as)
}
/* Add an AS to the confederation set. */
-int bgp_confederation_peers_add(struct bgp *bgp, as_t as)
+void bgp_confederation_peers_add(struct bgp *bgp, as_t as)
{
struct peer *peer;
struct listnode *node, *nnode;
if (bgp->as == as)
- return BGP_ERR_INVALID_AS;
+ return;
if (bgp_confederation_peers_check(bgp, as))
- return -1;
+ return;
bgp->confed_peers =
XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
@@ -699,11 +696,10 @@ int bgp_confederation_peers_add(struct bgp *bgp, as_t as)
}
}
}
- return 0;
}
/* Delete an AS from the confederation set. */
-int bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
+void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
{
int i;
int j;
@@ -711,10 +707,10 @@ int bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
struct listnode *node, *nnode;
if (!bgp)
- return -1;
+ return;
if (!bgp_confederation_peers_check(bgp, as))
- return -1;
+ return;
for (i = 0; i < bgp->confed_peers_cnt; i++)
if (bgp->confed_peers[i] == as)
@@ -751,71 +747,58 @@ int bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
}
}
}
-
- return 0;
}
/* Local preference configuration. */
-int bgp_default_local_preference_set(struct bgp *bgp, uint32_t local_pref)
+void bgp_default_local_preference_set(struct bgp *bgp, uint32_t local_pref)
{
if (!bgp)
- return -1;
+ return;
bgp->default_local_pref = local_pref;
-
- return 0;
}
-int bgp_default_local_preference_unset(struct bgp *bgp)
+void bgp_default_local_preference_unset(struct bgp *bgp)
{
if (!bgp)
- return -1;
+ return;
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
-
- return 0;
}
/* Local preference configuration. */
-int bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp, uint32_t queue_size)
+void bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp,
+ uint32_t queue_size)
{
if (!bgp)
- return -1;
+ return;
bgp->default_subgroup_pkt_queue_max = queue_size;
-
- return 0;
}
-int bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp)
+void bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp)
{
if (!bgp)
- return -1;
+ return;
bgp->default_subgroup_pkt_queue_max =
BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
-
- return 0;
}
/* Listen limit configuration. */
-int bgp_listen_limit_set(struct bgp *bgp, int listen_limit)
+void bgp_listen_limit_set(struct bgp *bgp, int listen_limit)
{
if (!bgp)
- return -1;
+ return;
bgp->dynamic_neighbors_limit = listen_limit;
-
- return 0;
}
-int bgp_listen_limit_unset(struct bgp *bgp)
+void bgp_listen_limit_unset(struct bgp *bgp)
{
if (!bgp)
- return -1;
+ return;
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
-
- return 0;
}
int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
@@ -1828,7 +1811,7 @@ struct peer *peer_create_accept(struct bgp *bgp)
/*
* Return true if we have a peer configured to use this afi/safi
*/
-int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
+bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
{
struct listnode *node;
struct peer *peer;
@@ -1838,10 +1821,10 @@ int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
continue;
if (peer->afc[afi][safi])
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* Change peer's AS number. */
@@ -5127,7 +5110,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname)
return 0;
}
-int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
+void peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
{
struct peer *member;
struct listnode *node, *nnode;
@@ -5136,7 +5119,7 @@ int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
if (peer->update_source) {
if (sockunion_cmp(peer->update_source, su) == 0)
- return 0;
+ return;
sockunion_free(peer->update_source);
}
peer->update_source = sockunion_dup(su);
@@ -5157,7 +5140,7 @@ int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
bgp_peer_bfd_update_source(peer);
/* Skip peer-group mechanics for regular peers. */
- return 0;
+ return;
}
/*
@@ -5193,17 +5176,15 @@ int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
if (member->bfd_config)
bgp_peer_bfd_update_source(member);
}
-
- return 0;
}
-int peer_update_source_unset(struct peer *peer)
+void peer_update_source_unset(struct peer *peer)
{
struct peer *member;
struct listnode *node, *nnode;
if (!CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE))
- return 0;
+ return;
/* Inherit configuration from peer-group if peer is member. */
if (peer_group_active(peer)) {
@@ -5234,7 +5215,7 @@ int peer_update_source_unset(struct peer *peer)
bgp_peer_bfd_update_source(peer);
/* Skip peer-group mechanics for regular peers. */
- return 0;
+ return;
}
/*
@@ -5269,8 +5250,6 @@ int peer_update_source_unset(struct peer *peer)
if (member->bfd_config)
bgp_peer_bfd_update_source(member);
}
-
- return 0;
}
int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
@@ -5497,12 +5476,23 @@ static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
return;
if (CHECK_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SOFT_RECONFIG))
+ PEER_FLAG_SOFT_RECONFIG)) {
bgp_soft_reconfig_in(peer, afi, safi);
- else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
- || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
- bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
- BGP_ROUTE_REFRESH_NORMAL);
+ } else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) ||
+ CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) {
+ if (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_SM_ADV) &&
+ (CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_RCV) ||
+ CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
+ peer_clear_soft(peer, afi, safi,
+ BGP_CLEAR_SOFT_IN_ORF_PREFIX);
+ else
+ bgp_route_refresh_send(
+ peer, afi, safi, 0, 0, 0,
+ BGP_ROUTE_REFRESH_NORMAL);
+ }
}
}
@@ -6546,7 +6536,7 @@ static void peer_distribute_update(struct access_list *access)
if (access->name)
update_group_policy_update(bgp,
BGP_POLICY_DISTRIBUTE_LIST,
- access->name, 0, 0);
+ access->name, true, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
FOREACH_AFI_SAFI (afi, safi) {
filter = &peer->filter[afi][safi];
@@ -6735,7 +6725,7 @@ static void peer_prefix_list_update(struct prefix_list *plist)
*/
update_group_policy_update(
bgp, BGP_POLICY_PREFIX_LIST,
- plist ? prefix_list_name(plist) : NULL, 0, 0);
+ plist ? prefix_list_name(plist) : NULL, true, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
FOREACH_AFI_SAFI (afi, safi) {
@@ -6753,6 +6743,14 @@ static void peer_prefix_list_update(struct prefix_list *plist)
filter->plist[direct].plist =
NULL;
}
+
+ /* If we touch prefix-list, we need to process
+ * new updates. This is important for ORF to
+ * work correctly as well.
+ */
+ if (peer->afc_nego[afi][safi])
+ peer_on_policy_change(peer, afi, safi,
+ 0);
}
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
@@ -6912,7 +6910,7 @@ static void peer_aslist_update(const char *aslist_name)
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
- aslist_name, 0, 0);
+ aslist_name, true, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
FOREACH_AFI_SAFI (afi, safi) {
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index bcb214873f..8348b37b8e 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2128,32 +2128,34 @@ extern void bgp_router_id_static_set(struct bgp *, struct in_addr);
extern void bm_wait_for_fib_set(bool set);
extern void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set);
-extern int bgp_cluster_id_set(struct bgp *, struct in_addr *);
-extern int bgp_cluster_id_unset(struct bgp *);
+extern void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id);
+extern void bgp_cluster_id_unset(struct bgp *bgp);
-extern void bgp_confederation_id_set(struct bgp *, as_t);
-extern int bgp_confederation_id_unset(struct bgp *);
+extern void bgp_confederation_id_set(struct bgp *bgp, as_t as);
+extern void bgp_confederation_id_unset(struct bgp *bgp);
extern bool bgp_confederation_peers_check(struct bgp *, as_t);
-extern int bgp_confederation_peers_add(struct bgp *, as_t);
-extern int bgp_confederation_peers_remove(struct bgp *, as_t);
+extern void bgp_confederation_peers_add(struct bgp *bgp, as_t as);
+extern void bgp_confederation_peers_remove(struct bgp *bgp, as_t as);
extern void bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime,
uint32_t connect_retry, uint32_t delayopen);
extern void bgp_timers_unset(struct bgp *);
-extern int bgp_default_local_preference_set(struct bgp *, uint32_t);
-extern int bgp_default_local_preference_unset(struct bgp *);
+extern void bgp_default_local_preference_set(struct bgp *bgp,
+ uint32_t local_pref);
+extern void bgp_default_local_preference_unset(struct bgp *bgp);
-extern int bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp, uint32_t);
-extern int bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp);
+extern void bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp,
+ uint32_t queue_size);
+extern void bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp);
-extern int bgp_listen_limit_set(struct bgp *, int);
-extern int bgp_listen_limit_unset(struct bgp *);
+extern void bgp_listen_limit_set(struct bgp *bgp, int listen_limit);
+extern void bgp_listen_limit_unset(struct bgp *bgp);
extern bool bgp_update_delay_active(struct bgp *);
extern bool bgp_update_delay_configured(struct bgp *);
-extern int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
+extern bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
extern void peer_as_change(struct peer *, as_t, int);
extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
int);
@@ -2194,8 +2196,9 @@ extern void peer_description_set(struct peer *, const char *);
extern void peer_description_unset(struct peer *);
extern int peer_update_source_if_set(struct peer *, const char *);
-extern int peer_update_source_addr_set(struct peer *, const union sockunion *);
-extern int peer_update_source_unset(struct peer *);
+extern void peer_update_source_addr_set(struct peer *peer,
+ const union sockunion *su);
+extern void peer_update_source_unset(struct peer *peer);
extern int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
const char *rmap,
diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst
index c47ed04f63..0eb1064519 100644
--- a/doc/user/bfd.rst
+++ b/doc/user/bfd.rst
@@ -518,6 +518,10 @@ You can inspect the current BFD peer status with the following commands:
frr# show bfd peer 192.168.0.1 json
{"multihop":false,"peer":"192.168.0.1","id":1,"remote-id":1,"status":"up","uptime":161,"diagnostic":"ok","remote-diagnostic":"ok","receive-interval":300,"transmit-interval":300,"echo-receive-interval":50,"echo-transmit-interval":0,"detect-multiplier":3,"remote-receive-interval":300,"remote-transmit-interval":300,"remote-echo-receive-interval":50,"remote-detect-multiplier":3,"peer-type":"dynamic"}
+If you are running IPV4 BFD Echo, on a Linux platform, we also
+calculate round trip time for the packets. We display minimum,
+average and maximum time it took to receive the looped Echo packets
+in the RTT fields.
You can inspect the current BFD peer status in brief with the following commands:
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index e7e13631cc..86cd513b57 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1672,7 +1672,7 @@ Configuring Peers
.. clicmd:: bgp fast-external-failover
- This command causes bgp to not take down ebgp peers immediately
+ This command causes bgp to take down ebgp peers immediately
when a link flaps. `bgp fast-external-failover` is the default
and will not be displayed as part of a `show run`. The no form
of the command turns off this ability.
diff --git a/doc/user/overview.rst b/doc/user/overview.rst
index bf401825e0..91ca1b89f0 100644
--- a/doc/user/overview.rst
+++ b/doc/user/overview.rst
@@ -258,7 +258,7 @@ feature you're interested in, it should be supported on your platform.
+-----------------------------------+----------------+--------------+------------+------------+
| **Multicast Routing** | | | | |
+-----------------------------------+----------------+--------------+------------+------------+
-| `pimd` (PIM) | :mark:`≥4.18` | :mark:`N` | :mark:`Y` | :mark:`Y` |
+| `pimd` (PIM) | :mark:`≥4.19` | :mark:`N` | :mark:`Y` | :mark:`Y` |
+-----------------------------------+----------------+--------------+------------+------------+
| SSM (Source Specific) | :mark:`Y` | :mark:`N` | :mark:`Y` | :mark:`Y` |
+-----------------------------------+----------------+--------------+------------+------------+
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index ae39f4220d..44ade916a2 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -13,7 +13,7 @@ network for optimizing forwarding of overlay BUM traffic.
.. note::
- On Linux for PIM-SM operation you *must* have kernel version 4.18 or greater.
+ On Linux for PIM-SM operation you *must* have kernel version 4.19 or greater.
To use PIM for EVPN BUM forwarding, kernels 5.0 or greater are required.
OpenBSD has no multicast support and FreeBSD, and NetBSD only
have support for SSM.
diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst
index e6585d0bac..851e58b814 100644
--- a/doc/user/pimv6.rst
+++ b/doc/user/pimv6.rst
@@ -445,3 +445,11 @@ the config was written out.
.. clicmd:: debug pimv6 zebra
This gathers data about events from zebra that come up through the ZAPI.
+
+.. clicmd:: debug mroute6
+
+ This turns on debugging for PIMv6 interaction with kernel MFC cache.
+
+.. clicmd:: debug mroute6 detail
+
+ This turns on detailed debugging for PIMv6 interaction with kernel MFC cache.
diff --git a/lib/link_state.c b/lib/link_state.c
index 0ef87b7a51..ab5a8515b5 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -1791,9 +1791,10 @@ struct ls_edge *ls_msg2edge(struct ls_ted *ted, struct ls_message *msg,
case LS_MSG_EVENT_DELETE:
edge = ls_find_edge_by_source(ted, attr);
if (edge) {
- if (delete)
+ if (delete) {
ls_edge_del_all(ted, edge);
- else
+ edge = NULL;
+ } else
edge->status = DELETE;
}
break;
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 4b03032566..e7f2eaf5a7 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -17,6 +17,7 @@
#include "memory.h"
#include "thread.h"
#include "hash.h"
+#include "network.h"
#include "nhrpd.h"
#include "nhrp_protocol.h"
@@ -334,7 +335,7 @@ int nhrp_peer_check(struct nhrp_peer *p, int establish)
&p->t_fallback);
} else {
/* Maximum timeout is 1 second */
- int r_time_ms = rand() % 1000;
+ int r_time_ms = frr_weak_random() % 1000;
debugf(NHRP_DEBUG_COMMON,
"Initiating IPsec connection request to %pSU after %d ms:",
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index efa5d2b7ab..155374d3f0 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -966,10 +966,6 @@ static const char *ospf6_iftype_str(uint8_t iftype)
return "UNKNOWN";
}
-#if CONFDATE > 20220709
-CPP_NOTICE("Time to remove ospf6Enabled from JSON output")
-#endif
-
/* show specified interface structure */
static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
json_object *json_obj, bool use_json)
@@ -996,11 +992,8 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp,
ospf6_iftype_str(default_iftype));
json_object_int_add(json_obj, "interfaceId", ifp->ifindex);
- if (ifp->info == NULL) {
- json_object_boolean_false_add(json_obj, "ospf6Enabled");
+ if (ifp->info == NULL)
return 0;
- }
- json_object_boolean_true_add(json_obj, "ospf6Enabled");
oi = (struct ospf6_interface *)ifp->info;
@@ -1719,8 +1712,11 @@ void ospf6_interface_start(struct ospf6_interface *oi)
if (oi->area_id_format == OSPF6_AREA_FMT_UNSET)
return;
- if (oi->area)
+ if (oi->area) {
+ /* Recompute cost */
+ ospf6_interface_recalculate_cost(oi);
return;
+ }
ospf6 = oi->interface->vrf->info;
if (!ospf6)
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c
index 93a062b215..360a9db0d6 100644
--- a/ospf6d/ospf6_message.c
+++ b/ospf6d/ospf6_message.c
@@ -2086,7 +2086,6 @@ static void ospf6_write(struct thread *thread)
{
struct ospf6 *ospf6 = THREAD_ARG(thread);
struct ospf6_interface *oi;
- struct ospf6_interface *last_serviced_oi = NULL;
struct ospf6_header *oh;
struct ospf6_packet *op;
struct listnode *node;
@@ -2106,9 +2105,7 @@ static void ospf6_write(struct thread *thread)
assert(node);
oi = listgetdata(node);
- while ((pkt_count < ospf6->write_oi_count) && oi
- && (last_serviced_oi != oi)) {
-
+ while ((pkt_count < ospf6->write_oi_count) && oi) {
op = ospf6_fifo_head(oi->obuf);
assert(op);
assert(op->length >= OSPF6_HEADER_SIZE);
@@ -2221,7 +2218,6 @@ static void ospf6_write(struct thread *thread)
list_delete_node(ospf6->oi_write_q, node);
if (ospf6_fifo_head(oi->obuf) == NULL) {
oi->on_write_q = 0;
- last_serviced_oi = NULL;
oi = NULL;
} else {
listnode_add(ospf6->oi_write_q, oi);
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 13243a55af..b7db1a6a83 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -1067,7 +1067,7 @@ static void ospf_abr_process_network_rt(struct ospf *ospf,
&& !OSPF_IS_AREA_ID_BACKBONE(or->u.std.area_id)) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
- "ospf_abr_process_network_rt(): this is route is not backbone one, skipping");
+ "ospf_abr_process_network_rt(): this route is not backbone one, skipping");
continue;
}
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index 848f340750..fb3fb21e08 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -638,13 +638,15 @@ int ospf_flood_through_interface(struct ospf_interface *oi,
if (oi->type == OSPF_IFTYPE_NBMA) {
struct ospf_neighbor *nbr;
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
- if ((nbr = rn->info) != NULL)
- if (nbr != oi->nbr_self
- && nbr->state >= NSM_Exchange)
- ospf_ls_upd_send_lsa(
- nbr, lsa,
- OSPF_SEND_PACKET_DIRECT);
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+ if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
+ ospf_ls_upd_send_lsa(nbr, lsa,
+ OSPF_SEND_PACKET_DIRECT);
+ }
} else
ospf_ls_upd_send_lsa(oi->nbr_self, lsa,
OSPF_SEND_PACKET_INDIRECT);
@@ -991,18 +993,20 @@ static void ospf_ls_retransmit_delete_nbr_if(struct ospf_interface *oi,
struct ospf_lsa *lsr;
if (ospf_if_is_enable(oi))
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
/* If LSA find in LS-retransmit list, then remove it. */
- if ((nbr = rn->info) != NULL) {
- lsr = ospf_ls_retransmit_lookup(nbr, lsa);
+ nbr = rn->info;
- /* If LSA find in ls-retransmit list, remove it.
- */
- if (lsr != NULL
- && lsr->data->ls_seqnum
- == lsa->data->ls_seqnum)
- ospf_ls_retransmit_delete(nbr, lsr);
- }
+ if (!nbr)
+ continue;
+
+ lsr = ospf_ls_retransmit_lookup(nbr, lsa);
+
+ /* If LSA find in ls-retransmit list, remove it. */
+ if (lsr != NULL &&
+ lsr->data->ls_seqnum == lsa->data->ls_seqnum)
+ ospf_ls_retransmit_delete(nbr, lsr);
+ }
}
void ospf_ls_retransmit_delete_nbr_area(struct ospf_area *area,
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 633ab05131..2a758d5583 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -66,15 +66,16 @@ int ospf_interface_neighbor_count(struct ospf_interface *oi)
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
nbr = rn->info;
- if (nbr) {
- /* Do not show myself. */
- if (nbr == oi->nbr_self)
- continue;
- /* Down state is not shown. */
- if (nbr->state == NSM_Down)
- continue;
- count++;
- }
+ if (!nbr)
+ continue;
+
+ /* Do not show myself. */
+ if (nbr == oi->nbr_self)
+ continue;
+ /* Down state is not shown. */
+ if (nbr->state == NSM_Down)
+ continue;
+ count++;
}
return count;
@@ -315,10 +316,11 @@ void ospf_if_cleanup(struct ospf_interface *oi)
}
/* send Neighbor event KillNbr to all associated neighbors. */
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
if ((nbr = rn->info) != NULL)
if (nbr != oi->nbr_self)
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
+ }
/* Cleanup Link State Acknowlegdment list. */
for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa))
@@ -492,6 +494,20 @@ struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf,
return match;
}
+void ospf_interface_fifo_flush(struct ospf_interface *oi)
+{
+ struct ospf *ospf = oi->ospf;
+
+ ospf_fifo_flush(oi->obuf);
+
+ if (oi->on_write_q) {
+ listnode_delete(ospf->oi_write_q, oi);
+ if (list_isempty(ospf->oi_write_q))
+ THREAD_OFF(ospf->t_write);
+ oi->on_write_q = 0;
+ }
+}
+
static void ospf_if_reset_stats(struct ospf_interface *oi)
{
oi->hello_in = oi->hello_out = 0;
@@ -503,19 +519,10 @@ static void ospf_if_reset_stats(struct ospf_interface *oi)
void ospf_if_stream_unset(struct ospf_interface *oi)
{
- struct ospf *ospf = oi->ospf;
-
/* flush the interface packet queue */
- ospf_fifo_flush(oi->obuf);
+ ospf_interface_fifo_flush(oi);
/*reset protocol stats */
ospf_if_reset_stats(oi);
-
- if (oi->on_write_q) {
- listnode_delete(ospf->oi_write_q, oi);
- if (list_isempty(ospf->oi_write_q))
- THREAD_OFF(ospf->t_write);
- oi->on_write_q = 0;
- }
}
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index e441016406..51fc1bf3c3 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -351,6 +351,8 @@ extern void ospf_if_interface(struct interface *ifp);
extern uint32_t ospf_if_count_area_params(struct interface *ifp);
extern void ospf_reset_hello_timer(struct interface *ifp, struct in_addr addr,
bool is_addr);
+
+extern void ospf_interface_fifo_flush(struct ospf_interface *oi);
DECLARE_HOOK(ospf_vl_add, (struct ospf_vl_data * vd), (vd));
DECLARE_HOOK(ospf_vl_delete, (struct ospf_vl_data * vd), (vd));
diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c
index 333389596b..a27550853b 100644
--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -382,6 +382,10 @@ static void nsm_clear_adj(struct ospf_neighbor *nbr)
static int nsm_kill_nbr(struct ospf_neighbor *nbr)
{
+ struct ospf_interface *oi = nbr->oi;
+ struct ospf_neighbor *on;
+ struct route_node *rn;
+
/* killing nbr_self is invalid */
if (nbr == nbr->oi->nbr_self) {
assert(nbr != nbr->oi->nbr_self);
@@ -407,6 +411,35 @@ static int nsm_kill_nbr(struct ospf_neighbor *nbr)
ospf_get_name(nbr->oi->ospf));
}
+ /*
+ * Do we have any neighbors that are also operating
+ * on this interface?
+ */
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ on = rn->info;
+
+ if (!on)
+ continue;
+
+ if (on == nbr || on == oi->nbr_self)
+ continue;
+
+ /*
+ * on is in some state where we might be
+ * sending packets on this interface
+ */
+ if (on->state > NSM_Down) {
+ route_unlock_node(rn);
+ return 0;
+ }
+ }
+ /*
+ * If we get here we know that this interface
+ * has no neighbors in a state where we could
+ * be sending packets. Let's flush anything
+ * we got.
+ */
+ ospf_interface_fifo_flush(oi);
return 0;
}
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 4b3f30a3f1..c5e26fa371 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -623,7 +623,6 @@ static void ospf_write(struct thread *thread)
{
struct ospf *ospf = THREAD_ARG(thread);
struct ospf_interface *oi;
- struct ospf_interface *last_serviced_oi = NULL;
struct ospf_packet *op;
struct sockaddr_in sa_dst;
struct ip iph;
@@ -664,13 +663,7 @@ static void ospf_write(struct thread *thread)
ipid = (time(NULL) & 0xffff);
#endif /* WANT_OSPF_WRITE_FRAGMENT */
- while ((pkt_count < ospf->write_oi_count) && oi
- && (last_serviced_oi != oi)) {
- /* If there is only packet in the queue, the oi is removed from
- write-q, so fix up the last interface that was serviced */
- if (last_serviced_oi == NULL) {
- last_serviced_oi = oi;
- }
+ while ((pkt_count < ospf->write_oi_count) && oi) {
pkt_count++;
#ifdef WANT_OSPF_WRITE_FRAGMENT
/* convenience - max OSPF data per packet */
@@ -853,11 +846,9 @@ static void ospf_write(struct thread *thread)
list_delete_node(ospf->oi_write_q, node);
if (ospf_fifo_head(oi->obuf) == NULL) {
oi->on_write_q = 0;
- last_serviced_oi = NULL;
oi = NULL;
- } else {
+ } else
listnode_add(ospf->oi_write_q, oi);
- }
/* Setup to service from the head of the queue again */
if (!list_isempty(ospf->oi_write_q)) {
@@ -3358,49 +3349,44 @@ static int ospf_make_hello(struct ospf_interface *oi, struct stream *s)
stream_put_ipv4(s, BDR(oi).s_addr);
/* Add neighbor seen. */
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
- if ((nbr = rn->info))
- if (nbr->router_id.s_addr
- != INADDR_ANY) /* Ignore 0.0.0.0 node. */
- if (nbr->state
- != NSM_Attempt) /* Ignore Down neighbor. */
- if (nbr->state
- != NSM_Down) /* This is myself for
- DR election. */
- if (!IPV4_ADDR_SAME(
- &nbr->router_id,
- &oi->ospf->router_id)) {
- /* Check neighbor is
- * sane? */
- if (nbr->d_router.s_addr
- != INADDR_ANY
- && IPV4_ADDR_SAME(
- &nbr->d_router,
- &oi->address
- ->u
- .prefix4)
- && IPV4_ADDR_SAME(
- &nbr->bd_router,
- &oi->address
- ->u
- .prefix4))
- flag = 1;
-
- /* Hello packet overflows interface MTU. */
- if (length + sizeof(uint32_t)
- > ospf_packet_max(oi)) {
- flog_err(
- EC_OSPF_LARGE_HELLO,
- "Oversized Hello packet! Larger than MTU. Not sending it out");
- return 0;
- }
-
- stream_put_ipv4(
- s,
- nbr->router_id
- .s_addr);
- length += 4;
- }
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+
+ /* Ignore the 0.0.0.0 node */
+ if (nbr->router_id.s_addr == INADDR_ANY)
+ continue;
+
+ /* Ignore Down neighbor */
+ if (nbr->state == NSM_Attempt)
+ continue;
+
+ /* This is myself for DR election */
+ if (nbr->state == NSM_Down)
+ continue;
+
+ if (IPV4_ADDR_SAME(&nbr->router_id, &oi->ospf->router_id))
+ continue;
+ /* Check neighbor is sane? */
+ if (nbr->d_router.s_addr != INADDR_ANY &&
+ IPV4_ADDR_SAME(&nbr->d_router, &oi->address->u.prefix4) &&
+ IPV4_ADDR_SAME(&nbr->bd_router, &oi->address->u.prefix4))
+ flag = 1;
+
+ /* Hello packet overflows interface MTU.
+ */
+ if (length + sizeof(uint32_t) > ospf_packet_max(oi)) {
+ flog_err(
+ EC_OSPF_LARGE_HELLO,
+ "Oversized Hello packet! Larger than MTU. Not sending it out");
+ return 0;
+ }
+
+ stream_put_ipv4(s, nbr->router_id.s_addr);
+ length += 4;
+ }
/* Let neighbor generate BackupSeen. */
if (flag == 1)
@@ -3781,54 +3767,44 @@ void ospf_hello_send(struct ospf_interface *oi)
struct ospf_neighbor *nbr;
struct route_node *rn;
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
- if ((nbr = rn->info))
- if (nbr != oi->nbr_self)
- if (nbr->state != NSM_Down) {
- /* RFC 2328 Section 9.5.1
- If the router is not
- eligible to become Designated
- Router,
- it must periodically send
- Hello Packets to both the
- Designated Router and the
- Backup Designated Router (if
- they
- exist). */
- if (PRIORITY(oi) == 0
- && IPV4_ADDR_CMP(
- &DR(oi),
- &nbr->address.u
- .prefix4)
- && IPV4_ADDR_CMP(
- &BDR(oi),
- &nbr->address.u
- .prefix4))
- continue;
-
- /* If the router is eligible to
- become Designated Router, it
- must periodically send Hello
- Packets to all neighbors that
- are also eligible. In
- addition, if the router is
- itself the
- Designated Router or Backup
- Designated Router, it must
- also
- send periodic Hello Packets
- to all other neighbors. */
-
- if (nbr->priority == 0
- && oi->state == ISM_DROther)
- continue;
- /* if oi->state == Waiting, send
- * hello to all neighbors */
- ospf_hello_send_sub(
- oi,
- nbr->address.u.prefix4
- .s_addr);
- }
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
+ if (!nbr)
+ continue;
+
+ if (nbr == oi->nbr_self)
+ continue;
+
+ if (nbr->state == NSM_Down)
+ continue;
+
+ /*
+ * RFC 2328 Section 9.5.1
+ * If the router is not eligible to become Designated
+ * Router, it must periodically send Hello Packets to
+ * both the Designated Router and the Backup
+ * Designated Router (if they exist).
+ */
+ if (PRIORITY(oi) == 0 &&
+ IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
+ IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
+ continue;
+
+ /*
+ * If the router is eligible to become Designated
+ * Router, it must periodically send Hello Packets to
+ * all neighbors that are also eligible. In addition,
+ * if the router is itself the Designated Router or
+ * Backup Designated Router, it must also send periodic
+ * Hello Packets to all other neighbors.
+ */
+ if (nbr->priority == 0 && oi->state == ISM_DROther)
+ continue;
+
+ /* if oi->state == Waiting, send
+ * hello to all neighbors */
+ ospf_hello_send_sub(oi, nbr->address.u.prefix4.s_addr);
+ }
} else {
/* Decide destination address. */
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
@@ -4300,14 +4276,18 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi)
struct ospf_neighbor *nbr;
struct route_node *rn;
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
- if ((nbr = rn->info) != NULL)
- if (nbr != oi->nbr_self
- && nbr->state >= NSM_Exchange)
- while (listcount(oi->ls_ack))
- ospf_ls_ack_send_list(
- oi, oi->ls_ack,
- nbr->address.u.prefix4);
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+
+ if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
+ while (listcount(oi->ls_ack))
+ ospf_ls_ack_send_list(
+ oi, oi->ls_ack,
+ nbr->address.u.prefix4);
+ }
return;
}
if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
index 2c7c80686c..3a71e55710 100644
--- a/ospfd/ospf_sr.c
+++ b/ospfd/ospf_sr.c
@@ -756,13 +756,14 @@ static struct ospf_neighbor *get_neighbor_by_addr(struct ospf *top,
for (ALL_LIST_ELEMENTS_RO(top->oiflist, node, oi))
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
nbr = rn->info;
- if (nbr)
- if (IPV4_ADDR_SAME(&nbr->address.u.prefix4,
- &addr)
- || IPV4_ADDR_SAME(&nbr->router_id, &addr)) {
- route_unlock_node(rn);
- return nbr;
- }
+ if (!nbr)
+ continue;
+
+ if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &addr) ||
+ IPV4_ADDR_SAME(&nbr->router_id, &addr)) {
+ route_unlock_node(rn);
+ return nbr;
+ }
}
return NULL;
}
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 1c22fad669..a6572794aa 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -4008,13 +4008,15 @@ static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
oi->ls_ack_in);
json_object_int_add(json_interface_sub, "lsAckOut",
oi->ls_ack_out);
+ json_object_int_add(json_interface_sub, "packetsQueued",
+ listcount(oi->obuf));
} else {
vty_out(vty,
- "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
+ "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %12lu\n",
oi->ifp->name, oi->hello_in, oi->hello_out,
oi->db_desc_in, oi->db_desc_out, oi->ls_req_in,
oi->ls_req_out, oi->ls_upd_in, oi->ls_upd_out,
- oi->ls_ack_in, oi->ls_ack_out);
+ oi->ls_ack_in, oi->ls_ack_out, listcount(oi->obuf));
}
}
@@ -4030,14 +4032,14 @@ static int show_ip_ospf_interface_traffic_common(
if (!use_json && !display_once) {
vty_out(vty, "\n");
- vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n", "Interface",
- " HELLO", " DB-Desc", " LS-Req", " LS-Update",
- " LS-Ack");
- vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
+ vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s\n",
+ "Interface", " HELLO", " DB-Desc", " LS-Req",
+ " LS-Update", " LS-Ack", " Packets");
+ vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s%-17s\n", "",
" Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
- " Rx/Tx");
+ " Rx/Tx", " Queued");
vty_out(vty,
- "--------------------------------------------------------------------------------------------\n");
+ "-------------------------------------------------------------------------------------------------------------\n");
} else if (use_json) {
if (use_vrf)
json_vrf = json_object_new_object();
@@ -4476,19 +4478,22 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
struct ospf_neighbor *nbr, *prev_nbr = NULL;
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
- if ((nbr = rn->info)) {
- /* Do not show myself. */
- if (nbr == oi->nbr_self)
- continue;
- /* Down state is not shown. */
- if (nbr->state == NSM_Down)
- continue;
+ nbr = rn->info;
- prev_nbr = nbr;
+ if (!nbr)
+ continue;
- show_ip_ospf_neighbour_brief(vty, nbr, prev_nbr, json,
- use_json);
- }
+ /* Do not show myself. */
+ if (nbr == oi->nbr_self)
+ continue;
+ /* Down state is not shown. */
+ if (nbr->state == NSM_Down)
+ continue;
+
+ prev_nbr = nbr;
+
+ show_ip_ospf_neighbour_brief(vty, nbr, prev_nbr, json,
+ use_json);
}
}
@@ -5402,14 +5407,17 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
ospf_show_vrf_name(ospf, vty, json, use_vrf);
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
- if ((nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id))) {
- if (is_detail)
- show_ip_ospf_neighbor_detail_sub(
- vty, oi, nbr, NULL, json, use_json);
- else
- show_ip_ospf_neighbour_brief(vty, nbr, NULL,
- json, use_json);
- }
+ nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, router_id);
+
+ if (!nbr)
+ continue;
+
+ if (is_detail)
+ show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, NULL,
+ json, use_json);
+ else
+ show_ip_ospf_neighbour_brief(vty, nbr, NULL, json,
+ use_json);
}
if (use_json)
@@ -5498,16 +5506,19 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
struct ospf_neighbor *nbr, *prev_nbr = NULL;
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
- if ((nbr = rn->info)) {
- if (nbr != oi->nbr_self) {
- if (nbr->state != NSM_Down) {
- show_ip_ospf_neighbor_detail_sub(
- vty, oi, nbr, prev_nbr,
- json_nbr_sub, use_json);
- }
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+
+ if (nbr != oi->nbr_self) {
+ if (nbr->state != NSM_Down) {
+ show_ip_ospf_neighbor_detail_sub(
+ vty, oi, nbr, prev_nbr,
+ json_nbr_sub, use_json);
}
- prev_nbr = nbr;
}
+ prev_nbr = nbr;
}
}
@@ -5668,27 +5679,29 @@ static int show_ip_ospf_neighbor_detail_all_common(struct vty *vty,
struct ospf_nbr_nbma *nbr_nbma;
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
- if ((nbr = rn->info)) {
- if (nbr != oi->nbr_self)
- if (nbr->state != NSM_Down)
- show_ip_ospf_neighbor_detail_sub(
- vty, oi, rn->info,
- prev_nbr,
- json_vrf, use_json);
- prev_nbr = nbr;
- }
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+
+ if (nbr != oi->nbr_self)
+ if (nbr->state != NSM_Down)
+ show_ip_ospf_neighbor_detail_sub(
+ vty, oi, rn->info, prev_nbr,
+ json_vrf, use_json);
+ prev_nbr = nbr;
}
- if (oi->type == OSPF_IFTYPE_NBMA) {
- struct listnode *nd;
+ if (oi->type != OSPF_IFTYPE_NBMA)
+ continue;
- for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nd, nbr_nbma)) {
- if (nbr_nbma->nbr == NULL
- || nbr_nbma->nbr->state == NSM_Down)
- show_ip_ospf_nbr_nbma_detail_sub(
- vty, oi, nbr_nbma, use_json,
- json_vrf);
- }
+ struct listnode *nd;
+
+ for (ALL_LIST_ELEMENTS_RO(oi->nbr_nbma, nd, nbr_nbma)) {
+ if (nbr_nbma->nbr == NULL ||
+ nbr_nbma->nbr->state == NSM_Down)
+ show_ip_ospf_nbr_nbma_detail_sub(
+ vty, oi, nbr_nbma, use_json, json_vrf);
}
}
@@ -5853,19 +5866,25 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
}
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
- if ((oi = rn->info)) {
- for (nrn = route_top(oi->nbrs); nrn;
- nrn = route_next(nrn)) {
- if ((nbr = nrn->info)) {
- if (nbr != oi->nbr_self) {
- if (nbr->state != NSM_Down)
- show_ip_ospf_neighbor_detail_sub(
- vty, oi, nbr,
- NULL,
- json, use_json);
- }
- }
- }
+ oi = rn->info;
+
+ if (!oi)
+ continue;
+
+ for (nrn = route_top(oi->nbrs); nrn; nrn = route_next(nrn)) {
+ nbr = nrn->info;
+
+ if (!nbr)
+ continue;
+
+ if (nbr == oi->nbr_self)
+ continue;
+
+ if (nbr->state == NSM_Down)
+ continue;
+
+ show_ip_ospf_neighbor_detail_sub(vty, oi, nbr, NULL,
+ json, use_json);
}
}
@@ -8019,13 +8038,17 @@ static void ospf_nbr_timer_update(struct ospf_interface *oi)
struct route_node *rn;
struct ospf_neighbor *nbr;
- for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
- if ((nbr = rn->info)) {
- nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait);
- nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval);
- nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval);
- nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval);
- }
+ for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+ nbr = rn->info;
+
+ if (!nbr)
+ continue;
+
+ nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait);
+ nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval);
+ nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval);
+ nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval);
+ }
}
static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str,
diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c
index b72a536ef4..a1c56f93ad 100644
--- a/pathd/path_pcep_pcc.c
+++ b/pathd/path_pcep_pcc.c
@@ -1326,9 +1326,9 @@ void handle_pcep_lsp_initiate(struct ctrl_state *ctrl_state,
* possibly disconnect and blacklist */
flog_warn(EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE,
"Unsupported PCEP protocol feature: %s", err);
- pcep_free_path(path);
send_pcep_error(pcc_state, PCEP_ERRT_INVALID_OPERATION,
PCEP_ERRV_LSP_NOT_PCE_INITIATED, path);
+ pcep_free_path(path);
}
}
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index d68bcfa160..a2b3431b94 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -137,6 +137,9 @@ DEFPY(pbr_map_match_src, pbr_map_match_src_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (pbrms->dst && pbrms->family && prefix->family != pbrms->family) {
vty_out(vty, "Cannot mismatch families within match src/dst\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -170,6 +173,9 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (pbrms->src && pbrms->family && prefix->family != pbrms->family) {
vty_out(vty, "Cannot mismatch families within match src/dst\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -204,6 +210,9 @@ DEFPY(pbr_map_match_ip_proto, pbr_map_match_ip_proto_cmd,
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
struct protoent *p;
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no) {
p = getprotobyname(ip_proto);
if (!p) {
@@ -228,6 +237,9 @@ DEFPY(pbr_map_match_src_port, pbr_map_match_src_port_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no) {
if (pbrms->src_prt == port)
return CMD_SUCCESS;
@@ -250,6 +262,9 @@ DEFPY(pbr_map_match_dst_port, pbr_map_match_dst_port_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no) {
if (pbrms->dst_prt == port)
return CMD_SUCCESS;
@@ -274,6 +289,9 @@ DEFPY(pbr_map_match_dscp, pbr_map_match_dscp_cmd,
char dscpname[100];
uint8_t rawDscp;
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
/* Discriminate dscp enums (cs0, cs1 etc.) and numbers */
bool isANumber = true;
for (int i = 0; i < (int)strlen(dscp); i++) {
@@ -333,6 +351,9 @@ DEFPY(pbr_map_match_ecn, pbr_map_match_ecn_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no) {
if ((pbrms->dsfield & PBR_DSFIELD_ECN) == ecn)
return CMD_SUCCESS;
@@ -357,6 +378,9 @@ DEFPY(pbr_map_match_mark, pbr_map_match_mark_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
#ifndef GNU_LINUX
vty_out(vty, "pbr marks are not supported on this platform\n");
return CMD_WARNING_CONFIG_FAILED;
@@ -417,6 +441,9 @@ DEFPY(pbr_map_action_queue_id, pbr_map_action_queue_id_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no)
pbrms->action_queue_id = queue_id;
else if ((uint32_t)queue_id == pbrms->action_queue_id)
@@ -435,6 +462,9 @@ DEFPY(pbr_map_action_pcp, pbr_map_action_pcp_cmd, "[no] set pcp <(0-7)$pcp>",
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no)
pbrms->action_pcp = pcp;
else if (pcp == pbrms->action_pcp)
@@ -454,6 +484,9 @@ DEFPY(pbr_map_action_vlan_id, pbr_map_action_vlan_id_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no)
pbrms->action_vlan_id = vlan_id;
else if (pbrms->action_vlan_id == vlan_id)
@@ -472,6 +505,9 @@ DEFPY(pbr_map_action_strip_vlan, pbr_map_action_strip_vlan_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (!no)
pbrms->action_vlan_flags = PBR_MAP_STRIP_INNER_ANY;
else
@@ -492,6 +528,9 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
struct nexthop_group_cmd *nhgc;
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
nhgc = nhgc_find(name);
if (!nhgc) {
vty_out(vty, "Specified nexthop-group %s does not exist\n",
@@ -522,6 +561,9 @@ DEFPY(no_pbr_map_nexthop_group, no_pbr_map_nexthop_group_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
pbrms_clear_set_config(pbrms);
return CMD_SUCCESS;
@@ -548,6 +590,9 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd,
struct nexthop nhop;
struct nexthop *nh = NULL;
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (vrf_name)
vrf = vrf_lookup_by_name(vrf_name);
else
@@ -670,6 +715,9 @@ DEFPY(no_pbr_map_nexthop, no_pbr_map_nexthop_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
pbrms_clear_set_config(pbrms);
return CMD_SUCCESS;
@@ -684,6 +732,9 @@ DEFPY(pbr_map_vrf, pbr_map_vrf_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
/*
* If an equivalent set vrf * exists, just return success.
*/
@@ -722,6 +773,9 @@ DEFPY(no_pbr_map_vrf, no_pbr_map_vrf_cmd,
{
struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
+ if (!pbrms)
+ return CMD_WARNING_CONFIG_FAILED;
+
pbrms_clear_set_config(pbrms);
return CMD_SUCCESS;
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index 01c5745426..dc84de6bfd 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -1516,6 +1516,37 @@ DEFPY (debug_pimv6_zebra,
return CMD_SUCCESS;
}
+DEFPY (debug_mroute6,
+ debug_mroute6_cmd,
+ "[no] debug mroute6",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MROUTE6_STR)
+{
+ if (!no)
+ PIM_DO_DEBUG_MROUTE;
+ else
+ PIM_DONT_DEBUG_MROUTE;
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (debug_mroute6_detail,
+ debug_mroute6_detail_cmd,
+ "[no] debug mroute6 detail",
+ NO_STR
+ DEBUG_STR
+ DEBUG_MROUTE6_STR
+ "detailed\n")
+{
+ if (!no)
+ PIM_DO_DEBUG_MROUTE_DETAIL;
+ else
+ PIM_DONT_DEBUG_MROUTE_DETAIL;
+
+ return CMD_SUCCESS;
+}
+
DEFUN_NOSH (show_debugging_pimv6,
show_debugging_pimv6_cmd,
"show debugging [pimv6]",
@@ -1660,6 +1691,8 @@ void pim_cmd_init(void)
install_element(ENABLE_NODE, &debug_pimv6_trace_cmd);
install_element(ENABLE_NODE, &debug_pimv6_trace_detail_cmd);
install_element(ENABLE_NODE, &debug_pimv6_zebra_cmd);
+ install_element(ENABLE_NODE, &debug_mroute6_cmd);
+ install_element(ENABLE_NODE, &debug_mroute6_detail_cmd);
install_element(CONFIG_NODE, &debug_pimv6_cmd);
install_element(CONFIG_NODE, &debug_pimv6_nht_cmd);
@@ -1671,4 +1704,6 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &debug_pimv6_trace_cmd);
install_element(CONFIG_NODE, &debug_pimv6_trace_detail_cmd);
install_element(CONFIG_NODE, &debug_pimv6_zebra_cmd);
+ install_element(CONFIG_NODE, &debug_mroute6_cmd);
+ install_element(CONFIG_NODE, &debug_mroute6_detail_cmd);
}
diff --git a/pimd/pim6_cmd.h b/pimd/pim6_cmd.h
index 8fb82d9f26..c45c998453 100644
--- a/pimd/pim6_cmd.h
+++ b/pimd/pim6_cmd.h
@@ -57,6 +57,7 @@
#define DEBUG_PIMV6_PACKETDUMP_RECV_STR "Dump received packets\n"
#define DEBUG_PIMV6_TRACE_STR "PIMv6 internal daemon activity\n"
#define DEBUG_PIMV6_ZEBRA_STR "ZEBRA protocol activity\n"
+#define DEBUG_MROUTE6_STR "PIMv6 interaction with kernel MFC cache\n"
void pim_cmd_init(void);
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index 2f0743b570..2f2ff24675 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -36,6 +36,7 @@ typedef struct in_addr pim_addr;
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
#define PIM_AF_NAME "ip"
#define PIM_AF_DBG "pim"
+#define PIM_MROUTE_DBG "mroute"
#define PIMREG "pimreg"
#define PIM_ADDR_FUNCNAME(name) ipv4_##name
@@ -61,6 +62,7 @@ typedef struct in6_addr pim_addr;
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
#define PIM_AF_NAME "ipv6"
#define PIM_AF_DBG "pimv6"
+#define PIM_MROUTE_DBG "mroute6"
#define PIMREG "pim6reg"
#define PIM_ADDR_FUNCNAME(name) ipv6_##name
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index a3188128fa..c2453efa06 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -5526,12 +5526,13 @@ DEFUN (show_ip_msdp_mesh_group,
int idx = 2;
struct pim_msdp_mg *mg;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
- struct pim_instance *pim = vrf->info;
+ struct pim_instance *pim;
struct json_object *json = NULL;
if (!vrf)
return CMD_WARNING;
+ pim = vrf->info;
/* Quick case: list is empty. */
if (SLIST_EMPTY(&pim->msdp.mglist)) {
if (uj)
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index 45726b4e56..1d3f5f430a 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -3285,13 +3285,22 @@ void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
json_object *json)
{
struct interface *ifp;
+ struct ttable *tt = NULL;
+ char *table = NULL;
json_object *json_row = NULL;
vty_out(vty, "\n");
- if (!json)
- vty_out(vty,
- "Interface Address ifi Vif PktsIn PktsOut BytesIn BytesOut\n");
+ if (!json) {
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt,
+ "Interface|Address|ifi|Vif|PktsIn|PktsOut|BytesIn|BytesOut");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
+ }
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
@@ -3347,16 +3356,22 @@ void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
(unsigned long)vreq.obytes);
json_object_object_add(json, ifp->name, json_row);
} else {
- vty_out(vty,
- "%-16s %-15pPAs %3d %3d %7lu %7lu %10lu %10lu\n",
- ifp->name, &pim_ifp->primary_address,
- ifp->ifindex, pim_ifp->mroute_vif_index,
- (unsigned long)vreq.icount,
- (unsigned long)vreq.ocount,
- (unsigned long)vreq.ibytes,
- (unsigned long)vreq.obytes);
+ ttable_add_row(tt, "%s|%pPAs|%d|%d|%lu|%lu|%lu|%lu",
+ ifp->name, &pim_ifp->primary_address,
+ ifp->ifindex, pim_ifp->mroute_vif_index,
+ (unsigned long)vreq.icount,
+ (unsigned long)vreq.ocount,
+ (unsigned long)vreq.ibytes,
+ (unsigned long)vreq.obytes);
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty)
@@ -3412,6 +3427,8 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
struct listnode *node;
struct channel_oil *c_oil;
struct static_route *s_route;
+ struct ttable *tt = NULL;
+ char *table = NULL;
time_t now;
json_object *json_group = NULL;
json_object *json_source = NULL;
@@ -3434,8 +3451,14 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n");
vty_out(vty,
" R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n");
- vty_out(vty,
- "\nSource Group Flags Proto Input Output TTL Uptime\n");
+
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(
+ tt, "Source|Group|Flags|Proto|Input|Output|TTL|Uptime");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
now = pim_time_monotonic_sec();
@@ -3639,11 +3662,10 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
strlcpy(proto, "STAR", sizeof(proto));
}
- vty_out(vty,
- "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
- src_str, grp_str, state_str, proto,
- in_ifname, out_ifname, ttl,
- mroute_uptime);
+ ttable_add_row(tt, "%s|%s|%s|%s|%s|%s|%d|%s",
+ src_str, grp_str, state_str,
+ proto, in_ifname, out_ifname,
+ ttl, mroute_uptime);
if (first) {
src_str[0] = '\0';
@@ -3657,11 +3679,10 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
}
if (!json && !found_oif) {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
- oil_origin(c_oil), oil_mcastgrp(c_oil),
- state_str, "none", in_ifname, "none", 0,
- "--:--:--");
+ ttable_add_row(tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
+ oil_origin(c_oil), oil_mcastgrp(c_oil),
+ state_str, "none", in_ifname, "none", 0,
+ "--:--:--");
}
}
@@ -3765,8 +3786,8 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
json_object_object_add(json_oil, out_ifname,
json_ifp_out);
} else {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
+ ttable_add_row(
+ tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
&s_route->source, &s_route->group, "-",
proto, in_ifname, out_ifname, ttl,
oif_uptime);
@@ -3780,17 +3801,24 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
}
if (!json && !found_oif) {
- vty_out(vty,
- "%-15pPAs %-15pPAs %-8s %-6s %-16s %-16s %-3d %8s\n",
- &s_route->source, &s_route->group, "-", proto,
- in_ifname, "none", 0, "--:--:--");
+ ttable_add_row(tt, "%pPAs|%pPAs|%s|%s|%s|%s|%d|%s",
+ &s_route->source, &s_route->group, "-",
+ proto, in_ifname, "none", 0, "--:--:--");
}
}
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
json_object *json,
- struct vty *vty)
+ struct vty *vty,
+ struct ttable *tt)
{
json_object *json_group = NULL;
json_object *json_source = NULL;
@@ -3825,12 +3853,12 @@ static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil,
json_object_int_add(json_source, "wrongIf", c_oil->cc.wrong_if);
} else {
- vty_out(vty, "%-15pPAs %-15pPAs %-8llu %-7ld %-10ld %-7ld\n",
- oil_origin(c_oil), oil_mcastgrp(c_oil),
- c_oil->cc.lastused / 100,
- c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
- c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
- c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
+ ttable_add_row(tt, "%pPAs|%pPAs|%llu|%ld|%ld|%ld",
+ oil_origin(c_oil), oil_mcastgrp(c_oil),
+ c_oil->cc.lastused / 100,
+ c_oil->cc.pktcnt - c_oil->cc.origpktcnt,
+ c_oil->cc.bytecnt - c_oil->cc.origbytecnt,
+ c_oil->cc.wrong_if - c_oil->cc.origwrong_if);
}
}
@@ -3840,20 +3868,35 @@ void show_mroute_count(struct pim_instance *pim, struct vty *vty,
struct listnode *node;
struct channel_oil *c_oil;
struct static_route *sr;
+ struct ttable *tt = NULL;
+ char *table = NULL;
if (!json) {
vty_out(vty, "\n");
- vty_out(vty,
- "Source Group LastUsed Packets Bytes WrongIf \n");
+ /* Prepare table. */
+ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
+ ttable_add_row(tt,
+ "Source|Group|LastUsed|Packets|Bytes|WrongIf");
+ tt->style.cell.rpad = 2;
+ tt->style.corner = '+';
+ ttable_restyle(tt);
}
/* Print PIM and IGMP route counts */
frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil)
- show_mroute_count_per_channel_oil(c_oil, json, vty);
+ show_mroute_count_per_channel_oil(c_oil, json, vty, tt);
for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr))
- show_mroute_count_per_channel_oil(&sr->c_oil, json, vty);
+ show_mroute_count_per_channel_oil(&sr->c_oil, json, vty, tt);
+
+ /* Dump the generated table. */
+ if (!json) {
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP, table);
+ ttable_del(tt);
+ }
}
void show_mroute_summary(struct pim_instance *pim, struct vty *vty,
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index ac2eee0a30..ce252366ce 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -539,10 +539,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_sgaddr *sg,
if (up_flags == PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
PIM_IF_FLAG_SET_PROTO_IGMP(ch->flags);
- if (ch->upstream)
- ch->upstream->flags |= up_flags;
- else if (PIM_DEBUG_EVENTS)
- zlog_debug("%s:%pSG No Upstream found", __func__, sg);
+ ch->upstream->flags |= up_flags;
return ch;
}
@@ -637,8 +634,7 @@ static void ifjoin_to_noinfo(struct pim_ifchannel *ch)
pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO);
pim_forward_stop(ch);
- if (ch->upstream)
- PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags);
+ PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags);
PIM_IF_FLAG_UNSET_PROTO_PIM(ch->flags);
@@ -696,31 +692,29 @@ static void on_ifjoin_prune_pending_timer(struct thread *t)
* message on RP path upon prune timer expiry.
*/
ch->ifjoin_state = PIM_IFJOIN_PRUNE;
- if (ch->upstream) {
- struct pim_upstream *parent =
- ch->upstream->parent;
+ struct pim_upstream *parent =
+ ch->upstream->parent;
- pim_upstream_update_join_desired(pim_ifp->pim,
- ch->upstream);
+ pim_upstream_update_join_desired(pim_ifp->pim,
+ ch->upstream);
- pim_jp_agg_single_upstream_send(&parent->rpf,
- parent, true);
- /*
- * SGRpt prune pending expiry has to install
- * SG entry with empty olist to drop the SG
- * traffic incase no other intf exists.
- * On that scenario, SG entry wouldn't have
- * got installed until Prune pending timer
- * expired. So install now.
- */
- pim_channel_del_oif(
- ch->upstream->channel_oil, ifp,
- PIM_OIF_FLAG_PROTO_STAR, __func__);
- if (!ch->upstream->channel_oil->installed)
- pim_upstream_mroute_add(
- ch->upstream->channel_oil,
- __func__);
- }
+ pim_jp_agg_single_upstream_send(&parent->rpf,
+ parent, true);
+ /*
+ * SGRpt prune pending expiry has to install
+ * SG entry with empty olist to drop the SG
+ * traffic incase no other intf exists.
+ * On that scenario, SG entry wouldn't have
+ * got installed until Prune pending timer
+ * expired. So install now.
+ */
+ pim_channel_del_oif(
+ ch->upstream->channel_oil, ifp,
+ PIM_OIF_FLAG_PROTO_STAR, __func__);
+ if (!ch->upstream->channel_oil->installed)
+ pim_upstream_mroute_add(
+ ch->upstream->channel_oil,
+ __func__);
}
/* from here ch may have been deleted */
}
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 25e7e52705..0742daa4de 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1061,15 +1061,13 @@ struct pim_upstream *pim_upstream_add(struct pim_instance *pim, pim_sgaddr *sg,
}
if (PIM_DEBUG_PIM_TRACE) {
- if (up)
- zlog_debug("%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d",
- __func__, name,
- up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ?
- up->rpf.source_nexthop.interface->name : "Unknown" ,
- found, up->ref_count);
- else
- zlog_debug("%s(%s): (%pSG) failure to create", __func__,
- name, sg);
+ zlog_debug(
+ "%s(%s): %s, iif %pPA (%s) found: %d: ref_count: %d",
+ __func__, name, up->sg_str, &up->rpf.rpf_addr,
+ up->rpf.source_nexthop.interface ? up->rpf.source_nexthop
+ .interface->name
+ : "Unknown",
+ found, up->ref_count);
}
return up;
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index f9642b2133..3d5d68b1f4 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -78,11 +78,11 @@ int pim_debug_config_write(struct vty *vty)
/* PIM_DEBUG_MROUTE catches _DETAIL too */
if (router->debugs & PIM_MASK_MROUTE) {
- vty_out(vty, "debug mroute\n");
+ vty_out(vty, "debug " PIM_MROUTE_DBG "\n");
++writes;
}
if (PIM_DEBUG_MROUTE_DETAIL) {
- vty_out(vty, "debug mroute detail\n");
+ vty_out(vty, "debug " PIM_MROUTE_DBG " detail\n");
++writes;
}
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index c94785ec01..962541405f 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -409,9 +409,6 @@ routing state through standard SNMP MIBs.
--disable-bgp-vnc \
%endif
--enable-isisd \
-%if "%{initsystem}" == "systemd"
- --enable-systemd \
-%endif
--enable-rpki \
%if %{with_bfdd}
--enable-bfdd \
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c
index 9ccffe53d9..5a7044e9f9 100644
--- a/staticd/static_nb_config.c
+++ b/staticd/static_nb_config.c
@@ -263,6 +263,7 @@ nexthop_mpls_label_stack_entry_destroy(struct nb_cb_destroy_args *args)
struct static_nexthop *nh;
uint32_t pos;
uint8_t index;
+ uint old_num_labels;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -278,8 +279,12 @@ nexthop_mpls_label_stack_entry_destroy(struct nb_cb_destroy_args *args)
return NB_ERR;
}
index = pos - 1;
+ old_num_labels = nh->snh_label.num_labels;
nh->snh_label.label[index] = 0;
nh->snh_label.num_labels--;
+
+ if (old_num_labels != nh->snh_label.num_labels)
+ nh->state = STATIC_START;
break;
}
@@ -291,6 +296,7 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
struct static_nexthop *nh;
uint32_t pos;
uint8_t index;
+ mpls_label_t old_label;
nh = nb_running_get_entry(args->dnode, NULL, true);
pos = yang_get_list_pos(lyd_parent(args->dnode));
@@ -301,8 +307,13 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
}
/* Mapping to array = list-index -1 */
index = pos - 1;
+
+ old_label = nh->snh_label.label[index];
nh->snh_label.label[index] = yang_dnode_get_uint32(args->dnode, NULL);
+ if (old_label != nh->snh_label.label[index])
+ nh->state = STATIC_START;
+
return NB_OK;
}
@@ -310,6 +321,7 @@ static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
{
struct static_nexthop *nh;
enum static_nh_type nh_type;
+ bool old_onlink;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -327,7 +339,11 @@ static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
break;
case NB_EV_APPLY:
nh = nb_running_get_entry(args->dnode, NULL, true);
+ old_onlink = nh->onlink;
nh->onlink = yang_dnode_get_bool(args->dnode, NULL);
+
+ if (old_onlink != nh->onlink)
+ nh->state = STATIC_START;
break;
}
@@ -337,20 +353,30 @@ static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
static int static_nexthop_color_modify(struct nb_cb_modify_args *args)
{
struct static_nexthop *nh;
+ uint32_t old_color;
nh = nb_running_get_entry(args->dnode, NULL, true);
+ old_color = nh->color;
nh->color = yang_dnode_get_uint32(args->dnode, NULL);
+ if (old_color != nh->color)
+ nh->state = STATIC_START;
+
return NB_OK;
}
static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args)
{
struct static_nexthop *nh;
+ uint32_t old_color;
nh = nb_running_unset_entry(args->dnode);
+ old_color = nh->color;
nh->color = 0;
+ if (old_color != nh->color)
+ nh->state = STATIC_START;
+
return NB_OK;
}
diff --git a/tests/topotests/bgp_orf/__init__.py b/tests/topotests/bgp_orf/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_orf/__init__.py
diff --git a/tests/topotests/bgp_orf/r1/bgpd.conf b/tests/topotests/bgp_orf/r1/bgpd.conf
new file mode 100644
index 0000000000..800bf1b7ab
--- /dev/null
+++ b/tests/topotests/bgp_orf/r1/bgpd.conf
@@ -0,0 +1,9 @@
+!
+router bgp 65001
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.2 remote-as external
+ address-family ipv4 unicast
+ redistribute connected
+ neighbor 192.168.1.2 capability orf prefix-list both
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_orf/r1/zebra.conf b/tests/topotests/bgp_orf/r1/zebra.conf
new file mode 100644
index 0000000000..85ab53102f
--- /dev/null
+++ b/tests/topotests/bgp_orf/r1/zebra.conf
@@ -0,0 +1,8 @@
+!
+int lo
+ ip address 10.10.10.1/32
+ ip address 10.10.10.2/32
+!
+int r1-eth0
+ ip address 192.168.1.1/24
+!
diff --git a/tests/topotests/bgp_orf/r2/bgpd.conf b/tests/topotests/bgp_orf/r2/bgpd.conf
new file mode 100644
index 0000000000..8c488aa106
--- /dev/null
+++ b/tests/topotests/bgp_orf/r2/bgpd.conf
@@ -0,0 +1,9 @@
+router bgp 65002
+ no bgp ebgp-requires-policy
+ neighbor 192.168.1.1 remote-as external
+ address-family ipv4 unicast
+ neighbor 192.168.1.1 capability orf prefix-list both
+ neighbor 192.168.1.1 prefix-list r1 in
+ exit-address-family
+!
+ip prefix-list r1 seq 5 permit 10.10.10.1/32
diff --git a/tests/topotests/bgp_orf/r2/zebra.conf b/tests/topotests/bgp_orf/r2/zebra.conf
new file mode 100644
index 0000000000..cffe827363
--- /dev/null
+++ b/tests/topotests/bgp_orf/r2/zebra.conf
@@ -0,0 +1,4 @@
+!
+int r2-eth0
+ ip address 192.168.1.2/24
+!
diff --git a/tests/topotests/bgp_orf/test_bgp_orf.py b/tests/topotests/bgp_orf/test_bgp_orf.py
new file mode 100644
index 0000000000..cb74b85b76
--- /dev/null
+++ b/tests/topotests/bgp_orf/test_bgp_orf.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2022 by
+# Donatas Abraitis <donatas@opensourcerouting.org>
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+Test if BGP ORF filtering is working correctly when modifying
+prefix-list.
+
+Initially advertise 10.10.10.1/32 from R1 to R2. Add new prefix
+10.10.10.2/32 to r1 prefix list on R2. Test if we updated ORF
+prefix-list correctly.
+"""
+
+import os
+import sys
+import json
+import pytest
+import functools
+
+pytestmark = pytest.mark.bgpd
+
+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
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def setup_module(mod):
+ topodef = {"s1": ("r1", "r2")}
+ tgen = Topogen(topodef, 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_orf():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r1 = tgen.gears["r1"]
+ r2 = tgen.gears["r2"]
+
+ def _bgp_converge_r1():
+ output = json.loads(
+ r1.vtysh_cmd(
+ "show bgp ipv4 unicast neighbor 192.168.1.2 advertised-routes json"
+ )
+ )
+ expected = {"advertisedRoutes": {"10.10.10.1/32": {}, "10.10.10.2/32": None}}
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge_r1)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Can't apply ORF from R1 to R2"
+
+ def _bgp_converge_r2():
+ output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast summary json"))
+ expected = {
+ "peers": {
+ "192.168.1.1": {
+ "pfxRcd": 1,
+ "pfxSnt": 1,
+ "state": "Established",
+ "peerState": "OK",
+ }
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_converge_r2)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "ORF filtering is not working from R1 to R2"
+
+ r2.vtysh_cmd(
+ """
+ configure terminal
+ ip prefix-list r1 seq 10 permit 10.10.10.2/32
+ """
+ )
+
+ def _bgp_orf_changed_r1():
+ output = json.loads(
+ r1.vtysh_cmd(
+ "show bgp ipv4 unicast neighbor 192.168.1.2 advertised-routes json"
+ )
+ )
+ expected = {"advertisedRoutes": {"10.10.10.1/32": {}, "10.10.10.2/32": {}}}
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_orf_changed_r1)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Can't apply new ORF from R1 to R2"
+
+ def _bgp_orf_changed_r2():
+ output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json"))
+ expected = {
+ "routes": {
+ "10.10.10.1/32": [{"valid": True}],
+ "10.10.10.2/32": [{"valid": True}],
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_bgp_orf_changed_r2)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "New ORF filtering is not working from R1 to R2"
+
+ r2.vtysh_cmd(
+ """
+ configure terminal
+ no ip prefix-list r1 seq 10 permit 10.10.10.2/32
+ """
+ )
+
+ test_func = functools.partial(_bgp_converge_r1)
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Can't apply initial ORF from R1 to R2"
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
index c9824e79c5..d318ec0906 100644
--- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
+++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py
@@ -183,7 +183,7 @@ def test_ospfv3_p2p_tc3_p0(request):
step("Verify that interface is enabled in ospf.")
step("Verify that config is successful.")
dut = "r0"
- input_dict = {"r0": {"links": {"r3": {"ospf6": {"ospf6Enabled": True}}}}}
+ input_dict = {"r0": {"links": {"r3": {"ospf6": {}}}}}
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
@@ -339,7 +339,7 @@ def test_ospfv3_p2p_tc3_p0(request):
assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
step("Verify that interface is enabled in ospf.")
dut = "r0"
- input_dict = {"r0": {"links": {"r3": {"ospf6": {"ospf6Enabled": True}}}}}
+ input_dict = {"r0": {"links": {"r3": {"ospf6": {}}}}}
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
@@ -374,7 +374,7 @@ def test_ospfv3_p2p_tc3_p0(request):
step("Verify that interface is enabled in ospf.")
dut = "r0"
- input_dict = {"r0": {"links": {"r3": {"ospf6": {"ospf6Enabled": True}}}}}
+ input_dict = {"r0": {"links": {"r3": {"ospf6": {}}}}}
result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict)
assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
@@ -1172,7 +1172,6 @@ def test_ospfv3_show_p1(request):
"ospf6": {
"status": "up",
"type": "BROADCAST",
- "ospf6Enabled": True,
"attachedToArea": True,
"instanceId": 0,
"interfaceMtu": 1500,
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 04eb47feeb..ca119eb900 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -78,36 +78,56 @@ int execute_flag = 0;
/* Flag to indicate if in user/unprivileged mode. */
int user_mode;
-/* For sigsetjmp() & siglongjmp(). */
-static sigjmp_buf jmpbuf;
-
-/* Flag for avoid recursive siglongjmp() call. */
-static int jmpflag = 0;
-
/* Master of threads. */
struct thread_master *master;
/* Command logging */
FILE *logfile;
+static void vtysh_rl_callback(char *line_read)
+{
+ HIST_ENTRY *last;
+
+ rl_callback_handler_remove();
+
+ if (!line_read) {
+ vtysh_loop_exited = true;
+ return;
+ }
+
+ /* If the line has any text in it, save it on the history. But only if
+ * last command in history isn't the same one.
+ */
+ if (*line_read) {
+ using_history();
+ last = previous_history();
+ if (!last || strcmp(last->line, line_read) != 0) {
+ add_history(line_read);
+ append_history(1, history_file);
+ }
+ }
+
+ vtysh_execute(line_read);
+
+ if (!vtysh_loop_exited)
+ rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback);
+}
+
/* SIGTSTP handler. This function care user's ^Z input. */
static void sigtstp(int sig)
{
+ rl_callback_handler_remove();
+
/* Execute "end" command. */
vtysh_execute("end");
+ if (!vtysh_loop_exited)
+ rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback);
+
/* Initialize readline. */
rl_initialize();
printf("\n");
-
- /* Check jmpflag for duplicate siglongjmp(). */
- if (!jmpflag)
- return;
-
- jmpflag = 0;
-
- /* Back to main command loop. */
- siglongjmp(jmpbuf, 1);
+ rl_forced_update_display();
}
/* SIGINT handler. This function care user's ^Z input. */
@@ -207,34 +227,6 @@ struct option longopts[] = {
bool vtysh_loop_exited;
-static void vtysh_rl_callback(char *line_read)
-{
- HIST_ENTRY *last;
-
- rl_callback_handler_remove();
-
- if (!line_read) {
- vtysh_loop_exited = true;
- return;
- }
-
- /* If the line has any text in it, save it on the history. But only if
- * last command in history isn't the same one. */
- if (*line_read) {
- using_history();
- last = previous_history();
- if (!last || strcmp(last->line, line_read) != 0) {
- add_history(line_read);
- append_history(1, history_file);
- }
- }
-
- vtysh_execute(line_read);
-
- if (!vtysh_loop_exited)
- rl_callback_handler_install(vtysh_prompt(), vtysh_rl_callback);
-}
-
static struct thread *vtysh_rl_read_thread;
static void vtysh_rl_read(struct thread *thread)
@@ -752,10 +744,6 @@ int main(int argc, char **argv, char **env)
vtysh_add_timestamp = ts_flag;
- /* Preparation for longjmp() in sigtstp(). */
- sigsetjmp(jmpbuf, 1);
- jmpflag = 1;
-
/* Main command loop. */
vtysh_rl_run();
diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c
index fc285c748a..423f25faa2 100644
--- a/watchfrr/watchfrr.c
+++ b/watchfrr/watchfrr.c
@@ -1429,7 +1429,7 @@ int main(int argc, char **argv)
if ((sscanf(optarg, "%ld%1s", &gs.operational_timeout,
garbage) != 1) ||
- (gs.max_restart_interval < 0)) {
+ (gs.operational_timeout < 0)) {
fprintf(stderr,
"Invalid Operational_timeout argument: %s\n",
optarg);
diff --git a/zebra/interface.c b/zebra/interface.c
index b7a984e44d..205fa88293 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -848,10 +848,6 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)
/* Send out notification on interface VRF change. */
/* This is to issue an ADD, if needed. */
zebra_interface_vrf_update_add(ifp, old_vrf_id);
-
- /* Install connected routes (in new VRF). */
- if (if_is_operative(ifp))
- if_install_connected(ifp);
}
static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
diff --git a/zebra/rib.h b/zebra/rib.h
index 60092c9632..a40843e27f 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -454,9 +454,7 @@ int zebra_rib_queue_evpn_rem_vtep_add(vrf_id_t vrf_id, vni_t vni,
int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
struct in_addr vtep_ip);
-extern void meta_queue_free(struct meta_queue *mq);
-extern void rib_meta_queue_free_vrf(struct meta_queue *mq,
- struct zebra_vrf *zvrf);
+extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf);
extern int zebra_rib_labeled_unicast(struct route_entry *re);
extern struct route_table *rib_table_ipv6;
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 9895943016..a578395ef8 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -2492,7 +2492,6 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
{
struct stream *s;
struct zapi_labels zl;
- int ret;
/* Get input stream. */
s = msg;
@@ -2510,12 +2509,7 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
if (zapi_labels_validate(&zl) < 0)
return;
- ret = mpls_zapi_labels_process(true, zvrf, &zl);
- if (ret < 0) {
- if (IS_ZEBRA_DEBUG_RECV)
- zlog_debug("%s: Error processing zapi request",
- __func__);
- }
+ mpls_zapi_labels_process(true, zvrf, &zl);
}
/*
@@ -2532,7 +2526,6 @@ static void zread_mpls_labels_delete(ZAPI_HANDLER_ARGS)
{
struct stream *s;
struct zapi_labels zl;
- int ret;
/* Get input stream. */
s = msg;
@@ -2547,12 +2540,7 @@ static void zread_mpls_labels_delete(ZAPI_HANDLER_ARGS)
return;
if (zl.nexthop_num > 0) {
- ret = mpls_zapi_labels_process(false /*delete*/, zvrf, &zl);
- if (ret < 0) {
- if (IS_ZEBRA_DEBUG_RECV)
- zlog_debug("%s: Error processing zapi request",
- __func__);
- }
+ mpls_zapi_labels_process(false /*delete*/, zvrf, &zl);
} else {
mpls_lsp_uninstall_all_vrf(zvrf, zl.type, zl.local_label);
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 4c7838198e..fd170450f1 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3422,7 +3422,7 @@ static enum zebra_dplane_result
dplane_nexthop_update_internal(struct nhg_hash_entry *nhe, enum dplane_op_e op)
{
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
- int ret = EINVAL;
+ int ret;
struct zebra_dplane_ctx *ctx = NULL;
/* Obtain context block */
@@ -3700,7 +3700,7 @@ dplane_lsp_notif_update(struct zebra_lsp *lsp, enum dplane_op_e op,
struct zebra_dplane_ctx *notif_ctx)
{
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
- int ret = EINVAL;
+ int ret;
struct zebra_dplane_ctx *ctx = NULL;
struct nhlfe_list_head *head;
struct zebra_nhlfe *nhlfe, *new_nhlfe;
@@ -4075,7 +4075,7 @@ static enum zebra_dplane_result
dplane_intf_update_internal(const struct interface *ifp, enum dplane_op_e op)
{
enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
- int ret = EINVAL;
+ int ret;
struct zebra_dplane_ctx *ctx = NULL;
/* Obtain context block */
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index ade381e27f..3010a516b9 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -2747,9 +2747,9 @@ static bool ftn_update_nexthop(bool add_p, struct nexthop *nexthop,
return true;
}
-int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, uint8_t route_type,
- unsigned short route_instance)
+void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, uint8_t route_type,
+ unsigned short route_instance)
{
struct route_table *table;
struct route_node *rn;
@@ -2761,7 +2761,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
/* Lookup table. */
table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
if (!table)
- return -1;
+ return;
/* Lookup existing route */
rn = route_node_get(table, prefix);
@@ -2772,7 +2772,7 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
break;
}
if (re == NULL)
- return -1;
+ return;
/*
* Nexthops are now shared by multiple routes, so we have to make
@@ -2801,8 +2801,6 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
zebra_nhg_free(new_nhe);
rib_queue_add(rn);
-
- return 0;
}
/*
@@ -2884,8 +2882,8 @@ static bool ftn_update_znh(bool add_p, enum lsp_types_t type,
* There are several changes that need to be made, in several zebra
* data structures, so we want to do all the work required at once.
*/
-int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
- const struct zapi_labels *zl)
+void mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
+ const struct zapi_labels *zl)
{
int i, counter, ret = 0;
char buf[NEXTHOP_STRLEN];
@@ -2906,7 +2904,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
/* Lookup table. */
lsp_table = zvrf->lsp_table;
if (!lsp_table)
- return -1;
+ return;
/* Find or create LSP object */
tmp_ile.in_label = zl->local_label;
@@ -3070,8 +3068,6 @@ znh_done:
if (new_nhe)
zebra_nhg_free(new_nhe);
-
- return ret;
}
/*
diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h
index a7a955a80b..a114f01339 100644
--- a/zebra/zebra_mpls.h
+++ b/zebra/zebra_mpls.h
@@ -261,15 +261,15 @@ void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
* Handle zapi request to install/uninstall LSP and
* (optionally) FEC-To-NHLFE (FTN) bindings.
*/
-int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
- const struct zapi_labels *zl);
+void mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
+ const struct zapi_labels *zl);
/*
* Uninstall all NHLFEs bound to a single FEC.
*/
-int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, uint8_t route_type,
- unsigned short route_instance);
+void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, uint8_t route_type,
+ unsigned short route_instance);
/*
* Install/update a NHLFE for an LSP in the forwarding table. This may be
diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c
index 6dde513f40..be089fc759 100644
--- a/zebra/zebra_pw.c
+++ b/zebra/zebra_pw.c
@@ -101,13 +101,15 @@ void zebra_pw_del(struct zebra_vrf *zvrf, struct zebra_pw *pw)
if (pw->status == PW_FORWARDING) {
hook_call(pw_uninstall, pw);
dplane_pw_uninstall(pw);
- } else if (pw->install_retry_timer)
- THREAD_OFF(pw->install_retry_timer);
+ }
+
+ THREAD_OFF(pw->install_retry_timer);
/* unlink and release memory */
RB_REMOVE(zebra_pw_head, &zvrf->pseudowires, pw);
if (pw->protocol == ZEBRA_ROUTE_STATIC)
RB_REMOVE(zebra_static_pw_head, &zvrf->static_pseudowires, pw);
+
XFREE(MTYPE_PW, pw);
}
@@ -230,7 +232,6 @@ static void zebra_pw_install_retry(struct thread *thread)
{
struct zebra_pw *pw = THREAD_ARG(thread);
- pw->install_retry_timer = NULL;
zebra_pw_install(pw);
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d0babbb9e4..79eb99ddf9 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -77,51 +77,65 @@ static struct dplane_ctx_q rib_dplane_q;
DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason),
(rn, reason));
+/* Meta Q's specific names */
+enum meta_queue_indexes {
+ META_QUEUE_NHG,
+ META_QUEUE_EVPN,
+ META_QUEUE_CONNECTED,
+ META_QUEUE_KERNEL,
+ META_QUEUE_STATIC,
+ META_QUEUE_NOTBGP,
+ META_QUEUE_BGP,
+ META_QUEUE_OTHER,
+};
+
/* Each route type's string and default distance value. */
static const struct {
int key;
uint8_t distance;
- uint8_t meta_q_map;
+ enum meta_queue_indexes meta_q_map;
} route_info[ZEBRA_ROUTE_MAX] = {
- [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */, 0},
- [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 7},
- [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 3},
- [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 2},
- [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 4},
- [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 5},
- [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 5},
- [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 5},
- [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 5},
- [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 5},
- [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 6},
- [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 7},
- [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 5},
- [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 5},
- [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 7},
- [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 7},
- [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 4},
- [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 7},
- [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 6},
- [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 6},
- [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 6},
- [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 6},
- [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 6},
- [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 5},
- [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 7},
- [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 7},
- [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 7},
- [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 5},
- [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 7},
- [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 7},
- [ZEBRA_ROUTE_ALL] = {ZEBRA_ROUTE_ALL, 255, 7},
+ [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Unneeded for nhg's */,
+ META_QUEUE_NHG},
+ [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, META_QUEUE_KERNEL},
+ [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, META_QUEUE_KERNEL},
+ [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, META_QUEUE_CONNECTED},
+ [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, META_QUEUE_STATIC},
+ [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, META_QUEUE_STATIC},
+ [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20,
+ META_QUEUE_BGP},
+ [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115,
+ META_QUEUE_NOTBGP},
+ [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, META_QUEUE_OTHER},
+ [ZEBRA_ROUTE_ALL] = {ZEBRA_ROUTE_ALL, 255, META_QUEUE_OTHER},
/* Any new route type added to zebra, should be mirrored here */
/* no entry/default: 150 */
};
-/* EVPN/VXLAN subqueue is number 1 */
-#define META_QUEUE_EVPN 1
-
/* Wrapper struct for nhg workqueue items; a 'ctx' is an incoming update
* from the OS, and an 'nhe' is a nhe update.
*/
@@ -164,24 +178,24 @@ struct wq_evpn_wrapper {
#pragma FRR printfrr_ext "%pZN" (struct route_node *)
#endif
-static const char *subqueue2str(uint8_t index)
+static const char *subqueue2str(enum meta_queue_indexes index)
{
switch (index) {
- case 0:
+ case META_QUEUE_NHG:
return "NHG Objects";
- case 1:
+ case META_QUEUE_EVPN:
return "EVPN/VxLan Objects";
- case 2:
+ case META_QUEUE_CONNECTED:
return "Connected Routes";
- case 3:
+ case META_QUEUE_KERNEL:
return "Kernel Routes";
- case 4:
+ case META_QUEUE_STATIC:
return "Static Routes";
- case 5:
+ case META_QUEUE_NOTBGP:
return "RIP/OSPF/ISIS/EIGRP/NHRP Routes";
- case 6:
+ case META_QUEUE_BGP:
return "BGP Routes";
- case 7:
+ case META_QUEUE_OTHER:
return "Other Routes";
}
@@ -2407,7 +2421,7 @@ static void process_subq_nhg(struct listnode *lnode)
struct nhg_ctx *ctx;
struct nhg_hash_entry *nhe, *newnhe;
struct wq_nhg_wrapper *w;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
w = listgetdata(lnode);
@@ -2496,19 +2510,30 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
* Examine the specified subqueue; process one entry and return 1 if
* there is a node, return 0 otherwise.
*/
-static unsigned int process_subq(struct list *subq, uint8_t qindex)
+static unsigned int process_subq(struct list *subq,
+ enum meta_queue_indexes qindex)
{
struct listnode *lnode = listhead(subq);
if (!lnode)
return 0;
- if (qindex == META_QUEUE_EVPN)
+ switch (qindex) {
+ case META_QUEUE_EVPN:
process_subq_evpn(lnode);
- else if (qindex == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
+ break;
+ case META_QUEUE_NHG:
process_subq_nhg(lnode);
- else
+ break;
+ case META_QUEUE_CONNECTED:
+ case META_QUEUE_KERNEL:
+ case META_QUEUE_STATIC:
+ case META_QUEUE_NOTBGP:
+ case META_QUEUE_BGP:
+ case META_QUEUE_OTHER:
process_subq_route(lnode, qindex);
+ break;
+ }
list_delete_node(subq, lnode);
@@ -2613,7 +2638,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
{
struct nhg_ctx *ctx = NULL;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
ctx = (struct nhg_ctx *)data;
@@ -2639,7 +2664,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
static int rib_meta_queue_nhg_add(struct meta_queue *mq, void *data)
{
struct nhg_hash_entry *nhe = NULL;
- uint8_t qindex = route_info[ZEBRA_ROUTE_NHG].meta_q_map;
+ uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
nhe = (struct nhg_hash_entry *)data;
@@ -2933,131 +2958,130 @@ int zebra_rib_queue_evpn_rem_vtep_del(vrf_id_t vrf_id, vni_t vni,
return mq_add_handler(w, rib_meta_queue_evpn_add);
}
+
+/* Create new meta queue.
+ A destructor function doesn't seem to be necessary here.
+ */
+static struct meta_queue *meta_queue_new(void)
+{
+ struct meta_queue *new;
+ unsigned i;
+
+ new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
+
+ for (i = 0; i < MQ_SIZE; i++) {
+ new->subq[i] = list_new();
+ assert(new->subq[i]);
+ }
+
+ return new;
+}
+
/* Clean up the EVPN meta-queue list */
-static void evpn_meta_queue_free(struct list *l)
+static void evpn_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
- struct listnode *node;
+ struct listnode *node, *nnode;
struct wq_evpn_wrapper *w;
/* Free the node wrapper object, and the struct it wraps */
- while ((node = listhead(l)) != NULL) {
- w = node->data;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
+ if (zvrf) {
+ vrf_id_t vrf_id = zvrf->vrf->vrf_id;
+
+ if (w->vrf_id != vrf_id)
+ continue;
+ }
+
node->data = NULL;
XFREE(MTYPE_WQ_WRAPPER, w);
list_delete_node(l, node);
+ mq->size--;
}
}
/* Clean up the nhg meta-queue list */
-static void nhg_meta_queue_free(struct list *l)
+static void nhg_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
struct wq_nhg_wrapper *w;
- struct listnode *node;
+ struct listnode *node, *nnode;
/* Free the node wrapper object, and the struct it wraps */
- while ((node = listhead(l)) != NULL) {
- w = node->data;
- node->data = NULL;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, w)) {
+ if (zvrf) {
+ vrf_id_t vrf_id = zvrf->vrf->vrf_id;
+ if (w->type == WQ_NHG_WRAPPER_TYPE_CTX &&
+ w->u.ctx->vrf_id != vrf_id)
+ continue;
+ else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG &&
+ w->u.nhe->vrf_id != vrf_id)
+ continue;
+ }
if (w->type == WQ_NHG_WRAPPER_TYPE_CTX)
nhg_ctx_free(&w->u.ctx);
else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG)
zebra_nhg_free(w->u.nhe);
+ node->data = NULL;
XFREE(MTYPE_WQ_WRAPPER, w);
list_delete_node(l, node);
+ mq->size--;
}
}
-/* Create new meta queue.
- A destructor function doesn't seem to be necessary here.
- */
-static struct meta_queue *meta_queue_new(void)
+static void rib_meta_queue_free(struct meta_queue *mq, struct list *l,
+ struct zebra_vrf *zvrf)
{
- struct meta_queue *new;
- unsigned i;
-
- new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
-
- for (i = 0; i < MQ_SIZE; i++) {
- new->subq[i] = list_new();
- assert(new->subq[i]);
- }
+ struct route_node *rnode;
+ struct listnode *node, *nnode;
- return new;
-}
-
-void meta_queue_free(struct meta_queue *mq)
-{
- unsigned i;
+ for (ALL_LIST_ELEMENTS(l, node, nnode, rnode)) {
+ rib_dest_t *dest = rib_dest_from_rnode(rnode);
- for (i = 0; i < MQ_SIZE; i++) {
- /* Some subqueues may need cleanup - nhgs for example */
- if (i == route_info[ZEBRA_ROUTE_NHG].meta_q_map)
- nhg_meta_queue_free(mq->subq[i]);
- else if (i == META_QUEUE_EVPN)
- evpn_meta_queue_free(mq->subq[i]);
+ if (dest && rib_dest_vrf(dest) != zvrf)
+ continue;
- list_delete(&mq->subq[i]);
+ route_unlock_node(rnode);
+ node->data = NULL;
+ list_delete_node(l, node);
+ mq->size--;
}
-
- XFREE(MTYPE_WORK_QUEUE, mq);
}
-void rib_meta_queue_free_vrf(struct meta_queue *mq, struct zebra_vrf *zvrf)
+
+void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
{
- vrf_id_t vrf_id = zvrf->vrf->vrf_id;
- unsigned int i;
+ enum meta_queue_indexes i;
for (i = 0; i < MQ_SIZE; i++) {
- struct listnode *lnode, *nnode;
- void *data;
- bool del;
-
- for (ALL_LIST_ELEMENTS(mq->subq[i], lnode, nnode, data)) {
- del = false;
-
- if (i == META_QUEUE_EVPN) {
- struct wq_evpn_wrapper *w = data;
-
- if (w->vrf_id == vrf_id) {
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- }
- } else if (i ==
- route_info[ZEBRA_ROUTE_NHG].meta_q_map) {
- struct wq_nhg_wrapper *w = data;
-
- if (w->type == WQ_NHG_WRAPPER_TYPE_CTX &&
- w->u.ctx->vrf_id == vrf_id) {
- nhg_ctx_free(&w->u.ctx);
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- } else if (w->type == WQ_NHG_WRAPPER_TYPE_NHG &&
- w->u.nhe->vrf_id == vrf_id) {
- zebra_nhg_free(w->u.nhe);
- XFREE(MTYPE_WQ_WRAPPER, w);
- del = true;
- }
- } else {
- struct route_node *rnode = data;
- rib_dest_t *dest = rib_dest_from_rnode(rnode);
-
- if (dest && rib_dest_vrf(dest) == zvrf) {
- route_unlock_node(rnode);
- del = true;
- }
- }
-
- if (del) {
- list_delete_node(mq->subq[i], lnode);
- mq->size--;
- }
+ /* Some subqueues may need cleanup - nhgs for example */
+ switch (i) {
+ case META_QUEUE_NHG:
+ nhg_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
+ case META_QUEUE_EVPN:
+ evpn_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
+ case META_QUEUE_CONNECTED:
+ case META_QUEUE_KERNEL:
+ case META_QUEUE_STATIC:
+ case META_QUEUE_NOTBGP:
+ case META_QUEUE_BGP:
+ case META_QUEUE_OTHER:
+ rib_meta_queue_free(mq, mq->subq[i], zvrf);
+ break;
}
+ if (!zvrf)
+ list_delete(&mq->subq[i]);
}
+
+ if (!zvrf)
+ XFREE(MTYPE_WORK_QUEUE, mq);
}
/* initialise zebra rib work queue */
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c
index 24e71b4a8b..c66849863e 100644
--- a/zebra/zebra_router.c
+++ b/zebra/zebra_router.c
@@ -239,7 +239,7 @@ void zebra_router_terminate(void)
zebra_router_free_table(zrt);
work_queue_free_and_null(&zrouter.ribq);
- meta_queue_free(zrouter.mq);
+ meta_queue_free(zrouter.mq, NULL);
zebra_vxlan_disable();
zebra_mlag_terminate();
diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c
index 553864d089..6624f0beb9 100644
--- a/zebra/zebra_vrf.c
+++ b/zebra/zebra_vrf.c
@@ -218,7 +218,7 @@ static int zebra_vrf_disable(struct vrf *vrf)
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
/* clean-up work queues */
- rib_meta_queue_free_vrf(zrouter.mq, zvrf);
+ meta_queue_free(zrouter.mq, zvrf);
/* Cleanup (free) routing tables and NHT tables. */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
@@ -253,7 +253,7 @@ static int zebra_vrf_delete(struct vrf *vrf)
table_manager_disable(zvrf);
/* clean-up work queues */
- rib_meta_queue_free_vrf(zrouter.mq, zvrf);
+ meta_queue_free(zrouter.mq, zvrf);
/* Free Vxlan and MPLS. */
zebra_vxlan_close_tables(zvrf);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 49689c6ac4..5a6321ae7e 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -4062,7 +4062,7 @@ int zebra_vxlan_dp_network_mac_add(struct interface *ifp,
}
/* If local MAC on a down local ES translate the network-mac-add
- * to a local-inactive-mac-add
+ * to a local-active-mac-add
*/
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
zlog_debug("dpAdd local-nw-MAC %pEA VID %u", macaddr, vid);