]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Netlink: Handle alien routes with unsorted nexthops
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 2 Jul 2019 16:23:06 +0000 (18:23 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 2 Jul 2019 16:23:06 +0000 (18:23 +0200)
Nest requires that nexthops are sorted, the kernel protocol have to
ensure that for alien routes.

nest/route.h
nest/rt-attr.c
sysdep/linux/netlink.c

index 15aac8f6128505886c2059e929885d778d3884cf..e356f68691f419aad88f1849796bdd922afd45a8 100644 (file)
@@ -628,6 +628,7 @@ int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath ne
 static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
 { return (x == y) || nexthop__same(x, y); }
 struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
+struct nexthop *nexthop_sort(struct nexthop *x);
 static inline void nexthop_link(struct rta *a, struct nexthop *from)
 { memcpy(&a->nh, from, nexthop_size(from)); }
 void nexthop_insert(struct nexthop **n, struct nexthop *y);
index cc362cab03cd486d2f4c28277b0464a53257540c..1803db92e36d1c732af5c819889734dfd0b6add7 100644 (file)
@@ -200,7 +200,7 @@ nexthop__same(struct nexthop *x, struct nexthop *y)
 }
 
 static int
-nexthop_compare_node(struct nexthop *x, struct nexthop *y)
+nexthop_compare_node(const struct nexthop *x, const  struct nexthop *y)
 {
   int r;
 
@@ -318,6 +318,24 @@ nexthop_insert(struct nexthop **n, struct nexthop *x)
   *n = x;
 }
 
+struct nexthop *
+nexthop_sort(struct nexthop *x)
+{
+  struct nexthop *s = NULL;
+
+  /* Simple insert-sort */
+  while (x)
+  {
+    struct nexthop *n = x;
+    x = n->next;
+    n->next = NULL;
+
+    nexthop_insert(&s, n);
+  }
+
+  return s;
+}
+
 int
 nexthop_is_sorted(struct nexthop *x)
 {
index 5a0b4d0c97fc7b0a343f7c7fcbb94c7be9698ceb..6e3fe48893330a1805ad08b6c939cea74260eaf5 100644 (file)
@@ -725,6 +725,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
       nh = RTNH_NEXT(nh);
     }
 
+  /* Ensure nexthops are sorted to satisfy nest invariant */
+  if (!nexthop_is_sorted(first))
+    first = nexthop_sort(first);
+
   return first;
 }