From: Igor Putovny Date: Tue, 29 Jul 2025 13:38:16 +0000 (+0200) Subject: Add parsing of netlink attributes of vxlan device X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48b6fd6c64effeed3f1760f3bcb52059b80a3555;p=thirdparty%2Fbird.git Add parsing of netlink attributes of vxlan device --- diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 15df573b9..251841be8 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -381,6 +381,14 @@ static struct nl_want_attrs ifinfo_attr_want[BIRD_INFO_MAX] = { [IFLA_INFO_DATA]= { 1, 0, 0 }, }; +#define BIRD_IFLA_VXLAN_MAX (IFLA_VXLAN_LOCAL6+1) + +static struct nl_want_attrs ifla_vxlan_attr_want[BIRD_IFLA_VXLAN_MAX] = { + [IFLA_VXLAN_ID] = { 1, 1, sizeof(u32) }, + [IFLA_VXLAN_LEARNING] = { 1, 1, sizeof(u8) }, + [IFLA_VXLAN_LOCAL] = { 1, 1, sizeof(ip4_addr) }, + [IFLA_VXLAN_LOCAL6] = { 1, 1, sizeof(ip6_addr) }, +}; #define BIRD_IFA_MAX (IFA_FLAGS+1) @@ -397,7 +405,6 @@ static struct nl_want_attrs ifa_attr_want6[BIRD_IFA_MAX] = { [IFA_FLAGS] = { 1, 1, sizeof(u32) }, }; - #define BIRD_RTA_MAX (RTA_ENCAP+1) static struct nl_want_attrs nexthop_attr_want4[BIRD_RTA_MAX] = { @@ -514,6 +521,9 @@ nl_parse_attrs(struct rtattr *a, struct nl_want_attrs *want, struct rtattr **k, return 1; } +static inline u8 rta_get_u8(struct rtattr *a) +{ return *(u8 *) RTA_DATA(a); } + static inline u16 rta_get_u16(struct rtattr *a) { return *(u16 *) RTA_DATA(a); } @@ -986,8 +996,35 @@ nl_parse_link(struct nlmsghdr *h, int scan) struct rtattr *li[BIRD_INFO_MAX]; nl_attr_len = RTA_PAYLOAD(a[IFLA_LINKINFO]); nl_parse_attrs(RTA_DATA(a[IFLA_LINKINFO]), ifinfo_attr_want, li, sizeof(li)); + if (li[IFLA_INFO_KIND]) kind = RTA_DATA(li[IFLA_INFO_KIND]); + + if (!strcmp(kind, "vxlan") && li[IFLA_INFO_DATA]) + { + struct rtattr *data[BIRD_IFLA_VXLAN_MAX]; + nl_attr_len = RTA_PAYLOAD(li[IFLA_INFO_DATA]); + nl_parse_attrs(RTA_DATA(li[IFLA_INFO_DATA]), ifla_vxlan_attr_want, data, sizeof(data)); + + if (data[IFLA_VXLAN_ID]) + { + u32 id = rta_get_u32(data[IFLA_VXLAN_ID]); + ea_set_attr(&f.attrs->eattrs, tmp_linpool, EA_DEVICE_IF_VXLAN_ID, 0, EAF_TYPE_INT, id); + } + + if (data[IFLA_VXLAN_LEARNING]) + { + u8 learning = rta_get_u8(data[IFLA_VXLAN_LEARNING]); + ea_set_attr(&f.attrs->eattrs, tmp_linpool, EA_DEVICE_IF_VXLAN_LEARNING, 0, EAF_TYPE_INT, learning); + } + + if (data[IFLA_VXLAN_LOCAL] || data[IFLA_VXLAN_LOCAL6]) + { + struct rtattr *attr = data[IFLA_VXLAN_LOCAL] ? data[IFLA_VXLAN_LOCAL] : data[IFLA_VXLAN_LOCAL6]; + ip_addr addr = rta_get_ipa(attr); + ea_set_attr_data(&f.attrs->eattrs, tmp_linpool, EA_DEVICE_IF_VXLAN_IP_ADDR, 0, EAF_TYPE_IP_ADDRESS, &addr, sizeof(addr)); + } + } } ifi = if_find_by_index(i->ifi_index);