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_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.c21
-rw-r--r--bgpd/bgpd.c26
-rw-r--r--isisd/isis_te.c103
-rw-r--r--isisd/isisd.c6
-rw-r--r--ldpd/neighbor.c3
-rw-r--r--lib/if.c26
-rw-r--r--lib/if.h2
-rw-r--r--lib/zclient.c70
-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_nht.c5
-rw-r--r--pimd/pim_rp.c4
-rw-r--r--pimd/pim_tib.c3
-rw-r--r--pimd/pim_vty.c2
-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
-rw-r--r--zebra/interface.c83
-rw-r--r--zebra/zapi_msg.c5
46 files changed, 574 insertions, 217 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_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 c5ce295c55..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])
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 1583eba50b..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;
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 0093279cde..155d1e6fed 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -66,6 +66,8 @@
DEFINE_MTYPE_STATIC(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters");
+static void isis_mpls_te_circuit_ip_update(struct isis_circuit *circuit);
+
/*------------------------------------------------------------------------*
* Following are control functions for MPLS-TE parameters management.
*------------------------------------------------------------------------*/
@@ -111,9 +113,13 @@ void isis_mpls_te_create(struct isis_area *area)
if (area->mta->ted)
isis_te_init_ted(area);
- /* Update Extended TLVs according to Interface link parameters */
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit))
+ /* Update Extended TLVs according to Interface link parameters
+ * and neighbor IP addresses
+ */
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
isis_link_params_update(circuit, circuit->interface);
+ isis_mpls_te_circuit_ip_update(circuit);
+ }
}
/**
@@ -132,7 +138,7 @@ void isis_mpls_te_disable(struct isis_area *area)
area->mta->status = disable;
/* Remove Link State Database */
- ls_ted_del_all(&area->mta->ted);
+ ls_ted_clean(area->mta->ted);
/* Disable Extended SubTLVs on all circuit */
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
@@ -336,16 +342,12 @@ void isis_link_params_update(struct isis_circuit *circuit,
return;
}
-static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family,
- bool global)
+static int _isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family,
+ bool global)
{
struct isis_circuit *circuit;
struct isis_ext_subtlvs *ext;
- /* Sanity Check */
- if (!adj || !adj->circuit)
- return 0;
-
circuit = adj->circuit;
/* Check that MPLS TE is enabled */
@@ -366,6 +368,12 @@ static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family,
}
break;
case AF_INET6:
+ /* Nothing to do for link-local addresses - ie. not global.
+ * https://datatracker.ietf.org/doc/html/rfc6119#section-3.1.1
+ * Because the IPv6 traffic engineering TLVs present in LSPs are
+ * propagated across networks, they MUST NOT use link-local
+ * addresses.
+ */
if (!global)
return 0;
@@ -381,22 +389,32 @@ static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family,
return 0;
}
- /* Update LSP */
- lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
-
return 0;
}
-static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family,
- bool global)
+static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family,
+ bool global)
{
- struct isis_circuit *circuit;
- struct isis_ext_subtlvs *ext;
+ int ret;
/* Sanity Check */
- if (!adj || !adj->circuit || !adj->circuit->ext)
+ if (!adj || !adj->circuit)
return 0;
+ ret = _isis_mpls_te_adj_ip_enabled(adj, family, global);
+
+ /* Update LSP */
+ lsp_regenerate_schedule(adj->circuit->area, adj->circuit->is_type, 0);
+
+ return ret;
+}
+
+static int _isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family,
+ bool global)
+{
+ struct isis_circuit *circuit;
+ struct isis_ext_subtlvs *ext;
+
circuit = adj->circuit;
/* Check that MPLS TE is enabled */
@@ -422,12 +440,59 @@ static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family,
return 0;
}
+ return 0;
+}
+
+static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family,
+ bool global)
+{
+ int ret;
+
+ /* Sanity Check */
+ if (!adj || !adj->circuit || !adj->circuit->ext)
+ return 0;
+
+ ret = _isis_mpls_te_adj_ip_disabled(adj, family, global);
+
/* Update LSP */
- lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
+ lsp_regenerate_schedule(adj->circuit->area, adj->circuit->is_type, 0);
- return 0;
+ return ret;
}
+static void isis_mpls_te_circuit_ip_update(struct isis_circuit *circuit)
+{
+ struct isis_adjacency *adj;
+
+ /* https://datatracker.ietf.org/doc/html/rfc6119#section-3.2.3
+ * This sub-TLV of the Extended IS Reachability TLV is used for point-
+ * to-point links
+ */
+ if (circuit->circ_type != CIRCUIT_T_P2P)
+ return;
+
+ adj = circuit->u.p2p.neighbor;
+
+ if (!adj)
+ return;
+
+ /* Nothing to do for link-local addresses.
+ * https://datatracker.ietf.org/doc/html/rfc6119#section-3.1.1
+ * Because the IPv6 traffic engineering TLVs present in LSPs are
+ * propagated across networks, they MUST NOT use link-local addresses.
+ */
+ if (adj->ipv4_address_count > 0)
+ _isis_mpls_te_adj_ip_enabled(adj, AF_INET, false);
+ else
+ _isis_mpls_te_adj_ip_disabled(adj, AF_INET, false);
+
+ if (adj->global_ipv6_count > 0)
+ _isis_mpls_te_adj_ip_enabled(adj, AF_INET6, true);
+ else
+ _isis_mpls_te_adj_ip_disabled(adj, AF_INET6, true);
+}
+
+
int isis_mpls_te_update(struct interface *ifp)
{
struct isis_circuit *circuit;
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/if.c b/lib/if.c
index fa4fdb82d3..deb0690dcf 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1095,13 +1095,15 @@ const char *if_link_type_str(enum zebra_link_type llt)
struct if_link_params *if_link_params_get(struct interface *ifp)
{
- int i;
+ return ifp->link_params;
+}
- if (ifp->link_params != NULL)
- return ifp->link_params;
+struct if_link_params *if_link_params_enable(struct interface *ifp)
+{
+ struct if_link_params *iflp;
+ int i;
- struct if_link_params *iflp =
- XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params));
+ iflp = if_link_params_init(ifp);
/* Compute default bandwidth based on interface */
iflp->default_bw =
@@ -1129,6 +1131,20 @@ struct if_link_params *if_link_params_get(struct interface *ifp)
return iflp;
}
+struct if_link_params *if_link_params_init(struct interface *ifp)
+{
+ struct if_link_params *iflp = if_link_params_get(ifp);
+
+ if (iflp)
+ return iflp;
+
+ iflp = XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params));
+
+ ifp->link_params = iflp;
+
+ return iflp;
+}
+
void if_link_params_free(struct interface *ifp)
{
XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
diff --git a/lib/if.h b/lib/if.h
index 1c948b875a..478a90d63a 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -588,6 +588,8 @@ struct connected *connected_get_linklocal(struct interface *ifp);
/* link parameters */
struct if_link_params *if_link_params_get(struct interface *);
+struct if_link_params *if_link_params_enable(struct interface *ifp);
+struct if_link_params *if_link_params_init(struct interface *ifp);
void if_link_params_free(struct interface *);
/* Northbound. */
diff --git a/lib/zclient.c b/lib/zclient.c
index 8ec82ab7bb..4a553f4718 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -2299,13 +2299,22 @@ static int zclient_handle_error(ZAPI_CALLBACK_ARGS)
return 0;
}
-static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
+static int link_params_set_value(struct stream *s, struct interface *ifp)
{
+ uint8_t link_params_enabled;
+ struct if_link_params *iflp;
+ uint32_t bwclassnum;
+
+ iflp = if_link_params_get(ifp);
if (iflp == NULL)
- return -1;
+ iflp = if_link_params_init(ifp);
- uint32_t bwclassnum;
+ STREAM_GETC(s, link_params_enabled);
+ if (!link_params_enabled) {
+ if_link_params_free(ifp);
+ return 0;
+ }
STREAM_GETL(s, iflp->lp_status);
STREAM_GETL(s, iflp->te_metric);
@@ -2346,9 +2355,9 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
bool *changed)
{
struct if_link_params *iflp;
- struct if_link_params iflp_copy;
+ struct if_link_params iflp_prev;
ifindex_t ifindex;
- bool params_changed = false;
+ bool iflp_prev_set;
STREAM_GETL(s, ifindex);
@@ -2361,22 +2370,33 @@ struct interface *zebra_interface_link_params_read(struct stream *s,
return NULL;
}
- if (ifp->link_params == NULL)
- params_changed = true;
-
- if ((iflp = if_link_params_get(ifp)) == NULL)
- return NULL;
-
- memcpy(&iflp_copy, iflp, sizeof(iflp_copy));
+ if (if_link_params_get(ifp)) {
+ iflp_prev_set = true;
+ memcpy(&iflp_prev, ifp->link_params, sizeof(iflp_prev));
+ } else
+ iflp_prev_set = false;
- if (link_params_set_value(s, iflp) != 0)
+ /* read the link_params from stream
+ * Free ifp->link_params if the stream has no params
+ * to means that link-params are not enabled on links.
+ */
+ if (link_params_set_value(s, ifp) != 0)
goto stream_failure;
- if (memcmp(&iflp_copy, iflp, sizeof(iflp_copy)))
- params_changed = true;
+ if (changed == NULL)
+ return ifp;
+
+ iflp = if_link_params_get(ifp);
- if (changed)
- *changed = params_changed;
+ if (iflp_prev_set && iflp) {
+ if (memcmp(&iflp_prev, iflp, sizeof(iflp_prev)))
+ *changed = true;
+ else
+ *changed = false;
+ } else if (!iflp_prev_set && !iflp)
+ *changed = false;
+ else
+ *changed = true;
return ifp;
@@ -2415,10 +2435,8 @@ static void zebra_interface_if_set_value(struct stream *s,
/* Read Traffic Engineering status */
link_params_status = stream_getc(s);
/* Then, Traffic Engineering parameters if any */
- if (link_params_status) {
- struct if_link_params *iflp = if_link_params_get(ifp);
- link_params_set_value(s, iflp);
- }
+ if (link_params_status)
+ link_params_set_value(s, ifp);
nexthop_group_interface_state_change(ifp, old_ifindex);
@@ -2435,12 +2453,20 @@ size_t zebra_interface_link_params_write(struct stream *s,
struct if_link_params *iflp;
int i;
- if (s == NULL || ifp == NULL || ifp->link_params == NULL)
+ if (s == NULL || ifp == NULL)
return 0;
iflp = ifp->link_params;
w = 0;
+ /* encode if link_params is enabled */
+ if (iflp) {
+ w += stream_putc(s, true);
+ } else {
+ w += stream_putc(s, false);
+ return w;
+ }
+
w += stream_putl(s, iflp->lp_status);
w += stream_putl(s, iflp->te_metric);
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_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_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_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/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");
diff --git a/zebra/interface.c b/zebra/interface.c
index c674b499ac..5d62ec071f 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -3279,14 +3279,8 @@ DEFUN (link_params_enable,
"Link-params: enable TE link parameters on interface %s",
ifp->name);
- if (!if_link_params_get(ifp)) {
- if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS)
- zlog_debug(
- "Link-params: failed to init TE link parameters %s",
- ifp->name);
-
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!if_link_params_get(ifp))
+ if_link_params_enable(ifp);
/* force protocols to update LINK STATE due to parameters change */
if (if_is_operative(ifp))
@@ -3330,6 +3324,9 @@ DEFUN (link_params_metric,
metric = strtoul(argv[idx_number]->arg, NULL, 10);
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update TE metric if needed */
link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric);
@@ -3370,17 +3367,20 @@ DEFUN (link_params_maxbw,
/* Check that Maximum bandwidth is not lower than other bandwidth
* parameters */
- if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0])
- || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2])
- || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4])
- || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6])
- || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw)
- || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) {
+ if (iflp && ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) ||
+ (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) ||
+ (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) ||
+ (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) ||
+ (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) ||
+ (bw <= iflp->res_bw) || (bw <= iflp->use_bw))) {
vty_out(vty,
"Maximum Bandwidth could not be lower than others bandwidth\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Maximum Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw);
@@ -3406,13 +3406,16 @@ DEFUN (link_params_max_rsv_bw,
/* Check that bandwidth is not greater than maximum bandwidth parameter
*/
- if (bw > iflp->max_bw) {
+ if (iflp && bw > iflp->max_bw) {
vty_out(vty,
"Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
iflp->max_bw);
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Maximum Reservable Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw);
@@ -3448,13 +3451,16 @@ DEFUN (link_params_unrsv_bw,
/* Check that bandwidth is not greater than maximum bandwidth parameter
*/
- if (bw > iflp->max_bw) {
+ if (iflp && bw > iflp->max_bw) {
vty_out(vty,
"UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
iflp->max_bw);
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Unreserved Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW,
bw);
@@ -3479,6 +3485,9 @@ DEFUN (link_params_admin_grp,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Administrative Group if needed */
link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value);
@@ -3521,6 +3530,9 @@ DEFUN (link_params_inter_as,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
as = strtoul(argv[idx_number]->arg, NULL, 10);
/* Update Remote IP and Remote AS fields if needed */
@@ -3548,6 +3560,9 @@ DEFUN (no_link_params_inter_as,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct if_link_params *iflp = if_link_params_get(ifp);
+ if (!iflp)
+ return CMD_SUCCESS;
+
/* Reset Remote IP and AS neighbor */
iflp->rmt_as = 0;
iflp->rmt_ip.s_addr = 0;
@@ -3595,13 +3610,17 @@ DEFUN (link_params_delay,
* Therefore, it is also allowed that the average
* delay be equal to the min delay or max delay.
*/
- if (IS_PARAM_SET(iflp, LP_MM_DELAY)
- && (delay < iflp->min_delay || delay > iflp->max_delay)) {
+ if (iflp && IS_PARAM_SET(iflp, LP_MM_DELAY) &&
+ (delay < iflp->min_delay || delay > iflp->max_delay)) {
vty_out(vty,
"Average delay should be in range Min (%d) - Max (%d) delay\n",
iflp->min_delay, iflp->max_delay);
return CMD_WARNING_CONFIG_FAILED;
}
+
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update delay if value is not set or change */
if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) {
iflp->av_delay = delay;
@@ -3626,6 +3645,10 @@ DEFUN (link_params_delay,
low, high);
return CMD_WARNING_CONFIG_FAILED;
}
+
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Delays if needed */
if (IS_PARAM_UNSET(iflp, LP_DELAY)
|| IS_PARAM_UNSET(iflp, LP_MM_DELAY)
@@ -3656,6 +3679,9 @@ DEFUN (no_link_params_delay,
VTY_DECLVAR_CONTEXT(interface, ifp);
struct if_link_params *iflp = if_link_params_get(ifp);
+ if (!iflp)
+ return CMD_SUCCESS;
+
/* Unset Delays */
iflp->av_delay = 0;
UNSET_PARAM(iflp, LP_DELAY);
@@ -3683,6 +3709,9 @@ DEFUN (link_params_delay_var,
value = strtoul(argv[idx_number]->arg, NULL, 10);
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Delay Variation if needed */
link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value);
@@ -3723,6 +3752,9 @@ DEFUN (link_params_pkt_loss,
if (fval > MAX_PKT_LOSS)
fval = MAX_PKT_LOSS;
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Packet Loss if needed */
link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval);
@@ -3762,13 +3794,16 @@ DEFUN (link_params_res_bw,
/* Check that bandwidth is not greater than maximum bandwidth parameter
*/
- if (bw > iflp->max_bw) {
+ if (iflp && bw > iflp->max_bw) {
vty_out(vty,
"Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
iflp->max_bw);
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Residual Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw);
@@ -3808,13 +3843,16 @@ DEFUN (link_params_ava_bw,
/* Check that bandwidth is not greater than maximum bandwidth parameter
*/
- if (bw > iflp->max_bw) {
+ if (iflp && bw > iflp->max_bw) {
vty_out(vty,
"Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
iflp->max_bw);
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Residual Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw);
@@ -3854,13 +3892,16 @@ DEFUN (link_params_use_bw,
/* Check that bandwidth is not greater than maximum bandwidth parameter
*/
- if (bw > iflp->max_bw) {
+ if (iflp && bw > iflp->max_bw) {
vty_out(vty,
"Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n",
iflp->max_bw);
return CMD_WARNING_CONFIG_FAILED;
}
+ if (!iflp)
+ iflp = if_link_params_enable(ifp);
+
/* Update Utilized Bandwidth if needed */
link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw);
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 761ba789b8..4d7ad21bf3 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -232,11 +232,6 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- if (!ifp->link_params) {
- stream_free(s);
- return 0;
- }
-
zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf->vrf_id);
/* Add Interface Index */