summaryrefslogtreecommitdiff
path: root/sysdep/linux/netlink.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-08-23 15:55:31 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-08-23 16:08:40 +0200
commite3c0eca95642a846ab65261424a51dd99d954017 (patch)
treee108f29222cd8b62a40f7b05360c05b9f34d3b9a /sysdep/linux/netlink.c
parent5121101136cb80151a9361c63dc4822afeb44eef (diff)
Nest: Treat VRF interfaces as inside respective VRFs
Despite not having defined 'master interface', VRF interfaces should be treated as being inside respective VRFs. They behave as a loopback for respective VRFs. Treating the VRF interface as inside the VRF allows e.g. OSPF to pick up IP addresses defined on the VRF interface. For this, we also need to tell apart VRF interfaces and regular interfaces. Extend Netlink code to parse interface type and mark VRF interfaces with IF_VRF flag. Based on the patch from Erin Shepherd, thanks!
Diffstat (limited to 'sysdep/linux/netlink.c')
-rw-r--r--sysdep/linux/netlink.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index e3298a0f..1af78766 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -333,13 +333,21 @@ struct nl_want_attrs {
};
-#define BIRD_IFLA_MAX (IFLA_WIRELESS+1)
+#define BIRD_IFLA_MAX (IFLA_LINKINFO+1)
static struct nl_want_attrs ifla_attr_want[BIRD_IFLA_MAX] = {
[IFLA_IFNAME] = { 1, 0, 0 },
[IFLA_MTU] = { 1, 1, sizeof(u32) },
[IFLA_MASTER] = { 1, 1, sizeof(u32) },
[IFLA_WIRELESS] = { 1, 0, 0 },
+ [IFLA_LINKINFO] = { 1, 0, 0 },
+};
+
+#define BIRD_INFO_MAX (IFLA_INFO_DATA+1)
+
+static struct nl_want_attrs ifinfo_attr_want[BIRD_INFO_MAX] = {
+ [IFLA_INFO_KIND]= { 1, 0, 0 },
+ [IFLA_INFO_DATA]= { 1, 0, 0 },
};
@@ -868,7 +876,7 @@ nl_parse_link(struct nlmsghdr *h, int scan)
int new = h->nlmsg_type == RTM_NEWLINK;
struct iface f = {};
struct iface *ifi;
- char *name;
+ const char *name, *kind = NULL;
u32 mtu, master = 0;
uint fl;
@@ -895,6 +903,15 @@ nl_parse_link(struct nlmsghdr *h, int scan)
if (a[IFLA_MASTER])
master = rta_get_u32(a[IFLA_MASTER]);
+ if (a[IFLA_LINKINFO])
+ {
+ 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]);
+ }
+
ifi = if_find_by_index(i->ifi_index);
if (!new)
{
@@ -934,6 +951,9 @@ nl_parse_link(struct nlmsghdr *h, int scan)
if (fl & IFF_MULTICAST)
f.flags |= IF_MULTICAST;
+ if (kind && !strcmp(kind, "vrf"))
+ f.flags |= IF_VRF;
+
ifi = if_update(&f);
if (!scan)