diff options
131 files changed, 1933 insertions, 1437 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 6479126d0..ca9c428b4 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -11,7 +11,6 @@ #include "queue.h" #include "filter.h" #include "stream.h" -#include "jhash.h" #include "frrstr.h" #include "bgpd/bgpd.h" diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index d4ccca84b..3d2dda4ee 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 490451f19..cadef3997 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 844f6b9af..f1bea1c18 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 61ca19a34..ed1a72ec8 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 bf0f3b15c..1ef90a8e3 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 9b633b713..ed83757ea 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 a76a300c1..e9cc52449 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 d1238bc8d..6ff94129d 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 16f4a0d2d..688dfacaa 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 258fc87f9..dccac3ece 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; @@ -2901,6 +2859,7 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name) group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name); group->conf->group = group; group->conf->as = 0; + group->conf->as_type = AS_UNSPECIFIED; group->conf->ttl = BGP_DEFAULT_TTL; group->conf->gtsm_hops = BGP_GTSM_HOPS_DISABLED; group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; @@ -3076,11 +3035,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 +3075,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 +3324,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 +3359,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 +4600,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 +4693,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 +4705,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 +4904,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 +5388,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 +5403,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 +5438,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 +5453,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 +5605,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 +5640,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 +5670,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 +5704,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(member->connection)) bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -5816,10 +5752,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 +5785,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 +6299,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 +6320,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 +6353,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 +6374,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 +6815,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 +6841,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 +6870,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 +6905,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 +6948,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 +6972,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 +8649,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 +8752,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 f123188ae..df55d879e 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 c0db7f2b8..dafcac7c8 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 5c4649dc3..aaad3bc17 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 3bf93894e..cf185de22 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 acfc87615..c31be2b68 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 199f4d75d..cae93c6e5 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 8768819fe..2d038507a 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 0ffd76273..06a350c8e 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_bmp/bgpbmp.py b/tests/topotests/bgp_bmp/bgpbmp.py new file mode 100644 index 000000000..41995e2b5 --- /dev/null +++ b/tests/topotests/bgp_bmp/bgpbmp.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0-or-later + +# Copyright 2023, 6wind +import json +import os + +from lib import topotest +from lib.topogen import get_topogen +from lib.topolog import logger + +# remember the last sequence number of the logging messages +SEQ = 0 + + +def bmp_reset_seq(): + global SEQ + SEQ = 0 + + +def get_bmp_messages(bmp_collector, bmp_log_file): + """ + Read the BMP logging messages. + """ + messages = [] + text_output = bmp_collector.run(f"cat {bmp_log_file}") + + for m in text_output.splitlines(): + # some output in the bash can break the message decoding + try: + messages.append(json.loads(m)) + except Exception as e: + logger.warning(str(e) + " message: {}".format(str(m))) + continue + + if not messages: + logger.error("Bad BMP log format, check your BMP server") + + return messages + + +def bmp_update_seq(bmp_collector, bmp_log_file): + global SEQ + + messages = get_bmp_messages(bmp_collector, bmp_log_file) + + if len(messages): + SEQ = messages[-1]["seq"] + + +def bmp_update_expected_files( + bmp_actual, + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_client, + bmp_log_folder, +): + tgen = get_topogen() + + with open( + f"{bmp_log_folder}/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w" + ) as json_file: + json.dump(bmp_actual, json_file, indent=4) + + out = bmp_client.vtysh_cmd("show bgp vrf vrf1 ipv4 json", isjson=True) + filtered_out = { + "routes": { + prefix: route_info + for prefix, route_info in out["routes"].items() + if prefix in expected_prefixes + } + } + if bmp_log_type == "withdraw": + for pfx in expected_prefixes: + if "::" in pfx: + continue + filtered_out["routes"][pfx] = None + + # ls {bmp_log_folder}/tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done + with open( + f"{bmp_log_folder}/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w" + ) as json_file: + json.dump(filtered_out, json_file, indent=4) + + out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv6 json", isjson=True) + filtered_out = { + "routes": { + prefix: route_info + for prefix, route_info in out["routes"].items() + if prefix in expected_prefixes + } + } + if bmp_log_type == "withdraw": + for pfx in expected_prefixes: + if "::" not in pfx: + continue + filtered_out["routes"][pfx] = None + + with open( + f"{bmp_log_folder}/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w" + ) as json_file: + json.dump(filtered_out, json_file, indent=4) + + +def bmp_check_for_prefixes( + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_collector, + bmp_log_folder, + bmp_client, + expected_json_path, + update_expected_json, + loc_rib, +): + """ + Check for the presence of the given prefixes in the BMP server logs with + the given message type and the set policy. + + """ + global SEQ + + bmp_log_file = f"{bmp_log_folder}/bmp.log" + # we care only about the new messages + messages = [ + m + for m in sorted( + get_bmp_messages(bmp_collector, bmp_log_file), key=lambda d: d["seq"] + ) + if m["seq"] > SEQ + ] + + # create empty initial files + # for step in $(seq 1); do + # for i in "update" "withdraw"; do + # for j in "pre-policy" "post-policy" "loc-rib"; do + # echo '{"null": {}}'> bmp-$i-$j-step$step.json + # done + # done + # done + + ref_file = f"{expected_json_path}/bmp-{bmp_log_type}-{policy}-step{step}.json" + expected = json.loads(open(ref_file).read()) + + # Build actual json from logs + actual = {} + for m in messages: + if ( + "bmp_log_type" in m.keys() + and "ip_prefix" in m.keys() + and m["ip_prefix"] in expected_prefixes + and m["bmp_log_type"] == bmp_log_type + and m["policy"] == policy + ): + policy_dict = actual.setdefault(m["policy"], {}) + bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {}) + + # Add or update the ip_prefix dictionary with filtered key-value pairs + bmp_log_type_dict[m["ip_prefix"]] = { + k: v + for k, v in sorted(m.items()) + # filter out variable keys + if k not in ["timestamp", "seq", "nxhp_link-local"] + and ( + # When policy is loc-rib, the peer-distinguisher is 0:0 + # for the default VRF or the RD if any or the 0:<vrf_id>. + # 0:<vrf_id> is used to distinguished. RFC7854 says: "If the + # peer is a "Local Instance Peer", it is set to a unique, + # locally defined value." The value is not tested because it + # is variable. + k != "peer_distinguisher" + or policy != loc_rib + or v == "0:0" + or not v.startswith("0:") + ) + } + + # build expected JSON files + if ( + update_expected_json + and actual + and set(actual.get(policy, {}).get(bmp_log_type, {}).keys()) + == set(expected_prefixes) + ): + bmp_update_expected_files( + actual, + expected_prefixes, + bmp_log_type, + policy, + step, + bmp_client, + bmp_log_folder, + ) + + return topotest.json_cmp(actual, expected, exact=True) + + +def bmp_check_for_peer_message( + expected_peers, bmp_log_type, bmp_collector, bmp_log_file +): + """ + Check for the presence of a peer up message for the peer + """ + global SEQ + + # we care only about the new messages + messages = [ + m + for m in sorted( + get_bmp_messages(bmp_collector, bmp_log_file), key=lambda d: d["seq"] + ) + if m["seq"] > SEQ + ] + + # get the list of pairs (prefix, policy, seq) for the given message type + peers = [ + m["peer_ip"] + for m in messages + if "peer_ip" in m.keys() and m["bmp_log_type"] == bmp_log_type + ] + + # check for prefixes + for ep in expected_peers: + if ep not in peers: + msg = "The peer {} is not present in the {} log messages." + logger.debug(msg.format(ep, bmp_log_type)) + return False + + SEQ = messages[-1]["seq"] + return True diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-loc-rib-step1.json index ba31bf1d5..ba31bf1d5 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-loc-rib-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-loc-rib-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-post-policy-step1.json index d5d9d6518..d5d9d6518 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-post-policy-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-post-policy-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-pre-policy-step1.json index e11badc04..e11badc04 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-update-pre-policy-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-update-pre-policy-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-loc-rib-step1.json index 37ddc09ff..37ddc09ff 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-loc-rib-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-loc-rib-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-post-policy-step1.json index de84307a4..de84307a4 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-post-policy-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-post-policy-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-pre-policy-step1.json index 1c34498b7..1c34498b7 100644 --- a/tests/topotests/bgp_bmp_vrf/bmp1/bmp-withdraw-pre-policy-step1.json +++ b/tests/topotests/bgp_bmp/bmp1vrf/bmp-withdraw-pre-policy-step1.json diff --git a/tests/topotests/bgp_bmp/r1/bgpd.conf b/tests/topotests/bgp_bmp/r1/frr.conf index 485c21709..f7cb669b3 100644 --- a/tests/topotests/bgp_bmp/r1/bgpd.conf +++ b/tests/topotests/bgp_bmp/r1/frr.conf @@ -1,3 +1,10 @@ +interface r1-eth0 + ip address 192.0.2.1/24 +! +interface r1-eth1 + ip address 192.168.0.1/24 + ipv6 address 192:168::1/64 +! router bgp 65501 bgp router-id 192.168.0.1 bgp log-neighbor-changes @@ -41,7 +48,7 @@ router bgp 65501 exit-address-family ! router bgp 65501 vrf vrf1 - bgp router_id 192.168.0.1 + bgp router-id 192.168.0.1 bgp log-neighbor-changes address-family ipv4 unicast label vpn export 101 diff --git a/tests/topotests/bgp_bmp/r1/zebra.conf b/tests/topotests/bgp_bmp/r1/zebra.conf deleted file mode 100644 index 0b523c9e1..000000000 --- a/tests/topotests/bgp_bmp/r1/zebra.conf +++ /dev/null @@ -1,7 +0,0 @@ -interface r1-eth0 - ip address 192.0.2.1/24 -! -interface r1-eth1 - ip address 192.168.0.1/24 - ipv6 address 192:168::1/64 -! diff --git a/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf b/tests/topotests/bgp_bmp/r1vrf/frr.conf index 961e20498..cb8a7d2b1 100644 --- a/tests/topotests/bgp_bmp_vrf/r1/bgpd.conf +++ b/tests/topotests/bgp_bmp/r1vrf/frr.conf @@ -1,3 +1,10 @@ +interface r1vrf-eth0 + ip address 192.0.2.1/24 +! +interface r1vrf-eth1 + ip address 192.168.0.1/24 + ipv6 address 192:168::1/64 +! router bgp 65501 vrf vrf1 bgp router-id 192.168.0.1 bgp log-neighbor-changes @@ -15,7 +22,6 @@ router bgp 65501 vrf vrf1 bmp monitor ipv6 unicast loc-rib exit ! - address-family ipv4 unicast neighbor 192.168.0.2 activate neighbor 192.168.0.2 soft-reconfiguration inbound diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-update-step1.json index 038c87ca9..dc0228db6 100644 --- a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-update-step1.json +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-update-step1.json @@ -9,7 +9,6 @@ "nexthops": [ { "ip": "192.168.0.2", - "hostname": "r2", "afi": "ipv4", "used": true } diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-withdraw-step1.json index 6a7781377..6a7781377 100644 --- a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv4-withdraw-step1.json +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv4-withdraw-step1.json diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-update-step1.json index db3422014..64c8622ab 100644 --- a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-update-step1.json +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-update-step1.json @@ -9,12 +9,10 @@ "nexthops": [ { "ip": "192:168::2", - "hostname": "r2", "afi": "ipv6", "scope": "global" }, { - "hostname": "r2", "afi": "ipv6", "scope": "link-local", "used": true diff --git a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-withdraw-step1.json index 93f4a75e8..93f4a75e8 100644 --- a/tests/topotests/bgp_bmp_vrf/r1/show-bgp-ipv6-withdraw-step1.json +++ b/tests/topotests/bgp_bmp/r1vrf/show-bgp-ipv6-withdraw-step1.json diff --git a/tests/topotests/bgp_bmp/r2/bgpd.conf b/tests/topotests/bgp_bmp/r2/frr.conf index 40e2cd5bb..250071f48 100644 --- a/tests/topotests/bgp_bmp/r2/bgpd.conf +++ b/tests/topotests/bgp_bmp/r2/frr.conf @@ -1,3 +1,11 @@ +interface r2-eth0 + ip address 192.168.0.2/24 + ipv6 address 192:168::2/64 +! +interface r2-eth1 + ip address 172.31.0.2/24 + ipv6 address 172:31::2/64 +! router bgp 65502 bgp router-id 192.168.0.2 bgp log-neighbor-changes diff --git a/tests/topotests/bgp_bmp/r2/zebra.conf b/tests/topotests/bgp_bmp/r2/zebra.conf deleted file mode 100644 index 9d82bfe2d..000000000 --- a/tests/topotests/bgp_bmp/r2/zebra.conf +++ /dev/null @@ -1,8 +0,0 @@ -interface r2-eth0 - ip address 192.168.0.2/24 - ipv6 address 192:168::2/64 -! -interface r2-eth1 - ip address 172.31.0.2/24 - ipv6 address 172:31::2/64 -! diff --git a/tests/topotests/bgp_bmp_vrf/r2/bgpd.conf b/tests/topotests/bgp_bmp/r2vrf/frr.conf index 7c8255a17..5268190de 100644 --- a/tests/topotests/bgp_bmp_vrf/r2/bgpd.conf +++ b/tests/topotests/bgp_bmp/r2vrf/frr.conf @@ -1,3 +1,11 @@ +interface r2vrf-eth0 + ip address 192.168.0.2/24 + ipv6 address 192:168::2/64 +! +interface r2vrf-eth1 + ip address 172.31.0.2/24 + ipv6 address 172:31::2/64 +! router bgp 65502 bgp router-id 192.168.0.2 bgp log-neighbor-changes diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp.py b/tests/topotests/bgp_bmp/test_bgp_bmp.py deleted file mode 100644 index 658ad2b99..000000000 --- a/tests/topotests/bgp_bmp/test_bgp_bmp.py +++ /dev/null @@ -1,476 +0,0 @@ -#!/usr/bin/env python -# SPDX-License-Identifier: ISC - -# Copyright 2023 6WIND S.A. -# Authored by Farid Mihoub <farid.mihoub@6wind.com> -# - -""" -test_bgp_bmp.py: Test BGP BMP functionalities - - +------+ +------+ +------+ - | | | | | | - | BMP1 |------------| R1 |---------------| R2 | - | | | | | | - +------+ +------+ +------+ - -Setup two routers R1 and R2 with one link configured with IPv4 and -IPv6 addresses. -Configure BGP in R1 and R2 to exchange prefixes from -the latter to the first router. -Setup a link between R1 and the BMP server, activate the BMP feature in R1 -and ensure the monitored BGP sessions logs are well present on the BMP server. -""" - -from functools import partial -from ipaddress import ip_network -import json -import os -import pytest -import sys - -# Save the Current Working Directory to find configuration files. -CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join("../")) -sys.path.append(os.path.join("../lib/")) - -# pylint: disable=C0413 -# Import topogen and topotest helpers -from lib import topotest -from lib.bgp import verify_bgp_convergence_from_running_config -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger - -pytestmark = [pytest.mark.bgpd] - -# remember the last sequence number of the logging messages -SEQ = 0 - -PRE_POLICY = "pre-policy" -POST_POLICY = "post-policy" -LOC_RIB = "loc-rib" - -UPDATE_EXPECTED_JSON = False -DEBUG_PCAP = False - - -def build_topo(tgen): - tgen.add_router("r1") - tgen.add_router("r2") - tgen.add_bmp_server("bmp1", ip="192.0.2.10", defaultRoute="via 192.0.2.1") - - switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["r1"]) - switch.add_link(tgen.gears["bmp1"]) - - tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth1", "r2-eth0") - - -def setup_module(mod): - tgen = Topogen(build_topo, mod.__name__) - tgen.start_topology() - - if DEBUG_PCAP: - tgen.gears["r1"].run("rm /tmp/bmp.pcap") - tgen.gears["r1"].run( - "tcpdump -nni r1-eth0 -s 0 -w /tmp/bmp.pcap &", stdout=None - ) - - for rname, router in tgen.routers().items(): - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, "{}/bgpd.conf".format(rname)), - "-M bmp", - ) - - tgen.start_router() - - logger.info("starting BMP servers") - for bmp_name, server in tgen.get_bmp_servers().items(): - server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) - - -def teardown_module(_mod): - tgen = get_topogen() - tgen.stop_topology() - - -def test_bgp_convergence(): - tgen = get_topogen() - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - result = verify_bgp_convergence_from_running_config(tgen, dut="r1") - assert result is True, "BGP is not converging" - - -def get_bmp_messages(): - """ - Read the BMP logging messages. - """ - messages = [] - tgen = get_topogen() - text_output = tgen.gears["bmp1"].run( - "cat {}".format(os.path.join(tgen.logdir, "bmp1", "bmp.log")) - ) - - for m in text_output.splitlines(): - # some output in the bash can break the message decoding - try: - messages.append(json.loads(m)) - except Exception as e: - logger.warning(str(e) + " message: {}".format(str(m))) - continue - - if not messages: - logger.error("Bad BMP log format, check your BMP server") - - return messages - - -def update_seq(): - global SEQ - - messages = get_bmp_messages() - - if len(messages): - SEQ = messages[-1]["seq"] - - -def update_expected_files(bmp_actual, expected_prefixes, bmp_log_type, policy, step): - tgen = get_topogen() - - with open(f"/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w") as json_file: - json.dump(bmp_actual, json_file, indent=4) - - if step == 2: # vpn - rd = "444:2" - out = tgen.gears["r1"].vtysh_cmd("show bgp ipv4 vpn json", isjson=True) - filtered_out = { - "routes": { - "routeDistinguishers": { - rd: { - prefix: route_info - for prefix, route_info in out["routes"] - .get("routeDistinguishers", {}) - .get(rd, {}) - .items() - if prefix in expected_prefixes - } - } - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" in pfx: - continue - filtered_out["routes"]["routeDistinguishers"][rd][pfx] = None - - # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done - with open( - f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w" - ) as json_file: - json.dump(filtered_out, json_file, indent=4) - - rd = "555:2" - out = tgen.gears["r1"].vtysh_cmd("show bgp ipv6 vpn json", isjson=True) - filtered_out = { - "routes": { - "routeDistinguishers": { - rd: { - prefix: route_info - for prefix, route_info in out["routes"] - .get("routeDistinguishers", {}) - .get(rd, {}) - .items() - if prefix in expected_prefixes - } - } - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" not in pfx: - continue - filtered_out["routes"]["routeDistinguishers"][rd][pfx] = None - with open( - f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w" - ) as json_file: - json.dump(filtered_out, json_file, indent=4) - - return - - out = tgen.gears["r1"].vtysh_cmd("show bgp ipv4 json", isjson=True) - filtered_out = { - "routes": { - prefix: route_info - for prefix, route_info in out["routes"].items() - if prefix in expected_prefixes - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" in pfx: - continue - filtered_out["routes"][pfx] = None - - # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done - with open(f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w") as json_file: - json.dump(filtered_out, json_file, indent=4) - - out = tgen.gears["r1"].vtysh_cmd("show bgp ipv6 json", isjson=True) - filtered_out = { - "routes": { - prefix: route_info - for prefix, route_info in out["routes"].items() - if prefix in expected_prefixes - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" not in pfx: - continue - filtered_out["routes"][pfx] = None - with open(f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w") as json_file: - json.dump(filtered_out, json_file, indent=4) - - -def check_for_prefixes(expected_prefixes, bmp_log_type, policy, step): - """ - Check for the presence of the given prefixes in the BMP server logs with - the given message type and the set policy. - - """ - global SEQ - - # we care only about the new messages - messages = [ - m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ - ] - - # create empty initial files - # for step in $(seq 2); do - # for i in "update" "withdraw"; do - # for j in "pre-policy" "post-policy" "loc-rib"; do - # echo '{"null": {}}'> bmp-$i-$j-step$step.json - # done - # done - # done - - ref_file = f"{CWD}/bmp1/bmp-{bmp_log_type}-{policy}-step{step}.json" - expected = json.loads(open(ref_file).read()) - - # Build actual json from logs - actual = {} - for m in messages: - if ( - "bmp_log_type" in m.keys() - and "ip_prefix" in m.keys() - and m["ip_prefix"] in expected_prefixes - and m["bmp_log_type"] == bmp_log_type - and m["policy"] == policy - ): - policy_dict = actual.setdefault(m["policy"], {}) - bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {}) - - # Add or update the ip_prefix dictionary with filtered key-value pairs - bmp_log_type_dict[m["ip_prefix"]] = { - k: v - for k, v in sorted(m.items()) - # filter out variable keys - if k not in ["timestamp", "seq", "nxhp_link-local"] - and ( - # When policy is loc-rib, the peer-distinguisher is 0:0 - # for the default VRF or the RD if any or the 0:<vrf_id>. - # 0:<vrf_id> is used to distinguished. RFC7854 says: "If the - # peer is a "Local Instance Peer", it is set to a unique, - # locally defined value." The value is not tested because it - # is variable. - k != "peer_distinguisher" - or policy != LOC_RIB - or v == "0:0" - or not v.startswith("0:") - ) - } - - # build expected JSON files - if ( - UPDATE_EXPECTED_JSON - and actual - and set(actual.get(policy, {}).get(bmp_log_type, {}).keys()) - == set(expected_prefixes) - ): - update_expected_files(actual, expected_prefixes, bmp_log_type, policy, step) - - return topotest.json_cmp(actual, expected, exact=True) - - -def check_for_peer_message(expected_peers, bmp_log_type): - """ - Check for the presence of a peer up message for the peer - """ - global SEQ - # we care only about the new messages - messages = [ - m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ - ] - - # get the list of pairs (prefix, policy, seq) for the given message type - peers = [ - m["peer_ip"] - for m in messages - if "peer_ip" in m.keys() and m["bmp_log_type"] == bmp_log_type - ] - - # check for prefixes - for ep in expected_peers: - if ep not in peers: - msg = "The peer {} is not present in the {} log messages." - logger.debug(msg.format(ep, bmp_log_type)) - return False - - SEQ = messages[-1]["seq"] - return True - - -def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True): - """ - Configure the bgp prefixes. - """ - withdraw = "no " if not update else "" - vrf = " vrf {}".format(vrf) if vrf else "" - for p in prefixes: - ip = ip_network(p) - cmd = [ - "conf t\n", - "router bgp {}{}\n".format(asn, vrf), - "address-family ipv{} {}\n".format(ip.version, safi), - "{}network {}\n".format(withdraw, ip), - "exit-address-family\n", - ] - logger.debug("setting prefix: ipv{} {} {}".format(ip.version, safi, ip)) - tgen.gears[node].vtysh_cmd("".join(cmd)) - - -def _test_prefixes(policy, vrf=None, step=0): - """ - Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. - Check if the previous actions are logged in the BMP server with the right - message type and the right policy. - """ - tgen = get_topogen() - - safi = "vpn" if vrf else "unicast" - - prefixes = ["172.31.0.15/32", "2001::1111/128"] - - for type in ("update", "withdraw"): - update_seq() - - configure_prefixes( - tgen, "r2", 65502, "unicast", prefixes, vrf=vrf, update=(type == "update") - ) - - logger.info(f"checking for prefixes {type}") - - for ipver in [4, 6]: - if UPDATE_EXPECTED_JSON: - continue - ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format( - CWD, ipver, type, step - ) - expected = json.loads(open(ref_file).read()) - - test_func = partial( - topotest.router_json_cmp, - tgen.gears["r1"], - f"show bgp ipv{ipver} {safi} json", - expected, - ) - _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) - assertmsg = f"r1: BGP IPv{ipver} convergence failed" - assert res is None, assertmsg - - # check - test_func = partial(check_for_prefixes, prefixes, type, policy, step) - success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert success, "Checking the updated prefixes has failed ! %s" % res - - -def test_bmp_server_logging(): - """ - Assert the logging of the bmp server. - """ - - def check_for_log_file(): - tgen = get_topogen() - output = tgen.gears["bmp1"].run( - "ls {}".format(os.path.join(tgen.logdir, "bmp1")) - ) - if "bmp.log" not in output: - return False - return True - - success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) - assert success, "The BMP server is not logging" - - -def test_peer_up(): - """ - Checking for BMP peers up messages - """ - - peers = ["192.168.0.2", "192:168::2"] - - logger.info("checking for BMP peers up messages") - - test_func = partial(check_for_peer_message, peers, "peer up") - success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) - assert success, "Checking the updated prefixes has been failed !." - - -def test_bmp_bgp_unicast(): - """ - Add/withdraw bgp unicast prefixes and check the bmp logs. - """ - logger.info("*** Unicast prefixes pre-policy logging ***") - _test_prefixes(PRE_POLICY, step=1) - logger.info("*** Unicast prefixes post-policy logging ***") - _test_prefixes(POST_POLICY, step=1) - logger.info("*** Unicast prefixes loc-rib logging ***") - _test_prefixes(LOC_RIB, step=1) - - -def test_bmp_bgp_vpn(): - # check for the prefixes in the BMP server logging file - logger.info("***** VPN prefixes pre-policy logging *****") - _test_prefixes(PRE_POLICY, vrf="vrf1", step=2) - logger.info("***** VPN prefixes post-policy logging *****") - _test_prefixes(POST_POLICY, vrf="vrf1", step=2) - logger.info("***** VPN prefixes loc-rib logging *****") - _test_prefixes(LOC_RIB, vrf="vrf1", step=2) - - -def test_peer_down(): - """ - Checking for BMP peers down messages - """ - tgen = get_topogen() - - tgen.gears["r2"].vtysh_cmd("clear bgp *") - - peers = ["192.168.0.2", "192:168::2"] - - logger.info("checking for BMP peers down messages") - - test_func = partial(check_for_peer_message, peers, "peer down") - success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) - assert success, "Checking the updated prefixes has been failed !." - - -if __name__ == "__main__": - args = ["-s"] + sys.argv[1:] - sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp_1.py b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py new file mode 100644 index 000000000..614286344 --- /dev/null +++ b/tests/topotests/bgp_bmp/test_bgp_bmp_1.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright 2023 6WIND S.A. +# Authored by Farid Mihoub <farid.mihoub@6wind.com> +# + +""" +test_bgp_bmp.py: Test BGP BMP functionalities + + +------+ +------+ +------+ + | | | | | | + | BMP1 |------------| R1 |---------------| R2 | + | | | | | | + +------+ +------+ +------+ + +Setup two routers R1 and R2 with one link configured with IPv4 and +IPv6 addresses. +Configure BGP in R1 and R2 to exchange prefixes from +the latter to the first router. +Setup a link between R1 and the BMP server, activate the BMP feature in R1 +and ensure the monitored BGP sessions logs are well present on the BMP server. +""" + +from functools import partial +import json +import os +import pytest +import sys + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join("../")) +sys.path.append(os.path.join("../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.bgp import verify_bgp_convergence_from_running_config +from lib.bgp import bgp_configure_prefixes +from .bgpbmp import ( + bmp_check_for_prefixes, + bmp_check_for_peer_message, + bmp_update_seq, +) +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +PRE_POLICY = "pre-policy" +POST_POLICY = "post-policy" +LOC_RIB = "loc-rib" + +UPDATE_EXPECTED_JSON = False +DEBUG_PCAP = False + + +def build_topo(tgen): + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_bmp_server("bmp1", ip="192.0.2.10", defaultRoute="via 192.0.2.1") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["bmp1"]) + + tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth1", "r2-eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + if DEBUG_PCAP: + pcap_file = os.path.join(tgen.logdir, "r1/bmp.pcap") + tgen.gears["r1"].run( + "tcpdump -nni r1-eth0 -s 0 -w {} &".format(pcap_file), stdout=None + ) + + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [(TopoRouter.RD_ZEBRA, None), (TopoRouter.RD_BGP, "-M bmp")], + ) + + tgen.start_router() + + logger.info("starting BMP servers") + for bmp_name, server in tgen.get_bmp_servers().items(): + server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) + + +def teardown_module(_mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_convergence(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + result = verify_bgp_convergence_from_running_config(tgen, dut="r1") + assert result is True, "BGP is not converging" + + +def _test_prefixes(policy, vrf=None, step=0): + """ + Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. + Check if the previous actions are logged in the BMP server with the right + message type and the right policy. + """ + tgen = get_topogen() + + safi = "vpn" if vrf else "unicast" + + prefixes = ["172.31.0.15/32", "2001::1111/128"] + + for type in ("update", "withdraw"): + bmp_update_seq(tgen.gears["bmp1"], os.path.join(tgen.logdir, "bmp1", "bmp.log")) + + bgp_configure_prefixes( + tgen.gears["r2"], + 65502, + "unicast", + prefixes, + vrf=vrf, + update=(type == "update"), + ) + + logger.info(f"checking for prefixes {type}") + + for ipver in [4, 6]: + if UPDATE_EXPECTED_JSON: + continue + ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format( + CWD, ipver, type, step + ) + expected = json.loads(open(ref_file).read()) + + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1"], + f"show bgp ipv{ipver} {safi} json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = f"r1: BGP IPv{ipver} convergence failed" + assert res is None, assertmsg + + # check + test_func = partial( + bmp_check_for_prefixes, + prefixes, + type, + policy, + step, + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1"), + tgen.gears["r1"], + f"{CWD}/bmp1", + UPDATE_EXPECTED_JSON, + LOC_RIB, + ) + success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert success, "Checking the updated prefixes has failed ! %s" % res + + +def test_bmp_server_logging(): + """ + Assert the logging of the bmp server. + """ + + def check_for_log_file(): + tgen = get_topogen() + output = tgen.gears["bmp1"].run( + "ls {}".format(os.path.join(tgen.logdir, "bmp1")) + ) + if "bmp.log" not in output: + return False + return True + + success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) + assert success, "The BMP server is not logging" + + +def test_peer_up(): + """ + Checking for BMP peers up messages + """ + + tgen = get_topogen() + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers up messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer up", + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +def test_bmp_bgp_unicast(): + """ + Add/withdraw bgp unicast prefixes and check the bmp logs. + """ + logger.info("*** Unicast prefixes pre-policy logging ***") + _test_prefixes(PRE_POLICY, step=1) + logger.info("*** Unicast prefixes post-policy logging ***") + _test_prefixes(POST_POLICY, step=1) + logger.info("*** Unicast prefixes loc-rib logging ***") + _test_prefixes(LOC_RIB, step=1) + + +def test_bmp_bgp_vpn(): + # check for the prefixes in the BMP server logging file + logger.info("***** VPN prefixes pre-policy logging *****") + _test_prefixes(PRE_POLICY, vrf="vrf1", step=2) + logger.info("***** VPN prefixes post-policy logging *****") + _test_prefixes(POST_POLICY, vrf="vrf1", step=2) + logger.info("***** VPN prefixes loc-rib logging *****") + _test_prefixes(LOC_RIB, vrf="vrf1", step=2) + + +def test_peer_down(): + """ + Checking for BMP peers down messages + """ + tgen = get_topogen() + + tgen.gears["r2"].vtysh_cmd("clear bgp *") + + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers down messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer down", + tgen.gears["bmp1"], + os.path.join(tgen.logdir, "bmp1", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp_2.py b/tests/topotests/bgp_bmp/test_bgp_bmp_2.py new file mode 100644 index 000000000..b45452e7c --- /dev/null +++ b/tests/topotests/bgp_bmp/test_bgp_bmp_2.py @@ -0,0 +1,255 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright 2023 6WIND S.A. +# Authored by Farid Mihoub <farid.mihoub@6wind.com> +# + +""" +test_bgp_bmp.py: Test BGP BMP functionalities + + +------+ +------+ +------+ + | | | | | | + | BMP1 |------------| R1 |---------------| R2 | + | | | | | | + +------+ +------+ +------+ + +Setup two routers R1 and R2 with one link configured with IPv4 and +IPv6 addresses. +Configure BGP in R1 and R2 to exchange prefixes from +the latter to the first router. +Setup a link between R1 and the BMP server, activate the BMP feature in R1 +and ensure the monitored BGP sessions logs are well present on the BMP server. +""" + +from functools import partial +import json +import os +import platform +import pytest +import sys + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join("../")) +sys.path.append(os.path.join("../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.bgp import verify_bgp_convergence_from_running_config +from lib.bgp import bgp_configure_prefixes +from .bgpbmp import ( + bmp_check_for_prefixes, + bmp_check_for_peer_message, + bmp_update_seq, + bmp_reset_seq, +) + + +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +PRE_POLICY = "pre-policy" +POST_POLICY = "post-policy" +LOC_RIB = "loc-rib" + +UPDATE_EXPECTED_JSON = False +DEBUG_PCAP = False + + +def build_topo(tgen): + tgen.add_router("r1vrf") + tgen.add_router("r2vrf") + tgen.add_bmp_server("bmp1vrf", ip="192.0.2.10", defaultRoute="via 192.0.2.1") + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1vrf"]) + switch.add_link(tgen.gears["bmp1vrf"]) + + tgen.add_link(tgen.gears["r1vrf"], tgen.gears["r2vrf"], "r1vrf-eth1", "r2vrf-eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + tgen.net["r1vrf"].cmd( + """ +ip link add vrf1 type vrf table 10 +ip link set vrf1 up +ip link set r1vrf-eth1 master vrf1 +""" + ) + bmp_reset_seq() + if DEBUG_PCAP: + pcap_file = os.path.join(tgen.logdir, "r1vrf/bmp.pcap") + tgen.gears["r1vrf"].run( + "tcpdump -nni r1vrf-eth0 -s 0 -w {} &".format(pcap_file), stdout=None + ) + + for rname, router in tgen.routers().items(): + logger.info("Loading router %s" % rname) + router.load_frr_config( + os.path.join(CWD, "{}/frr.conf".format(rname)), + [(TopoRouter.RD_ZEBRA, None), (TopoRouter.RD_BGP, "-M bmp")], + ) + + tgen.start_router() + + logger.info("starting BMP servers") + for bmp_name, server in tgen.get_bmp_servers().items(): + server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) + + +def teardown_module(_mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_convergence(): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + result = verify_bgp_convergence_from_running_config(tgen, dut="r1vrf") + assert result is True, "BGP is not converging" + + +def _test_prefixes(policy, step=1): + """ + Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. + Check if the previous actions are logged in the BMP server with the right + message type and the right policy. + """ + tgen = get_topogen() + + prefixes = ["172.31.0.15/32", "2111::1111/128"] + + for type in ("update", "withdraw"): + bmp_update_seq( + tgen.gears["bmp1vrf"], os.path.join(tgen.logdir, "bmp1vrf", "bmp.log") + ) + + # add prefixes + bgp_configure_prefixes( + tgen.gears["r2vrf"], 65502, "unicast", prefixes, update=(type == "update") + ) + + logger.info(f"checking for prefixes {type}") + + for ipver in [4, 6]: + if UPDATE_EXPECTED_JSON: + continue + ref_file = "{}/r1vrf/show-bgp-ipv{}-{}-step{}.json".format( + CWD, ipver, type, step + ) + expected = json.loads(open(ref_file).read()) + + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1vrf"], + f"show bgp vrf vrf1 ipv{ipver} json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = f"r1vrf: BGP IPv{ipver} convergence failed" + assert res is None, assertmsg + + # check + test_func = partial( + bmp_check_for_prefixes, + prefixes, + type, + policy, + step, + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf"), + tgen.gears["r1vrf"], + f"{CWD}/bmp1vrf", + UPDATE_EXPECTED_JSON, + LOC_RIB, + ) + success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert success, "Checking the updated prefixes has failed ! %s" % res + + +def test_bmp_server_logging(): + """ + Assert the logging of the bmp server. + """ + + def check_for_log_file(): + tgen = get_topogen() + output = tgen.gears["bmp1vrf"].run( + "ls {}".format(os.path.join(tgen.logdir, "bmp1vrf")) + ) + if "bmp.log" not in output: + return False + return True + + success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) + assert success, "The BMP server is not logging" + + +def test_peer_up(): + """ + Checking for BMP peers up messages + """ + + tgen = get_topogen() + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers up messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer up", + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +def test_bmp_bgp_unicast(): + """ + Add/withdraw bgp unicast prefixes and check the bmp logs. + """ + logger.info("*** Unicast prefixes pre-policy logging ***") + _test_prefixes(PRE_POLICY) + logger.info("*** Unicast prefixes post-policy logging ***") + _test_prefixes(POST_POLICY) + logger.info("*** Unicast prefixes loc-rib logging ***") + _test_prefixes(LOC_RIB) + + +def test_peer_down(): + """ + Checking for BMP peers down messages + """ + tgen = get_topogen() + + tgen.gears["r2vrf"].vtysh_cmd("clear bgp *") + + peers = ["192.168.0.2", "192:168::2"] + + logger.info("checking for BMP peers down messages") + + test_func = partial( + bmp_check_for_peer_message, + peers, + "peer down", + tgen.gears["bmp1vrf"], + os.path.join(tgen.logdir, "bmp1vrf", "bmp.log"), + ) + success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) + assert success, "Checking the updated prefixes has been failed !." + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_bmp_vrf/__init__.py b/tests/topotests/bgp_bmp_vrf/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/tests/topotests/bgp_bmp_vrf/__init__.py +++ /dev/null diff --git a/tests/topotests/bgp_bmp_vrf/r1/zebra.conf b/tests/topotests/bgp_bmp_vrf/r1/zebra.conf deleted file mode 100644 index 0b523c9e1..000000000 --- a/tests/topotests/bgp_bmp_vrf/r1/zebra.conf +++ /dev/null @@ -1,7 +0,0 @@ -interface r1-eth0 - ip address 192.0.2.1/24 -! -interface r1-eth1 - ip address 192.168.0.1/24 - ipv6 address 192:168::1/64 -! diff --git a/tests/topotests/bgp_bmp_vrf/r2/zebra.conf b/tests/topotests/bgp_bmp_vrf/r2/zebra.conf deleted file mode 100644 index 9d82bfe2d..000000000 --- a/tests/topotests/bgp_bmp_vrf/r2/zebra.conf +++ /dev/null @@ -1,8 +0,0 @@ -interface r2-eth0 - ip address 192.168.0.2/24 - ipv6 address 192:168::2/64 -! -interface r2-eth1 - ip address 172.31.0.2/24 - ipv6 address 172:31::2/64 -! diff --git a/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py b/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py deleted file mode 100644 index d31328bdb..000000000 --- a/tests/topotests/bgp_bmp_vrf/test_bgp_bmp_vrf.py +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/env python -# SPDX-License-Identifier: ISC - -# Copyright 2023 6WIND S.A. -# Authored by Farid Mihoub <farid.mihoub@6wind.com> -# - -""" -test_bgp_bmp.py: Test BGP BMP functionalities - - +------+ +------+ +------+ - | | | | | | - | BMP1 |------------| R1 |---------------| R2 | - | | | | | | - +------+ +------+ +------+ - -Setup two routers R1 and R2 with one link configured with IPv4 and -IPv6 addresses. -Configure BGP in R1 and R2 to exchange prefixes from -the latter to the first router. -Setup a link between R1 and the BMP server, activate the BMP feature in R1 -and ensure the monitored BGP sessions logs are well present on the BMP server. -""" - -from functools import partial -from ipaddress import ip_network -import json -import os -import platform -import pytest -import sys - -# Save the Current Working Directory to find configuration files. -CWD = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(os.path.join("../")) -sys.path.append(os.path.join("../lib/")) - -# pylint: disable=C0413 -# Import topogen and topotest helpers -from lib import topotest -from lib.bgp import verify_bgp_convergence_from_running_config -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger - -pytestmark = [pytest.mark.bgpd] - -# remember the last sequence number of the logging messages -SEQ = 0 - -PRE_POLICY = "pre-policy" -POST_POLICY = "post-policy" -LOC_RIB = "loc-rib" - -UPDATE_EXPECTED_JSON = False -DEBUG_PCAP = False - - -def build_topo(tgen): - tgen.add_router("r1") - tgen.add_router("r2") - tgen.add_bmp_server("bmp1", ip="192.0.2.10", defaultRoute="via 192.0.2.1") - - switch = tgen.add_switch("s1") - switch.add_link(tgen.gears["r1"]) - switch.add_link(tgen.gears["bmp1"]) - - tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "r1-eth1", "r2-eth0") - - -def setup_module(mod): - tgen = Topogen(build_topo, mod.__name__) - tgen.start_topology() - - tgen.net["r1"].cmd( - """ -ip link add vrf1 type vrf table 10 -ip link set vrf1 up -ip link set r1-eth1 master vrf1 -""" - ) - - if DEBUG_PCAP: - tgen.gears["r1"].run("rm /tmp/bmp_vrf.pcap") - tgen.gears["r1"].run( - "tcpdump -nni r1-eth0 -s 0 -w /tmp/bmp_vrf.pcap &", stdout=None - ) - - for rname, router in tgen.routers().items(): - router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) - router.load_config( - TopoRouter.RD_BGP, - os.path.join(CWD, "{}/bgpd.conf".format(rname)), - "-M bmp", - ) - - tgen.start_router() - - logger.info("starting BMP servers") - for bmp_name, server in tgen.get_bmp_servers().items(): - server.start(log_file=os.path.join(tgen.logdir, bmp_name, "bmp.log")) - - -def teardown_module(_mod): - tgen = get_topogen() - tgen.stop_topology() - - -def test_bgp_convergence(): - tgen = get_topogen() - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - result = verify_bgp_convergence_from_running_config(tgen, dut="r1") - assert result is True, "BGP is not converging" - - -def get_bmp_messages(): - """ - Read the BMP logging messages. - """ - messages = [] - tgen = get_topogen() - text_output = tgen.gears["bmp1"].run( - "cat {}".format(os.path.join(tgen.logdir, "bmp1", "bmp.log")) - ) - - for m in text_output.splitlines(): - # some output in the bash can break the message decoding - try: - messages.append(json.loads(m)) - except Exception as e: - logger.warning(str(e) + " message: {}".format(str(m))) - continue - - if not messages: - logger.error("Bad BMP log format, check your BMP server") - - return messages - - -def update_seq(): - global SEQ - - messages = get_bmp_messages() - - if len(messages): - SEQ = messages[-1]["seq"] - - -def update_expected_files(bmp_actual, expected_prefixes, bmp_log_type, policy, step): - tgen = get_topogen() - - with open(f"/tmp/bmp-{bmp_log_type}-{policy}-step{step}.json", "w") as json_file: - json.dump(bmp_actual, json_file, indent=4) - - out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 json", isjson=True) - filtered_out = { - "routes": { - prefix: route_info - for prefix, route_info in out["routes"].items() - if prefix in expected_prefixes - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" in pfx: - continue - filtered_out["routes"][pfx] = None - - # ls /tmp/show*json | while read file; do egrep -v 'prefix|network|metric|ocPrf|version|weight|peerId|vrf|Version|valid|Reason|fe80' $file >$(basename $file); echo >> $(basename $file); done - with open(f"/tmp/show-bgp-ipv4-{bmp_log_type}-step{step}.json", "w") as json_file: - json.dump(filtered_out, json_file, indent=4) - - out = tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv6 json", isjson=True) - filtered_out = { - "routes": { - prefix: route_info - for prefix, route_info in out["routes"].items() - if prefix in expected_prefixes - } - } - if bmp_log_type == "withdraw": - for pfx in expected_prefixes: - if "::" not in pfx: - continue - filtered_out["routes"][pfx] = None - - with open(f"/tmp/show-bgp-ipv6-{bmp_log_type}-step{step}.json", "w") as json_file: - json.dump(filtered_out, json_file, indent=4) - - -def check_for_prefixes(expected_prefixes, bmp_log_type, policy, step): - """ - Check for the presence of the given prefixes in the BMP server logs with - the given message type and the set policy. - - """ - global SEQ - - # we care only about the new messages - messages = [ - m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ - ] - - # create empty initial files - # for step in $(seq 1); do - # for i in "update" "withdraw"; do - # for j in "pre-policy" "post-policy" "loc-rib"; do - # echo '{"null": {}}'> bmp-$i-$j-step$step.json - # done - # done - # done - - ref_file = f"{CWD}/bmp1/bmp-{bmp_log_type}-{policy}-step{step}.json" - expected = json.loads(open(ref_file).read()) - - # Build actual json from logs - actual = {} - for m in messages: - if ( - "bmp_log_type" in m.keys() - and "ip_prefix" in m.keys() - and m["ip_prefix"] in expected_prefixes - and m["bmp_log_type"] == bmp_log_type - and m["policy"] == policy - ): - policy_dict = actual.setdefault(m["policy"], {}) - bmp_log_type_dict = policy_dict.setdefault(m["bmp_log_type"], {}) - - # Add or update the ip_prefix dictionary with filtered key-value pairs - bmp_log_type_dict[m["ip_prefix"]] = { - k: v - for k, v in sorted(m.items()) - # filter out variable keys - if k not in ["timestamp", "seq", "nxhp_link-local"] - and ( - # When policy is loc-rib, the peer-distinguisher is 0:0 - # for the default VRF or the RD if any or the 0:<vrf_id>. - # 0:<vrf_id> is used to distinguished. RFC7854 says: "If the - # peer is a "Local Instance Peer", it is set to a unique, - # locally defined value." The value is not tested because it - # is variable. - k != "peer_distinguisher" - or policy != LOC_RIB - or v == "0:0" - or not v.startswith("0:") - ) - } - - # build expected JSON files - if ( - UPDATE_EXPECTED_JSON - and actual - and set(actual.get(policy, {}).get(bmp_log_type, {}).keys()) - == set(expected_prefixes) - ): - update_expected_files(actual, expected_prefixes, bmp_log_type, policy, step) - - return topotest.json_cmp(actual, expected, exact=True) - - -def check_for_peer_message(expected_peers, bmp_log_type): - """ - Check for the presence of a peer up message for the peer - """ - global SEQ - # we care only about the new messages - messages = [ - m for m in sorted(get_bmp_messages(), key=lambda d: d["seq"]) if m["seq"] > SEQ - ] - - # get the list of pairs (prefix, policy, seq) for the given message type - peers = [ - m["peer_ip"] - for m in messages - if "peer_ip" in m.keys() and m["bmp_log_type"] == bmp_log_type - ] - - # check for prefixes - for ep in expected_peers: - if ep not in peers: - msg = "The peer {} is not present in the {} log messages." - logger.debug(msg.format(ep, bmp_log_type)) - return False - - SEQ = messages[-1]["seq"] - return True - - -def configure_prefixes(tgen, node, asn, safi, prefixes, vrf=None, update=True): - """ - Configure the bgp prefixes. - """ - withdraw = "no " if not update else "" - vrf = " vrf {}".format(vrf) if vrf else "" - for p in prefixes: - ip = ip_network(p) - cmd = [ - "conf t\n", - "router bgp {}{}\n".format(asn, vrf), - "address-family ipv{} {}\n".format(ip.version, safi), - "{}network {}\n".format(withdraw, ip), - "exit-address-family\n", - ] - logger.debug("setting prefix: ipv{} {} {}".format(ip.version, safi, ip)) - tgen.gears[node].vtysh_cmd("".join(cmd)) - - -def _test_prefixes(policy, step=1): - """ - Setup the BMP monitor policy, Add and withdraw ipv4/v6 prefixes. - Check if the previous actions are logged in the BMP server with the right - message type and the right policy. - """ - tgen = get_topogen() - - prefixes = ["172.31.0.15/32", "2111::1111/128"] - - for type in ("update", "withdraw"): - update_seq() - - # add prefixes - configure_prefixes( - tgen, "r2", 65502, "unicast", prefixes, update=(type == "update") - ) - - logger.info(f"checking for prefixes {type}") - - for ipver in [4, 6]: - if UPDATE_EXPECTED_JSON: - continue - ref_file = "{}/r1/show-bgp-ipv{}-{}-step{}.json".format( - CWD, ipver, type, step - ) - expected = json.loads(open(ref_file).read()) - - test_func = partial( - topotest.router_json_cmp, - tgen.gears["r1"], - f"show bgp vrf vrf1 ipv{ipver} json", - expected, - ) - _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) - assertmsg = f"r1: BGP IPv{ipver} convergence failed" - assert res is None, assertmsg - - # check - test_func = partial(check_for_prefixes, prefixes, type, policy, step) - success, res = topotest.run_and_expect(test_func, None, count=30, wait=1) - assert success, "Checking the updated prefixes has been failed ! %s" % res - - -def test_bmp_server_logging(): - """ - Assert the logging of the bmp server. - """ - - def check_for_log_file(): - tgen = get_topogen() - output = tgen.gears["bmp1"].run( - "ls {}".format(os.path.join(tgen.logdir, "bmp1")) - ) - if "bmp.log" not in output: - return False - return True - - success, _ = topotest.run_and_expect(check_for_log_file, True, count=30, wait=1) - assert success, "The BMP server is not logging" - - -def test_peer_up(): - """ - Checking for BMP peers up messages - """ - - peers = ["192.168.0.2", "192:168::2"] - - logger.info("checking for BMP peers up messages") - - test_func = partial(check_for_peer_message, peers, "peer up") - success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) - assert success, "Checking the updated prefixes has been failed !." - - -def test_bmp_bgp_unicast(): - """ - Add/withdraw bgp unicast prefixes and check the bmp logs. - """ - logger.info("*** Unicast prefixes pre-policy logging ***") - _test_prefixes(PRE_POLICY) - logger.info("*** Unicast prefixes post-policy logging ***") - _test_prefixes(POST_POLICY) - logger.info("*** Unicast prefixes loc-rib logging ***") - _test_prefixes(LOC_RIB) - - -def test_peer_down(): - """ - Checking for BMP peers down messages - """ - tgen = get_topogen() - - tgen.gears["r2"].vtysh_cmd("clear bgp *") - - peers = ["192.168.0.2", "192:168::2"] - - logger.info("checking for BMP peers down messages") - - test_func = partial(check_for_peer_message, peers, "peer down") - success, _ = topotest.run_and_expect(test_func, True, count=30, wait=1) - assert success, "Checking the updated prefixes has been failed !." - - -if __name__ == "__main__": - args = ["-s"] + sys.argv[1:] - sys.exit(pytest.main(args)) 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 000000000..7532ce933 --- /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 000000000..a14ba1291 --- /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 000000000..597bca5fd --- /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 de5a0efc4..4f1d8e4a3 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 9dfb7fc4d..a9636a92f 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/bgp_lu_topo1/R3/bgpd.conf b/tests/topotests/bgp_lu_topo1/R3/bgpd.conf index 31d26ea1e..9ba059aee 100644 --- a/tests/topotests/bgp_lu_topo1/R3/bgpd.conf +++ b/tests/topotests/bgp_lu_topo1/R3/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log ! ! debug bgp updates ! diff --git a/tests/topotests/bgp_lu_topo1/R3/zebra.conf b/tests/topotests/bgp_lu_topo1/R3/zebra.conf index ea4a1482d..fedcd6bc3 100644 --- a/tests/topotests/bgp_lu_topo1/R3/zebra.conf +++ b/tests/topotests/bgp_lu_topo1/R3/zebra.conf @@ -1,4 +1,3 @@ -log file /tmp/zebra.log ! ! debug zebra events ! debug zebra packet detail diff --git a/tests/topotests/bgp_lu_topo2/R3/bgpd.conf b/tests/topotests/bgp_lu_topo2/R3/bgpd.conf index 6443445b8..a0dd0fe00 100644 --- a/tests/topotests/bgp_lu_topo2/R3/bgpd.conf +++ b/tests/topotests/bgp_lu_topo2/R3/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log no log unique-id ! ! diff --git a/tests/topotests/bgp_lu_topo2/R3/staticd.conf b/tests/topotests/bgp_lu_topo2/R3/staticd.conf index 867fc5a83..c0eee461e 100644 --- a/tests/topotests/bgp_lu_topo2/R3/staticd.conf +++ b/tests/topotests/bgp_lu_topo2/R3/staticd.conf @@ -1,4 +1,3 @@ -log file /tmp/staticd.log no log unique-id ! ! diff --git a/tests/topotests/bgp_lu_topo2/R3/zebra.conf b/tests/topotests/bgp_lu_topo2/R3/zebra.conf index dd24deb21..fd29ed54d 100644 --- a/tests/topotests/bgp_lu_topo2/R3/zebra.conf +++ b/tests/topotests/bgp_lu_topo2/R3/zebra.conf @@ -1,4 +1,3 @@ -log file /tmp/zebra.log no log unique-id ! ! diff --git a/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py index e478139eb..7875f2e0f 100644 --- a/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py +++ b/tests/topotests/bgp_nexthop_ipv6/test_bgp_nexthop_ipv6_topo1.py @@ -222,7 +222,6 @@ def test_bgp_ipv6_table_step1(): link_local_cache = {} router_list = tgen.routers().values() for router in router_list: - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -275,7 +274,6 @@ router bgp 65000 router_list = tgen.routers().values() for router in router_list: - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step2.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -327,7 +325,6 @@ router bgp 65000 router_list = tgen.routers().values() for router in router_list: - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) diff --git a/tests/topotests/bgp_peer_group/r1/frr.conf b/tests/topotests/bgp_peer_group/r1/frr.conf index 035c8e4cf..cf9d16c91 100644 --- a/tests/topotests/bgp_peer_group/r1/frr.conf +++ b/tests/topotests/bgp_peer_group/r1/frr.conf @@ -5,6 +5,9 @@ interface r1-eth0 interface r1-eth1 ip address 192.168.251.1/30 ! +interface r1-eth2 + ip address 192.168.252.1/30 +! ip forwarding ! router bgp 65001 @@ -17,5 +20,9 @@ router bgp 65001 neighbor PG1 remote-as external neighbor PG1 timers 3 20 neighbor PG1 graceful-restart-disable + neighbor PG2 peer-group + neighbor PG2 local-as 65554 no-prepend replace-as neighbor 192.168.251.2 peer-group PG1 + neighbor 192.168.252.2 remote-as 65004 + neighbor 192.168.252.2 peer-group PG2 ! diff --git a/tests/topotests/bgp_peer_group/r4/frr.conf b/tests/topotests/bgp_peer_group/r4/frr.conf new file mode 100644 index 000000000..b1da90f06 --- /dev/null +++ b/tests/topotests/bgp_peer_group/r4/frr.conf @@ -0,0 +1,7 @@ +! +interface r4-eth0 + ip address 192.168.252.2/30 +! +router bgp 65004 + neighbor 192.168.252.1 remote-as external +! diff --git a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py index 45f713b8a..e98d5f8b3 100644 --- a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py +++ b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py @@ -30,7 +30,7 @@ pytestmark = [pytest.mark.bgpd] def build_topo(tgen): - for routern in range(1, 4): + for routern in range(1, 5): tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") @@ -42,6 +42,10 @@ def build_topo(tgen): switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r4"]) + def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) @@ -84,6 +88,11 @@ def test_bgp_peer_group(): "bgpState": "Established", "neighborCapabilities": {"gracefulRestart": "received"}, }, + "192.168.252.2": { + "peerGroup": "PG2", + "bgpState": "Established", + "neighborCapabilities": {"gracefulRestart": "advertisedAndReceived"}, + }, } return topotest.json_cmp(output, expected) @@ -110,6 +119,24 @@ def test_bgp_peer_group(): assert result is None, "Failed checking advertised routes from r3" +def test_show_running_remote_as_peer_group(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + output = ( + tgen.gears["r1"] + .cmd( + 'vtysh -c "show running bgpd" | grep "^ neighbor 192.168.252.2 remote-as 65004"' + ) + .rstrip() + ) + assert ( + output == " neighbor 192.168.252.2 remote-as 65004" + ), "192.168.252.2 remote-as is flushed" + + def test_bgp_peer_group_remote_as_del_readd(): tgen = get_topogen() diff --git a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py index a6334918d..9dfeec6de 100644 --- a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py +++ b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py @@ -180,7 +180,6 @@ def test_bgp_route_server_client_step1(): else: cmd = "show bgp ipv6 unicast json" - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -230,7 +229,6 @@ router bgp 65000 view RS else: cmd = "show bgp ipv6 unicast json" - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step2.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) @@ -286,7 +284,6 @@ router bgp 65000 view RS else: cmd = "show bgp ipv6 unicast json" - # router.cmd("vtysh -c 'sh bgp ipv6 json' >/tmp/show_bgp_ipv6_%s.json" % router.name) ref_file = "{}/{}/show_bgp_ipv6_step1.json".format(CWD, router.name) expected = json.loads(open(ref_file).read()) replace_link_local(expected, link_local_cache) diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf index b598666df..75d8c9e55 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65001 timers bgp 3 9 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf index 4a8579845..8e6743c5f 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce1/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf index e388ccba8..37d40651c 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf index 5e0aa5d3f..02afea114 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce2/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf index e388ccba8..37d40651c 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf index fabc11e84..714f1ec35 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce3/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf index e388ccba8..37d40651c 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65001 bgp router-id 192.168.200.10 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf index e369f41b3..d5efab4bf 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/ce4/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf index 098e55d0e..b80a90ac7 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r1/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65000 bgp router-id 10.1.1.1 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf index 4fec8af3d..87cffebd8 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r2/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf index e43399559..162f5bbcc 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r3/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf index 2a834c799..1f44feb0d 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r4/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 65000 bgp router-id 10.4.4.4 diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf b/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf index 14580e5b3..7b0719d26 100644 --- a/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf +++ b/tests/topotests/bgp_snmp_mplsl3vpn/r4/zebra.conf @@ -1,5 +1,3 @@ -log file /tmp/zebra.log -log stdout ! ! debug zebra events ! debug zebra dplane diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index bcd1c7481..329c2b54f 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -5638,3 +5638,22 @@ def configure_bgp_soft_configuration(tgen, dut, neighbor_dict, direction): ) ) return True + + +def bgp_configure_prefixes(router, asn, safi, prefixes, vrf=None, update=True): + """ + Configure the bgp prefixes. + """ + withdraw = "no " if not update else "" + vrf = " vrf {}".format(vrf) if vrf else "" + for p in prefixes: + ip = ipaddress.ip_network(p) + cmd = [ + "conf t\n", + f"router bgp {asn}{vrf}\n" + f"address-family ipv{ip.version} {safi}\n" + f"{withdraw}network {ip}\n".format(withdraw, ip), + "exit-address-family\n", + ] + logger.debug(f"setting prefix: ipv{ip.version} {safi} {ip}") + router.vtysh_cmd("".join(cmd)) diff --git a/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py b/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py index 3694cb4fe..ca49c405d 100644 --- a/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py +++ b/tests/topotests/lib/bmp_collector/bgp/update/path_attributes.py @@ -72,6 +72,12 @@ class PathAttribute: if path_attr_cls == cls.UNKNOWN_ATTR: return data[offset + attr_len :], None + # RFC1771, 4.3 UPDATE Message Format + # The path segment length is a 1-octet long field containing + # the number of ASs in the path segment value field. + if type_code == PATH_ATTR_TYPE_AS_PATH and attr_len == 0: + return data[offset:], path_attr_cls.dissect(data[offset : offset + 2]) + return data[offset + attr_len :], path_attr_cls.dissect( data[offset : offset + attr_len] ) diff --git a/tests/topotests/lib/bmp_collector/bmpserver b/tests/topotests/lib/bmp_collector/bmpserver.py index 56d85fc74..c42c38756 100755 --- a/tests/topotests/lib/bmp_collector/bmpserver +++ b/tests/topotests/lib/bmp_collector/bmpserver.py @@ -5,8 +5,11 @@ # Authored by Farid Mihoub <farid.mihoub@6wind.com> # import argparse +import errno +import logging # XXX: something more reliable should be used "Twisted" a great choice. +import os import signal import socket import sys @@ -20,11 +23,11 @@ BGP_MAX_SIZE = 4096 # Global variable to track shutdown signal shutdown = False - parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", type=str, default="0.0.0.0") parser.add_argument("-p", "--port", type=int, default=1789) parser.add_argument("-l", "--logfile", type=str, default="/var/log/bmp.log") +parser.add_argument("-r", "--pidfile", type=str, default="/var/run/bmp.pid") def handle_signal(signum, frame): @@ -40,6 +43,74 @@ def timestamp_print(message, file=sys.stderr): print(f"[{current_time}] {message}", file=file) +def check_pid(pid): + if pid < 0: # user input error + return False + if pid == 0: # all processes + return False + try: + os.kill(pid, 0) + return True + except OSError as err: + if err.errno == errno.EPERM: # a process we were denied access to + return True + if err.errno == errno.ESRCH: # No such process + return False + # should never happen + return False + + +def savepid(): + ownid = os.getpid() + + flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY + mode = ((os.R_OK | os.W_OK) << 6) | (os.R_OK << 3) | os.R_OK + + try: + fd = os.open(pid_file, flags, mode) + except OSError: + try: + pid = open(pid_file, "r").readline().strip() + if check_pid(int(pid)): + timestamp_print( + "PID file already exists and program still running %s\n" % pid_file + ) + return False + else: + # If pid is not running, reopen file without O_EXCL + fd = os.open(pid_file, flags ^ os.O_EXCL, mode) + except (OSError, IOError, ValueError): + timestamp_print( + "issue accessing PID file %s (most likely permission or ownership)\n" + % pid_file + ) + return False + + try: + f = os.fdopen(fd, "w") + line = "%d\n" % ownid + f.write(line) + f.close() + saved_pid = True + except IOError: + timestamp_print("Can not create PID file %s\n" % pid_file) + return False + timestamp_print("Created PID file %s with value %d\n" % (pid_file, ownid)) + return True + + +def removepid(): + try: + os.remove(pid_file) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + timestamp_print("Can not remove PID file %s\n" % pid_file) + return + timestamp_print("Removed PID file %s\n" % pid_file) + + def main(): global shutdown @@ -51,8 +122,13 @@ def main(): ADDRESS, PORT = args.address, args.port LOG_FILE = args.logfile + global pid_file + pid_file = args.pidfile + timestamp_print(f"Starting bmpserver on {args.address}:{args.port}") + savepid() + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: @@ -80,9 +156,7 @@ def main(): while len(data) > BMPMsg.MIN_LEN: data = BMPMsg.dissect(data, log_file=LOG_FILE) - timestamp_print( - f"Finished dissecting data from {client_address}" - ) + timestamp_print(f"Finished dissecting data from {client_address}") except Exception as e: timestamp_print(f"{e}") @@ -99,6 +173,7 @@ def main(): timestamp_print(f"{e}") finally: timestamp_print(f"Server shutting down on {ADDRESS}:{PORT}") + removepid() if __name__ == "__main__": @@ -106,4 +181,5 @@ if __name__ == "__main__": sys.exit(main()) except KeyboardInterrupt: logging.info("BMP server was interrupted and is shutting down.") + removepid() sys.exit(0) diff --git a/tests/topotests/lib/snmptest.py b/tests/topotests/lib/snmptest.py index 8e2e76d15..6d586cee5 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/lib/topogen.py b/tests/topotests/lib/topogen.py index 4d7c56423..0a9a84a4b 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -1293,18 +1293,19 @@ class TopoBMPCollector(TopoHost): log_err = os.path.join(log_dir, "bmpserver.log") log_arg = "-l {}".format(log_file) if log_file else "" + self.pid_file = os.path.join(log_dir, "bmpserver.pid") with open(log_err, "w") as err: self.run( - "{}/bmp_collector/bmpserver -a {} -p {} {}&".format( - CWD, self.ip, self.port, log_arg + "{}/bmp_collector/bmpserver.py -a {} -p {} -r {} {}&".format( + CWD, self.ip, self.port, self.pid_file, log_arg ), stdout=None, stderr=err, ) def stop(self): - self.run("pkill -f bmpserver") + self.run(f"kill $(cat {self.pid_file}") return "" diff --git a/tests/topotests/ospf_metric_propagation/h1/frr.conf b/tests/topotests/ospf_metric_propagation/h1/frr.conf index 1196a192d..b8d1834e2 100644 --- a/tests/topotests/ospf_metric_propagation/h1/frr.conf +++ b/tests/topotests/ospf_metric_propagation/h1/frr.conf @@ -1,10 +1,8 @@ ! hostname h1 -password zebra -log file /tmp/h1-frr.log ! ip route 0.0.0.0/0 10.0.91.1 ! interface h1-eth0 ip address 10.0.91.2/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/ospf_metric_propagation/h2/frr.conf b/tests/topotests/ospf_metric_propagation/h2/frr.conf index f951fe6ba..437725626 100644 --- a/tests/topotests/ospf_metric_propagation/h2/frr.conf +++ b/tests/topotests/ospf_metric_propagation/h2/frr.conf @@ -1,10 +1,8 @@ ! hostname h2 -password zebra -log file /tmp/h2-frr.log ! ip route 0.0.0.0/0 10.0.94.4 ! interface h2-eth0 ip address 10.0.94.2/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/ospf_metric_propagation/r1/frr.conf b/tests/topotests/ospf_metric_propagation/r1/frr.conf index 4966e6a9d..082f7df51 100644 --- a/tests/topotests/ospf_metric_propagation/r1/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r1/frr.conf @@ -1,8 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r1-eth0 ip address 10.0.1.1/24 @@ -93,4 +90,4 @@ route-map costplus permit 30 route-map costplus permit 40 set metric-type type-1 set metric +1 - exit
\ No newline at end of file + exit diff --git a/tests/topotests/ospf_metric_propagation/r2/frr.conf b/tests/topotests/ospf_metric_propagation/r2/frr.conf index 0ac5001b1..e6ced31d8 100644 --- a/tests/topotests/ospf_metric_propagation/r2/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r2/frr.conf @@ -1,8 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r2-frr.log -ip forwarding ! interface r2-eth0 ip address 10.0.1.2/24 diff --git a/tests/topotests/ospf_metric_propagation/r3/frr.conf b/tests/topotests/ospf_metric_propagation/r3/frr.conf index 0859173f7..f6989057f 100644 --- a/tests/topotests/ospf_metric_propagation/r3/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r3/frr.conf @@ -1,8 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-frr.log -ip forwarding ! interface r3-eth0 ip address 10.0.3.3/24 diff --git a/tests/topotests/ospf_metric_propagation/r4/frr.conf b/tests/topotests/ospf_metric_propagation/r4/frr.conf index 743da2727..b02ae18fc 100644 --- a/tests/topotests/ospf_metric_propagation/r4/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r4/frr.conf @@ -1,8 +1,5 @@ ! hostname r4 -password zebra -log file /tmp/r4-frr.log -ip forwarding ! interface r4-eth0 ip address 10.0.3.4/24 diff --git a/tests/topotests/ospf_metric_propagation/ra/frr.conf b/tests/topotests/ospf_metric_propagation/ra/frr.conf index 2434faeab..5ad819da0 100644 --- a/tests/topotests/ospf_metric_propagation/ra/frr.conf +++ b/tests/topotests/ospf_metric_propagation/ra/frr.conf @@ -1,8 +1,5 @@ ! hostname ra -password zebra -log file /tmp/ra-frr.log -ip forwarding ! interface ra-eth0 ip address 10.0.50.5/24 diff --git a/tests/topotests/ospf_metric_propagation/rb/frr.conf b/tests/topotests/ospf_metric_propagation/rb/frr.conf index b83532a84..21abefed2 100644 --- a/tests/topotests/ospf_metric_propagation/rb/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rb/frr.conf @@ -1,8 +1,5 @@ ! hostname rb -password zebra -log file /tmp/rb-frr.log -ip forwarding ! interface rb-eth0 ip address 10.0.50.6/24 diff --git a/tests/topotests/ospf_metric_propagation/rc/frr.conf b/tests/topotests/ospf_metric_propagation/rc/frr.conf index dd8077c39..0e6edd92a 100644 --- a/tests/topotests/ospf_metric_propagation/rc/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rc/frr.conf @@ -1,8 +1,5 @@ ! hostname rc -password zebra -log file /tmp/rc-frr.log -ip forwarding ! interface rc-eth0 ip address 10.0.70.7/24 diff --git a/tests/topotests/ospf_multi_instance/r1/frr.conf b/tests/topotests/ospf_multi_instance/r1/frr.conf index c341a7176..b9752c63a 100644 --- a/tests/topotests/ospf_multi_instance/r1/frr.conf +++ b/tests/topotests/ospf_multi_instance/r1/frr.conf @@ -1,8 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface lo ip address 1.1.1.1/32 diff --git a/tests/topotests/ospf_multi_instance/r3/frr.conf b/tests/topotests/ospf_multi_instance/r3/frr.conf index 97a3e19c9..e6f681a46 100644 --- a/tests/topotests/ospf_multi_instance/r3/frr.conf +++ b/tests/topotests/ospf_multi_instance/r3/frr.conf @@ -1,8 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-frr.log -ip forwarding ! interface lo ip address 3.3.3.1/32 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf index 995958132..bcbe2eded 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf @@ -1,7 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log ! interface r1-eth0 ip address 10.0.1.1/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf index 29909de64..0d3eb3c8c 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf @@ -1,7 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r2-frr.log ! interface r2-eth0 ip address 10.0.2.2/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf index 35fe22e9f..1cc2972f0 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf @@ -1,7 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-frr.log ! interface r3-eth0 ip address 10.0.3.3/24 diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf index 721c3d91c..a82d5b033 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf @@ -1,7 +1,5 @@ ! hostname r4 -password zebra -log file /tmp/r4-frr.log ! interface r4-eth0 ip address 10.0.4.4/24 diff --git a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf index ba1314656..75f38d005 100644 --- a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf @@ -1,7 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-ospfd.log ! interface r1-eth0 vrf r1-ospf-cust1 ip ospf hello-interval 1 diff --git a/tests/topotests/ospf_netns_vrf/r1/zebra.conf b/tests/topotests/ospf_netns_vrf/r1/zebra.conf index 56d7a9764..1c08f1e26 100644 --- a/tests/topotests/ospf_netns_vrf/r1/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r1/zebra.conf @@ -4,8 +4,6 @@ ! debug zebra event ! hostname r1 -password zebra -log file /tmp/r1-zebra.log ! interface r1-eth0 vrf r1-ospf-cust1 ip address 10.0.1.1/24 diff --git a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf index 01b6b1526..3cd69bb8f 100644 --- a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf @@ -1,7 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r2-ospfd.log ! interface r2-eth0 vrf r2-ospf-cust1 ip ospf hello-interval 1 diff --git a/tests/topotests/ospf_netns_vrf/r2/zebra.conf b/tests/topotests/ospf_netns_vrf/r2/zebra.conf index 6ff72d126..f997028c7 100644 --- a/tests/topotests/ospf_netns_vrf/r2/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r2/zebra.conf @@ -1,7 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r2-zebra.log ! interface r2-eth0 vrf r2-ospf-cust1 ip address 10.0.2.1/24 diff --git a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf index abfaa5b9e..4581a609b 100644 --- a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf @@ -1,7 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-ospfd.log ! ! interface r3-eth0 vrf r3-ospf-cust1 diff --git a/tests/topotests/ospf_netns_vrf/r3/zebra.conf b/tests/topotests/ospf_netns_vrf/r3/zebra.conf index 153415004..4053d94a6 100644 --- a/tests/topotests/ospf_netns_vrf/r3/zebra.conf +++ b/tests/topotests/ospf_netns_vrf/r3/zebra.conf @@ -1,7 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-zebra.log ! interface r3-eth0 vrf r3-ospf-cust1 ip address 10.0.3.1/24 diff --git a/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf index ca84349cd..fdc75633b 100644 --- a/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r1/frr-p2mp-non-broadcast.conf @@ -1,8 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r1-eth0 ip address 10.1.0.1/24 diff --git a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf index 89f255bb4..350c0de7b 100644 --- a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf @@ -1,13 +1,10 @@ ! -!log file ospfd.log debug ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all hostname r1 -password zebra -log file /tmp/r1-frr.log ip forwarding ! interface r1-eth0 diff --git a/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf index 6e26897c4..c44e936f9 100644 --- a/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r2/frr-p2mp-non-broadcast.conf @@ -1,8 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r2-eth0 ip address 10.1.0.2/24 diff --git a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf index 429330987..806914d81 100644 --- a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf @@ -1,14 +1,10 @@ ! -!log file ospfd.log debug ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r2 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r2-eth0 ip address 10.1.0.2/24 diff --git a/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf index a69e0557b..d89269b32 100644 --- a/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r3/frr-p2mp-non-broadcast.conf @@ -1,8 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r3-eth0 ip address 10.1.0.3/24 diff --git a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf index eada78450..343a9d008 100644 --- a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf @@ -1,14 +1,10 @@ ! -!log file ospfd.log debug ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r3 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r3-eth0 ip address 10.1.0.3/24 diff --git a/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf b/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf index 1b8388584..aa6c80d41 100644 --- a/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf +++ b/tests/topotests/ospf_p2mp/r4/frr-p2mp-non-broadcast.conf @@ -1,8 +1,5 @@ ! hostname r4 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r4-eth0 ip address 10.1.0.4/24 diff --git a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf index 3146ea095..a1527f5aa 100644 --- a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf @@ -1,14 +1,10 @@ ! -!log file ospfd.log debug ! debug ospf event ! debug ospf client ! debug ospf lsa ! debug ospf packet all ! hostname r4 -password zebra -log file /tmp/r1-frr.log -ip forwarding ! interface r4-eth0 ip address 10.1.0.4/24 diff --git a/tests/topotests/ospf_prefix_suppression/r1/frr.conf b/tests/topotests/ospf_prefix_suppression/r1/frr.conf index 437b47415..4b9df834b 100644 --- a/tests/topotests/ospf_prefix_suppression/r1/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r1/frr.conf @@ -1,7 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log ip forwarding ! interface r1-eth0 diff --git a/tests/topotests/ospf_prefix_suppression/r2/frr.conf b/tests/topotests/ospf_prefix_suppression/r2/frr.conf index 68390f15f..cf4a25a09 100644 --- a/tests/topotests/ospf_prefix_suppression/r2/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r2/frr.conf @@ -1,7 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r1-frr.log ip forwarding ! interface r2-eth0 diff --git a/tests/topotests/ospf_prefix_suppression/r3/frr.conf b/tests/topotests/ospf_prefix_suppression/r3/frr.conf index 984a39d98..dbd1bc375 100644 --- a/tests/topotests/ospf_prefix_suppression/r3/frr.conf +++ b/tests/topotests/ospf_prefix_suppression/r3/frr.conf @@ -1,7 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r1-frr.log ip forwarding ! interface r3-eth0 diff --git a/tests/topotests/pim_autorp/r1/frr.conf b/tests/topotests/pim_autorp/r1/frr.conf index 92b9b3b41..fc4e63445 100644 --- a/tests/topotests/pim_autorp/r1/frr.conf +++ b/tests/topotests/pim_autorp/r1/frr.conf @@ -1,9 +1,7 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log ! -debug pim autorp +!debug pim autorp ! interface r1-eth0 ip address 10.0.0.1/24 @@ -23,4 +21,4 @@ ip route 10.0.3.0/24 10.0.0.2 50 router pim autorp discovery rp 10.0.3.4 224.0.1.0/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/pim_autorp/r2/frr.conf b/tests/topotests/pim_autorp/r2/frr.conf index d67dade6f..ded462cad 100644 --- a/tests/topotests/pim_autorp/r2/frr.conf +++ b/tests/topotests/pim_autorp/r2/frr.conf @@ -1,9 +1,7 @@ ! hostname r2 -password zebra -log file /tmp/r2-frr.log ! -debug pim autorp +!debug pim autorp ! interface r2-eth0 ip address 10.0.0.2/24 @@ -23,4 +21,4 @@ ip route 10.0.3.0/24 10.0.2.4 50 router pim autorp discovery rp 10.0.3.4 224.0.1.0/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/pim_autorp/r3/frr.conf b/tests/topotests/pim_autorp/r3/frr.conf index 4e93d4ba2..31726f2c0 100644 --- a/tests/topotests/pim_autorp/r3/frr.conf +++ b/tests/topotests/pim_autorp/r3/frr.conf @@ -1,9 +1,7 @@ ! hostname r3 -password zebra -log file /tmp/r3-frr.log ! -debug pim autorp +!debug pim autorp ! interface r3-eth0 ip address 10.0.1.3/24 @@ -23,4 +21,4 @@ ip route 10.0.2.0/24 10.0.3.4 50 router pim autorp discovery rp 10.0.3.4 224.0.1.0/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/pim_autorp/r4/frr.conf b/tests/topotests/pim_autorp/r4/frr.conf index 382999b11..9d37da99a 100644 --- a/tests/topotests/pim_autorp/r4/frr.conf +++ b/tests/topotests/pim_autorp/r4/frr.conf @@ -1,9 +1,7 @@ ! hostname r4 -password zebra -log file /tmp/r4-frr.log ! -debug pim autorp +!debug pim autorp ! interface r4-eth0 ip address 10.0.2.4/24 @@ -23,4 +21,4 @@ ip route 10.0.1.0/24 10.0.2.2 50 router pim autorp discovery rp 10.0.3.4 224.0.1.0/24 -!
\ No newline at end of file +! diff --git a/tests/topotests/pim_basic/test_pim.py b/tests/topotests/pim_basic/test_pim.py index ce1abe42b..74d540697 100644 --- a/tests/topotests/pim_basic/test_pim.py +++ b/tests/topotests/pim_basic/test_pim.py @@ -132,14 +132,14 @@ def test_pim_send_mcast_stream(): # Let's establish a S,G stream from r2 -> r1 CWD = os.path.dirname(os.path.realpath(__file__)) r2.run( - "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r2-eth0 > /tmp/bar".format( - CWD + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r2-eth0 > {}/r2/mcast_tx_output".format( + CWD, tgen.logdir ) ) # And from r3 -> r1 r3.run( - "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r3-eth0 > /tmp/bar".format( - CWD + "{}/mcast-tx.py --ttl 5 --count 40 --interval 2 229.1.1.1 r3-eth0 > {}/r3/mcast_tx_output".format( + CWD, tgen.logdir ) ) diff --git a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf index 899e9c068..badcb8307 100644 --- a/tests/topotests/pim_cand_rp_bsr/r1/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r1/frr.conf @@ -1,7 +1,5 @@ ! hostname r1 -password zebra -log file /tmp/r1-frr.log ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf index 85af461d5..65926688a 100644 --- a/tests/topotests/pim_cand_rp_bsr/r2/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r2/frr.conf @@ -1,7 +1,5 @@ ! hostname r2 -password zebra -log file /tmp/r2-frr.log ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf index 022c44ea5..eae90c987 100644 --- a/tests/topotests/pim_cand_rp_bsr/r3/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r3/frr.conf @@ -1,7 +1,5 @@ ! hostname r3 -password zebra -log file /tmp/r3-frr.log ! !debug pim packet !debug pim bsm diff --git a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf index 2d0a035f9..276e87921 100644 --- a/tests/topotests/pim_cand_rp_bsr/r4/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r4/frr.conf @@ -1,7 +1,5 @@ ! hostname r4 -password zebra -log file /tmp/r4-frr.log ! ! interface lo diff --git a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf index 552e51f41..b86c62600 100644 --- a/tests/topotests/pim_cand_rp_bsr/r5/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r5/frr.conf @@ -1,7 +1,5 @@ ! hostname r5 -password zebra -log file /tmp/r5-frr.log ! ! interface r5-eth0 diff --git a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf index 20955a12c..1fd358221 100644 --- a/tests/topotests/pim_cand_rp_bsr/r6/frr.conf +++ b/tests/topotests/pim_cand_rp_bsr/r6/frr.conf @@ -1,7 +1,5 @@ ! hostname r6 -password zebra -log file /tmp/r6-frr.log ! ! interface r6-eth0 diff --git a/tests/topotests/simple_snmp_test/r1/bgpd.conf b/tests/topotests/simple_snmp_test/r1/bgpd.conf index 00d1e1767..bcdf1c4f7 100644 --- a/tests/topotests/simple_snmp_test/r1/bgpd.conf +++ b/tests/topotests/simple_snmp_test/r1/bgpd.conf @@ -1,4 +1,3 @@ -log file /tmp/bgpd.log debugging ! router bgp 100 bgp router-id 1.1.1.1 diff --git a/tests/topotests/simple_snmp_test/r1/isisd.conf b/tests/topotests/simple_snmp_test/r1/isisd.conf index 435abde33..c53d2509e 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 000000000..e81151710 --- /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 000000000..cc0d9e52c --- /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 000000000..71cdb058c --- /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 5281d0055..6483a661c 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 0387e2927..c74ffcc2d 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/tests/topotests/zebra_rib/r1/frr-import.conf b/tests/topotests/zebra_rib/r1/frr-import.conf index d07433144..687843be0 100644 --- a/tests/topotests/zebra_rib/r1/frr-import.conf +++ b/tests/topotests/zebra_rib/r1/frr-import.conf @@ -1,7 +1,6 @@ ! hostname r1 password zebra -log file /tmp/r1-frr.log ! interface r1-eth0 ip address 10.0.0.1/24 @@ -15,4 +14,4 @@ ip route 10.3.0.0/24 10.10.0.2 table 10 ip route 10.4.0.0/24 10.10.0.2 table 10 ! ip forwarding -!
\ No newline at end of file +! diff --git a/zebra/interface.c b/zebra/interface.c index 86de5dbae..f7fd112cd 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 a35784cd3..47ce7c943 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 0658f996e..ad112a4ab 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 2658c9f01..ea0be2f64 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); } |