[PATCH] krt: Dump routing tables separetely on linux to avoid congestion

Daniel Gröber dxld at darkboxed.org
Sat Apr 16 15:10:40 CEST 2022


When dumping the routing table bird currently doesn't set the rtm_table
netlink field to select any particular one but rather wants to get all at
once.

This can be problematic when multiple routing daemons are running on a
system as the kernel's route modification performance goes down
drasticly (by a factor of 20-200ish) when the table is being modified while
it's being dumped.

To avoid this situation we make bird do dumps on a per-kernel-table
basis. This then allows the administrator to have multiple routing daemons
use different kernel tables which sidesteps the problem.

See also this discussion on the babel-users mailing list:
  https://alioth-lists.debian.net/pipermail/babel-users/2022-April/003902.html
---
 sysdep/cf/linux.h      | 2 +-
 sysdep/linux/netlink.c | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/sysdep/cf/linux.h b/sysdep/cf/linux.h
index 047d3764..d6211d16 100644
--- a/sysdep/cf/linux.h
+++ b/sysdep/cf/linux.h
@@ -9,7 +9,7 @@
 #define CONFIG_AUTO_ROUTES
 #define CONFIG_SELF_CONSCIOUS
 #define CONFIG_MULTIPLE_TABLES
-#define CONFIG_ALL_TABLES_AT_ONCE
+#undef  CONFIG_ALL_TABLES_AT_ONCE
 #define CONFIG_IP6_SADR_KERNEL
 
 #define CONFIG_MC_PROPER_SRC
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 29b744cb..003b7939 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -256,7 +256,7 @@ nl_request_dump_addr(int af)
 }
 
 static void
-nl_request_dump_route(int af)
+nl_request_dump_route(int af, int table_id)
 {
   struct {
     struct nlmsghdr nh;
@@ -267,6 +267,7 @@ nl_request_dump_route(int af)
     .nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP,
     .nh.nlmsg_seq = ++(nl_scan.seq),
     .rtm.rtm_family = af,
+    .rtm.rtm_table = table_id,
   };
 
   send(nl_scan.fd, &req, sizeof(req), 0);
@@ -1976,13 +1977,13 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
 }
 
 void
-krt_do_scan(struct krt_proto *p UNUSED)	/* CONFIG_ALL_TABLES_AT_ONCE => p is NULL */
+krt_do_scan(struct krt_proto *p)
 {
   struct nlmsghdr *h;
   struct nl_parse_state s;
 
   nl_parse_begin(&s, 1);
-  nl_request_dump_route(AF_UNSPEC);
+  nl_request_dump_route(AF_UNSPEC, KRT_CF->sys.table_id);
   while (h = nl_get_scan())
     if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
       nl_parse_route(&s, h);
-- 
2.30.2



More information about the Bird-users mailing list