summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChirag Shah <chirag@nvidia.com>2022-02-13 02:02:03 +0100
committerChirag Shah <chirag@nvidia.com>2022-05-18 16:56:35 +0200
commit47e2eb270d4cd1c73440ea6b4367ab02b78f2ed4 (patch)
tree62adfabcef8543ac5a171a977585ce473d560ede
parentMerge pull request #11203 from donaldsharp/coverity_bgp_memcpy (diff)
downloadfrr-47e2eb270d4cd1c73440ea6b4367ab02b78f2ed4.tar.xz
frr-47e2eb270d4cd1c73440ea6b4367ab02b78f2ed4.zip
zebra: netlink registry rtm tunnel notif
The kernel supports l3vxlan device to have (l3vni) vni filter similar to vlan filtering on bridge device. To receive netlink notification, FRR to register for new netlink RTNLGRP_TUNNEL message. This message required to register via additional socket option as it's beyond bitmap size. kernel patches: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/ linux.git/commit/?h=v5.18-rc7&id=7b8135f4df98b155b23754b6065c157861e268f1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/ linux.git/commit/?h=v5.18-rc7&id=f9c4bb0b245cee35ef66f75bf409c9573d934cf9 Ticket:#3073812 Testing Done: Signed-off-by: Chirag Shah <chirag@nvidia.com>
-rw-r--r--include/linux/if_link.h28
-rw-r--r--include/linux/rtnetlink.h17
-rw-r--r--zebra/kernel_netlink.c20
3 files changed, 59 insertions, 6 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index e5cea2782..53892303b 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 5888492a5..b15b72a26 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/kernel_netlink.c b/zebra/kernel_netlink.c
index 35f3274c6..ec1e6456f 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));
}
@@ -1611,7 +1617,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
@@ -1643,11 +1649,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);
@@ -1658,7 +1666,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);
@@ -1671,7 +1679,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);
@@ -1684,7 +1692,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);