diff options
author | Timo Teräs <timo.teras@iki.fi> | 2015-05-14 16:11:58 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2015-06-04 11:30:34 +0300 |
commit | f15d207f22922ca8b194152315459565f15ad161 (patch) | |
tree | f57bae41c0df08f7d53b732382573f3b038b543e /zebra/rt_socket.c | |
parent | 415f2236cb08027a93577255bfdf549e32c787d7 (diff) | |
download | quagga-f15d207f22922ca8b194152315459565f15ad161.tar.bz2 quagga-f15d207f22922ca8b194152315459565f15ad161.tar.xz |
zebra: atomic FIB updates
This commit updates the kernel API so that route changes are
atomically updated using change/replaces messages instead
of first sending a withdraw followed with update.
Same for zclient updates, changes are sent as single ADD
instead of DELETE + ADD.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Diffstat (limited to 'zebra/rt_socket.c')
-rw-r--r-- | zebra/rt_socket.c | 69 |
1 files changed, 25 insertions, 44 deletions
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index bf21ca95..00093c2a 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -214,34 +214,6 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) return 0; /*XXX*/ } -int -kernel_add_ipv4 (struct prefix *p, struct rib *rib) -{ - int route; - - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog (NULL, LOG_ERR, "Can't raise privileges"); - route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog (NULL, LOG_ERR, "Can't lower privileges"); - - return route; -} - -int -kernel_delete_ipv4 (struct prefix *p, struct rib *rib) -{ - int route; - - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog (NULL, LOG_ERR, "Can't raise privileges"); - route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog (NULL, LOG_ERR, "Can't lower privileges"); - - return route; -} - #ifdef HAVE_IPV6 /* Calculate sin6_len value for netmask socket value. */ @@ -384,31 +356,40 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib, return 0; /*XXX*/ } +#endif + int -kernel_add_ipv6 (struct prefix *p, struct rib *rib) +kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new) { - int route; + struct rib *rib; + int route = 0, cmd; - if (zserv_privs.change(ZPRIVS_RAISE)) - zlog (NULL, LOG_ERR, "Can't raise privileges"); - route = kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6); - if (zserv_privs.change(ZPRIVS_LOWER)) - zlog (NULL, LOG_ERR, "Can't lower privileges"); + if (!old && new) + cmd = RTM_ADD; + else if (old && !new) + cmd = RTM_DEL; + else + cmd = RTM_CHANGE; - return route; -} - -int -kernel_delete_ipv6 (struct prefix *p, struct rib *rib) -{ - int route; + rib = new ? new : old; if (zserv_privs.change(ZPRIVS_RAISE)) zlog (NULL, LOG_ERR, "Can't raise privileges"); - route = kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6); + + switch (PREFIX_FAMILY(p)) + { + case AF_INET: + route = kernel_rtm_ipv4 (cmd, p, rib, AF_INET); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + route = kernel_rtm_ipv6 (cmd, p, rib, AF_INET6); + break; +#endif + } + if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); return route; } -#endif /* HAVE_IPV6 */ |