summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_flowspec_vty.c2
-rw-r--r--bgpd/bgp_fsm.c46
-rw-r--r--bgpd/bgp_network.c18
-rw-r--r--bgpd/bgp_network.h4
-rw-r--r--bgpd/bgp_nexthop.c2
-rw-r--r--bgpd/bgp_nht.c11
-rw-r--r--bgpd/bgp_packet.c2
-rw-r--r--bgpd/bgp_vty.c23
-rw-r--r--bgpd/bgp_zebra.c2
-rw-r--r--bgpd/bgpd.c240
-rw-r--r--bgpd/bgpd.h5
-rw-r--r--doc/user/bgp.rst1
-rw-r--r--docker/ubuntu-ci/Dockerfile3
-rw-r--r--lib/table.c26
-rw-r--r--lib/table.h4
-rw-r--r--nhrpd/nhrp_vty.c7
-rw-r--r--ripd/ripd.c8
-rw-r--r--tests/topotests/all_protocol_startup/test_all_protocol_startup.py72
-rw-r--r--tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json131
-rw-r--r--tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json191
-rw-r--r--tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json131
-rw-r--r--tests/topotests/bgp_evpn_rt5/r2/bgpd.conf22
-rw-r--r--tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py243
-rw-r--r--tests/topotests/lib/snmptest.py6
-rw-r--r--tests/topotests/simple_snmp_test/r1/isisd.conf2
-rw-r--r--tests/topotests/simple_snmp_test/r1/ospf6d.conf12
-rw-r--r--tests/topotests/simple_snmp_test/r1/ospfd.conf11
-rw-r--r--tests/topotests/simple_snmp_test/r1/ripd.conf8
-rw-r--r--tests/topotests/simple_snmp_test/r1/zebra.conf3
-rwxr-xr-xtests/topotests/simple_snmp_test/test_simple_snmp.py52
-rw-r--r--zebra/interface.c36
-rw-r--r--zebra/ioctl.c2
-rw-r--r--zebra/zebra_vxlan.c7
-rw-r--r--zebra/zebra_vxlan_if.c2
34 files changed, 989 insertions, 346 deletions
diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c
index d4ccca84bb..3d2dda4ee4 100644
--- a/bgpd/bgp_flowspec_vty.c
+++ b/bgpd/bgp_flowspec_vty.c
@@ -441,7 +441,7 @@ int bgp_show_table_flowspec(struct vty *vty, struct bgp *bgp, afi_t afi,
}
if (total_count && !use_json)
vty_out(vty,
- "\nDisplayed %ld flowspec entries\n",
+ "\nDisplayed %ld flowspec entries\n",
total_count);
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 490451f193..cadef39974 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -265,7 +265,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
from_peer->addpath_paths_limit[afi][safi];
}
- if (bgp_getsockname(peer) < 0) {
+ if (bgp_getsockname(keeper) < 0) {
flog_err(EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s peer %s fd %d (from_peer fd %d)",
(CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)
@@ -277,7 +277,7 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
return NULL;
}
if (going_away->status > Active) {
- if (bgp_getsockname(from_peer) < 0) {
+ if (bgp_getsockname(going_away) < 0) {
flog_err(EC_LIB_SOCKET,
"%%bgp_getsockname() failed for %s from_peer %s fd %d (peer fd %d)",
@@ -325,8 +325,8 @@ void bgp_timer_set(struct peer_connection *connection)
/* First entry point of peer's finite state machine. In Idle
status start timer is on unless peer is shutdown or peer is
inactive. All other timer must be turned off */
- if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(peer)
- || peer->bgp->vrf_id == VRF_UNKNOWN) {
+ if (BGP_PEER_START_SUPPRESSED(peer) || !peer_active(connection) ||
+ peer->bgp->vrf_id == VRF_UNKNOWN) {
EVENT_OFF(connection->t_start);
} else {
BGP_TIMER_ON(connection->t_start, bgp_start_timer,
@@ -1694,11 +1694,11 @@ bgp_connect_success(struct peer_connection *connection)
return bgp_stop(connection);
}
- if (bgp_getsockname(peer) < 0) {
+ if (bgp_getsockname(connection) < 0) {
flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname(): failed for peer %s, fd %d",
__func__, peer->host, connection->fd);
- bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR,
+ bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR,
bgp_fsm_error_subcode(connection->status));
bgp_writes_on(connection);
return BGP_FSM_FAILURE;
@@ -1740,11 +1740,11 @@ bgp_connect_success_w_delayopen(struct peer_connection *connection)
return bgp_stop(connection);
}
- if (bgp_getsockname(peer) < 0) {
+ if (bgp_getsockname(connection) < 0) {
flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname(): failed for peer %s, fd %d",
__func__, peer->host, connection->fd);
- bgp_notify_send(peer->connection, BGP_NOTIFY_FSM_ERR,
+ bgp_notify_send(connection, BGP_NOTIFY_FSM_ERR,
bgp_fsm_error_subcode(connection->status));
bgp_writes_on(connection);
return BGP_FSM_FAILURE;
@@ -1807,12 +1807,14 @@ bgp_connect_fail(struct peer_connection *connection)
/* after connect is called(), getpeername is able to return
* port and address on non established streams
*/
-static void bgp_connect_in_progress_update_connection(struct peer *peer)
+static void bgp_connect_in_progress_update_connection(struct peer_connection *connection)
{
- bgp_updatesockname(peer);
+ struct peer *peer = connection->peer;
+
+ bgp_updatesockname(peer, connection);
if (!peer->su_remote && !BGP_CONNECTION_SU_UNSPEC(peer->connection)) {
/* if connect initiated, then dest port and dest addresses are well known */
- peer->su_remote = sockunion_dup(&peer->connection->su);
+ peer->su_remote = sockunion_dup(&connection->su);
if (sockunion_family(peer->su_remote) == AF_INET)
peer->su_remote->sin.sin_port = htons(peer->port);
else if (sockunion_family(peer->su_remote) == AF_INET6)
@@ -1916,7 +1918,7 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection)
__func__, peer->connection->fd);
return BGP_FSM_FAILURE;
}
- bgp_connect_in_progress_update_connection(peer);
+ bgp_connect_in_progress_update_connection(connection);
/*
* - when the socket becomes ready, poll() will signify POLLOUT
@@ -2745,10 +2747,7 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp,
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset_safe(peer, &nnode);
} else {
group = peer->group;
@@ -2768,10 +2767,7 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp,
member->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
}
}
@@ -2973,10 +2969,7 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state,
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
} else {
group = peer->group;
@@ -2984,10 +2977,7 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state,
member->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
bgp_peer_move_to_gr_mode(member, new_state);
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
}
}
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 844f6b9af2..f1bea1c189 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -504,7 +504,7 @@ static void bgp_accept(struct event *thread)
bgp_fsm_change_status(connection1, Active);
EVENT_OFF(connection1->t_start);
- if (peer_active(peer1)) {
+ if (peer_active(peer1->connection)) {
if (CHECK_FLAG(peer1->flags,
PEER_FLAG_TIMER_DELAYOPEN))
BGP_EVENT_ADD(connection1,
@@ -557,7 +557,7 @@ static void bgp_accept(struct event *thread)
}
/* Check that at least one AF is activated for the peer. */
- if (!peer_active(peer1)) {
+ if (!peer_active(connection1)) {
if (bgp_debug_neighbor_events(peer1))
zlog_debug(
"%s - incoming conn rejected - no AF activated for peer",
@@ -658,7 +658,7 @@ static void bgp_accept(struct event *thread)
bgp_event_update(connection1, TCP_connection_closed);
}
- if (peer_active(peer)) {
+ if (peer_active(peer->connection)) {
if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER_DELAYOPEN))
BGP_EVENT_ADD(connection, TCP_connection_open_w_delay);
else
@@ -861,7 +861,7 @@ enum connect_result bgp_connect(struct peer_connection *connection)
htons(peer->port), ifindex);
}
-void bgp_updatesockname(struct peer *peer)
+void bgp_updatesockname(struct peer *peer, struct peer_connection *connection)
{
if (peer->su_local) {
sockunion_free(peer->su_local);
@@ -873,14 +873,16 @@ void bgp_updatesockname(struct peer *peer)
peer->su_remote = NULL;
}
- peer->su_local = sockunion_getsockname(peer->connection->fd);
- peer->su_remote = sockunion_getpeername(peer->connection->fd);
+ peer->su_local = sockunion_getsockname(connection->fd);
+ peer->su_remote = sockunion_getpeername(connection->fd);
}
/* After TCP connection is established. Get local address and port. */
-int bgp_getsockname(struct peer *peer)
+int bgp_getsockname(struct peer_connection *connection)
{
- bgp_updatesockname(peer);
+ struct peer *peer = connection->peer;
+
+ bgp_updatesockname(peer, peer->connection);
if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote,
&peer->nexthop, peer)) {
diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h
index 61ca19a34d..ed1a72ec89 100644
--- a/bgpd/bgp_network.h
+++ b/bgpd/bgp_network.h
@@ -22,8 +22,8 @@ extern int bgp_socket(struct bgp *bgp, unsigned short port,
extern void bgp_close_vrf_socket(struct bgp *bgp);
extern void bgp_close(void);
extern enum connect_result bgp_connect(struct peer_connection *connection);
-extern int bgp_getsockname(struct peer *peer);
-extern void bgp_updatesockname(struct peer *peer);
+extern int bgp_getsockname(struct peer_connection *connection);
+extern void bgp_updatesockname(struct peer *peer, struct peer_connection *connection);
extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p,
const char *password);
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index bf0f3b15cf..1ef90a8e38 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -444,7 +444,7 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc)
!peer_established(peer->connection) &&
!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) {
connection = peer->connection;
- if (peer_active(peer))
+ if (peer_active(connection))
BGP_EVENT_ADD(connection, BGP_Stop);
BGP_EVENT_ADD(connection, BGP_Start);
}
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 9b633b7139..ed83757ea3 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -1066,9 +1066,16 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
case AFI_IP6:
p->family = AF_INET6;
if (pi->attr->srv6_l3vpn) {
- IPV6_ADDR_COPY(&(p->u.prefix6),
- &(pi->attr->srv6_l3vpn->sid));
p->prefixlen = IPV6_MAX_BITLEN;
+ if (pi->attr->srv6_l3vpn->transposition_len != 0 &&
+ BGP_PATH_INFO_NUM_LABELS(pi)) {
+ IPV6_ADDR_COPY(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid);
+ transpose_sid(&p->u.prefix6,
+ decode_label(&pi->extra->labels->label[0]),
+ pi->attr->srv6_l3vpn->transposition_offset,
+ pi->attr->srv6_l3vpn->transposition_len);
+ } else
+ IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3vpn->sid));
} else if (is_bgp_static) {
p->u.prefix6 = p_orig->u.prefix6;
p->prefixlen = p_orig->prefixlen;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index a76a300c11..e9cc52449b 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2054,7 +2054,7 @@ static int bgp_open_receive(struct peer_connection *connection,
return BGP_Stop;
/* Get sockname. */
- if (bgp_getsockname(peer) < 0) {
+ if (bgp_getsockname(connection) < 0) {
flog_err_sys(EC_LIB_SOCKET,
"%s: bgp_getsockname() failed for peer: %s",
__func__, peer->host);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index d1238bc8de..6ff94129dc 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2940,9 +2940,7 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd,
*/
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
peer->last_reset = PEER_DOWN_AS_SETS_REJECT;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
return CMD_SUCCESS;
@@ -2965,9 +2963,7 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd,
*/
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
peer->last_reset = PEER_DOWN_AS_SETS_REJECT;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
return CMD_SUCCESS;
@@ -5100,10 +5096,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
peer->last_reset = PEER_DOWN_V6ONLY_CHANGE;
/* v6only flag changed. Reset bgp seesion */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
}
@@ -5264,7 +5257,7 @@ DEFUN (no_neighbor,
* interface. */
if (peer->ifp)
bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
+ peer_notify_unconfig(peer->connection);
peer_delete(peer);
return CMD_SUCCESS;
}
@@ -5300,10 +5293,10 @@ DEFUN (no_neighbor,
if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
+ peer_notify_unconfig(peer->connection);
peer_delete(peer);
if (other && other->connection->status != Deleted) {
- peer_notify_unconfig(other);
+ peer_notify_unconfig(other->connection);
peer_delete(other);
}
}
@@ -5338,7 +5331,7 @@ DEFUN (no_neighbor_interface_config,
/* Request zebra to terminate IPv6 RAs on this interface. */
if (peer->ifp)
bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
+ peer_notify_unconfig(peer->connection);
peer_delete(peer);
} else {
vty_out(vty, "%% Create the bgp interface first\n");
@@ -5746,7 +5739,7 @@ DEFUN (no_neighbor_set_peer_group,
if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
+ peer_notify_unconfig(peer->connection);
ret = peer_delete(peer);
return bgp_vty_return(vty, ret);
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 16f4a0d2df..688dfacaa0 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -137,7 +137,7 @@ static void bgp_start_interface_nbrs(struct bgp *bgp, struct interface *ifp)
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->conf_if && (strcmp(peer->conf_if, ifp->name) == 0) &&
!peer_established(peer->connection)) {
- if (peer_active(peer))
+ if (peer_active(peer->connection))
BGP_EVENT_ADD(peer->connection, BGP_Stop);
BGP_EVENT_ADD(peer->connection, BGP_Start);
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 258fc87f96..f92ae969f8 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -309,9 +309,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id,
peer->last_reset = PEER_DOWN_RID_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
/* EVPN uses router id in RD, update them */
@@ -447,8 +445,7 @@ void bm_wait_for_fib_set(bool set)
peer->connection->status))
continue;
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
}
}
@@ -507,8 +504,7 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set)
if (!BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
continue;
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
}
@@ -532,9 +528,7 @@ void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
peer->last_reset = PEER_DOWN_CLID_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
}
@@ -556,9 +550,7 @@ void bgp_cluster_id_unset(struct bgp *bgp)
peer->last_reset = PEER_DOWN_CLID_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
}
@@ -637,14 +629,10 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str)
if (already_confed) {
if (ptype == BGP_PEER_EBGP) {
peer->local_as = as;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status)) {
+ if (peer_notify_config_change(peer->connection))
peer->last_reset =
PEER_DOWN_CONFED_ID_CHANGE;
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
+ else
bgp_session_reset_safe(peer, &nnode);
}
} else {
@@ -655,14 +643,10 @@ void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str)
/* Reset the local_as to be our EBGP one */
if (ptype == BGP_PEER_EBGP)
peer->local_as = as;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status)) {
+ if (peer_notify_config_change(peer->connection))
peer->last_reset =
PEER_DOWN_CONFED_ID_CHANGE;
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
+ else
bgp_session_reset_safe(peer, &nnode);
}
}
@@ -684,12 +668,7 @@ void bgp_confederation_id_unset(struct bgp *bgp)
if (peer_sort(peer) != BGP_PEER_IBGP) {
peer->local_as = bgp->as;
peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status))
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset_safe(peer, &nnode);
}
}
@@ -736,14 +715,10 @@ void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str)
if (peer->as == as) {
peer->local_as = bgp->as;
(void)peer_sort(peer);
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status)) {
+ if (peer_notify_config_change(peer->connection))
peer->last_reset =
PEER_DOWN_CONFED_PEER_CHANGE;
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
+ else
bgp_session_reset_safe(peer, &nnode);
}
}
@@ -793,14 +768,10 @@ void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
if (peer->as == as) {
peer->local_as = bgp->confed_id;
(void)peer_sort(peer);
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status)) {
+ if (peer_notify_config_change(peer->connection))
peer->last_reset =
PEER_DOWN_CONFED_PEER_CHANGE;
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
+ else
bgp_session_reset_safe(peer, &nnode);
}
}
@@ -2015,7 +1986,7 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
}
- active = peer_active(peer);
+ active = peer_active(peer->connection);
if (!active) {
if (peer->connection->su.sa.sa_family == AF_UNSPEC)
peer->last_reset = PEER_DOWN_NBR_ADDR;
@@ -2048,7 +2019,7 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
if (bgp->autoshutdown)
peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
/* Set up peer's events and timers. */
- else if (!active && peer_active(peer))
+ else if (!active && peer_active(peer->connection))
bgp_timer_set(peer->connection);
bgp_peer_gr_flags_update(peer);
@@ -2099,10 +2070,7 @@ void peer_as_change(struct peer *peer, as_t as, enum peer_asn_type as_type,
/* Stop peer. */
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
}
origtype = peer_sort_lookup(peer);
@@ -2444,13 +2412,13 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
if (peer_af_create(peer, afi, safi) == NULL)
return 1;
- active = peer_active(peer);
+ active = peer_active(peer->connection);
peer->afc[afi][safi] = 1;
if (peer->group)
peer_group2peer_config_copy_af(peer->group, peer, afi, safi);
- if (!active && peer_active(peer)) {
+ if (!active && peer_active(peer->connection)) {
bgp_timer_set(peer->connection);
} else {
peer->last_reset = PEER_DOWN_AF_ACTIVATE;
@@ -2467,15 +2435,11 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
false);
}
} else {
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
}
- if (peer->connection->status == OpenSent ||
- peer->connection->status == OpenConfirm)
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
+
/*
* If we are turning on a AFI/SAFI locally and we've
* started bringing a peer up, we need to tell
@@ -2486,10 +2450,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
* activation.
*/
other = peer->doppelganger;
- if (other && (other->connection->status == OpenSent ||
- other->connection->status == OpenConfirm))
- bgp_notify_send(other->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ if (other)
+ peer_notify_config_change(other->connection);
}
return 0;
@@ -2596,14 +2558,10 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi,
bgp_clear_route(peer, afi, safi);
peer->pcount[afi][safi] = 0;
} else {
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
- } else {
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- }
+ } else
+ peer_notify_config_change(peer->connection);
}
return false;
@@ -3076,11 +3034,20 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
return 0;
}
-void peer_notify_unconfig(struct peer *peer)
+bool peer_notify_config_change(struct peer_connection *connection)
{
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(connection->status)) {
+ bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ return true;
+ }
+
+ return false;
+}
+
+void peer_notify_unconfig(struct peer_connection *connection)
+{
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(connection->status))
+ bgp_notify_send(connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG);
}
static void peer_notify_shutdown(struct peer *peer)
@@ -3107,9 +3074,9 @@ void peer_group_notify_unconfig(struct peer_group *group)
other = peer->doppelganger;
if (other && other->connection->status != Deleted) {
other->group = NULL;
- peer_notify_unconfig(other);
+ peer_notify_unconfig(other->connection);
} else
- peer_notify_unconfig(peer);
+ peer_notify_unconfig(peer->connection);
}
}
@@ -3356,10 +3323,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
peer->last_reset = PEER_DOWN_RMAP_BIND;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
}
@@ -3394,7 +3358,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
}
/* Set up peer's events and timers. */
- if (peer_active(peer))
+ if (peer_active(peer->connection))
bgp_timer_set(peer->connection);
}
@@ -4635,9 +4599,11 @@ bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf,
}
/* If peer is configured at least one address family return 1. */
-bool peer_active(struct peer *peer)
+bool peer_active(struct peer_connection *connection)
{
- if (BGP_CONNECTION_SU_UNSPEC(peer->connection))
+ struct peer *peer = connection->peer;
+
+ if (BGP_CONNECTION_SU_UNSPEC(connection))
return false;
if (peer->bfd_config) {
@@ -4726,8 +4692,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
PEER_FLAG_CONFIG_NODE)))
peer_delete(peer->doppelganger);
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
} else if (type == peer_change_reset_in) {
if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_RCV))
bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
@@ -4739,8 +4704,7 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
PEER_FLAG_CONFIG_NODE)))
peer_delete(peer->doppelganger);
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ peer_notify_config_change(peer->connection);
}
} else if (type == peer_change_reset_out) {
paf = peer_af_find(peer, afi, safi);
@@ -4939,10 +4903,7 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag)
peer->v_start = BGP_INIT_START_TIMER;
BGP_EVENT_ADD(peer->connection, BGP_Stop);
}
- } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) {
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
+ } else if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
}
@@ -5426,12 +5387,7 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
if (peer->sort != BGP_PEER_IBGP) {
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status))
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Reconfigure BFD peer with new TTL. */
@@ -5446,10 +5402,7 @@ int peer_ebgp_multihop_set(struct peer *peer, int ttl)
member->ttl = group->conf->ttl;
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
/* Reconfigure BFD peer with new TTL. */
@@ -5484,10 +5437,7 @@ int peer_ebgp_multihop_unset(struct peer *peer)
peer->ttl = ttl;
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Reconfigure BFD peer with new TTL. */
@@ -5502,10 +5452,7 @@ int peer_ebgp_multihop_unset(struct peer *peer)
member->ttl = BGP_DEFAULT_TTL;
if (member->connection->fd >= 0) {
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
}
@@ -5657,10 +5604,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Apply new source configuration to BFD session. */
@@ -5695,10 +5639,7 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname)
member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
/* Apply new source configuration to BFD session. */
@@ -5728,10 +5669,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Apply new source configuration to BFD session. */
@@ -5765,10 +5703,7 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(member);
/* Apply new source configuration to BFD session. */
@@ -5816,10 +5751,7 @@ void peer_update_source_unset(struct peer *peer)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Apply new source configuration to BFD session. */
@@ -5852,10 +5784,7 @@ void peer_update_source_unset(struct peer *peer)
member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
/* Apply new source configuration to BFD session. */
@@ -6369,7 +6298,7 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect)
/* Skip peer-group mechanics for regular peers. */
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
if (!peer_established(peer->connection)) {
- if (peer_active(peer))
+ if (peer_active(peer->connection))
BGP_EVENT_ADD(peer->connection, BGP_Stop);
BGP_EVENT_ADD(peer->connection, BGP_Start);
}
@@ -6390,7 +6319,7 @@ int peer_timers_connect_set(struct peer *peer, uint32_t connect)
member->v_connect = connect;
if (!peer_established(member->connection)) {
- if (peer_active(member))
+ if (peer_active(member->connection))
BGP_EVENT_ADD(member->connection, BGP_Stop);
BGP_EVENT_ADD(member->connection, BGP_Start);
}
@@ -6423,7 +6352,7 @@ int peer_timers_connect_unset(struct peer *peer)
/* Skip peer-group mechanics for regular peers. */
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
if (!peer_established(peer->connection)) {
- if (peer_active(peer))
+ if (peer_active(peer->connection))
BGP_EVENT_ADD(peer->connection, BGP_Stop);
BGP_EVENT_ADD(peer->connection, BGP_Start);
}
@@ -6444,7 +6373,7 @@ int peer_timers_connect_unset(struct peer *peer)
member->v_connect = peer->bgp->default_connect_retry;
if (!peer_established(member->connection)) {
- if (peer_active(member))
+ if (peer_active(member->connection))
BGP_EVENT_ADD(member->connection, BGP_Stop);
BGP_EVENT_ADD(member->connection, BGP_Start);
}
@@ -6885,10 +6814,7 @@ int peer_local_as_unset(struct peer *peer)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
/* Send notification or stop peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
BGP_EVENT_ADD(peer->connection, BGP_Stop);
/* Skip peer-group mechanics for regular peers. */
@@ -6914,10 +6840,7 @@ int peer_local_as_unset(struct peer *peer)
member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
/* Send notification or stop peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
}
@@ -6946,10 +6869,7 @@ int peer_password_set(struct peer *peer, const char *password)
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
peer->last_reset = PEER_DOWN_PASSWORD_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/*
@@ -6984,10 +6904,7 @@ int peer_password_set(struct peer *peer, const char *password)
member->last_reset = PEER_DOWN_PASSWORD_CHANGE;
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
/* Attempt to install password on socket. */
@@ -7030,10 +6947,7 @@ int peer_password_unset(struct peer *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->connection->status))
- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(peer->connection))
bgp_session_reset(peer);
/* Attempt to uninstall password on socket. */
@@ -7057,10 +6971,7 @@ int peer_password_unset(struct peer *peer)
XFREE(MTYPE_PEER_PASSWORD, member->password);
/* Send notification or reset peer depending on state. */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status))
- bgp_notify_send(member->connection, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- else
+ if (!peer_notify_config_change(member->connection))
bgp_session_reset(member);
/* Attempt to uninstall password on socket. */
@@ -8737,8 +8648,7 @@ static int peer_unshut_after_cfg(struct bgp *bgp)
peer->host);
peer->shut_during_cfg = false;
- if (peer_active(peer) &&
- peer->connection->status != Established) {
+ if (peer_active(peer->connection) && peer->connection->status != Established) {
if (peer->connection->status != Idle)
BGP_EVENT_ADD(peer->connection, BGP_Stop);
BGP_EVENT_ADD(peer->connection, BGP_Start);
@@ -8841,11 +8751,7 @@ void bgp_terminate(void)
peer);
continue;
}
- if (BGP_IS_VALID_STATE_FOR_NOTIF(
- peer->connection->status))
- bgp_notify_send(peer->connection,
- BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+ peer_notify_unconfig(peer->connection);
}
}
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index f123188ae8..df55d879e7 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2295,7 +2295,7 @@ extern struct peer *peer_unlock_with_caller(const char *, struct peer *);
extern enum bgp_peer_sort peer_sort(struct peer *peer);
extern enum bgp_peer_sort peer_sort_lookup(struct peer *peer);
-extern bool peer_active(struct peer *);
+extern bool peer_active(struct peer_connection *connection);
extern bool peer_active_nego(struct peer *);
extern bool peer_afc_received(struct peer *peer);
extern bool peer_afc_advertised(struct peer *peer);
@@ -2385,7 +2385,8 @@ extern int peer_remote_as(struct bgp *bgp, union sockunion *su,
extern int peer_group_remote_as(struct bgp *bgp, const char *peer_str, as_t *as,
enum peer_asn_type as_type, const char *as_str);
extern int peer_delete(struct peer *peer);
-extern void peer_notify_unconfig(struct peer *peer);
+extern void peer_notify_unconfig(struct peer_connection *connection);
+extern bool peer_notify_config_change(struct peer_connection *connection);
extern int peer_group_delete(struct peer_group *);
extern int peer_group_remote_as_delete(struct peer_group *);
extern int peer_group_listen_range_add(struct peer_group *, struct prefix *);
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index c0db7f2b87..dafcac7c84 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2938,6 +2938,7 @@ BGP Extended Communities in Route Map
match on to for the purpose of determining what type of SR-TE Policy Tunnel
a BGP route can resolve over, and it also shows the order for resolving the
BGP route if there are different tunnels.
+
- ``00`` Can match on a specific endpoint only which should be the nexthop
of the route(Default Setting).
- ``01`` Can match on a specific endpoint or a null endpoint.
diff --git a/docker/ubuntu-ci/Dockerfile b/docker/ubuntu-ci/Dockerfile
index 5c4649dc32..aaad3bc172 100644
--- a/docker/ubuntu-ci/Dockerfile
+++ b/docker/ubuntu-ci/Dockerfile
@@ -84,10 +84,11 @@ RUN apt update && apt upgrade -y && \
python3 -m pip install xmltodict && \
python3 -m pip install git+https://github.com/Exa-Networks/exabgp@0659057837cd6c6351579e9f0fa47e9fb7de7311
+ARG UID=1000
RUN groupadd -r -g 92 frr && \
groupadd -r -g 85 frrvty && \
adduser --system --ingroup frr --home /home/frr \
- --gecos "FRR suite" --shell /bin/bash frr && \
+ --gecos "FRR suite" -u $UID --shell /bin/bash frr && \
usermod -a -G frrvty frr && \
useradd -d /var/run/exabgp/ -s /bin/false exabgp && \
echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \
diff --git a/lib/table.c b/lib/table.c
index 3bf93894ec..cf185de226 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -208,32 +208,6 @@ struct route_node *route_node_match(struct route_table *table,
return NULL;
}
-struct route_node *route_node_match_ipv4(struct route_table *table,
- const struct in_addr *addr)
-{
- struct prefix_ipv4 p;
-
- memset(&p, 0, sizeof(p));
- p.family = AF_INET;
- p.prefixlen = IPV4_MAX_BITLEN;
- p.prefix = *addr;
-
- return route_node_match(table, (struct prefix *)&p);
-}
-
-struct route_node *route_node_match_ipv6(struct route_table *table,
- const struct in6_addr *addr)
-{
- struct prefix_ipv6 p;
-
- memset(&p, 0, sizeof(p));
- p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_BITLEN;
- p.prefix = *addr;
-
- return route_node_match(table, &p);
-}
-
/* Lookup same prefix node. Return NULL when we can't find route. */
struct route_node *route_node_lookup(struct route_table *table,
union prefixconstptr pu)
diff --git a/lib/table.h b/lib/table.h
index acfc876154..c31be2b688 100644
--- a/lib/table.h
+++ b/lib/table.h
@@ -195,10 +195,6 @@ extern struct route_node *route_node_lookup_maynull(struct route_table *table,
union prefixconstptr pu);
extern struct route_node *route_node_match(struct route_table *table,
union prefixconstptr pu);
-extern struct route_node *route_node_match_ipv4(struct route_table *table,
- const struct in_addr *addr);
-extern struct route_node *route_node_match_ipv6(struct route_table *table,
- const struct in6_addr *addr);
extern unsigned long route_table_count(struct route_table *table);
diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c
index 199f4d75d4..cae93c6e53 100644
--- a/nhrpd/nhrp_vty.c
+++ b/nhrpd/nhrp_vty.c
@@ -933,6 +933,10 @@ static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
if (ctx->afi != family2afi(sockunion_family(&c->remote_addr)))
return;
+ if (ctx->count && !ctx->json)
+ vty_out(ctx->vty, "\n");
+ ctx->count++;
+
sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0]));
if (c->cur.peer)
sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1],
@@ -985,8 +989,6 @@ static void show_ip_opennhrp_cache(struct nhrp_cache *c, void *pctx)
if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC)
vty_out(ctx->vty, "NBMA-NAT-OA-Address: %s\n", buf[2]);
-
- vty_out(ctx->vty, "\n\n");
}
DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
@@ -1030,7 +1032,6 @@ DEFUN(show_ip_nhrp, show_ip_nhrp_cmd,
else
json_object_string_add(json_vrf, "status", "ok");
- ctx.count++;
FOR_ALL_INTERFACES (vrf, ifp)
nhrp_cache_foreach(ifp, show_ip_opennhrp_cache, &ctx);
}
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 8768819fe2..2d038507ab 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -1263,9 +1263,13 @@ static void rip_response_process(struct rip_packet *packet, int size,
rip->vrf->vrf_id)) {
struct route_node *rn;
struct rip_info *rinfo;
+ struct prefix p = { 0 };
- rn = route_node_match_ipv4(rip->table,
- &rte->nexthop);
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_BITLEN;
+ p.u.prefix4 = rte->nexthop;
+
+ rn = route_node_match(rip->table, &p);
if (rn) {
rinfo = rn->info;
diff --git a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
index 0ffd762734..06a350c8e9 100644
--- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
+++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
@@ -20,6 +20,7 @@ import sys
import pytest
import glob
from time import sleep
+from lib.topolog import logger
pytestmark = [
pytest.mark.babeld,
@@ -1715,6 +1716,77 @@ def test_resilient_nexthop_group():
net["r1"].cmd('vtysh -c "conf" -c "no nexthop-group resilience"')
+def test_interface_stuff():
+ global fatal_error
+ net = get_topogen().net
+
+ # Skip if previous fatal error condition is raised
+ if fatal_error != "":
+ pytest.skip(fatal_error)
+
+ print("\n\n** Verifying some interface code")
+ print("************************************\n")
+
+ net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "multicast enable"')
+
+ def _test_interface_multicast_on():
+ output = json.loads(net["r1"].cmd('vtysh -c "show int r1-eth0 json"'))
+ expected = {
+ "r1-eth0": {
+ "flags": "<UP,LOWER_UP,BROADCAST,RUNNING,MULTICAST>",
+ "multicastConfig": "Enabled by CLI",
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_test_interface_multicast_on)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Multicast bit was not set on r1-eth0"
+
+ net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "multicast disable"')
+
+ def _test_interface_multicast_off():
+ output = json.loads(
+ net["r1"].cmd('vtysh -c "show int r1-eth0 vrf default json"')
+ )
+ expected = {
+ "r1-eth0": {
+ "flags": "<UP,LOWER_UP,BROADCAST,RUNNING>",
+ "multicastConfig": "Disabled by CLI",
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_test_interface_multicast_off)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Multicast bit was not turned off on r1-eth0"
+
+ net["r1"].cmd('vtysh -c "conf" -c "interface r1-eth0" -c "no multicast disable"')
+
+ def _test_interface_multicast_disable():
+ output = json.loads(net["r1"].cmd('vtysh -c "show int r1-eth0 json"'))
+ expected = {
+ "r1-eth0": {
+ "flags": "<UP,LOWER_UP,BROADCAST,RUNNING>",
+ "multicastConfig": "Not specified by CLI",
+ }
+ }
+ return topotest.json_cmp(output, expected)
+
+ test_func = functools.partial(_test_interface_multicast_disable)
+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
+ assert result is None, "Multicast bit was set on r1-eth0"
+
+ logger.info("Ensure that these commands are still nominally working")
+ rc, o, e = net["r1"].cmd_status('vtysh -c "show interface description vrf all"')
+ logger.info(o)
+ assert rc == 0
+
+ rc, o, e = net["r1"].cmd_status('vtysh -c "show interface description vrf default"')
+ logger.info(o)
+ assert rc == 0
+
+
def test_shutdown_check_stderr():
global fatal_error
net = get_topogen().net
diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json
new file mode 100644
index 0000000000..7532ce9331
--- /dev/null
+++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes.json
@@ -0,0 +1,131 @@
+{
+ "bgpLocalRouterId":"192.168.100.21",
+ "defaultLocPrf":100,
+ "localAS":65000,
+ "192.168.101.41:2":{
+ "rd":"192.168.101.41:2",
+ "[5]:[0]:[32]:[192.168.101.41]":{
+ "prefix":"[5]:[0]:[32]:[192.168.101.41]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.101.41",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::2]":{
+ "prefix":"[5]:[0]:[128]:[fd00::2]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::2",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "192.168.102.21:2":{
+ "rd":"192.168.102.21:2",
+ "[5]:[0]:[32]:[192.168.102.21]":{
+ "prefix":"[5]:[0]:[32]:[192.168.102.21]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.102.21",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::1]":{
+ "prefix":"[5]:[0]:[128]:[fd00::1]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::1",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "numPrefix":4,
+ "totalPrefix":4
+}
diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json
new file mode 100644
index 0000000000..a14ba1291e
--- /dev/null
+++ b/tests/topotests/bgp_evpn_rt5/r1/bgp_l2vpn_evpn_routes_all.json
@@ -0,0 +1,191 @@
+{
+ "bgpLocalRouterId":"192.168.100.21",
+ "defaultLocPrf":100,
+ "localAS":65000,
+ "192.168.101.41:2":{
+ "rd":"192.168.101.41:2",
+ "[5]:[0]:[32]:[192.168.101.41]":{
+ "prefix":"[5]:[0]:[32]:[192.168.101.41]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.101.41",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[32]:[192.168.102.41]":{
+ "prefix":"[5]:[0]:[32]:[192.168.102.41]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.102.41",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::2]":{
+ "prefix":"[5]:[0]:[128]:[fd00::2]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::2",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::3]":{
+ "prefix":"[5]:[0]:[128]:[fd00::3]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::3",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.41",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "192.168.102.21:2":{
+ "rd":"192.168.102.21:2",
+ "[5]:[0]:[32]:[192.168.102.21]":{
+ "prefix":"[5]:[0]:[32]:[192.168.102.21]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.102.21",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::1]":{
+ "prefix":"[5]:[0]:[128]:[fd00::1]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::1",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "numPrefix":6,
+ "totalPrefix":6
+}
diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json
new file mode 100644
index 0000000000..597bca5fd3
--- /dev/null
+++ b/tests/topotests/bgp_evpn_rt5/r2/bgp_l2vpn_evpn_routes.json
@@ -0,0 +1,131 @@
+{
+ "bgpLocalRouterId":"192.168.100.41",
+ "defaultLocPrf":100,
+ "localAS":65000,
+ "192.168.101.41:2":{
+ "rd":"192.168.101.41:2",
+ "[5]:[0]:[32]:[192.168.101.41]":{
+ "prefix":"[5]:[0]:[32]:[192.168.101.41]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.101.41",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::2]":{
+ "prefix":"[5]:[0]:[128]:[fd00::2]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"external",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::2",
+ "metric":0,
+ "weight":32768,
+ "peerId":"(unspec)",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.41",
+ "hostname":"r2",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "192.168.102.21:2":{
+ "rd":"192.168.102.21:2",
+ "[5]:[0]:[32]:[192.168.102.21]":{
+ "prefix":"[5]:[0]:[32]:[192.168.102.21]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":32,
+ "ip":"192.168.102.21",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.21",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ },
+ "[5]:[0]:[128]:[fd00::1]":{
+ "prefix":"[5]:[0]:[128]:[fd00::1]",
+ "prefixLen":352,
+ "paths":[
+ {
+ "valid":true,
+ "bestpath":true,
+ "selectionReason":"First path received",
+ "pathFrom":"internal",
+ "routeType":5,
+ "ethTag":0,
+ "ipLen":128,
+ "ip":"fd00::1",
+ "metric":0,
+ "locPrf":100,
+ "weight":0,
+ "peerId":"192.168.100.21",
+ "path":"",
+ "origin":"IGP",
+ "nexthops":[
+ {
+ "ip":"192.168.100.21",
+ "hostname":"r1",
+ "afi":"ipv4",
+ "used":true
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "numPrefix":4,
+ "totalPrefix":4
+}
diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf
index de5a0efc44..4f1d8e4a37 100644
--- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf
+++ b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf
@@ -20,12 +20,30 @@ router bgp 65000 vrf r2-vrf-101
no bgp network import-check
address-family ipv4 unicast
network 192.168.101.41/32
+ network 192.168.102.41/32
exit-address-family
address-family ipv6 unicast
network fd00::2/128
+ network fd00::3/128
exit-address-family
address-family l2vpn evpn
- advertise ipv4 unicast
- advertise ipv6 unicast
+ advertise ipv4 unicast route-map rmap4
+ advertise ipv6 unicast route-map rmap6
exit-address-family
!
+access-list acl4_1 seq 10 permit 192.168.101.41/32
+access-list acl4_2 seq 10 permit 192.168.102.41/32
+ipv6 access-list acl6_1 seq 10 permit fd00::2/128
+ipv6 access-list acl6_2 seq 10 permit fd00::3/128
+route-map rmap4 permit 1
+ match ip address acl4_1
+exit
+route-map rmap4 deny 2
+ match ip address acl4_2
+exit
+route-map rmap6 permit 1
+ match ipv6 address acl6_1
+exit
+route-map rmap6 deny 2
+ match ipv6 address acl6_2
+exit
diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py
index 9dfb7fc4d9..a9636a92f4 100644
--- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py
+++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py
@@ -13,6 +13,8 @@
with route advertisements on a separate netns.
"""
+import json
+from functools import partial
import os
import sys
import pytest
@@ -160,6 +162,36 @@ def teardown_module(_mod):
tgen.stop_topology()
+def _test_evpn_ping_router(pingrouter, ipv4_only=False):
+ """
+ internal function to check ping between r1 and r2
+ """
+ # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn)
+ logger.info(
+ "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
+ )
+ output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
+ logger.info(output)
+ if "1000 packets transmitted, 1000 received" not in output:
+ assertmsg = (
+ "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
+ )
+ assert 0, assertmsg
+ else:
+ logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
+
+ if ipv4_only:
+ return
+
+ logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)")
+ output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000")
+ logger.info(output)
+ if "1000 packets transmitted, 1000 received" not in output:
+ assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok"
+ else:
+ logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK")
+
+
def test_protocols_convergence():
"""
Assert that all protocols have converged
@@ -168,7 +200,34 @@ def test_protocols_convergence():
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- topotest.sleep(4, "waiting 4 seconds for bgp convergence")
+ # Check BGP IPv4 routing tables on r1
+ logger.info("Checking BGP L2VPN EVPN routes for convergence on r1")
+
+ for rname in ("r1", "r2"):
+ router = tgen.gears[rname]
+ json_file = "{}/{}/bgp_l2vpn_evpn_routes.json".format(CWD, router.name)
+ if not os.path.isfile(json_file):
+ assert 0, "bgp_l2vpn_evpn_routes.json file not found"
+
+ expected = json.loads(open(json_file).read())
+ test_func = partial(
+ topotest.router_json_cmp,
+ router,
+ "show bgp l2vpn evpn json",
+ expected,
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
+
+
+def test_protocols_dump_info():
+ """
+ Dump EVPN information
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
# Check IPv4/IPv6 routing tables.
output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False)
logger.info("==== result from show bgp l2vpn evpn")
@@ -203,6 +262,15 @@ def test_protocols_convergence():
logger.info("==== result from show evpn rmac vni all")
logger.info(output)
+
+def test_router_check_ip():
+ """
+ Check routes are correctly installed
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
expected = {
"fd00::2/128": [
{
@@ -221,56 +289,112 @@ def test_protocols_convergence():
)
assert result is None, "ipv6 route check failed"
- expected = {
- "101": {
- "numNextHops": 2,
- "192.168.100.41": {
- "nexthopIp": "192.168.100.41",
- },
- "::ffff:192.168.100.41": {
- "nexthopIp": "::ffff:192.168.100.41",
- },
+
+def _test_router_check_evpn_contexts(router, ipv4_only=False):
+ """
+ Check EVPN nexthops and RMAC number are correctly configured
+ """
+ if ipv4_only:
+ expected = {
+ "101": {
+ "numNextHops": 1,
+ "192.168.100.41": {
+ "nexthopIp": "192.168.100.41",
+ },
+ }
+ }
+ else:
+ expected = {
+ "101": {
+ "numNextHops": 2,
+ "192.168.100.41": {
+ "nexthopIp": "192.168.100.41",
+ },
+ "::ffff:192.168.100.41": {
+ "nexthopIp": "::ffff:192.168.100.41",
+ },
+ }
}
- }
result = topotest.router_json_cmp(
- tgen.gears["r1"], "show evpn next-hops vni all json", expected
+ router, "show evpn next-hops vni all json", expected
)
assert result is None, "evpn next-hops check failed"
expected = {"101": {"numRmacs": 1}}
- result = topotest.router_json_cmp(
- tgen.gears["r1"], "show evpn rmac vni all json", expected
- )
+ result = topotest.router_json_cmp(router, "show evpn rmac vni all json", expected)
assert result is None, "evpn rmac number check failed"
- # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn)
- pingrouter = tgen.gears["r1"]
- logger.info(
- "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
+
+def test_router_check_evpn_contexts():
+ """
+ Check EVPN nexthops and RMAC number are correctly configured
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ _test_router_check_evpn_contexts(tgen.gears["r1"])
+
+
+def test_evpn_ping():
+ """
+ Check ping between R1 and R2 is ok
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ _test_evpn_ping_router(tgen.gears["r1"])
+
+
+def test_evpn_disable_routemap():
+ """
+ Check the removal of a route-map on R2. More EVPN Prefixes are expected
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ tgen.gears["r2"].vtysh_cmd(
+ """
+ configure terminal\n
+ router bgp 65000 vrf r2-vrf-101\n
+ address-family l2vpn evpn\n
+ advertise ipv4 unicast\n
+ advertise ipv6 unicast\n
+ """
)
- output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
- logger.info(output)
- if "1000 packets transmitted, 1000 received" not in output:
- assertmsg = (
- "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
- )
- assert 0, assertmsg
- else:
- logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
+ router = tgen.gears["r1"]
+ json_file = "{}/{}/bgp_l2vpn_evpn_routes_all.json".format(CWD, router.name)
+ if not os.path.isfile(json_file):
+ assert 0, "bgp_l2vpn_evpn_routes.json file not found"
+
+ expected = json.loads(open(json_file).read())
+ test_func = partial(
+ topotest.router_json_cmp,
+ router,
+ "show bgp l2vpn evpn json",
+ expected,
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
+ assertmsg = '"{}" JSON output mismatches'.format(router.name)
+ assert result is None, assertmsg
- logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)")
- output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000")
- logger.info(output)
- if "1000 packets transmitted, 1000 received" not in output:
- assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok"
- else:
- logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK")
+
+def test_evpn_remove_ip():
+ """
+ Check the removal of an EVPN route is correctly handled
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
config_no_ipv6 = {
"r2": {
"raw_config": [
"router bgp 65000 vrf r2-vrf-101",
"address-family ipv6 unicast",
+ "no network fd00::3/128",
"no network fd00::2/128",
]
}
@@ -293,6 +417,7 @@ def test_protocols_convergence():
}
result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False)
assert result is not True, "expect IPv6 route fd00::2/128 withdrawn"
+
output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False)
logger.info("==== result from show evpn next-hops vni all")
logger.info(output)
@@ -300,37 +425,27 @@ def test_protocols_convergence():
logger.info("==== result from show evpn next-hops vni all")
logger.info(output)
- expected = {
- "101": {
- "numNextHops": 1,
- "192.168.100.41": {
- "nexthopIp": "192.168.100.41",
- },
- }
- }
- result = topotest.router_json_cmp(
- tgen.gears["r1"], "show evpn next-hops vni all json", expected
- )
- assert result is None, "evpn next-hops check failed"
- expected = {"101": {"numRmacs": 1}}
- result = topotest.router_json_cmp(
- tgen.gears["r1"], "show evpn rmac vni all json", expected
- )
- assert result is None, "evpn rmac number check failed"
+def test_router_check_evpn_contexts_again():
+ """
+ Check EVPN nexthops and RMAC number are correctly configured
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
- logger.info(
- "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
- )
- output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
- logger.info(output)
- if "1000 packets transmitted, 1000 received" not in output:
- assertmsg = (
- "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
- )
- assert 0, assertmsg
- else:
- logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
+ _test_router_check_evpn_contexts(tgen.gears["r1"], ipv4_only=True)
+
+
+def test_evpn_ping_again():
+ """
+ Check ping between R1 and R2 is ok
+ """
+ tgen = get_topogen()
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ _test_evpn_ping_router(tgen.gears["r1"], ipv4_only=True)
def test_memory_leak():
diff --git a/tests/topotests/lib/snmptest.py b/tests/topotests/lib/snmptest.py
index 8e2e76d154..6d586cee50 100644
--- a/tests/topotests/lib/snmptest.py
+++ b/tests/topotests/lib/snmptest.py
@@ -104,12 +104,16 @@ class SnmpTester(object):
return None
return self._get_snmp_value(result)
- def walk(self, oid):
+ def walk(self, oid, raw=False):
cmd = "snmpwalk {0} {1} 2>&1 | grep -v SNMPv2-PDU".format(
self._snmp_config(), oid
)
result = self.router.cmd(cmd)
+
+ if raw:
+ return result
+
return self._parse_multiline(result)
def parse_notif_ipv4(self, notif):
diff --git a/tests/topotests/simple_snmp_test/r1/isisd.conf b/tests/topotests/simple_snmp_test/r1/isisd.conf
index 435abde330..c53d2509e2 100644
--- a/tests/topotests/simple_snmp_test/r1/isisd.conf
+++ b/tests/topotests/simple_snmp_test/r1/isisd.conf
@@ -3,6 +3,8 @@ log stdout debugging
! debug isis route-events
! debug isis events
!
+agentx
+!
interface r1-eth0
ip router isis ISIS1
ipv6 router isis ISIS1
diff --git a/tests/topotests/simple_snmp_test/r1/ospf6d.conf b/tests/topotests/simple_snmp_test/r1/ospf6d.conf
new file mode 100644
index 0000000000..e81151710b
--- /dev/null
+++ b/tests/topotests/simple_snmp_test/r1/ospf6d.conf
@@ -0,0 +1,12 @@
+agentx
+
+int r1-eth0
+ ipv6 ospf6 area 0.0.0.0
+
+int r1-eth1
+ ipv6 ospf6 area 0.0.0.0
+int r1-eth2
+ ipv6 ospf6 area 0.0.0.0
+
+router ospf6
+ redistribute local \ No newline at end of file
diff --git a/tests/topotests/simple_snmp_test/r1/ospfd.conf b/tests/topotests/simple_snmp_test/r1/ospfd.conf
new file mode 100644
index 0000000000..cc0d9e52c2
--- /dev/null
+++ b/tests/topotests/simple_snmp_test/r1/ospfd.conf
@@ -0,0 +1,11 @@
+agentx
+
+int r1-eth0
+ ip ospf area 0.0.0.0
+int r1-eth1
+ ip ospf area 0.0.0.0
+int r1-eth2
+ ip ospf area 0.0.0.0
+
+router ospf
+ redistribute local \ No newline at end of file
diff --git a/tests/topotests/simple_snmp_test/r1/ripd.conf b/tests/topotests/simple_snmp_test/r1/ripd.conf
new file mode 100644
index 0000000000..71cdb058cf
--- /dev/null
+++ b/tests/topotests/simple_snmp_test/r1/ripd.conf
@@ -0,0 +1,8 @@
+!
+!
+router rip
+ network 0.0.0.0/0
+ redistribute local
+!
+agentx
+! \ No newline at end of file
diff --git a/tests/topotests/simple_snmp_test/r1/zebra.conf b/tests/topotests/simple_snmp_test/r1/zebra.conf
index 5281d0055d..6483a661ce 100644
--- a/tests/topotests/simple_snmp_test/r1/zebra.conf
+++ b/tests/topotests/simple_snmp_test/r1/zebra.conf
@@ -1,5 +1,7 @@
log file zebra.log
!
+agentx
+!
interface r1-eth0
ip address 192.168.12.12/24
ipv6 address 2000:1:1:12::12/64
@@ -18,5 +20,4 @@ interface lo
ipv6 address 2000:1:1:1::1/128
!
!
-!
line vty
diff --git a/tests/topotests/simple_snmp_test/test_simple_snmp.py b/tests/topotests/simple_snmp_test/test_simple_snmp.py
index 0387e29274..c74ffcc2db 100755
--- a/tests/topotests/simple_snmp_test/test_simple_snmp.py
+++ b/tests/topotests/simple_snmp_test/test_simple_snmp.py
@@ -24,7 +24,8 @@ sys.path.append(os.path.join(CWD, "../"))
# Import topogen and topotest helpers
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.snmptest import SnmpTester
-
+from time import sleep
+from lib.topolog import logger
pytestmark = [pytest.mark.bgpd, pytest.mark.isisd, pytest.mark.snmp]
@@ -59,10 +60,14 @@ def setup_module(mod):
# For all registered routers, load the zebra configuration file
for rname, router in router_list.items():
router.load_config(
- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+ TopoRouter.RD_ZEBRA,
+ os.path.join(CWD, "{}/zebra.conf".format(rname)),
+ "-M snmp",
)
router.load_config(
- TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
+ TopoRouter.RD_ISIS,
+ os.path.join(CWD, "{}/isisd.conf".format(rname)),
+ "-M snmp",
)
router.load_config(
TopoRouter.RD_BGP,
@@ -70,6 +75,21 @@ def setup_module(mod):
"-M snmp",
)
router.load_config(
+ TopoRouter.RD_RIP,
+ os.path.join(CWD, "{}/ripd.conf".format(rname)),
+ "-M snmp",
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF,
+ os.path.join(CWD, "{}/ospfd.conf".format(rname)),
+ "-M snmp",
+ )
+ router.load_config(
+ TopoRouter.RD_OSPF6,
+ os.path.join(CWD, "{}/ospf6d.conf".format(rname)),
+ "-M snmp",
+ )
+ router.load_config(
TopoRouter.RD_SNMP,
os.path.join(CWD, "{}/snmpd.conf".format(rname)),
"-Le -Ivacm_conf,usmConf,iquery -V -DAgentX,trap",
@@ -77,6 +97,16 @@ def setup_module(mod):
# After loading the configurations, this function loads configured daemons.
tgen.start_router()
+ # Why this sleep? If you are using zebra w/ snmp we have a chicken
+ # and egg problem with the snmpd. snmpd is being started up with
+ # ip addresses, and as such snmpd may not be ready to listen yet
+ # (see startup stuff in topotest.py ) with the 2 second delay
+ # on starting snmpd after zebra. As such if we want to test
+ # anything in zebra we need to sleep a bit to allow the connection
+ # to happen. I have no good way to test to see if zebra is up
+ # and running with snmp at this point in time. So this will have
+ # to do.
+ sleep(17)
def teardown_module():
@@ -103,6 +133,22 @@ def test_r1_bgp_version():
assert r1_snmp.test_oid_walk("bgpVersion", ["10"])
assert r1_snmp.test_oid_walk("bgpVersion", ["10"], ["0"])
+ assert r1_snmp.test_oid(
+ "IP-FORWARD-MIB::ipForwardDest.192.168.12.0", "192.168.12.0"
+ )
+
+ assert r1_snmp.test_oid("ISIS-MIB::isisSysVersion", "one(1)")
+ # rip is not auto-loading agentx from mgmtd
+ # assert r1_snmp.test_oid("RIPv2-MIB::rip2GlobalQueries", "0")
+
+ assert r1_snmp.test_oid("OSPF-MIB::ospfVersionNumber", "version2(2)")
+ assert r1_snmp.test_oid("OSPFV3-MIB::ospfv3VersionNumber", "version3(3)")
+
+ # Let's just dump everything and make sure we get some additional test
+ # coverage
+ logger.info("Let's walk everything")
+ logger.info(r1_snmp.walk(".1", raw=True))
+
def test_memory_leak():
"Run the memory leak test and report results."
diff --git a/zebra/interface.c b/zebra/interface.c
index 86de5dbae6..f7fd112cd4 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -47,6 +47,20 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZIF_DESC, "Intf desc");
static void if_down_del_nbr_connected(struct interface *ifp);
+static const char *if_zebra_data_state(uint8_t state)
+{
+ switch (state) {
+ case IF_ZEBRA_DATA_UNSPEC:
+ return "Not specified by CLI";
+ case IF_ZEBRA_DATA_ON:
+ return "Enabled by CLI";
+ case IF_ZEBRA_DATA_OFF:
+ return "Disabled by CLI";
+ }
+
+ return "STATE IS WRONG DEV ESCAPE";
+}
+
static void if_zebra_speed_update(struct event *thread)
{
struct interface *ifp = EVENT_ARG(thread);
@@ -366,6 +380,7 @@ int if_subnet_delete(struct interface *ifp, struct connected *ifc)
return 0;
}
+#ifndef HAVE_NETLINK
/* if_flags_mangle: A place for hacks that require mangling
* or tweaking the interface flags.
*
@@ -417,6 +432,7 @@ void if_flags_update(struct interface *ifp, uint64_t newflags)
if_up(ifp, true);
}
}
+#endif
/* Wake up configured address if it is not in current kernel
address. */
@@ -2627,8 +2643,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
vty_out(vty, "mtu6 %d ", ifp->mtu6);
vty_out(vty, "\n flags: %s\n", if_flag_dump(ifp->flags));
- if (zebra_if->mpls)
- vty_out(vty, " MPLS enabled\n");
+ vty_out(vty, " MPLS %s %s\n", zebra_if->mpls ? "enabled" : "",
+ if_zebra_data_state(zebra_if->multicast));
if (zebra_if->linkdown)
vty_out(vty, " Ignore all v4 routes with linkdown\n");
@@ -2640,6 +2656,10 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
if (zebra_if->v6mcast_on)
vty_out(vty, " v6 Multicast forwarding is on\n");
+ vty_out(vty, " Multicast config is %s\n", if_zebra_data_state(zebra_if->multicast));
+
+ vty_out(vty, " Shutdown config is %s\n", if_zebra_data_state(zebra_if->shutdown));
+
/* Hardware address. */
vty_out(vty, " Type: %s\n", if_link_type_str(ifp->ll_type));
if (ifp->hw_addr_len != 0) {
@@ -2988,10 +3008,14 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
json_object_boolean_add(json_if, "mplsEnabled", zebra_if->mpls);
json_object_boolean_add(json_if, "linkDown", zebra_if->linkdown);
json_object_boolean_add(json_if, "linkDownV6", zebra_if->linkdownv6);
- json_object_boolean_add(json_if, "mcForwardingV4",
- zebra_if->v4mcast_on);
- json_object_boolean_add(json_if, "mcForwardingV6",
- zebra_if->v6mcast_on);
+ json_object_boolean_add(json_if, "mcForwardingV4", zebra_if->v4mcast_on);
+ json_object_boolean_add(json_if, "mcForwardingV6", zebra_if->v6mcast_on);
+
+ json_object_string_add(json_if, "multicastConfig", if_zebra_data_state(zebra_if->multicast));
+
+ json_object_string_add(json_if, "shutdownConfig", if_zebra_data_state(zebra_if->shutdown));
+
+ json_object_string_add(json_if, "mplsConfig", if_zebra_data_state(zebra_if->mpls_config));
if (ifp->ifindex == IFINDEX_INTERNAL) {
json_object_boolean_add(json_if, "pseudoInterface", true);
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index a35784cd36..47ce7c943d 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -390,6 +390,7 @@ int if_unset_prefix_ctx(const struct zebra_dplane_ctx *ctx)
#endif /* HAVE_STRUCT_IFALIASREQ */
#endif /* HAVE_NETLINK */
+#ifndef HAVE_NETLINK
/* get interface flags */
void if_get_flags(struct interface *ifp)
{
@@ -485,6 +486,7 @@ void if_get_flags(struct interface *ifp)
out:
if_flags_update(ifp, (ifreqflags.ifr_flags & 0x0000ffff));
}
+#endif
/* Set interface flags */
int if_set_flags(struct interface *ifp, uint64_t flags)
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 0658f996e6..ad112a4ab1 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -4757,10 +4757,9 @@ void zebra_vxlan_remote_vtep_add(vrf_id_t vrf_id, vni_t vni,
/* If down or not mapped to a bridge, we're done. */
if (!if_is_operative(ifp) || !zif->brslave_info.br_if) {
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug(
- "%s VNI %u VTEP %pI4 ifp %s oper %u br_if %u skipping update",
- __func__, zevpn->vni, &vtep_ip, ifp->name,
- if_is_operative(ifp), !zif->brslave_info.br_if);
+ zlog_debug("%s VNI %u VTEP %pI4 ifp %s oper %u br_if %u skipping update",
+ __func__, zevpn->vni, &vtep_ip, ifp->name, if_is_operative(ifp),
+ !zif->brslave_info.br_if);
return;
}
diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c
index 2658c9f01c..ea0be2f644 100644
--- a/zebra/zebra_vxlan_if.c
+++ b/zebra/zebra_vxlan_if.c
@@ -1037,7 +1037,7 @@ int zebra_vxlan_if_vni_up(struct interface *ifp, struct zebra_vxlan_vni *vnip)
} else {
if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("%s VNI %u vxlan_if %s oper down skipping vni up to client",
- __func__, zevpn->vni, zevpn->vxlan_if->name);
+ __func__, zevpn->vni, zevpn->vxlan_if->name);
}
zebra_evpn_read_mac_neigh(zevpn, ifp);
}