summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2016-02-19 03:19:54 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-10-18 14:36:25 +0200
commit62ccf1e5a3ca3bc44f7e1471e7683ad6739f4bb7 (patch)
tree9b1b2d79d7beaddf33052aec98cf396be9f89505 /zebra
parentzebra: kernel interface simplification (diff)
downloadfrr-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.c43
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");