]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: netlink registry rtm tunnel notif
authorChirag Shah <chirag@nvidia.com>
Sun, 13 Feb 2022 01:02:03 +0000 (17:02 -0800)
committerChirag Shah <chirag@nvidia.com>
Wed, 18 May 2022 14:56:35 +0000 (07:56 -0700)
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>
include/linux/if_link.h
include/linux/rtnetlink.h
zebra/kernel_netlink.c

index e5cea27829b05a6d3d4d8dd00b6f3a2bfcabda36..53892303baf9037c840bc01fe52880f396069964 100644 (file)
@@ -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)
index 5888492a5257b450d6518718a80c82a4d6c17b93..b15b72a262d2c1a5ce8fc4c3735780ebfd24096b 100644 (file)
@@ -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)
index 35f3274c6572be4c92b73c84f9e37510d5ec6ec7..ec1e6456f88406479f6b839c235a3a185d95cacb 100644 (file)
@@ -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);