summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_mplsvpn.c10
-rw-r--r--bgpd/bgp_network.c21
-rw-r--r--bgpd/bgp_network.h1
-rw-r--r--bgpd/bgp_route.c14
-rw-r--r--bgpd/bgpd.c6
-rw-r--r--doc/user/bgp.rst6
-rw-r--r--lib/systemd.c4
-rw-r--r--pimd/pim_ifchannel.c4
-rw-r--r--zebra/rt_netlink.c123
-rw-r--r--zebra/zebra_vxlan.c46
-rw-r--r--zebra/zebra_vxlan.h2
11 files changed, 166 insertions, 71 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 86c04b71f0..8758d0ca78 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1532,7 +1532,10 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
ecom = bgp->vpn_policy[afi].rtlist[edir];
for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
export_vrf, node, vname)) {
- bgp_import = bgp_lookup_by_name(vname);
+ if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
+ bgp_import = bgp_get_default();
+ else
+ bgp_import = bgp_lookup_by_name(vname);
if (!bgp_import)
continue;
@@ -1572,7 +1575,10 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
ecom = bgp->vpn_policy[afi].rtlist[edir];
for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
export_vrf, node, vname)) {
- bgp_import = bgp_lookup_by_name(vname);
+ if (strcmp(vname, VRF_DEFAULT_NAME) == 0)
+ bgp_import = bgp_get_default();
+ else
+ bgp_import = bgp_lookup_by_name(vname);
if (!bgp_import)
continue;
if (bgp_import->vpn_policy[afi].rtlist[idir])
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 8759a88444..037aeec288 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -57,8 +57,26 @@ struct bgp_listener {
union sockunion su;
struct thread *thread;
struct bgp *bgp;
+ char *name;
};
+void bgp_dump_listener_info(struct vty *vty)
+{
+ struct listnode *node;
+ struct bgp_listener *listener;
+
+ vty_out(vty, "Name fd Address\n");
+ vty_out(vty, "---------------------------\n");
+ for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, listener)) {
+ char buf[SU_ADDRSTRLEN];
+
+ vty_out(vty, "%-16s %d %s\n",
+ listener->name ? listener->name : VRF_DEFAULT_NAME,
+ listener->fd,
+ sockunion2str(&listener->su, buf, sizeof(buf)));
+ }
+}
+
/*
* Set MD5 key for the socket, for the given IPv4 peer address.
* If the password is NULL or zero-length, the option will be disabled.
@@ -762,6 +780,7 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen,
listener = XCALLOC(MTYPE_BGP_LISTENER, sizeof(*listener));
listener->fd = sock;
+ listener->name = XSTRDUP(MTYPE_BGP_LISTENER, bgp->name);
/* this socket needs a change of ns. record bgp back pointer */
if (bgp->vrf_id != VRF_DEFAULT && vrf_is_backend_netns())
@@ -871,6 +890,7 @@ void bgp_close_vrf_socket(struct bgp *bgp)
thread_cancel(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);
+ XFREE(MTYPE_BGP_LISTENER, listener->name);
XFREE(MTYPE_BGP_LISTENER, listener);
}
}
@@ -892,6 +912,7 @@ void bgp_close(void)
thread_cancel(listener->thread);
close(listener->fd);
listnode_delete(bm->listen_sockets, listener);
+ XFREE(MTYPE_BGP_LISTENER, listener->name);
XFREE(MTYPE_BGP_LISTENER, listener);
}
}
diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h
index 59b18f9376..018efbc08e 100644
--- a/bgpd/bgp_network.h
+++ b/bgpd/bgp_network.h
@@ -23,6 +23,7 @@
#define BGP_SOCKET_SNDBUF_SIZE 65536
+extern void bgp_dump_listener_info(struct vty *vty);
extern int bgp_socket(struct bgp *bgp, unsigned short port,
const char *address);
extern void bgp_close_vrf_socket(struct bgp *bgp);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index bcd87eb01b..c2c034d164 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -69,6 +69,7 @@
#include "bgpd/bgp_label.h"
#include "bgpd/bgp_addpath.h"
#include "bgpd/bgp_mac.h"
+#include "bgpd/bgp_network.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
@@ -12766,6 +12767,18 @@ static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
sockunion2str(&peer->su, buf, sizeof(buf)));
}
+DEFUN (show_bgp_listeners,
+ show_bgp_listeners_cmd,
+ "show bgp listeners",
+ SHOW_STR
+ BGP_STR
+ "Display Listen Sockets and who created them\n")
+{
+ bgp_dump_listener_info(vty);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_bgp_peerhash,
show_bgp_peerhash_cmd,
"show bgp peerhash",
@@ -13155,6 +13168,7 @@ void bgp_route_init(void)
/* show bgp ipv4 flowspec detailed */
install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
+ install_element(VIEW_NODE, &show_bgp_listeners_cmd);
install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
}
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 1a75888d68..267d67e46e 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -4071,6 +4071,9 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
/* Update flag override state accordingly. */
COND_FLAG(peer->flags_override, flag, set != invert);
+ if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
+ bgp_nht_register_enhe_capability_interfaces(peer);
+
/* Execute flag action on peer. */
if (action.type == peer_change_reset)
peer_flag_modify_action(peer, flag);
@@ -4079,9 +4082,6 @@ static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
return 0;
}
- if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
- bgp_nht_register_enhe_capability_interfaces(peer);
-
/*
* Update peer-group members, unless they are explicitely overriding
* peer-group configuration.
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index de690adb34..85ccc277a8 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -2412,6 +2412,12 @@ Debugging
Show all enabled debugs.
+.. index:: show bgp listeners
+.. clicmd:: show bgp listeners
+
+ Display Listen sockets and the vrf that created them. Useful for debugging of when
+ listen is not working and this is considered a developer debug statement.
+
.. index:: [no] debug bgp neighbor-events
.. clicmd:: [no] debug bgp neighbor-events
diff --git a/lib/systemd.c b/lib/systemd.c
index 81b0400ab9..c5cc3aa447 100644
--- a/lib/systemd.c
+++ b/lib/systemd.c
@@ -114,8 +114,10 @@ void systemd_send_started(struct thread_master *m, int the_process)
systemd_master = m;
systemd_send_information("READY=1");
- if (wsecs != 0)
+ if (wsecs != 0) {
+ systemd_send_information("WATCHDOG=1");
thread_add_timer(m, systemd_send_watchdog, m, wsecs, NULL);
+ }
}
void systemd_send_status(const char *status)
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 8d8534a794..44d4ee7192 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -234,8 +234,8 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
RB_REMOVE(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch);
if (PIM_DEBUG_PIM_TRACE)
- zlog_debug("%s: ifchannel entry %s is deleted ", __func__,
- ch->sg_str);
+ zlog_debug("%s: ifchannel entry %s(%s) is deleted ", __func__,
+ ch->sg_str, ch->interface->name);
XFREE(MTYPE_PIM_IFCHANNEL, ch);
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 7011342ab4..b76eb6be48 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -2588,7 +2588,7 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
struct interface *br_if;
struct ethaddr mac;
vlanid_t vid = 0;
- struct prefix vtep_ip;
+ struct in_addr vtep_ip;
int vid_present = 0, dst_present = 0;
char buf[ETHER_ADDR_STRLEN];
char vid_buf[20];
@@ -2601,66 +2601,25 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
if (!is_evpn_enabled())
return 0;
- /* The interface should exist. */
- ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
- ndm->ndm_ifindex);
- if (!ifp || !ifp->info) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("\t%s without associated interface: %u",
- __func__, ndm->ndm_ifindex);
- return 0;
- }
-
- /* The interface should be something we're interested in. */
- if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("\t%s Not interested in %s, not a slave",
- __func__, ifp->name);
- return 0;
- }
-
- /* Drop "permanent" entries. */
- if (ndm->ndm_state & NUD_PERMANENT) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("\t%s Entry is PERMANENT, dropping",
- __func__);
- return 0;
- }
-
- zif = (struct zebra_if *)ifp->info;
- if ((br_if = zif->brslave_info.br_if) == NULL) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug(
- "%s family %s IF %s(%u) brIF %u - no bridge master",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex,
- zif->brslave_info.bridge_ifindex);
- return 0;
- }
-
- /* Parse attributes and extract fields of interest. */
- memset(tb, 0, sizeof(tb));
+ /* Parse attributes and extract fields of interest. Do basic
+ * validation of the fields.
+ */
+ memset(tb, 0, sizeof tb);
netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
if (!tb[NDA_LLADDR]) {
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR",
+ zlog_debug("%s AF_BRIDGE IF %u - no LLADDR",
nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex,
- zif->brslave_info.bridge_ifindex);
+ ndm->ndm_ifindex);
return 0;
}
if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu",
- nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
- ndm->ndm_ifindex,
- zif->brslave_info.bridge_ifindex,
+ "%s AF_BRIDGE IF %u - LLADDR is not MAC, len %lu",
+ nl_msg_type_to_str(h->nlmsg_type), ndm->ndm_ifindex,
(unsigned long)RTA_PAYLOAD(tb[NDA_LLADDR]));
return 0;
}
@@ -2676,24 +2635,42 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
if (tb[NDA_DST]) {
/* TODO: Only IPv4 supported now. */
dst_present = 1;
- vtep_ip.family = AF_INET;
- vtep_ip.prefixlen = IPV4_MAX_BITLEN;
- memcpy(&(vtep_ip.u.prefix4.s_addr), RTA_DATA(tb[NDA_DST]),
+ memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]),
IPV4_MAX_BYTELEN);
- sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip.u.prefix4));
+ sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip));
}
- sticky = !!(ndm->ndm_state & NUD_NOARP);
-
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("Rx %s family %s IF %s(%u)%s %sMAC %s%s",
+ zlog_debug("Rx %s AF_BRIDGE IF %u%s st 0x%x fl 0x%x MAC %s%s",
nl_msg_type_to_str(h->nlmsg_type),
- nl_family_to_str(ndm->ndm_family), ifp->name,
ndm->ndm_ifindex, vid_present ? vid_buf : "",
- sticky ? "sticky " : "",
+ ndm->ndm_state, ndm->ndm_flags,
prefix_mac2str(&mac, buf, sizeof(buf)),
dst_present ? dst_buf : "");
+ /* The interface should exist. */
+ ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id),
+ ndm->ndm_ifindex);
+ if (!ifp || !ifp->info)
+ return 0;
+
+ /* The interface should be something we're interested in. */
+ if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
+ return 0;
+
+ zif = (struct zebra_if *)ifp->info;
+ if ((br_if = zif->brslave_info.br_if) == NULL) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s AF_BRIDGE IF %s(%u) brIF %u - no bridge master",
+ nl_msg_type_to_str(h->nlmsg_type), ifp->name,
+ ndm->ndm_ifindex,
+ zif->brslave_info.bridge_ifindex);
+ return 0;
+ }
+
+ sticky = !!(ndm->ndm_state & NUD_NOARP);
+
if (filter_vlan && vid != filter_vlan) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("\tFiltered due to filter vlan: %d",
@@ -2707,6 +2684,13 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
* so perform an implicit delete of any local entry (if it exists).
*/
if (h->nlmsg_type == RTM_NEWNEIGH) {
+ /* Drop "permanent" entries. */
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("\tDropping entry because of NUD_PERMANENT");
+ return 0;
+ }
+
if (IS_ZEBRA_IF_VXLAN(ifp))
return zebra_vxlan_check_del_local_mac(ifp, br_if, &mac,
vid);
@@ -2716,16 +2700,20 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
}
/* This is a delete notification.
+ * Ignore the notification with IP dest as it may just signify that the
+ * MAC has moved from remote to local. The exception is the special
+ * all-zeros MAC that represents the BUM flooding entry; we may have
+ * to readd it. Otherwise,
* 1. For a MAC over VxLan, check if it needs to be refreshed(readded)
* 2. For a MAC over "local" interface, delete the mac
* Note: We will get notifications from both bridge driver and VxLAN
* driver.
- * Ignore the notification from VxLan driver as it is also generated
- * when mac moves from remote to local.
*/
if (dst_present) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("\tNo Destination Present");
+ u_char zero_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+ if (!memcmp(zero_mac, mac.octet, ETH_ALEN))
+ return zebra_vxlan_check_readd_vtep(ifp, vtep_ip);
return 0;
}
@@ -3285,6 +3273,15 @@ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns,
addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len);
+ if (IS_ZEBRA_DEBUG_KERNEL) {
+ char buf[INET6_ADDRSTRLEN];
+
+ zlog_debug("%s: Tx %s family %s IF %u IP %s flags 0x%x",
+ __func__, nl_msg_type_to_str(type),
+ nl_family_to_str(req.ndm.ndm_family), ifindex,
+ ipaddr2str(ip, buf, sizeof(buf)), req.n.nlmsg_flags);
+ }
+
return netlink_request(&zns->netlink_cmd, &req.n);
}
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index dce48d39bd..61865e5baf 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -7788,6 +7788,52 @@ stream_failure:
}
/*
+ * Handle remote vtep delete by kernel; re-add the vtep if we have it
+ */
+int zebra_vxlan_check_readd_vtep(struct interface *ifp,
+ struct in_addr vtep_ip)
+{
+ struct zebra_if *zif;
+ struct zebra_vrf *zvrf = NULL;
+ struct zebra_l2info_vxlan *vxl;
+ vni_t vni;
+ zebra_vni_t *zvni = NULL;
+ zebra_vtep_t *zvtep = NULL;
+
+ zif = ifp->info;
+ assert(zif);
+ vxl = &zif->l2info.vxl;
+ vni = vxl->vni;
+
+ /* If EVPN is not enabled, nothing to do. */
+ if (!is_evpn_enabled())
+ return 0;
+
+ /* Locate VRF corresponding to interface. */
+ zvrf = vrf_info_lookup(ifp->vrf_id);
+ if (!zvrf)
+ return -1;
+
+ /* Locate hash entry; it is expected to exist. */
+ zvni = zvni_lookup(vni);
+ if (!zvni)
+ return 0;
+
+ /* If the remote vtep entry doesn't exists nothing to do */
+ zvtep = zvni_vtep_find(zvni, &vtep_ip);
+ if (!zvtep)
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "Del MAC for remote VTEP %s intf %s(%u) VNI %u - readd",
+ inet_ntoa(vtep_ip), ifp->name, ifp->ifindex, vni);
+
+ zvni_vtep_install(zvni, zvtep);
+ return 0;
+}
+
+/*
* Handle notification of MAC add/update over VxLAN. If the kernel is notifying
* us, this must involve a multihoming scenario. Treat this as implicit delete
* of any prior local MAC.
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index b551ba8dff..6ca93f6cb6 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -183,6 +183,8 @@ extern int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
extern int zebra_vxlan_check_del_local_mac(struct interface *ifp,
struct interface *br_if,
struct ethaddr *mac, vlanid_t vid);
+extern int zebra_vxlan_check_readd_vtep(struct interface *ifp,
+ struct in_addr vtep_ip);
extern int zebra_vxlan_if_up(struct interface *ifp);
extern int zebra_vxlan_if_down(struct interface *ifp);
extern int zebra_vxlan_if_add(struct interface *ifp);