diff options
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"); |
