summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn_vty.c7
-rw-r--r--bgpd/bgp_fsm.c12
-rw-r--r--bgpd/bgp_vty.c2
-rw-r--r--include/linux/if_link.h28
-rw-r--r--include/linux/rtnetlink.h17
-rw-r--r--zebra/debug_nl.c59
-rw-r--r--zebra/kernel_netlink.c22
-rw-r--r--zebra/zebra_vxlan.c2
8 files changed, 134 insertions, 15 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 32dc2a785f..d94dcdd362 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -2256,9 +2256,6 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni)
struct bgpevpn *vpn;
struct in_addr mcast_grp = {INADDR_ANY};
- if (!bgp->vnihash)
- return NULL;
-
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (!vpn) {
/* Check if this L2VNI is already configured as L3VNI */
@@ -2290,8 +2287,6 @@ static struct bgpevpn *evpn_create_update_vni(struct bgp *bgp, vni_t vni)
*/
static void evpn_delete_vni(struct bgp *bgp, struct bgpevpn *vpn)
{
- assert(bgp->vnihash);
-
if (!is_vni_live(vpn)) {
bgp_evpn_free(bgp, vpn);
return;
@@ -6291,7 +6286,7 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (bgp->advertise_all_vni)
vty_out(vty, " advertise-all-vni\n");
- if (bgp->vnihash) {
+ if (hashcount(bgp->vnihash)) {
struct list *vnilist = hash_to_list(bgp->vnihash);
struct listnode *ln;
struct bgpevpn *data;
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index ba018d3f56..fe4ab272ac 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -1701,6 +1701,12 @@ static int bgp_connect_success(struct peer *peer)
return -1;
}
+ /*
+ * If we are doing nht for a peer that ls v6 LL based
+ * massage the event system to make things happy
+ */
+ bgp_nht_interface_events(peer);
+
bgp_reads_on(peer);
if (bgp_debug_neighbor_events(peer)) {
@@ -1739,6 +1745,12 @@ static int bgp_connect_success_w_delayopen(struct peer *peer)
return -1;
}
+ /*
+ * If we are doing nht for a peer that ls v6 LL based
+ * massage the event system to make things happy
+ */
+ bgp_nht_interface_events(peer);
+
bgp_reads_on(peer);
if (bgp_debug_neighbor_events(peer)) {
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9e22c6cdbd..9cfec0fe2f 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1554,7 +1554,7 @@ DEFUN (no_router_bgp,
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST) ||
CHECK_FLAG(tmp_bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP))) ||
- (tmp_bgp->vnihash && hashcount(tmp_bgp->vnihash))) {
+ (hashcount(tmp_bgp->vnihash))) {
vty_out(vty,
"%% Cannot delete default BGP instance. Dependent VRF instances exist\n");
return CMD_WARNING_CONFIG_FAILED;
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index e5cea27829..53892303ba 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -519,6 +519,31 @@ enum ipvlan_mode {
#define IPVLAN_F_PRIVATE 0x01
#define IPVLAN_F_VEPA 0x02
+/* Tunnel RTM header */
+struct tunnel_msg {
+ __u8 family;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 ifindex;
+};
+
+enum {
+ VXLAN_VNIFILTER_ENTRY_UNSPEC,
+ VXLAN_VNIFILTER_ENTRY_START,
+ VXLAN_VNIFILTER_ENTRY_END,
+ VXLAN_VNIFILTER_ENTRY_GROUP,
+ VXLAN_VNIFILTER_ENTRY_GROUP6,
+ __VXLAN_VNIFILTER_ENTRY_MAX
+};
+#define VXLAN_VNIFILTER_ENTRY_MAX (__VXLAN_VNIFILTER_ENTRY_MAX - 1)
+
+enum {
+ VXLAN_VNIFILTER_UNSPEC,
+ VXLAN_VNIFILTER_ENTRY,
+ __VXLAN_VNIFILTER_MAX
+};
+#define VXLAN_VNIFILTER_MAX (__VXLAN_VNIFILTER_MAX - 1)
+
/* VXLAN section */
enum {
IFLA_VXLAN_UNSPEC,
@@ -550,6 +575,9 @@ enum {
IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE,
IFLA_VXLAN_TTL_INHERIT,
+ IFLA_VXLAN_DF,
+ IFLA_VXLAN_VNIFILTER, /* only applicable when COLLECT_METADATA mode is
+ on */
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 5888492a52..b15b72a262 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -185,6 +185,16 @@ enum {
RTM_GETNEXTHOPBUCKET,
#define RTM_GETNEXTHOPBUCKET RTM_GETNEXTHOPBUCKET
+ RTM_SETHWFLAGS = 119,
+#define RTM_SETHWFLAGS RTM_SETHWFLAGS
+
+ RTM_NEWTUNNEL = 120,
+#define RTM_NEWTUNNEL RTM_NEWTUNNEL
+ RTM_DELTUNNEL,
+#define RTM_DELTUNNEL RTM_DELTUNNEL
+ RTM_GETTUNNEL,
+#define RTM_GETTUNNEL RTM_GETTUNNEL
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -217,6 +227,11 @@ struct rtattr {
#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
+#ifndef TUNNEL_RTA
+#define TUNNEL_RTA(r) \
+ ((struct rtattr *)(((char *)(r)) + \
+ NLMSG_ALIGN(sizeof(struct tunnel_msg))))
+#endif
@@ -754,6 +769,8 @@ enum rtnetlink_groups {
#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
RTNLGRP_BRVLAN,
#define RTNLGRP_BRVLAN RTNLGRP_BRVLAN
+ RTNLGRP_TUNNEL,
+#define RTNLGRP_TUNNEL RTNLGRP_TUNNEL
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c
index f058205c25..89ef7a2076 100644
--- a/zebra/debug_nl.c
+++ b/zebra/debug_nl.c
@@ -33,6 +33,7 @@
#include "zebra/rt_netlink.h"
#include "zebra/kernel_netlink.h"
+#include "lib/vxlan.h"
const char *nlmsg_type2str(uint16_t type)
{
@@ -92,6 +93,13 @@ const char *nlmsg_type2str(uint16_t type)
case RTM_GETNEXTHOP:
return "GETNEXTHOP";
+ case RTM_NEWTUNNEL:
+ return "NEWTUNNEL";
+ case RTM_DELTUNNEL:
+ return "DELTUNNEL";
+ case RTM_GETTUNNEL:
+ return "GETTUNNEL";
+
case RTM_NEWNETCONF:
return "RTM_NEWNETCONF";
case RTM_DELNETCONF:
@@ -1241,6 +1249,44 @@ next_rta:
goto next_rta;
}
+static void nltnl_dump(struct tunnel_msg *tnlm, size_t msglen)
+{
+ struct rtattr *attr;
+ vni_t vni_start = 0, vni_end = 0;
+ struct rtattr *ttb[VXLAN_VNIFILTER_ENTRY_MAX + 1];
+ uint8_t rta_type;
+
+ attr = TUNNEL_RTA(tnlm);
+next_attr:
+ /* Check the header for valid length and for outbound access. */
+ if (RTA_OK(attr, msglen) == 0)
+ return;
+
+ rta_type = attr->rta_type & NLA_TYPE_MASK;
+
+ if (rta_type != VXLAN_VNIFILTER_ENTRY) {
+ attr = RTA_NEXT(attr, msglen);
+ goto next_attr;
+ }
+
+ memset(ttb, 0, sizeof(ttb));
+
+ netlink_parse_rtattr_flags(ttb, VXLAN_VNIFILTER_ENTRY_MAX,
+ RTA_DATA(attr), RTA_PAYLOAD(attr),
+ NLA_F_NESTED);
+
+ if (ttb[VXLAN_VNIFILTER_ENTRY_START])
+ vni_start =
+ *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_START]);
+
+ if (ttb[VXLAN_VNIFILTER_ENTRY_END])
+ vni_end = *(uint32_t *)RTA_DATA(ttb[VXLAN_VNIFILTER_ENTRY_END]);
+ zlog_debug(" vni_start %u, vni_end %u", vni_start, vni_end);
+
+ attr = RTA_NEXT(attr, msglen);
+ goto next_attr;
+}
+
static const char *lwt_type2str(uint16_t type)
{
switch (type) {
@@ -1529,6 +1575,7 @@ void nl_dump(void *msg, size_t msglen)
struct nhmsg *nhm;
struct netconfmsg *ncm;
struct ifinfomsg *ifi;
+ struct tunnel_msg *tnlm;
struct fib_rule_hdr *frh;
char fbuf[128];
char ibuf[128];
@@ -1645,6 +1692,18 @@ next_header:
nlnh_dump(nhm, nlmsg->nlmsg_len - NLMSG_LENGTH(sizeof(*nhm)));
break;
+ case RTM_NEWTUNNEL:
+ case RTM_DELTUNNEL:
+ case RTM_GETTUNNEL:
+ tnlm = NLMSG_DATA(nlmsg);
+ zlog_debug(" tnlm [family=(%d) %s ifindex=%d ", tnlm->family,
+ af_type2str(tnlm->family), tnlm->ifindex);
+ nltnl_dump(tnlm,
+ nlmsg->nlmsg_len -
+ NLMSG_LENGTH(sizeof(struct tunnel_msg)));
+ break;
+
+
case RTM_NEWNETCONF:
case RTM_DELNETCONF:
ncm = NLMSG_DATA(nlmsg);
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index aa31883dea..7adbb5ab85 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -289,7 +289,7 @@ static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize)
/* Make socket for Linux netlink interface. */
static int netlink_socket(struct nlsock *nl, unsigned long groups,
- ns_id_t ns_id)
+ unsigned long ext_groups, ns_id_t ns_id)
{
int ret;
struct sockaddr_nl snl;
@@ -308,6 +308,12 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
snl.nl_family = AF_NETLINK;
snl.nl_groups = groups;
+#if defined SOL_NETLINK
+ if (ext_groups)
+ setsockopt(sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
+ &ext_groups, sizeof(ext_groups));
+#endif
+
/* Bind the socket to the netlink structure for anything. */
ret = bind(sock, (struct sockaddr *)&snl, sizeof(snl));
}
@@ -591,7 +597,7 @@ bool nl_addraw_l(struct nlmsghdr *n, unsigned int maxlen, const void *data,
unsigned int len)
{
if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
- zlog_err("ERROR message exceeded bound of %d\n", maxlen);
+ zlog_err("ERROR message exceeded bound of %d", maxlen);
return false;
}
@@ -1678,7 +1684,7 @@ static bool kernel_netlink_nlsock_hash_equal(const void *arg1, const void *arg2)
netlink_socket (). */
void kernel_init(struct zebra_ns *zns)
{
- uint32_t groups, dplane_groups;
+ uint32_t groups, dplane_groups, ext_groups;
#if defined SOL_NETLINK
int one, ret;
#endif
@@ -1710,11 +1716,13 @@ void kernel_init(struct zebra_ns *zns)
((uint32_t) 1 << (RTNLGRP_IPV6_NETCONF - 1)) |
((uint32_t) 1 << (RTNLGRP_MPLS_NETCONF - 1)));
+ /* Use setsockopt for > 31 group */
+ ext_groups = RTNLGRP_TUNNEL;
snprintf(zns->netlink.name, sizeof(zns->netlink.name),
"netlink-listen (NS %u)", zns->ns_id);
zns->netlink.sock = -1;
- if (netlink_socket(&zns->netlink, groups, zns->ns_id) < 0) {
+ if (netlink_socket(&zns->netlink, groups, ext_groups, zns->ns_id) < 0) {
zlog_err("Failure to create %s socket",
zns->netlink.name);
exit(-1);
@@ -1725,7 +1733,7 @@ void kernel_init(struct zebra_ns *zns)
snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name),
"netlink-cmd (NS %u)", zns->ns_id);
zns->netlink_cmd.sock = -1;
- if (netlink_socket(&zns->netlink_cmd, 0, zns->ns_id) < 0) {
+ if (netlink_socket(&zns->netlink_cmd, 0, 0, zns->ns_id) < 0) {
zlog_err("Failure to create %s socket",
zns->netlink_cmd.name);
exit(-1);
@@ -1738,7 +1746,7 @@ void kernel_init(struct zebra_ns *zns)
sizeof(zns->netlink_dplane_out.name), "netlink-dp (NS %u)",
zns->ns_id);
zns->netlink_dplane_out.sock = -1;
- if (netlink_socket(&zns->netlink_dplane_out, 0, zns->ns_id) < 0) {
+ if (netlink_socket(&zns->netlink_dplane_out, 0, 0, zns->ns_id) < 0) {
zlog_err("Failure to create %s socket",
zns->netlink_dplane_out.name);
exit(-1);
@@ -1751,7 +1759,7 @@ void kernel_init(struct zebra_ns *zns)
sizeof(zns->netlink_dplane_in.name), "netlink-dp-in (NS %u)",
zns->ns_id);
zns->netlink_dplane_in.sock = -1;
- if (netlink_socket(&zns->netlink_dplane_in, dplane_groups,
+ if (netlink_socket(&zns->netlink_dplane_in, dplane_groups, 0,
zns->ns_id) < 0) {
zlog_err("Failure to create %s socket",
zns->netlink_dplane_in.name);
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 2145a10aa8..58a1713c56 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -2115,7 +2115,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
zebra_evpn_mac_del_all(zevpn, 0, 0, DEL_ALL_MAC);
/* Free up all remote VTEPs, if any. */
- zebra_evpn_vtep_del_all(zevpn, 0);
+ zebra_evpn_vtep_del_all(zevpn, 1);
/* Delete the hash entry. */
if (zebra_evpn_vxlan_del(zevpn)) {