summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn_vty.c27
-rw-r--r--bgpd/bgp_fsm.c73
-rw-r--r--bgpd/bgp_io.c172
-rw-r--r--bgpd/bgp_packet.c21
-rw-r--r--bgpd/bgp_route.c24
-rw-r--r--bgpd/bgp_route.h2
-rw-r--r--bgpd/bgp_updgrp_packet.c2
-rw-r--r--bgpd/bgp_vty.c58
-rw-r--r--bgpd/bgpd.c27
-rw-r--r--bgpd/bgpd.h3
-rw-r--r--doc/user/bgp.rst5
-rw-r--r--isisd/isisd.c6
-rw-r--r--ldpd/neighbor.c3
-rw-r--r--lib/zclient.c5
-rw-r--r--ospf6d/ospf6_area.c12
-rw-r--r--ospf6d/ospf6_asbr.c8
-rw-r--r--ospf6d/ospf6_route.c6
-rw-r--r--ospfd/ospf_flood.c7
-rw-r--r--ospfd/ospf_packet.c3
-rw-r--r--pathd/path_ted.c2
-rw-r--r--pceplib/pcep_msg_messages.c2
-rw-r--r--pceplib/pcep_msg_messages_encoding.c2
-rw-r--r--pceplib/pcep_pcc.c4
-rw-r--r--pceplib/pcep_pcc_api.c14
-rw-r--r--pceplib/pcep_session_logic.c6
-rw-r--r--pceplib/pcep_socket_comm.c6
-rw-r--r--pceplib/pcep_timers.c4
-rw-r--r--pceplib/pcep_utils_double_linked_list.c2
-rw-r--r--pceplib/pcep_utils_logging.c2
-rw-r--r--pceplib/pcep_utils_memory.c4
-rw-r--r--pceplib/pcep_utils_queue.c2
-rw-r--r--pimd/pim_br.c93
-rw-r--r--pimd/pim_br.h30
-rw-r--r--pimd/pim_memory.c1
-rw-r--r--pimd/pim_memory.h1
-rw-r--r--pimd/pim_nht.c5
-rw-r--r--pimd/pim_register.c16
-rw-r--r--pimd/pim_rp.c4
-rw-r--r--pimd/pim_tib.c3
-rw-r--r--pimd/pim_upstream.c3
-rw-r--r--pimd/pim_vty.c2
-rw-r--r--pimd/subdir.am2
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref4
-rw-r--r--tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref4
-rw-r--r--tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py156
-rw-r--r--vtysh/vtysh_config.c13
51 files changed, 519 insertions, 352 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 24fa2b2a53..c0ad72dc33 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -5866,13 +5866,6 @@ static int parse_rtlist(struct bgp *bgp, struct vty *vty, int argc,
* the ecommunity parser.
*/
if ((argv[i]->arg)[0] == '*') {
- if (!is_import) {
- vty_out(vty,
- "%% Wildcard '*' only applicable for import\n");
- ret = CMD_WARNING;
- continue;
- }
-
(argv[i]->arg)[0] = '0';
is_wildcard = true;
}
@@ -5950,6 +5943,16 @@ DEFUN (bgp_evpn_vrf_rt,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (rt_type != RT_TYPE_IMPORT) {
+ for (int i = 2; i < argc; i++) {
+ if ((argv[i]->arg)[0] == '*') {
+ vty_out(vty,
+ "%% Wildcard '*' only applicable for import\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+ }
+
/* Add/update the import route-target */
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
tmp_ret = parse_rtlist(bgp, vty, argc, argv, 2, true, true);
@@ -6056,6 +6059,16 @@ DEFUN (no_bgp_evpn_vrf_rt,
}
}
+ if (rt_type != RT_TYPE_IMPORT) {
+ for (int i = 3; i < argc; i++) {
+ if ((argv[i]->arg)[0] == '*') {
+ vty_out(vty,
+ "%% Wildcard '*' only applicable for import\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+ }
+
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
tmp_ret = parse_rtlist(bgp, vty, argc, argv, 3, false, true);
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index a85432a33b..40598b7757 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -601,40 +601,40 @@ void bgp_delayopen_timer(struct thread *thread)
/* BGP Peer Down Cause */
const char *const peer_down_str[] = {"",
- "Router ID changed",
- "Remote AS changed",
- "Local AS change",
- "Cluster ID changed",
- "Confederation identifier changed",
- "Confederation peer changed",
- "RR client config change",
- "RS client config change",
- "Update source change",
- "Address family activated",
- "Admin. shutdown",
- "User reset",
- "BGP Notification received",
- "BGP Notification send",
- "Peer closed the session",
- "Neighbor deleted",
- "Peer-group add member",
- "Peer-group delete member",
- "Capability changed",
- "Passive config change",
- "Multihop config change",
- "NSF peer closed the session",
- "Intf peering v6only config change",
- "BFD down received",
- "Interface down",
- "Neighbor address lost",
- "Waiting for NHT",
- "Waiting for Peer IPv6 LLA",
- "Waiting for VRF to be initialized",
- "No AFI/SAFI activated for peer",
- "AS Set config change",
- "Waiting for peer OPEN",
- "Reached received prefix count",
- "Socket Error"};
+ "Router ID changed",
+ "Remote AS changed",
+ "Local AS change",
+ "Cluster ID changed",
+ "Confederation identifier changed",
+ "Confederation peer changed",
+ "RR client config change",
+ "RS client config change",
+ "Update source change",
+ "Address family activated",
+ "Admin. shutdown",
+ "User reset",
+ "BGP Notification received",
+ "BGP Notification send",
+ "Peer closed the session",
+ "Neighbor deleted",
+ "Peer-group add member",
+ "Peer-group delete member",
+ "Capability changed",
+ "Passive config change",
+ "Multihop config change",
+ "NSF peer closed the session",
+ "Intf peering v6only config change",
+ "BFD down received",
+ "Interface down",
+ "Neighbor address lost",
+ "No path to specified Neighbor",
+ "Waiting for Peer IPv6 LLA",
+ "Waiting for VRF to be initialized",
+ "No AFI/SAFI activated for peer",
+ "AS Set config change",
+ "Waiting for peer OPEN",
+ "Reached received prefix count",
+ "Socket Error"};
static void bgp_graceful_restart_timer_off(struct peer *peer)
{
@@ -1880,8 +1880,9 @@ int bgp_start(struct peer *peer)
if (!bgp_peer_reg_with_nht(peer)) {
if (bgp_zebra_num_connects()) {
if (bgp_debug_neighbor_events(peer))
- zlog_debug("%s [FSM] Waiting for NHT",
- peer->host);
+ zlog_debug(
+ "%s [FSM] Waiting for NHT, no path to neighbor present",
+ peer->host);
peer->last_reset = PEER_DOWN_WAITING_NHT;
BGP_EVENT_ADD(peer, TCP_connection_open_failed);
return 0;
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index f9bb8d518d..ce8ce96a0d 100644
--- a/bgpd/bgp_io.c
+++ b/bgpd/bgp_io.c
@@ -50,8 +50,9 @@ static void bgp_process_reads(struct thread *);
static bool validate_header(struct peer *);
/* generic i/o status codes */
-#define BGP_IO_TRANS_ERR (1 << 0) // EAGAIN or similar occurred
-#define BGP_IO_FATAL_ERR (1 << 1) // some kind of fatal TCP error
+#define BGP_IO_TRANS_ERR (1 << 0) /* EAGAIN or similar occurred */
+#define BGP_IO_FATAL_ERR (1 << 1) /* some kind of fatal TCP error */
+#define BGP_IO_WORK_FULL_ERR (1 << 2) /* No room in work buffer */
/* Thread external API ----------------------------------------------------- */
@@ -163,6 +164,58 @@ static void bgp_process_writes(struct thread *thread)
}
}
+static int read_ibuf_work(struct peer *peer)
+{
+ /* static buffer for transferring packets */
+ /* shorter alias to peer's input buffer */
+ struct ringbuf *ibw = peer->ibuf_work;
+ /* packet size as given by header */
+ uint16_t pktsize = 0;
+ struct stream *pkt;
+
+ /* Hold the I/O lock, we might not have space on the InQ */
+ frr_mutex_lock_autounlock(&peer->io_mtx);
+ /* ============================================== */
+
+ if (peer->ibuf->count >= bm->inq_limit)
+ return -ENOMEM;
+
+ /* check that we have enough data for a header */
+ if (ringbuf_remain(ibw) < BGP_HEADER_SIZE)
+ return 0;
+
+ /* check that header is valid */
+ if (!validate_header(peer))
+ return -EBADMSG;
+
+ /* header is valid; retrieve packet size */
+ ringbuf_peek(ibw, BGP_MARKER_SIZE, &pktsize, sizeof(pktsize));
+
+ pktsize = ntohs(pktsize);
+
+ /* if this fails we are seriously screwed */
+ assert(pktsize <= peer->max_packet_size);
+
+ /*
+ * If we have that much data, chuck it into its own
+ * stream and append to input queue for processing.
+ *
+ * Otherwise, come back later.
+ */
+ if (ringbuf_remain(ibw) < pktsize)
+ return 0;
+
+ pkt = stream_new(pktsize);
+ assert(STREAM_WRITEABLE(pkt) == pktsize);
+ assert(ringbuf_get(ibw, pkt->data, pktsize) == pktsize);
+ stream_set_endp(pkt, pktsize);
+
+ frrtrace(2, frr_bgp, packet_read, peer, pkt);
+ stream_fifo_push(peer->ibuf, pkt);
+
+ return pktsize;
+}
+
/*
* Called from I/O pthread when a file descriptor has become ready for reading,
* or has hung up.
@@ -173,12 +226,14 @@ static void bgp_process_writes(struct thread *thread)
static void bgp_process_reads(struct thread *thread)
{
/* clang-format off */
- static struct peer *peer; // peer to read from
- uint16_t status; // bgp_read status code
- bool more = true; // whether we got more data
- bool fatal = false; // whether fatal error occurred
- bool added_pkt = false; // whether we pushed onto ->ibuf
- int code = 0; // FSM code if error occurred
+ static struct peer *peer; /* peer to read from */
+ uint16_t status; /* bgp_read status code */
+ bool fatal = false; /* whether fatal error occurred */
+ bool added_pkt = false; /* whether we pushed onto ->ibuf */
+ int code = 0; /* FSM code if error occurred */
+ bool ibuf_full = false; /* Is peer fifo IN Buffer full */
+ static bool ibuf_full_logged; /* Have we logged full already */
+ int ret = 1;
/* clang-format on */
peer = THREAD_ARG(thread);
@@ -195,12 +250,11 @@ static void bgp_process_reads(struct thread *thread)
/* error checking phase */
if (CHECK_FLAG(status, BGP_IO_TRANS_ERR)) {
/* no problem; just don't process packets */
- more = false;
+ goto done;
}
if (CHECK_FLAG(status, BGP_IO_FATAL_ERR)) {
/* problem; tear down session */
- more = false;
fatal = true;
/* Handle the error in the main pthread, include the
@@ -208,67 +262,53 @@ static void bgp_process_reads(struct thread *thread)
*/
thread_add_event(bm->master, bgp_packet_process_error,
peer, code, &peer->t_process_packet_error);
+ goto done;
}
- while (more) {
- /* static buffer for transferring packets */
- /* shorter alias to peer's input buffer */
- struct ringbuf *ibw = peer->ibuf_work;
- /* packet size as given by header */
- uint16_t pktsize = 0;
-
- /* check that we have enough data for a header */
- if (ringbuf_remain(ibw) < BGP_HEADER_SIZE)
+ while (true) {
+ ret = read_ibuf_work(peer);
+ if (ret <= 0)
break;
- /* check that header is valid */
- if (!validate_header(peer)) {
- fatal = true;
- break;
- }
-
- /* header is valid; retrieve packet size */
- ringbuf_peek(ibw, BGP_MARKER_SIZE, &pktsize, sizeof(pktsize));
-
- pktsize = ntohs(pktsize);
-
- /* if this fails we are seriously screwed */
- assert(pktsize <= peer->max_packet_size);
-
- /*
- * If we have that much data, chuck it into its own
- * stream and append to input queue for processing.
- */
- if (ringbuf_remain(ibw) >= pktsize) {
- struct stream *pkt = stream_new(pktsize);
-
- assert(STREAM_WRITEABLE(pkt) == pktsize);
- assert(ringbuf_get(ibw, pkt->data, pktsize) == pktsize);
- stream_set_endp(pkt, pktsize);
-
- frrtrace(2, frr_bgp, packet_read, peer, pkt);
- frr_with_mutex (&peer->io_mtx) {
- stream_fifo_push(peer->ibuf, pkt);
- }
+ added_pkt = true;
+ }
- added_pkt = true;
- } else
- break;
+ switch (ret) {
+ case -EBADMSG:
+ fatal = true;
+ break;
+ case -ENOMEM:
+ ibuf_full = true;
+ if (!ibuf_full_logged) {
+ flog_warn(
+ EC_BGP_UPDATE_RCV,
+ "%s [Warning] Peer Input-Queue is full: limit (%u)",
+ peer->host, bm->inq_limit);
+ ibuf_full_logged = true;
+ }
+ break;
+ default:
+ ibuf_full_logged = false;
+ break;
}
+done:
/* handle invalid header */
if (fatal) {
/* wipe buffer just in case someone screwed up */
ringbuf_wipe(peer->ibuf_work);
- } else {
+ return;
+ }
+
+ /* ringbuf should be fully drained unless ibuf is full */
+ if (!ibuf_full)
assert(ringbuf_space(peer->ibuf_work) >= peer->max_packet_size);
- thread_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
- &peer->t_read);
- if (added_pkt)
- thread_add_event(bm->master, bgp_process_packet,
- peer, 0, &peer->t_process_packet);
- }
+ thread_add_read(fpt->master, bgp_process_reads, peer, peer->fd,
+ &peer->t_read);
+ if (added_pkt)
+ thread_add_event(bm->master, bgp_process_packet, peer, 0,
+ &peer->t_process_packet);
}
/*
@@ -462,12 +502,20 @@ done : {
*/
static uint16_t bgp_read(struct peer *peer, int *code_p)
{
- size_t readsize; // how many bytes we want to read
- ssize_t nbytes; // how many bytes we actually read
+ size_t readsize; /* how many bytes we want to read */
+ ssize_t nbytes; /* how many bytes we actually read */
+ size_t ibuf_work_space; /* space we can read into the work buf */
uint16_t status = 0;
- readsize =
- MIN(ringbuf_space(peer->ibuf_work), sizeof(peer->ibuf_scratch));
+ ibuf_work_space = ringbuf_space(peer->ibuf_work);
+
+ if (ibuf_work_space == 0) {
+ SET_FLAG(status, BGP_IO_WORK_FULL_ERR);
+ return status;
+ }
+
+ readsize = MIN(ibuf_work_space, sizeof(peer->ibuf_scratch));
+
nbytes = read(peer->fd, peer->ibuf_scratch, readsize);
/* EAGAIN or EWOULDBLOCK; come back later */
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 8ae31bf2e6..769f9613da 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -124,6 +124,7 @@ static void bgp_packet_add(struct peer *peer, struct stream *s)
{
intmax_t delta;
uint32_t holdtime;
+ intmax_t sendholdtime;
frr_with_mutex (&peer->io_mtx) {
/* if the queue is empty, reset the "last OK" timestamp to
@@ -136,8 +137,14 @@ static void bgp_packet_add(struct peer *peer, struct stream *s)
stream_fifo_push(peer->obuf, s);
delta = monotime(NULL) - peer->last_sendq_ok;
- holdtime = atomic_load_explicit(&peer->holdtime,
- memory_order_relaxed);
+
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER))
+ holdtime = atomic_load_explicit(&peer->holdtime,
+ memory_order_relaxed);
+ else
+ holdtime = peer->bgp->default_holdtime;
+
+ sendholdtime = holdtime * 2;
/* Note that when we're here, we're adding some packet to the
* OutQ. That includes keepalives when there is nothing to
@@ -149,18 +156,18 @@ static void bgp_packet_add(struct peer *peer, struct stream *s)
*/
if (!holdtime) {
/* no holdtime, do nothing. */
- } else if (delta > 2 * (intmax_t)holdtime) {
+ } else if (delta > sendholdtime) {
flog_err(
EC_BGP_SENDQ_STUCK_PROPER,
- "%s has not made any SendQ progress for 2 holdtimes, terminating session",
- peer->host);
+ "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session",
+ peer, sendholdtime);
BGP_EVENT_ADD(peer, TCP_fatal_error);
} else if (delta > (intmax_t)holdtime &&
monotime(NULL) - peer->last_sendq_warn > 5) {
flog_warn(
EC_BGP_SENDQ_STUCK_WARN,
- "%s has not made any SendQ progress for 1 holdtime, peer overloaded?",
- peer->host);
+ "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?",
+ peer, holdtime);
peer->last_sendq_warn = monotime(NULL);
}
}
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f6b6cb93db..cbb597fdab 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -2418,7 +2418,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
if (aspath_check_as_sets(attr->aspath))
return false;
- /* If neighbor sso is configured, then check if the route has
+ /* If neighbor soo is configured, then check if the route has
* SoO extended community and validate against the configured
* one. If they match, do not announce, to prevent routing
* loops.
@@ -2431,6 +2431,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
ECOMMUNITY_SITE_ORIGIN) ||
ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
+ ECOMMUNITY_SITE_ORIGIN) ||
+ ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
ECOMMUNITY_SITE_ORIGIN)) &&
ecommunity_include(ecomm, ecomm_soo)) {
if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
@@ -4000,6 +4002,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bool force_evpn_import = false;
safi_t orig_safi = safi;
bool leak_success = true;
+ int allowas_in = 0;
if (frrtrace_enabled(frr_bgp, process_update)) {
char pfxprint[PREFIX2STR_BUFFER];
@@ -4045,6 +4048,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
&& peer != bgp->peer_self)
bgp_adj_in_set(dest, peer, attr, addpath_id);
+ /* Update permitted loop count */
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
+ allowas_in = peer->allowas_in[afi][safi];
+
/* Check previously received route. */
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
if (pi->peer == peer && pi->type == type
@@ -4054,8 +4061,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
/* AS path local-as loop check. */
if (peer->change_local_as) {
- if (peer->allowas_in[afi][safi])
- aspath_loop_count = peer->allowas_in[afi][safi];
+ if (allowas_in)
+ aspath_loop_count = allowas_in;
else if (!CHECK_FLAG(peer->flags,
PEER_FLAG_LOCAL_AS_NO_PREPEND))
aspath_loop_count = 1;
@@ -4078,11 +4085,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
/* AS path loop check. */
if (do_loop_check) {
- if (aspath_loop_check(attr->aspath, bgp->as)
- > peer->allowas_in[afi][safi]
- || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
- && aspath_loop_check(attr->aspath, bgp->confed_id)
- > peer->allowas_in[afi][safi])) {
+ if (aspath_loop_check(attr->aspath, bgp->as) > allowas_in ||
+ (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) &&
+ (aspath_loop_check(attr->aspath, bgp->confed_id) >
+ allowas_in))) {
peer->stat_pfx_aspath_loop++;
reason = "as-path contains our own AS;";
goto filtered;
@@ -9035,6 +9041,8 @@ static void route_vty_short_status_out(struct vty *vty,
vty_out(vty, "I");
else if (rpki_state == RPKI_NOTFOUND)
vty_out(vty, "N");
+ else
+ vty_out(vty, " ");
/* Route status display. */
if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 7c6e60bd92..dfe741914d 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -80,7 +80,7 @@ enum bgp_show_adj_route_type {
#define BGP_SHOW_NCODE_HEADER "Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self\n"
#define BGP_SHOW_RPKI_HEADER \
"RPKI validation codes: V valid, I invalid, N Not found\n\n"
-#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
+#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
#define BGP_SHOW_HEADER_WIDE " Network Next Hop Metric LocPrf Weight Path\n"
/* Maximum number of labels we can process or send with a prefix. We
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index 88a81f255d..344aea16f5 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -527,7 +527,7 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
&& !CHECK_FLAG(vec->flags,
BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED)
&& !peer_af_flag_check(
- peer, nhafi, paf->safi,
+ peer, paf->afi, paf->safi,
PEER_FLAG_NEXTHOP_UNCHANGED)) {
/* NOTE: not handling case where NH has new AFI
*/
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index f380460a95..e856529fc6 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -12282,6 +12282,16 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
json_addr,
"privateAsNumsRemovedInUpdatesToNbr");
+ if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) {
+ if (CHECK_FLAG(p->af_flags[afi][safi],
+ PEER_FLAG_ALLOWAS_IN_ORIGIN))
+ json_object_boolean_true_add(json_addr,
+ "allowAsInOrigin");
+ else
+ json_object_int_add(json_addr, "allowAsInCount",
+ p->allowas_in[afi][safi]);
+ }
+
if (p->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
json_object_boolean_true_add(
json_addr,
@@ -12598,6 +12608,17 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
vty_out(vty,
" Private AS numbers removed in updates to this neighbor\n");
+ if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) {
+ if (CHECK_FLAG(p->af_flags[afi][safi],
+ PEER_FLAG_ALLOWAS_IN_ORIGIN))
+ vty_out(vty,
+ " Local AS allowed as path origin\n");
+ else
+ vty_out(vty,
+ " Local AS allowed in path, %d occurrences\n",
+ p->allowas_in[afi][safi]);
+ }
+
if (p->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
vty_out(vty, " %s\n",
bgp_addpath_names(p->addpath_type[afi][safi])
@@ -17712,6 +17733,10 @@ int bgp_config_write(struct vty *vty)
if (bm->tcp_dscp != IPTOS_PREC_INTERNETCONTROL)
vty_out(vty, "bgp session-dscp %u\n", bm->tcp_dscp >> 2);
+ /* BGP InQ limit */
+ if (bm->inq_limit != BM_DEFAULT_INQ_LIMIT)
+ vty_out(vty, "bgp input-queue-limit %u\n", bm->inq_limit);
+
/* BGP configuration. */
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
@@ -18424,6 +18449,31 @@ DEFPY(mpls_bgp_forwarding, mpls_bgp_forwarding_cmd,
return CMD_SUCCESS;
}
+DEFPY (bgp_inq_limit,
+ bgp_inq_limit_cmd,
+ "bgp input-queue-limit (1-4294967295)$limit",
+ BGP_STR
+ "Set the BGP Input Queue limit for all peers when message parsing\n"
+ "Input-Queue limit\n")
+{
+ bm->inq_limit = limit;
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_bgp_inq_limit,
+ no_bgp_inq_limit_cmd,
+ "no bgp input-queue-limit [(1-4294967295)$limit]",
+ NO_STR
+ BGP_STR
+ "Set the BGP Input Queue limit for all peers when message parsing\n"
+ "Input-Queue limit\n")
+{
+ bm->inq_limit = BM_DEFAULT_INQ_LIMIT;
+
+ return CMD_SUCCESS;
+}
+
/* Initialization of BGP interface. */
static void bgp_vty_if_init(void)
{
@@ -18473,6 +18523,10 @@ void bgp_vty_init(void)
install_default(BGP_EVPN_VNI_NODE);
install_default(BGP_SRV6_NODE);
+ /* "global bgp inq-limit command */
+ install_element(CONFIG_NODE, &bgp_inq_limit_cmd);
+ install_element(CONFIG_NODE, &no_bgp_inq_limit_cmd);
+
/* "bgp local-mac" hidden commands. */
install_element(CONFIG_NODE, &bgp_local_mac_cmd);
install_element(CONFIG_NODE, &no_bgp_local_mac_cmd);
@@ -18668,6 +18722,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_graceful_restart_rib_stale_time_cmd);
install_element(BGP_NODE, &no_bgp_graceful_restart_rib_stale_time_cmd);
+ /* "bgp inq-limit command */
+ install_element(BGP_NODE, &bgp_inq_limit_cmd);
+ install_element(BGP_NODE, &no_bgp_inq_limit_cmd);
+
/* "bgp graceful-shutdown" commands */
install_element(BGP_NODE, &bgp_graceful_shutdown_cmd);
install_element(BGP_NODE, &no_bgp_graceful_shutdown_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 40e6c90dfc..512b52836d 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4272,9 +4272,9 @@ static const struct peer_flag_action peer_flag_action_list[] = {
{PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
{PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none},
{PEER_FLAG_PASSWORD, 0, peer_change_none},
- {PEER_FLAG_LOCAL_AS, 0, peer_change_none},
- {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none},
- {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_none},
+ {PEER_FLAG_LOCAL_AS, 0, peer_change_reset},
+ {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset},
+ {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset},
{PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
{PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none},
{PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset},
@@ -6160,18 +6160,8 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
(void)peer_sort(peer);
/* Check if handling a regular peer. */
- if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- /* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
- peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
- bgp_session_reset(peer);
-
- /* Skip peer-group mechanics for regular peers. */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
return 0;
- }
/*
* Set flag and configuration on all peer-group members, unless they are
@@ -6200,14 +6190,6 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
replace_as);
member->change_local_as = as;
-
- /* Send notification or stop peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
- member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
- bgp_notify_send(member, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
- BGP_EVENT_ADD(member, BGP_Stop);
}
return 0;
@@ -7886,6 +7868,7 @@ void bgp_master_init(struct thread_master *master, const int buffer_size,
bm->socket_buffer = buffer_size;
bm->wait_for_fib = false;
bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL;
+ bm->inq_limit = BM_DEFAULT_INQ_LIMIT;
bgp_mac_init();
/* init the rd id space.
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index c844f1530f..c41c2ee429 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -177,6 +177,9 @@ struct bgp_master {
/* DSCP value for TCP sessions */
uint8_t tcp_dscp;
+#define BM_DEFAULT_INQ_LIMIT 10000
+ uint32_t inq_limit;
+
QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(bgp_master);
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 7d7dd3d805..3d9b0b3606 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -4018,6 +4018,11 @@ The following command is available in ``config`` mode as well as in the
the startup configuration, graceful shutdown will remain in effect
across restarts of *bgpd* and will need to be explicitly disabled.
+.. clicmd:: bgp input-queue-limit (1-4294967295)
+
+ Set the BGP Input Queue limit for all peers when messaging parsing. Increase
+ this only if you have the memory to handle large queues of messages at once.
+
.. _bgp-displaying-bgp-information:
Displaying BGP Information
diff --git a/isisd/isisd.c b/isisd/isisd.c
index efea1e5d5e..17f4b20737 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -723,7 +723,7 @@ void isis_vrf_init(void)
vrf_cmd_init(NULL);
}
-void isis_terminate()
+void isis_terminate(void)
{
struct isis *isis;
struct listnode *node, *nnode;
@@ -2745,7 +2745,6 @@ static void show_isis_database_json(struct json_object *json, const char *sysid_
struct isis_area *area;
int level;
struct json_object *tag_area_json,*area_json, *lsp_json, *area_arr_json, *arr_json;
- uint8_t area_cnt = 0;
if (isis->area_list->count == 0)
return;
@@ -2770,7 +2769,6 @@ static void show_isis_database_json(struct json_object *json, const char *sysid_
json_object_array_add(arr_json, lsp_json);
}
json_object_array_add(area_arr_json, area_json);
- area_cnt++;
}
}
@@ -3232,7 +3230,7 @@ void isis_area_overload_on_startup_set(struct isis_area *area,
* Returns the path of the file (non-volatile memory) that contains restart
* information.
*/
-char *isis_restart_filepath()
+char *isis_restart_filepath(void)
{
static char filepath[MAXPATHLEN];
snprintf(filepath, sizeof(filepath), ISISD_RESTART, "");
diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c
index e1db9e8e1e..6d6c7d00cd 100644
--- a/ldpd/neighbor.c
+++ b/ldpd/neighbor.c
@@ -359,8 +359,7 @@ nbr_find_ldpid(uint32_t lsr_id)
return (RB_FIND(nbr_id_head, &nbrs_by_id, &n));
}
-struct nbr *
-nbr_get_first_ldpid()
+struct nbr *nbr_get_first_ldpid(void)
{
return (RB_MIN(nbr_id_head, &nbrs_by_id));
}
diff --git a/lib/zclient.c b/lib/zclient.c
index f5d45b40ef..4a553f4718 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2370,8 +2370,7 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
return NULL;
}
- iflp = if_link_params_get(ifp);
- if (iflp) {
+ if (if_link_params_get(ifp)) {
iflp_prev_set = true;
memcpy(&iflp_prev, ifp->link_params, sizeof(iflp_prev));
} else
@@ -2387,6 +2386,8 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
if (changed == NULL)
return ifp;
+ iflp = if_link_params_get(ifp);
+
if (iflp_prev_set && iflp) {
if (memcmp(&iflp_prev, iflp, sizeof(iflp_prev)))
*changed = true;
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index a0cb455798..78b2ffbcf3 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -39,6 +39,8 @@
#include "ospf6_spf.h"
#include "ospf6_top.h"
#include "ospf6_area.h"
+#include "ospf6_message.h"
+#include "ospf6_neighbor.h"
#include "ospf6_interface.h"
#include "ospf6_intra.h"
#include "ospf6_abr.h"
@@ -348,9 +350,17 @@ void ospf6_area_delete(struct ospf6_area *oa)
* deleting an area.
* So just detach the interface from the area and
* keep it around. */
- for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi))
+ for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) {
oi->area = NULL;
+ struct listnode *node;
+ struct listnode *nnode;
+ struct ospf6_neighbor *on;
+
+ for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on))
+ ospf6_neighbor_delete(on);
+ }
+
list_delete(&oa->if_list);
ospf6_lsdb_delete(oa->lsdb);
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index ae3ce2f0c7..924c2d6c5b 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -3169,6 +3169,14 @@ void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr)
hash_clean(aggr->match_extnl_hash,
ospf6_aggr_unlink_external_info);
+ if (aggr->route) {
+ if (aggr->route->route_option)
+ XFREE(MTYPE_OSPF6_EXTERNAL_INFO,
+ aggr->route->route_option);
+
+ ospf6_route_delete(aggr->route);
+ }
+
if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Release the aggregator Address(%pFX)",
__func__,
diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c
index 8e964393f1..fab0479d42 100644
--- a/ospf6d/ospf6_route.c
+++ b/ospf6d/ospf6_route.c
@@ -1360,7 +1360,7 @@ static void ospf6_route_show_table_summary(struct vty *vty,
struct ospf6_route *route, *prev = NULL;
int i, pathtype[OSPF6_PATH_TYPE_MAX];
unsigned int number = 0;
- int nh_count = 0, nhinval = 0, ecmp = 0;
+ int nh_count = 0, ecmp = 0;
int alternative = 0, destination = 0;
char path_str[30];
@@ -1374,9 +1374,7 @@ static void ospf6_route_show_table_summary(struct vty *vty,
else
alternative++;
nh_count = ospf6_num_nexthops(route->nh_list);
- if (!nh_count)
- nhinval++;
- else if (nh_count > 1)
+ if (nh_count > 1)
ecmp++;
pathtype[route->path.type]++;
number++;
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index e686a93ba9..c2af09a679 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -648,6 +648,13 @@ int ospf_flood_through_interface(struct ospf_interface *oi,
OSPF_SEND_PACKET_DIRECT);
}
} else
+ /* Optimization: for P2MP interfaces,
+ don't send back out the incoming interface immediately,
+ allow time to rx multicast ack to the rx'ed (multicast)
+ update */
+ if (retx_flag != 1 ||
+ oi->type != OSPF_IFTYPE_POINTOMULTIPOINT || inbr == NULL ||
+ oi != inbr->oi)
ospf_ls_upd_send_lsa(oi->nbr_self, lsa,
OSPF_SEND_PACKET_INDIRECT);
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 57643f637e..466b5fa2a2 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -4220,7 +4220,8 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack,
op->length = length;
/* Decide destination address. */
- if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
+ oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS);
else
op->dst.s_addr = dst.s_addr;
diff --git a/pathd/path_ted.c b/pathd/path_ted.c
index 316255a97e..bb04d285c9 100644
--- a/pathd/path_ted.c
+++ b/pathd/path_ted.c
@@ -162,7 +162,7 @@ bool path_ted_is_initialized(void)
*
* @return Ptr to ted or NULL
*/
-struct ls_ted *path_ted_create_ted()
+struct ls_ted *path_ted_create_ted(void)
{
struct ls_ted *ted = ls_ted_new(TED_KEY, TED_NAME, TED_ASN);
diff --git a/pceplib/pcep_msg_messages.c b/pceplib/pcep_msg_messages.c
index 9bbfc5372b..5a244098d4 100644
--- a/pceplib/pcep_msg_messages.c
+++ b/pceplib/pcep_msg_messages.c
@@ -163,7 +163,7 @@ pcep_msg_create_error_with_objects(uint8_t error_type, uint8_t error_value,
return message;
}
-struct pcep_message *pcep_msg_create_keepalive()
+struct pcep_message *pcep_msg_create_keepalive(void)
{
return (pcep_msg_create_common(PCEP_TYPE_KEEPALIVE));
}
diff --git a/pceplib/pcep_msg_messages_encoding.c b/pceplib/pcep_msg_messages_encoding.c
index e90ca1cfd8..2d27e40407 100644
--- a/pceplib/pcep_msg_messages_encoding.c
+++ b/pceplib/pcep_msg_messages_encoding.c
@@ -348,7 +348,7 @@ struct pcep_message *pcep_decode_message(const uint8_t *msg_buf)
return msg;
}
-struct pcep_versioning *create_default_pcep_versioning()
+struct pcep_versioning *create_default_pcep_versioning(void)
{
struct pcep_versioning *versioning =
pceplib_malloc(PCEPLIB_INFRA, sizeof(struct pcep_versioning));
diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c
index 18ccf250ae..47e357729c 100644
--- a/pceplib/pcep_pcc.c
+++ b/pceplib/pcep_pcc.c
@@ -74,7 +74,6 @@ static const short DEFAULT_SRC_TCP_PORT = 4999;
// Private fn's
struct cmd_line_args *get_cmdline_args(int argc, char *argv[]);
void handle_signal_action(int sig_number);
-int setup_signals(void);
void send_pce_path_request_message(pcep_session *session);
void send_pce_report_message(pcep_session *session);
void print_queue_event(struct pcep_event *event);
@@ -211,8 +210,7 @@ void handle_signal_action(int sig_number)
}
}
-
-int setup_signals()
+static int setup_signals(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
diff --git a/pceplib/pcep_pcc_api.c b/pceplib/pcep_pcc_api.c
index b7813c5a05..75c2b59b66 100644
--- a/pceplib/pcep_pcc_api.c
+++ b/pceplib/pcep_pcc_api.c
@@ -55,7 +55,7 @@ const char UNKNOWN_EVENT_STR[] = "UNKNOWN Event Type";
/* Session Logic Handle managed in pcep_session_logic.c */
extern pcep_event_queue *session_logic_event_queue_;
-bool initialize_pcc()
+bool initialize_pcc(void)
{
if (!run_session_logic()) {
pcep_log(LOG_ERR, "%s: Error initializing PCC session logic.",
@@ -85,13 +85,13 @@ bool initialize_pcc_infra(struct pceplib_infra_config *infra_config)
/* this function is blocking */
-bool initialize_pcc_wait_for_completion()
+bool initialize_pcc_wait_for_completion(void)
{
return run_session_logic_wait_for_completion();
}
-bool destroy_pcc()
+bool destroy_pcc(void)
{
if (!stop_session_logic()) {
pcep_log(LOG_WARNING, "%s: Error stopping PCC session logic.",
@@ -103,7 +103,7 @@ bool destroy_pcc()
}
-pcep_configuration *create_default_pcep_configuration()
+pcep_configuration *create_default_pcep_configuration(void)
{
pcep_configuration *config =
pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_configuration));
@@ -226,7 +226,7 @@ void send_message(pcep_session *session, struct pcep_message *msg,
}
/* Returns true if the queue is empty, false otherwise */
-bool event_queue_is_empty()
+bool event_queue_is_empty(void)
{
if (session_logic_event_queue_ == NULL) {
pcep_log(
@@ -246,7 +246,7 @@ bool event_queue_is_empty()
/* Return the number of events on the queue, 0 if empty */
-uint32_t event_queue_num_events_available()
+uint32_t event_queue_num_events_available(void)
{
if (session_logic_event_queue_ == NULL) {
pcep_log(
@@ -266,7 +266,7 @@ uint32_t event_queue_num_events_available()
/* Return the next event on the queue, NULL if empty */
-struct pcep_event *event_queue_get_event()
+struct pcep_event *event_queue_get_event(void)
{
if (session_logic_event_queue_ == NULL) {
pcep_log(
diff --git a/pceplib/pcep_session_logic.c b/pceplib/pcep_session_logic.c
index 78d1072552..02cf3bffbd 100644
--- a/pceplib/pcep_session_logic.c
+++ b/pceplib/pcep_session_logic.c
@@ -111,7 +111,7 @@ static bool run_session_logic_common(void)
}
-bool run_session_logic()
+bool run_session_logic(void)
{
if (!run_session_logic_common()) {
return false;
@@ -234,7 +234,7 @@ bool run_session_logic_with_infra(pceplib_infra_config *infra_config)
return true;
}
-bool run_session_logic_wait_for_completion()
+bool run_session_logic_wait_for_completion(void)
{
if (!run_session_logic()) {
return false;
@@ -247,7 +247,7 @@ bool run_session_logic_wait_for_completion()
}
-bool stop_session_logic()
+bool stop_session_logic(void)
{
if (session_logic_handle_ == NULL) {
pcep_log(LOG_WARNING, "%s: Session logic already stopped",
diff --git a/pceplib/pcep_socket_comm.c b/pceplib/pcep_socket_comm.c
index e22eb6e675..4a97c84891 100644
--- a/pceplib/pcep_socket_comm.c
+++ b/pceplib/pcep_socket_comm.c
@@ -62,7 +62,7 @@ int socket_fd_node_compare(void *list_entry, void *new_entry)
}
-bool initialize_socket_comm_pre()
+bool initialize_socket_comm_pre(void)
{
socket_comm_handle_ =
pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_socket_comm_handle));
@@ -129,7 +129,7 @@ bool initialize_socket_comm_external_infra(
return true;
}
-bool initialize_socket_comm_loop()
+bool initialize_socket_comm_loop(void)
{
if (socket_comm_handle_ != NULL) {
/* already initialized */
@@ -152,7 +152,7 @@ bool initialize_socket_comm_loop()
}
-bool destroy_socket_comm_loop()
+bool destroy_socket_comm_loop(void)
{
socket_comm_handle_->active = false;
diff --git a/pceplib/pcep_timers.c b/pceplib/pcep_timers.c
index b0f3e70b50..61fda16363 100644
--- a/pceplib/pcep_timers.c
+++ b/pceplib/pcep_timers.c
@@ -197,7 +197,7 @@ void free_all_timers(pcep_timers_context *timers_context)
}
-bool teardown_timers()
+bool teardown_timers(void)
{
if (timers_context_ == NULL) {
pcep_log(
@@ -252,7 +252,7 @@ bool teardown_timers()
}
-int get_next_timer_id()
+int get_next_timer_id(void)
{
if (timer_id_ == INT_MAX) {
timer_id_ = 0;
diff --git a/pceplib/pcep_utils_double_linked_list.c b/pceplib/pcep_utils_double_linked_list.c
index 696e46632a..7f90df40f2 100644
--- a/pceplib/pcep_utils_double_linked_list.c
+++ b/pceplib/pcep_utils_double_linked_list.c
@@ -31,7 +31,7 @@
#include "pcep_utils_logging.h"
#include "pcep_utils_memory.h"
-double_linked_list *dll_initialize()
+double_linked_list *dll_initialize(void)
{
double_linked_list *handle =
pceplib_malloc(PCEPLIB_INFRA, sizeof(double_linked_list));
diff --git a/pceplib/pcep_utils_logging.c b/pceplib/pcep_utils_logging.c
index 0286c23078..c9b2588b4b 100644
--- a/pceplib/pcep_utils_logging.c
+++ b/pceplib/pcep_utils_logging.c
@@ -45,7 +45,7 @@ void set_logging_level(int level)
logging_level_ = level;
}
-int get_logging_level()
+int get_logging_level(void)
{
return logging_level_;
}
diff --git a/pceplib/pcep_utils_memory.c b/pceplib/pcep_utils_memory.c
index c564705f66..10856cac2a 100644
--- a/pceplib/pcep_utils_memory.c
+++ b/pceplib/pcep_utils_memory.c
@@ -75,7 +75,7 @@ bool pceplib_memory_initialize(void *pceplib_infra_mt,
return true;
}
-void pceplib_memory_reset()
+void pceplib_memory_reset(void)
{
pceplib_infra_mt.total_bytes_allocated = 0;
pceplib_infra_mt.num_allocates = 0;
@@ -88,7 +88,7 @@ void pceplib_memory_reset()
pceplib_messages_mt.num_frees = 0;
}
-void pceplib_memory_dump()
+void pceplib_memory_dump(void)
{
if (PCEPLIB_INFRA) {
pcep_log(
diff --git a/pceplib/pcep_utils_queue.c b/pceplib/pcep_utils_queue.c
index 627533d01b..22e417111f 100644
--- a/pceplib/pcep_utils_queue.c
+++ b/pceplib/pcep_utils_queue.c
@@ -33,7 +33,7 @@
#include "pcep_utils_memory.h"
#include "pcep_utils_queue.h"
-queue_handle *queue_initialize()
+queue_handle *queue_initialize(void)
{
/* Set the max_entries to 0 to disable it */
return queue_initialize_with_size(0);
diff --git a/pimd/pim_br.c b/pimd/pim_br.c
deleted file mode 100644
index 6ec6b11e7b..0000000000
--- a/pimd/pim_br.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * PIM for Quagga
- * Copyright (C) 2015 Cumulus Networks, Inc.
- * Donald Sharp
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include <zebra.h>
-
-#include "memory.h"
-#include "log.h"
-#include "if.h"
-
-#include "pimd.h"
-#include "pim_str.h"
-#include "pim_br.h"
-#include "linklist.h"
-
-struct pim_br {
- pim_sgaddr sg;
- pim_addr pmbr;
-};
-
-static struct list *pim_br_list = NULL;
-
-pim_addr pim_br_get_pmbr(pim_sgaddr *sg)
-{
- struct listnode *node;
- struct pim_br *pim_br;
-
- for (ALL_LIST_ELEMENTS_RO(pim_br_list, node, pim_br)) {
- if (!pim_sgaddr_cmp(*sg, pim_br->sg))
- return pim_br->pmbr;
- }
-
- return PIMADDR_ANY;
-}
-
-void pim_br_set_pmbr(pim_sgaddr *sg, pim_addr br)
-{
- struct listnode *node, *next;
- struct pim_br *pim_br;
-
- for (ALL_LIST_ELEMENTS(pim_br_list, node, next, pim_br)) {
- if (!pim_sgaddr_cmp(*sg, pim_br->sg))
- break;
- }
-
- if (!pim_br) {
- pim_br = XCALLOC(MTYPE_PIM_BR, sizeof(*pim_br));
- pim_br->sg = *sg;
-
- listnode_add(pim_br_list, pim_br);
- }
-
- pim_br->pmbr = br;
-}
-
-/*
- * Remove the (S,G) from the stored values
- */
-void pim_br_clear_pmbr(pim_sgaddr *sg)
-{
- struct listnode *node, *next;
- struct pim_br *pim_br;
-
- for (ALL_LIST_ELEMENTS(pim_br_list, node, next, pim_br)) {
- if (!pim_sgaddr_cmp(*sg, pim_br->sg))
- break;
- }
-
- if (!pim_br)
- return;
-
- listnode_delete(pim_br_list, pim_br);
-}
-
-void pim_br_init(void)
-{
- pim_br_list = list_new();
-}
diff --git a/pimd/pim_br.h b/pimd/pim_br.h
deleted file mode 100644
index 7b87c0f1fd..0000000000
--- a/pimd/pim_br.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * PIM for Quagga
- * Copyright (C) 2015 Cumulus Networks, Inc.
- * Donald Sharp
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef PIM_BR_H
-#define PIM_BR_H
-
-pim_addr pim_br_get_pmbr(pim_sgaddr *sg);
-
-void pim_br_set_pmbr(pim_sgaddr *sg, pim_addr value);
-void pim_br_clear_pmbr(pim_sgaddr *sg);
-
-void pim_br_init(void);
-
-#endif
diff --git a/pimd/pim_memory.c b/pimd/pim_memory.c
index 1d811d9001..1780b60a65 100644
--- a/pimd/pim_memory.c
+++ b/pimd/pim_memory.c
@@ -37,7 +37,6 @@ DEFINE_MTYPE(PIMD, PIM_IFCHANNEL, "PIM interface (S,G) state");
DEFINE_MTYPE(PIMD, PIM_UPSTREAM, "PIM upstream (S,G) state");
DEFINE_MTYPE(PIMD, PIM_SSMPINGD, "PIM sspimgd socket");
DEFINE_MTYPE(PIMD, PIM_STATIC_ROUTE, "PIM Static Route");
-DEFINE_MTYPE(PIMD, PIM_BR, "PIM Bridge Router info");
DEFINE_MTYPE(PIMD, PIM_RP, "PIM RP info");
DEFINE_MTYPE(PIMD, PIM_FILTER_NAME, "PIM RP filter info");
DEFINE_MTYPE(PIMD, PIM_MSDP_PEER, "PIM MSDP peer");
diff --git a/pimd/pim_memory.h b/pimd/pim_memory.h
index 4e5fcde7dd..385c81052e 100644
--- a/pimd/pim_memory.h
+++ b/pimd/pim_memory.h
@@ -36,7 +36,6 @@ DECLARE_MTYPE(PIM_IFCHANNEL);
DECLARE_MTYPE(PIM_UPSTREAM);
DECLARE_MTYPE(PIM_SSMPINGD);
DECLARE_MTYPE(PIM_STATIC_ROUTE);
-DECLARE_MTYPE(PIM_BR);
DECLARE_MTYPE(PIM_RP);
DECLARE_MTYPE(PIM_FILTER_NAME);
DECLARE_MTYPE(PIM_MSDP_PEER);
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 9feb064e96..f9a9aeb1b0 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -495,12 +495,13 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
uint32_t hash_val = 0, mod_val = 0;
uint8_t nh_iter = 0, found = 0;
uint32_t i, num_nbrs = 0;
- pim_addr nh_addr = nexthop->mrib_nexthop_addr;
- pim_addr grp_addr = pim_addr_from_prefix(grp);
if (!pnc || !pnc->nexthop_num || !nexthop)
return 0;
+ pim_addr nh_addr = nexthop->mrib_nexthop_addr;
+ pim_addr grp_addr = pim_addr_from_prefix(grp);
+
memset(&nbrs, 0, sizeof(nbrs));
memset(&ifps, 0, sizeof(ifps));
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index 4e2c44b172..a37759e0d2 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -36,7 +36,6 @@
#include "pim_rp.h"
#include "pim_register.h"
#include "pim_upstream.h"
-#include "pim_br.h"
#include "pim_rpf.h"
#include "pim_oil.h"
#include "pim_zebra.h"
@@ -642,24 +641,13 @@ int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
}
if (*bits & PIM_REGISTER_BORDER_BIT) {
- pim_addr pimbr = pim_br_get_pmbr(&sg);
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug(
- "%s: Received Register message with Border bit set",
+ "%s: Received Register message with Border bit set, ignoring",
__func__);
- if (pim_addr_is_any(pimbr))
- pim_br_set_pmbr(&sg, src_addr);
- else if (pim_addr_cmp(src_addr, pimbr)) {
- pim_register_stop_send(ifp, &sg, dest_addr,
- src_addr);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: Sending register-Stop to %s and dropping mr. packet",
- __func__, "Sender");
/* Drop Packet Silently */
- return 0;
- }
+ return 0;
}
struct pim_upstream *upstream = pim_upstream_find(pim, &sg);
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 1dce6b3562..c3e6a303fc 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -950,10 +950,12 @@ void pim_rp_setup(struct pim_instance *pim)
pim_find_or_track_nexthop(pim, nht_p, NULL, rp_info, NULL);
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
- nht_p, &rp_info->group, 1))
+ nht_p, &rp_info->group, 1)) {
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug(
"Unable to lookup nexthop for rp specified");
+ pim_rp_nexthop_del(rp_info);
+ }
}
}
diff --git a/pimd/pim_tib.c b/pimd/pim_tib.c
index 8f5de3e938..3455e30064 100644
--- a/pimd/pim_tib.c
+++ b/pimd/pim_tib.c
@@ -49,7 +49,8 @@ tib_sg_oil_setup(struct pim_instance *pim, pim_sgaddr sg, struct interface *oif)
if (up) {
memcpy(&nexthop, &up->rpf.source_nexthop,
sizeof(struct pim_nexthop));
- pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp, 0);
+ (void)pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp,
+ 0);
if (nexthop.interface)
input_iface_vif_index = pim_if_find_vifindex_by_ifindex(
pim, nexthop.interface->ifindex);
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 0742daa4de..6b58fbb5cf 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -46,7 +46,6 @@
#include "pim_oil.h"
#include "pim_macro.h"
#include "pim_rp.h"
-#include "pim_br.h"
#include "pim_register.h"
#include "pim_msdp.h"
#include "pim_jp_agg.h"
@@ -1422,8 +1421,8 @@ struct pim_upstream *pim_upstream_keep_alive_timer_proc(
}
if (I_am_RP(pim, up->sg.grp)) {
- pim_br_clear_pmbr(&up->sg);
/*
+ * Handle Border Router
* We need to do more here :)
* But this is the start.
*/
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 9021f1e12f..553c1314d2 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -401,7 +401,7 @@ static int gm_config_write(struct vty *vty, int writes,
vty_out(vty, " ipv6 mld last-member-query-interval %d\n",
pim_ifp->gm_specific_query_max_response_time_dsec);
- return 0;
+ return writes;
}
#endif
diff --git a/pimd/subdir.am b/pimd/subdir.am
index aa06b86479..54292bba24 100644
--- a/pimd/subdir.am
+++ b/pimd/subdir.am
@@ -21,7 +21,6 @@ pim_common = \
pimd/pim_addr.c \
pimd/pim_assert.c \
pimd/pim_bfd.c \
- pimd/pim_br.c \
pimd/pim_bsm.c \
pimd/pim_cmd_common.c \
pimd/pim_errors.c \
@@ -103,7 +102,6 @@ noinst_HEADERS += \
pimd/pim_addr.h \
pimd/pim_assert.h \
pimd/pim_bfd.h \
- pimd/pim_br.h \
pimd/pim_bsm.h \
pimd/pim_cmd.h \
pimd/pim_cmd_common.h \
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref
index b38701a53d..b2e8de5ce1 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref
@@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
- Network Next Hop Metric LocPrf Weight Path
-*> 192.168.0.0 0.0.0.0 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> 192.168.0.0 0.0.0.0 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref
index 82b64c0d98..7bee704182 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref
@@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
- Network Next Hop Metric LocPrf Weight Path
-*> 192.168.0.0/24 0.0.0.0 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> 192.168.0.0/24 0.0.0.0 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref
index fd333b3084..31071e760d 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref
@@ -6,5 +6,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
- Network Next Hop Metric LocPrf Weight Path
-*> 192.168.0.0/24 0.0.0.0 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> 192.168.0.0/24 0.0.0.0 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref
index 3be6cd3d7b..53c4793bf4 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref
@@ -3,5 +3,5 @@ Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
- Network Next Hop Metric LocPrf Weight Path
-*> 192.168.0.0 0.0.0.0 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> 192.168.0.0 0.0.0.0 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref
index 20034b7408..fe3f0720d8 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref
@@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
- Network Next Hop Metric LocPrf Weight Path
-*> fc00::/64 :: 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> fc00::/64 :: 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref
index fffee63c6b..363b4f5349 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref
@@ -3,5 +3,5 @@ Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
- Network Next Hop Metric LocPrf Weight Path
-*> fc00::/64 :: 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> fc00::/64 :: 0 32768 i
diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref
index 5b5f8596cf..8c3229b45d 100644
--- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref
+++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref
@@ -6,5 +6,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
- Network Next Hop Metric LocPrf Weight Path
-*> fc00::/64 :: 0 32768 i
+ Network Next Hop Metric LocPrf Weight Path
+ *> fc00::/64 :: 0 32768 i
diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
index 3b84a99cdf..e131fba0c3 100644
--- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
+++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py
@@ -47,10 +47,12 @@ from lib.common_config import (
step,
create_interfaces_cfg,
topo_daemons,
+ retry,
+ run_frr_cmd,
)
from lib.topolog import logger
from lib.topojson import build_config_from_json
-from lib.topotest import frr_unicode
+from lib.topotest import frr_unicode, json_cmp
from lib.ospf import (
verify_ospf_interface,
@@ -378,6 +380,158 @@ def test_ospf_p2mp_tc1_p0(request):
write_test_footer(tc_name)
+@retry(retry_timeout=30)
+def verify_ospf_json(tgen, dut, input_dict, cmd="show ip ospf database json"):
+ del tgen
+ show_ospf_json = run_frr_cmd(dut, cmd, isjson=True)
+ if not bool(show_ospf_json):
+ return "ospf is not running"
+ result = json_cmp(show_ospf_json, input_dict)
+ return str(result) if result else None
+
+
+@pytest.mark.parametrize("tgen", [2], indirect=True)
+def test_ospf_nbrs(tgen):
+ db_full = {
+ "areas": {
+ "0.0.0.0": {
+ "routerLinkStates": [
+ {
+ "lsId": "100.1.1.0",
+ "advertisedRouter": "100.1.1.0",
+ "numOfRouterLinks": 6,
+ },
+ {
+ "lsId": "100.1.1.1",
+ "advertisedRouter": "100.1.1.1",
+ "numOfRouterLinks": 6,
+ },
+ {
+ "lsId": "100.1.1.2",
+ "advertisedRouter": "100.1.1.2",
+ "numOfRouterLinks": 6,
+ },
+ {
+ "lsId": "100.1.1.3",
+ "advertisedRouter": "100.1.1.3",
+ "numOfRouterLinks": 7,
+ },
+ ]
+ }
+ }
+ }
+ input = [
+ [
+ "r0",
+ "show ip ospf n json",
+ {
+ "neighbors": {
+ "100.1.1.1": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.2": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.3": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ }
+ },
+ ],
+ [
+ "r1",
+ "show ip ospf n json",
+ {
+ "neighbors": {
+ "100.1.1.0": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.2": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.3": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ }
+ },
+ ],
+ [
+ "r2",
+ "show ip ospf n json",
+ {
+ "neighbors": {
+ "100.1.1.0": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.1": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.3": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ }
+ },
+ ],
+ [
+ "r3",
+ "show ip ospf n json",
+ {
+ "neighbors": {
+ "100.1.1.0": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.1": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ "100.1.1.2": [
+ {
+ "state": "Full/DROther",
+ }
+ ],
+ }
+ },
+ ],
+ ["r0", "show ip ospf database json", db_full],
+ ["r1", "show ip ospf database json", db_full],
+ ["r2", "show ip ospf database json", db_full],
+ ["r3", "show ip ospf database json", db_full],
+ ["r0", "show ip ospf database json", db_full],
+ ["r0", "show ip ospf database router json", {}],
+ ["r0", "show ip ospf interface traffic json", {}],
+ ["r1", "show ip ospf interface traffic json", {}],
+ ["r2", "show ip ospf interface traffic json", {}],
+ ["r3", "show ip ospf interface traffic json", {}],
+ ]
+ for cmd_set in input:
+ step("test_ospf: %s - %s" % (cmd_set[0], cmd_set[1]))
+ assert (
+ verify_ospf_json(tgen, tgen.gears[cmd_set[0]], cmd_set[2], cmd_set[1])
+ is None
+ )
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index d98f83dbf6..0f28b49f72 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -652,18 +652,21 @@ int vtysh_read_config(const char *config_default_dir, bool dry_run)
*/
void vtysh_config_write(void)
{
+ const char *name;
char line[512];
- if (cmd_hostname_get()) {
- snprintf(line, sizeof(line), "hostname %s", cmd_hostname_get());
+ name = cmd_hostname_get();
+ if (name && name[0] != '\0') {
+ snprintf(line, sizeof(line), "hostname %s", name);
vtysh_config_parse_line(NULL, line);
}
- if (cmd_domainname_get()) {
- snprintf(line, sizeof(line), "domainname %s",
- cmd_domainname_get());
+ name = cmd_domainname_get();
+ if (name && name[0] != '\0') {
+ snprintf(line, sizeof(line), "domainname %s", name);
vtysh_config_parse_line(NULL, line);
}
+
if (vtysh_write_integrated == WRITE_INTEGRATED_NO)
vtysh_config_parse_line(NULL,
"no service integrated-vtysh-config");