diff options
author | Timo Teräs <timo.teras@iki.fi> | 2016-02-19 03:19:54 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-10-18 14:36:25 +0200 |
commit | 62ccf1e5a3ca3bc44f7e1471e7683ad6739f4bb7 (patch) | |
tree | 9b1b2d79d7beaddf33052aec98cf396be9f89505 /zebra | |
parent | zebra: kernel interface simplification (diff) | |
download | frr-62ccf1e5a3ca3bc44f7e1471e7683ad6739f4bb7.tar.xz frr-62ccf1e5a3ca3bc44f7e1471e7683ad6739f4bb7.zip |
zebra: Fix route deletion on *BSD
Fix for not handling RTM_CHANGE correctly. This patch change it to
delete/add instead. Using RTM_CHANGE on kernels where it works is better,
but is left as an exercise for developer who has access and will to fix it
on *BSD.
[ed note: collaboration with Martin Winter]
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/rt_socket.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index b00d77573..2bde3f4b0 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -73,7 +73,7 @@ sin_masklen (struct in_addr mask) /* Interface between zebra message and rtm message. */ static int -kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) +kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib) { struct sockaddr_in *mask = NULL; @@ -264,7 +264,7 @@ sin6_masklen (struct in6_addr mask) /* Interface between zebra message and rtm message. */ static int -kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib, int family) +kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib) { struct sockaddr_in6 *mask; struct sockaddr_in6 sin_dest, sin_mask, sin_gate; @@ -378,33 +378,32 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib, int family) return 0; /*XXX*/ } +static int +kernel_rtm (int cmd, struct prefix *p, struct rib *rib) +{ + switch (PREFIX_FAMILY(p)) + { + case AF_INET: + return kernel_rtm_ipv4 (cmd, p, rib); + case AF_INET6: + return kernel_rtm_ipv6 (cmd, p, rib); + } + return 0; +} + int kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new) { - struct rib *rib; - int route = 0, cmd; - - if (!old && new) - cmd = RTM_ADD; - else if (old && !new) - cmd = RTM_DELETE; - else - cmd = RTM_CHANGE; - - rib = new ? new : old; + int route = 0; if (zserv_privs.change(ZPRIVS_RAISE)) zlog (NULL, LOG_ERR, "Can't raise privileges"); - switch (PREFIX_FAMILY(p)) - { - case AF_INET: - route = kernel_rtm_ipv4 (cmd, p, rib, AF_INET); - break; - case AF_INET6: - route = kernel_rtm_ipv6 (cmd, p, rib, AF_INET6); - break; - } + if (old) + route |= kernel_rtm (RTM_DELETE, p, old); + + if (new) + route |= kernel_rtm (RTM_ADD, p, new); if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); |