aboutsummaryrefslogtreecommitdiffstats
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-07-02 16:30:36 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-07-02 16:30:36 +0200
commit1187627a1dded6a3673c0d43033f431f15cd1b8f (patch)
tree4d3cada10f09ea09625d4c80f8140d214cfef4f5 /sysdep
parent026bfedb332d8c0dde28c693c177fe993b5df26d (diff)
downloadbird-1187627a1dded6a3673c0d43033f431f15cd1b8f.tar.gz
Netlink: Do unified scan for both IPv4 and IPv6
Instead of separate scans for IPv4, IPv6 and MPLS, do one AF_UNSPEC scan. This also avoids kernel issue when kernel reported IPv4 and IPv6 routes during MPLS scan if MPLS is not active.
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/linux/netlink.c37
1 files changed, 8 insertions, 29 deletions
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index d773743d..5a0b4d0c 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -1393,10 +1393,10 @@ krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old)
}
static int
-nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint priority, uint krt_type)
+nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint priority, uint krt_type, uint rtm_family)
{
- /* Route merging must be active */
- if (!s->merge)
+ /* Route merging is used for IPv6 scans */
+ if (!s->scan || (rtm_family != AF_INET6))
return 0;
/* Saved and new route must have same network, proto/table, and priority */
@@ -1433,12 +1433,11 @@ nl_announce_route(struct nl_parse_state *s)
}
static inline void
-nl_parse_begin(struct nl_parse_state *s, int scan, int merge)
+nl_parse_begin(struct nl_parse_state *s, int scan)
{
memset(s, 0, sizeof (struct nl_parse_state));
s->pool = nl_linpool;
s->scan = scan;
- s->merge = merge;
}
static inline void
@@ -1581,7 +1580,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
net *net = net_get(p->p.main_channel->table, n);
- if (s->net && !nl_mergable_route(s, net, p, priority, i->rtm_type))
+ if (s->net && !nl_mergable_route(s, net, p, priority, i->rtm_type, i->rtm_family))
nl_announce_route(s);
rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE);
@@ -1814,34 +1813,14 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
struct nlmsghdr *h;
struct nl_parse_state s;
- nl_parse_begin(&s, 1, 0);
- nl_request_dump(AF_INET, RTM_GETROUTE);
+ nl_parse_begin(&s, 1);
+ nl_request_dump(AF_UNSPEC, RTM_GETROUTE);
while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
nl_parse_route(&s, h);
else
log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
nl_parse_end(&s);
-
- nl_parse_begin(&s, 1, 1);
- nl_request_dump(AF_INET6, RTM_GETROUTE);
- while (h = nl_get_scan())
- if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
- nl_parse_route(&s, h);
- else
- log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
- nl_parse_end(&s);
-
-#ifdef HAVE_MPLS_KERNEL
- nl_parse_begin(&s, 1, 1);
- nl_request_dump(AF_MPLS, RTM_GETROUTE);
- while (h = nl_get_scan())
- if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
- nl_parse_route(&s, h);
- else
- log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
- nl_parse_end(&s);
-#endif
}
/*
@@ -1861,7 +1840,7 @@ nl_async_msg(struct nlmsghdr *h)
case RTM_NEWROUTE:
case RTM_DELROUTE:
DBG("KRT: Received async route notification (%d)\n", h->nlmsg_type);
- nl_parse_begin(&s, 0, 0);
+ nl_parse_begin(&s, 0);
nl_parse_route(&s, h);
nl_parse_end(&s);
break;