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/kernel_netlink.c b/zebra/kernel_netlink.c index 35f3274c65..ec1e6456f8 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);