summaryrefslogtreecommitdiff
path: root/sysdep/linux/netlink.c
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2020-06-03 15:18:02 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2020-06-03 15:18:02 +0200
commitf1b5f179dbd8aaef5eca4936b557e753e377d818 (patch)
tree88af24f89bda57573bb8b28e614b8a52882b0c32 /sysdep/linux/netlink.c
parent19f8f173202d6f5cbf97ca2a9f66fcea6b9bb44f (diff)
Netlink: Fix parsing of MPLS multipath routes
Add support for RTA_MULTIPATH attribute parsing for AF_MPLS routes. BIRD is capable of installing a multipath route into kernel on Linux, but it would not be seen because parsing fails. This made BIRD attempt to install the same route repeatedly. (The patch minorly updated by committer)
Diffstat (limited to 'sysdep/linux/netlink.c')
-rw-r--r--sysdep/linux/netlink.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index a9e711b4..f85bcf35 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -357,6 +357,11 @@ static struct nl_want_attrs nexthop_attr_want6[BIRD_RTA_MAX] = {
};
#ifdef HAVE_MPLS_KERNEL
+static struct nl_want_attrs nexthop_attr_want_mpls[BIRD_RTA_MAX] = {
+ [RTA_VIA] = { 1, 0, 0 },
+ [RTA_NEWDST] = { 1, 0, 0 },
+};
+
static struct nl_want_attrs encap_mpls_want[BIRD_RTA_MAX] = {
[RTA_DST] = { 1, 0, 0 },
};
@@ -401,6 +406,7 @@ static struct nl_want_attrs rtm_attr_want_mpls[BIRD_RTA_MAX] = {
[RTA_OIF] = { 1, 1, sizeof(u32) },
[RTA_PRIORITY] = { 1, 1, sizeof(u32) },
[RTA_METRICS] = { 1, 0, 0 },
+ [RTA_MULTIPATH] = { 1, 0, 0 },
[RTA_FLOW] = { 1, 1, sizeof(u32) },
[RTA_TABLE] = { 1, 1, sizeof(u32) },
[RTA_VIA] = { 1, 0, 0 },
@@ -703,6 +709,17 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
return NULL;
break;
+#ifdef HAVE_MPLS_KERNEL
+ case AF_MPLS:
+ if (!nl_parse_attrs(RTNH_DATA(nh), nexthop_attr_want_mpls, a, sizeof(a)))
+ return NULL;
+
+ if (a[RTA_NEWDST])
+ rv->labels = rta_get_mpls(a[RTA_NEWDST], rv->label);
+
+ break;
+#endif
+
default:
return NULL;
}