]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Add parsing of netlink attributes of vxlan device
authorIgor Putovny <igor.putovny@nic.cz>
Tue, 29 Jul 2025 13:38:16 +0000 (15:38 +0200)
committerIgor Putovny <igor.putovny@nic.cz>
Wed, 30 Jul 2025 14:35:57 +0000 (16:35 +0200)
sysdep/linux/netlink.c

index 15df573b942a541d4dead096a1996f5375c8ba3b..251841be8b55ba440142110717e7da49d0be98ba 100644 (file)
@@ -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);