]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Netlink: Add parsing of bridge and VXLAN interface attributes oz-evpn
authorIgor Putovny <igor.putovny@nic.cz>
Tue, 5 Aug 2025 16:20:12 +0000 (18:20 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 7 Aug 2025 14:12:29 +0000 (16:12 +0200)
nest/iface.h
sysdep/linux/netlink.c
sysdep/unix/krt.h

index 93441b396922dc940bb55249dcf46b7a64892ac0..f06ab002885bc9fdc598704eb96d36f409d1f6c7 100644 (file)
@@ -45,6 +45,12 @@ struct iface {
   struct rta *attrs;
 };
 
+enum iface_type {
+  IF_TYPE_UNDEF,
+  IF_TYPE_BRIDGE,
+  IF_TYPE_VXLAN,
+};
+
 #define IF_UP 1                                /* Currently just IF_ADMIN_UP */
 #define IF_MULTIACCESS 2
 #define IF_BROADCAST 4
index 15df573b942a541d4dead096a1996f5375c8ba3b..a9b382cf848eb91da101b65f30e52298b2308ab0 100644 (file)
@@ -381,6 +381,21 @@ static struct nl_want_attrs ifinfo_attr_want[BIRD_INFO_MAX] = {
   [IFLA_INFO_DATA]= { 1, 0, 0 },
 };
 
+#define BIRD_IFLA_BR_MAX (IFLA_BR_VLAN_FILTERING+1)
+
+static struct nl_want_attrs ifla_br_attr_want[BIRD_IFLA_BR_MAX] = {
+  [IFLA_BR_VLAN_FILTERING] = { 1, 1, sizeof(u8) },
+};
+
+#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)
 
@@ -514,6 +529,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 +1004,51 @@ 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, "bridge") && li[IFLA_INFO_DATA])
+    {
+      ea_set_attr_u32(&f.attrs->eattrs, tmp_linpool, EA_IFACE_TYPE, 0, EAF_TYPE_INT, IF_TYPE_BRIDGE);
+
+      struct rtattr *data[BIRD_IFLA_BR_MAX];
+      nl_attr_len = RTA_PAYLOAD(li[IFLA_INFO_DATA]);
+      nl_parse_attrs(RTA_DATA(li[IFLA_INFO_DATA]), ifla_br_attr_want, data, sizeof(data));
+
+      if (data[IFLA_BR_VLAN_FILTERING])
+      {
+       u8 vlan_filtering = rta_get_u32(data[IFLA_BR_VLAN_FILTERING]);
+       ea_set_attr_u32(&f.attrs->eattrs, tmp_linpool, EA_IFACE_BRIDGE_VLAN_FILTERING, 0, EAF_TYPE_INT, vlan_filtering);
+      }
+    }
+    else if (!strcmp(kind, "vxlan") && li[IFLA_INFO_DATA])
+    {
+      ea_set_attr_u32(&f.attrs->eattrs, tmp_linpool, EA_IFACE_TYPE, 0, EAF_TYPE_INT, IF_TYPE_VXLAN);
+
+      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_u32(&f.attrs->eattrs, tmp_linpool, EA_IFACE_VXLAN_ID, 0, EAF_TYPE_INT, id);
+      }
+
+      if (data[IFLA_VXLAN_LEARNING])
+      {
+       u8 learning = rta_get_u8(data[IFLA_VXLAN_LEARNING]);
+       ea_set_attr_u32(&f.attrs->eattrs, tmp_linpool, EA_IFACE_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_IFACE_VXLAN_IP_ADDR, 0, EAF_TYPE_IP_ADDRESS, &addr, sizeof(addr));
+      }
+    }
   }
 
   ifi = if_find_by_index(i->ifi_index);
index 2b1dfa96df787389050a688e829e63ff9455eaf5..1377bea51dfb657c5fd7c59f5e89d5bbd23a8ca2 100644 (file)
@@ -31,6 +31,16 @@ struct kif_proto;
 #define KRT_LEARN_ALIEN        1       /* Learn KRT_SRC_ALIEN routes */
 #define KRT_LEARN_ALL  2       /* Learn both KRT_SRC_ALIEN and KRT_SRC_KERNEL routes */
 
+
+#define EA_IFACE_TYPE                  EA_CODE(PROTOCOL_DEVICE, 0)
+
+#define EA_IFACE_BRIDGE_VLAN_FILTERING EA_CODE(PROTOCOL_DEVICE, 1)
+
+#define EA_IFACE_VXLAN_ID              EA_CODE(PROTOCOL_DEVICE, 2)
+#define EA_IFACE_VXLAN_LEARNING                EA_CODE(PROTOCOL_DEVICE, 3)
+#define EA_IFACE_VXLAN_IP_ADDR         EA_CODE(PROTOCOL_DEVICE, 4)
+
+
 /* Whenever we recognize our own routes, we allow learing of foreign routes */
 
 #ifdef CONFIG_SELF_CONSCIOUS