[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)
[IFA_FLAGS] = { 1, 1, sizeof(u32) },
};
-
#define BIRD_RTA_MAX (RTA_ENCAP+1)
static struct nl_want_attrs nexthop_attr_want4[BIRD_RTA_MAX] = {
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); }
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);