From 5734509c0545ebd95a5b8e3f22a911c1a39ffa1b Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 25 Dec 2011 17:52:09 +0100 Subject: babeld: Initial import, for Babel routing protocol. * Initial import of the Babel routing protocol, ported to Quagga. * LICENCE: Update the original LICENCE file to include all known potentially applicable copyright claims. Ask that any future contributors to babeld/ grant MIT/X11 licence to their work. * *.{c,h}: Add GPL headers, in according with the SFLC guidance on dealing with potentially mixed GPL/other licensed work, at: https://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html --- babeld/kernel_zebra.c | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 461 insertions(+) create mode 100644 babeld/kernel_zebra.c (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c new file mode 100644 index 00000000..0fecb527 --- /dev/null +++ b/babeld/kernel_zebra.c @@ -0,0 +1,461 @@ +/* + * This file is free software: you may copy, redistribute and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 2 of the License, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * +Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include + +#include +#include "prefix.h" +#include "zclient.h" +#include "kernel.h" +#include "privs.h" +#include "command.h" +#include "vty.h" +#include "memory.h" +#include "thread.h" + +#include "util.h" +#include "babel_interface.h" +#include "babel_zebra.h" + + +static int +kernel_route_add_v4(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric); +static int +kernel_route_add_v6(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric); +static int +kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric); +static int +kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric); + + +int export_table = -1, import_table = -1; /* just for compatibility */ + +int +kernel_setup(int setup) +{ + return 0; +} + +/* get a connection with zebra client, at all costs */ +int +kernel_setup_socket(int setup) +{ + return -1; +} + +int +kernel_setup_interface(int setup, struct interface *interface) +{ + return 1; +} + +int +kernel_interface_operational(struct interface *interface) +{ + return if_is_operative(interface); +} + +int +kernel_interface_ipv4(struct interface *interface, unsigned char *addr_r) +{ + assert(0); /* function not used */ + return -1; +} + +int +kernel_interface_mtu(struct interface *interface) +{ + return MIN(interface->mtu, interface->mtu6); +} + +int +kernel_interface_wireless(struct interface *interface) +{ + return 0; +} + +extern int +zapi_ipv6_route (u_char cmd, struct zclient *zclient, + struct prefix_ipv6 *p, struct zapi_ipv6 *api); + +int +kernel_route(int operation, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric) +{ + int rc; + int added; + int ipv4; + + /* Check that the protocol family is consistent. */ + if(plen >= 96 && v4mapped(pref)) { + if(!v4mapped(gate)) { + errno = EINVAL; + return -1; + } + ipv4 = 1; + } else { + if(v4mapped(gate)) { + errno = EINVAL; + return -1; + } + ipv4 = 0; + } + + switch (operation) { + case ROUTE_ADD: + return ipv4 ? + kernel_route_add_v4(pref, plen, gate, ifindex, metric, + newgate, newifindex, newmetric): + kernel_route_add_v6(pref, plen, gate, ifindex, metric, + newgate, newifindex, newmetric); + break; + case ROUTE_FLUSH: + return ipv4 ? + kernel_route_delete_v4(pref, plen, gate, ifindex, metric, + newgate, newifindex, newmetric): + kernel_route_delete_v6(pref, plen, gate, ifindex, metric, + newgate, newifindex, newmetric); + break; + case ROUTE_MODIFY: + if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && + newifindex == ifindex) + return 0; + /* It is better to add the new route before removing the old + one, to avoid losing packets. However, if the old and new + priorities are equal, this only works if the kernel supports + ECMP. So we first try the "right" order, and fall back on + the "wrong" order if it fails with EEXIST. */ + rc = ipv4 ? + kernel_route_add_v4(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0): + kernel_route_add_v6(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0); + if(rc < 0) { + if(errno != EEXIST) + return rc; + added = 0; + } else { + added = 1; + } + + if (ipv4) { + kernel_route_delete_v4(pref, plen, + gate, ifindex, metric, + NULL, 0, 0); + } else { + kernel_route_delete_v6(pref, plen, + gate, ifindex, metric, + NULL, 0, 0); + } + + if(!added) { + rc = ipv4 ? + kernel_route_add_v4(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0): + kernel_route_add_v6(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0); + if(rc < 0) { + if(errno == EEXIST) + rc = 1; + /* In principle, we should try to re-install the flushed + route on failure to preserve. However, this should + hopefully not matter much in practice. */ + } + } + + return rc; + break; + default: + zlog_err("this should never appens (false value - kernel_route)"); + assert(0); + exit(1); + break; + } +} + +static int +kernel_route_add_v4(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric) +{ + unsigned int tmp_ifindex = ifindex; /* (for typing) */ + struct zapi_ipv4 api; /* quagga's communication system */ + struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ + struct in_addr babel_prefix_addr; /* babeld's prefix addr */ + struct in_addr nexthop; /* next router to go */ + struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */ + + /* convert to be comprehensive by quagga */ + /* convert given addresses */ + uchar_to_inaddr(&babel_prefix_addr, pref); + uchar_to_inaddr(&nexthop, gate); + + /* make prefix structure */ + memset (&quagga_prefix, 0, sizeof(quagga_prefix)); + quagga_prefix.family = AF_INET; + IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); + quagga_prefix.prefixlen = plen - 96; /* our plen is for v4mapped's addr */ + apply_mask_ipv4(&quagga_prefix); + + api.type = ZEBRA_ROUTE_BABEL; + api.flags = 0; + api.message = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + + debugf(BABEL_DEBUG_ROUTE, "adding route (ipv4) to zebra"); + return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, + &quagga_prefix, &api); +} + +static int +kernel_route_add_v6(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric) +{ + unsigned int tmp_ifindex = ifindex; /* (for typing) */ + struct zapi_ipv6 api; /* quagga's communication system */ + struct prefix_ipv6 quagga_prefix; /* quagga's prefix */ + struct in6_addr babel_prefix_addr; /* babeld's prefix addr */ + struct in6_addr nexthop; /* next router to go */ + struct in6_addr *nexthop_pointer = &nexthop; + + /* convert to be comprehensive by quagga */ + /* convert given addresses */ + uchar_to_in6addr(&babel_prefix_addr, pref); + uchar_to_in6addr(&nexthop, gate); + + /* make prefix structure */ + memset (&quagga_prefix, 0, sizeof(quagga_prefix)); + quagga_prefix.family = AF_INET6; + IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); + quagga_prefix.prefixlen = plen; + apply_mask_ipv6(&quagga_prefix); + + api.type = ZEBRA_ROUTE_BABEL; + api.flags = 0; + api.message = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + + debugf(BABEL_DEBUG_ROUTE, "adding route (ipv6) to zebra"); + return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, + &quagga_prefix, &api); +} + +static int +kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric) +{ + unsigned int tmp_ifindex = ifindex; /* (for typing) */ + struct zapi_ipv4 api; /* quagga's communication system */ + struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ + struct in_addr babel_prefix_addr; /* babeld's prefix addr */ + struct in_addr nexthop; /* next router to go */ + struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */ + + /* convert to be comprehensive by quagga */ + /* convert given addresses */ + uchar_to_inaddr(&babel_prefix_addr, pref); + uchar_to_inaddr(&nexthop, gate); + + /* make prefix structure */ + memset (&quagga_prefix, 0, sizeof(quagga_prefix)); + quagga_prefix.family = AF_INET; + IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); + quagga_prefix.prefixlen = plen - 96; + apply_mask_ipv4(&quagga_prefix); + + api.type = ZEBRA_ROUTE_BABEL; + api.flags = 0; + api.message = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + + debugf(BABEL_DEBUG_ROUTE, "removing route (ipv4) to zebra"); + return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, + &quagga_prefix, &api); +} + +static int +kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric, + const unsigned char *newgate, int newifindex, + unsigned int newmetric) +{ + unsigned int tmp_ifindex = ifindex; /* (for typing) */ + struct zapi_ipv6 api; /* quagga's communication system */ + struct prefix_ipv6 quagga_prefix; /* quagga's prefix */ + struct in6_addr babel_prefix_addr; /* babeld's prefix addr */ + struct in6_addr nexthop; /* next router to go */ + struct in6_addr *nexthop_pointer = &nexthop; + + /* convert to be comprehensive by quagga */ + /* convert given addresses */ + uchar_to_in6addr(&babel_prefix_addr, pref); + uchar_to_in6addr(&nexthop, gate); + + /* make prefix structure */ + memset (&quagga_prefix, 0, sizeof(quagga_prefix)); + quagga_prefix.family = AF_INET6; + IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); + quagga_prefix.prefixlen = plen; + apply_mask_ipv6(&quagga_prefix); + + api.type = ZEBRA_ROUTE_BABEL; + api.flags = 0; + api.message = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + + debugf(BABEL_DEBUG_ROUTE, "removing route (ipv6) to zebra"); + return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, + &quagga_prefix, &api); +} + +int +kernel_routes(struct kernel_route *routes, int maxroutes) +{ + fprintf(stderr, "\tkernel_routes --- not implemented\n"); + return 0; +} + +int +kernel_callback(int (*fn)(int, void*), void *closure) +{ + struct thread thread; + fprintf(stderr, "\tkernel_callback\n"); + /* do a little work on threads */ + if (thread_fetch(master, &thread) != NULL) { + thread_call (&thread); + } + return 0; +} + +int +kernel_addresses(struct interface *interface, int ll, + struct kernel_route *routes, int maxroutes) +{ + fprintf(stderr, "\tkernel_addresses --- not implemented\n"); + return 0; +} + +int +if_eui64(char *ifname, int ifindex, unsigned char *eui) +{ + struct interface *ifp = if_lookup_by_index(ifindex); + if (ifp == NULL) { + return -1; + } +#ifdef HAVE_STRUCT_SOCKADDR_DL + u_char len = ifp->sdl.sdl_alen; + char *tmp = ifp->sdl.sdl_data + ifp->sdl.sdl_nlen; +#else + u_char len = (u_char) ifp->hw_addr_len; + char *tmp = (void*) ifp->hw_addr; +#endif + if (len == 8) { + memcpy(eui, tmp, 8); + eui[0] ^= 2; + } else if (len == 6) { + memcpy(eui, tmp, 3); + eui[3] = 0xFF; + eui[4] = 0xFE; + memcpy(eui+5, tmp+3, 3); + } else if (len > 8) { + memcpy(eui, tmp, 8); + } else if (len > 0){ + memset(eui, 0, 8 - len); + memcpy(eui + 8 - len, tmp, len); + } else { + return -1; + } + return 0; +} -- cgit v1.2.1 From 089082b5d51c41a4498edb6a3f495ade0d517e73 Mon Sep 17 00:00:00 2001 From: Matthieu Boutier Date: Fri, 6 Jan 2012 23:09:23 +0100 Subject: babeld: clean kernel_zebra (old functions, fields...). --- babeld/kernel_zebra.c | 60 --------------------------------------------------- 1 file changed, 60 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 0fecb527..82f03e43 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -80,41 +80,12 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, const unsigned char *newgate, int newifindex, unsigned int newmetric); - -int export_table = -1, import_table = -1; /* just for compatibility */ - -int -kernel_setup(int setup) -{ - return 0; -} - -/* get a connection with zebra client, at all costs */ -int -kernel_setup_socket(int setup) -{ - return -1; -} - -int -kernel_setup_interface(int setup, struct interface *interface) -{ - return 1; -} - int kernel_interface_operational(struct interface *interface) { return if_is_operative(interface); } -int -kernel_interface_ipv4(struct interface *interface, unsigned char *addr_r) -{ - assert(0); /* function not used */ - return -1; -} - int kernel_interface_mtu(struct interface *interface) { @@ -127,10 +98,6 @@ kernel_interface_wireless(struct interface *interface) return 0; } -extern int -zapi_ipv6_route (u_char cmd, struct zclient *zclient, - struct prefix_ipv6 *p, struct zapi_ipv6 *api); - int kernel_route(int operation, const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, unsigned int metric, @@ -400,33 +367,6 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, &quagga_prefix, &api); } -int -kernel_routes(struct kernel_route *routes, int maxroutes) -{ - fprintf(stderr, "\tkernel_routes --- not implemented\n"); - return 0; -} - -int -kernel_callback(int (*fn)(int, void*), void *closure) -{ - struct thread thread; - fprintf(stderr, "\tkernel_callback\n"); - /* do a little work on threads */ - if (thread_fetch(master, &thread) != NULL) { - thread_call (&thread); - } - return 0; -} - -int -kernel_addresses(struct interface *interface, int ll, - struct kernel_route *routes, int maxroutes) -{ - fprintf(stderr, "\tkernel_addresses --- not implemented\n"); - return 0; -} - int if_eui64(char *ifname, int ifindex, unsigned char *eui) { -- cgit v1.2.1 From ec8d8d5ba648302cf9405f1346e3760d9b9d061c Mon Sep 17 00:00:00 2001 From: Matthieu Boutier Date: Fri, 20 Jan 2012 15:32:16 +0100 Subject: babeld: change the modify route system. Zebra doesn't set errno to EEXIST if we add a route who was already in the kernel, so we always returned after just doing "add; delete". This patch fix the problem by doing "delete; add" always. --- babeld/kernel_zebra.c | 49 ++++++++++++++----------------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 82f03e43..7ddc797d 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -142,26 +142,7 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && newifindex == ifindex) return 0; - /* It is better to add the new route before removing the old - one, to avoid losing packets. However, if the old and new - priorities are equal, this only works if the kernel supports - ECMP. So we first try the "right" order, and fall back on - the "wrong" order if it fails with EEXIST. */ - rc = ipv4 ? - kernel_route_add_v4(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0): - kernel_route_add_v6(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0); - if(rc < 0) { - if(errno != EEXIST) - return rc; - added = 0; - } else { - added = 1; - } - + debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new."); if (ipv4) { kernel_route_delete_v4(pref, plen, gate, ifindex, metric, @@ -172,21 +153,19 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, NULL, 0, 0); } - if(!added) { - rc = ipv4 ? - kernel_route_add_v4(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0): - kernel_route_add_v6(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0); - if(rc < 0) { - if(errno == EEXIST) - rc = 1; - /* In principle, we should try to re-install the flushed - route on failure to preserve. However, this should - hopefully not matter much in practice. */ - } + rc = ipv4 ? + kernel_route_add_v4(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0): + kernel_route_add_v6(pref, plen, + newgate, newifindex, newmetric, + NULL, 0, 0); + if(rc < 0) { + if(errno == EEXIST) + rc = 1; + /* In principle, we should try to re-install the flushed + route on failure to preserve. However, this should + hopefully not matter much in practice. */ } return rc; -- cgit v1.2.1 From a19a3bf94740aebff6fdfc76f3d4b17c0013fae4 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 21 Jan 2012 23:16:00 +0400 Subject: babeld: add MP-specific zclient API fix Add proper initialization of SAFI field, which is present in the revisions of zapi_ipv4 and zapi_ipv6 structures specific to MP-BGP patchset. Without this change no Babel routes could make into zebra RIB. --- babeld/kernel_zebra.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 7ddc797d..53da5f40 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -206,6 +206,7 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; @@ -248,6 +249,7 @@ kernel_route_add_v6(const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; @@ -291,6 +293,7 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; @@ -334,6 +337,7 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; -- cgit v1.2.1 From 16e51b246be6b18641327685f44bd4f5f6649367 Mon Sep 17 00:00:00 2001 From: Matthieu Boutier Date: Mon, 23 Jan 2012 00:22:14 +0100 Subject: babeld: remove unused variable. --- babeld/kernel_zebra.c | 1 - 1 file changed, 1 deletion(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 53da5f40..d556a605 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -105,7 +105,6 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, unsigned int newmetric) { int rc; - int added; int ipv4; /* Check that the protocol family is consistent. */ -- cgit v1.2.1 From 210f6f66287c40f247c1a4ff983aae85b9e42e2c Mon Sep 17 00:00:00 2001 From: Matthieu Boutier Date: Sat, 28 Jan 2012 00:07:14 +0100 Subject: babeld: fix eui64 features. We are interested by eui64 with at least 6 octets. --- babeld/kernel_zebra.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index d556a605..97b7c584 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -371,11 +371,6 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui) eui[3] = 0xFF; eui[4] = 0xFE; memcpy(eui+5, tmp+3, 3); - } else if (len > 8) { - memcpy(eui, tmp, 8); - } else if (len > 0){ - memset(eui, 0, 8 - len); - memcpy(eui + 8 - len, tmp, len); } else { return -1; } -- cgit v1.2.1 From 53b21956f650df86a76b7a7047cfa85114c99dcc Mon Sep 17 00:00:00 2001 From: Matthieu Boutier Date: Tue, 31 Jan 2012 17:09:55 +0100 Subject: babeld: remove some unused functions' arguments. --- babeld/kernel_zebra.c | 84 ++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 58 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 97b7c584..f23403ec 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -59,26 +59,20 @@ THE SOFTWARE. static int kernel_route_add_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric); + const unsigned char *gate, int ifindex, + unsigned int metric); static int kernel_route_add_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric); + const unsigned char *gate, int ifindex, + unsigned int metric); static int kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, - unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric); + unsigned int metric); static int kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, - unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric); + unsigned int metric); int kernel_interface_operational(struct interface *interface) @@ -125,47 +119,29 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, switch (operation) { case ROUTE_ADD: return ipv4 ? - kernel_route_add_v4(pref, plen, gate, ifindex, metric, - newgate, newifindex, newmetric): - kernel_route_add_v6(pref, plen, gate, ifindex, metric, - newgate, newifindex, newmetric); + kernel_route_add_v4(pref, plen, gate, ifindex, metric): + kernel_route_add_v6(pref, plen, gate, ifindex, metric); break; case ROUTE_FLUSH: return ipv4 ? - kernel_route_delete_v4(pref, plen, gate, ifindex, metric, - newgate, newifindex, newmetric): - kernel_route_delete_v6(pref, plen, gate, ifindex, metric, - newgate, newifindex, newmetric); + kernel_route_delete_v4(pref, plen, gate, ifindex, metric): + kernel_route_delete_v6(pref, plen, gate, ifindex, metric); break; case ROUTE_MODIFY: if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && newifindex == ifindex) return 0; debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new."); - if (ipv4) { - kernel_route_delete_v4(pref, plen, - gate, ifindex, metric, - NULL, 0, 0); - } else { - kernel_route_delete_v6(pref, plen, - gate, ifindex, metric, - NULL, 0, 0); - } + rc = ipv4 ? + kernel_route_delete_v4(pref, plen, gate, ifindex, metric): + kernel_route_delete_v6(pref, plen, gate, ifindex, metric); + + if (rc < 0) + return -1; rc = ipv4 ? - kernel_route_add_v4(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0): - kernel_route_add_v6(pref, plen, - newgate, newifindex, newmetric, - NULL, 0, 0); - if(rc < 0) { - if(errno == EEXIST) - rc = 1; - /* In principle, we should try to re-install the flushed - route on failure to preserve. However, this should - hopefully not matter much in practice. */ - } + kernel_route_add_v4(pref, plen, newgate, newifindex, newmetric): + kernel_route_add_v6(pref, plen, newgate, newifindex, newmetric); return rc; break; @@ -179,9 +155,7 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, static int kernel_route_add_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric) + const unsigned char *gate, int ifindex, unsigned int metric) { unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv4 api; /* quagga's communication system */ @@ -190,7 +164,7 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, struct in_addr nexthop; /* next router to go */ struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */ - /* convert to be comprehensive by quagga */ + /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_inaddr(&babel_prefix_addr, pref); uchar_to_inaddr(&nexthop, gate); @@ -222,9 +196,7 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, static int kernel_route_add_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric) + const unsigned char *gate, int ifindex, unsigned int metric) { unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv6 api; /* quagga's communication system */ @@ -233,7 +205,7 @@ kernel_route_add_v6(const unsigned char *pref, unsigned short plen, struct in6_addr nexthop; /* next router to go */ struct in6_addr *nexthop_pointer = &nexthop; - /* convert to be comprehensive by quagga */ + /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_in6addr(&babel_prefix_addr, pref); uchar_to_in6addr(&nexthop, gate); @@ -266,9 +238,7 @@ kernel_route_add_v6(const unsigned char *pref, unsigned short plen, static int kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, - unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric) + unsigned int metric) { unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv4 api; /* quagga's communication system */ @@ -277,7 +247,7 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, struct in_addr nexthop; /* next router to go */ struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */ - /* convert to be comprehensive by quagga */ + /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_inaddr(&babel_prefix_addr, pref); uchar_to_inaddr(&nexthop, gate); @@ -310,9 +280,7 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, static int kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, - unsigned int metric, - const unsigned char *newgate, int newifindex, - unsigned int newmetric) + unsigned int metric) { unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv6 api; /* quagga's communication system */ @@ -321,7 +289,7 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, struct in6_addr nexthop; /* next router to go */ struct in6_addr *nexthop_pointer = &nexthop; - /* convert to be comprehensive by quagga */ + /* convert to be understandable by quagga */ /* convert given addresses */ uchar_to_in6addr(&babel_prefix_addr, pref); uchar_to_in6addr(&nexthop, gate); -- cgit v1.2.1 From b6475ecb14abab936919894050f9ca47415d0f48 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 9 Feb 2012 12:29:10 +0100 Subject: babeld: Don't use an ifindex when installing IPv4 routes. Stand-alone babeld installs routes using both a next-hop gateway and an interface index. Unfortunately, this doesn't work for IPv4 under Quagga. We now ignore the ifindex when installing IPv4 routes, which makes Babel work for IPv4 in prefix-based networks. Of course this breaks IPv4 mesh networks, unless you play some tricks with your interfaces' netmasks. --- babeld/kernel_zebra.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index f23403ec..1df4217f 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -157,7 +157,6 @@ static int kernel_route_add_v4(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, unsigned int metric) { - unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv4 api; /* quagga's communication system */ struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ struct in_addr babel_prefix_addr; /* babeld's prefix addr */ @@ -180,12 +179,17 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, api.flags = 0; api.message = 0; api.safi = SAFI_UNICAST; + + /* Unlike the native Linux and BSD interfaces, Quagga doesn't like + there to be both and IPv4 nexthop and an ifindex. Omit the + ifindex, and assume that the connected prefixes be set up + correctly. */ + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &tmp_ifindex; + api.ifindex_num = 0; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; @@ -240,7 +244,6 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, const unsigned char *gate, int ifindex, unsigned int metric) { - unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv4 api; /* quagga's communication system */ struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ struct in_addr babel_prefix_addr; /* babeld's prefix addr */ @@ -266,9 +269,7 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &tmp_ifindex; + api.ifindex_num = 0; SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); api.metric = metric; -- cgit v1.2.1 From d70ab9dcd8f054ebd5f60a29dbbd9b39f9fe7566 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 9 Feb 2012 17:23:09 +0100 Subject: babeld: Add support for blackhole routes. Babel makes use of blackhole routes to prevent routing loops between overlapping prefixes shortly after a route is retracted (see RFC 6126 sections 2.8 and 3.5.5). This patch adds support for installing such blackhole routes. --- babeld/kernel_zebra.c | 64 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 1df4217f..d262a86b 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -186,12 +186,16 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, correctly. */ SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; api.ifindex_num = 0; - - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; + if(metric >= KERNEL_INFINITY) { + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.nexthop_num = 0; + } else { + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + } debugf(BABEL_DEBUG_ROUTE, "adding route (ipv4) to zebra"); return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, @@ -226,13 +230,18 @@ kernel_route_add_v6(const unsigned char *pref, unsigned short plen, api.message = 0; api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &tmp_ifindex; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; + if(metric >= KERNEL_INFINITY) { + api.nexthop_num = 0; + api.ifindex_num = 0; + } else { + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + } debugf(BABEL_DEBUG_ROUTE, "adding route (ipv6) to zebra"); return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, @@ -267,11 +276,16 @@ kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, api.message = 0; api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; api.ifindex_num = 0; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; + if(metric >= KERNEL_INFINITY) { + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.nexthop_num = 0; + } else { + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + } debugf(BABEL_DEBUG_ROUTE, "removing route (ipv4) to zebra"); return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, @@ -307,11 +321,19 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, api.message = 0; api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &tmp_ifindex; + if(metric >= KERNEL_INFINITY) { + api.flags = ZEBRA_FLAG_BLACKHOLE; + api.nexthop_num = 0; + api.ifindex_num = 0; + } else { + api.nexthop_num = 1; + api.nexthop = &nexthop_pointer; + SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); + api.ifindex_num = 1; + api.ifindex = &tmp_ifindex; + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); + api.metric = metric; + } debugf(BABEL_DEBUG_ROUTE, "removing route (ipv6) to zebra"); return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, -- cgit v1.2.1 From b63b4484c6d2c9d304d4ddd0756a4847c6dc5359 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Tue, 14 Feb 2012 11:17:32 +0100 Subject: babeld: fix typo in kernel_route_add_v6. --- babeld/kernel_zebra.c | 1 + 1 file changed, 1 insertion(+) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index d262a86b..85ee1f8d 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -231,6 +231,7 @@ kernel_route_add_v6(const unsigned char *pref, unsigned short plen, api.safi = SAFI_UNICAST; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); if(metric >= KERNEL_INFINITY) { + api.flags = ZEBRA_FLAG_BLACKHOLE; api.nexthop_num = 0; api.ifindex_num = 0; } else { -- cgit v1.2.1 From 5ca7986d546a1b65a4917aec0f1b594f950f7c27 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Tue, 14 Feb 2012 11:22:29 +0100 Subject: babeld: consolidate zebra interface into fewer functions. --- babeld/kernel_zebra.c | 153 ++++++++++---------------------------------------- 1 file changed, 29 insertions(+), 124 deletions(-) (limited to 'babeld/kernel_zebra.c') diff --git a/babeld/kernel_zebra.c b/babeld/kernel_zebra.c index 85ee1f8d..db7d0b39 100644 --- a/babeld/kernel_zebra.c +++ b/babeld/kernel_zebra.c @@ -58,21 +58,13 @@ THE SOFTWARE. static int -kernel_route_add_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); +kernel_route_v4(int add, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric); static int -kernel_route_add_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); -static int -kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); -static int -kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric); +kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, + unsigned int metric); int kernel_interface_operational(struct interface *interface) @@ -119,13 +111,13 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, switch (operation) { case ROUTE_ADD: return ipv4 ? - kernel_route_add_v4(pref, plen, gate, ifindex, metric): - kernel_route_add_v6(pref, plen, gate, ifindex, metric); + kernel_route_v4(1, pref, plen, gate, ifindex, metric): + kernel_route_v6(1, pref, plen, gate, ifindex, metric); break; case ROUTE_FLUSH: return ipv4 ? - kernel_route_delete_v4(pref, plen, gate, ifindex, metric): - kernel_route_delete_v6(pref, plen, gate, ifindex, metric); + kernel_route_v4(0, pref, plen, gate, ifindex, metric): + kernel_route_v6(0, pref, plen, gate, ifindex, metric); break; case ROUTE_MODIFY: if(newmetric == metric && memcmp(newgate, gate, 16) == 0 && @@ -133,15 +125,15 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, return 0; debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new."); rc = ipv4 ? - kernel_route_delete_v4(pref, plen, gate, ifindex, metric): - kernel_route_delete_v6(pref, plen, gate, ifindex, metric); + kernel_route_v4(0, pref, plen, gate, ifindex, metric): + kernel_route_v6(0, pref, plen, gate, ifindex, metric); if (rc < 0) return -1; rc = ipv4 ? - kernel_route_add_v4(pref, plen, newgate, newifindex, newmetric): - kernel_route_add_v6(pref, plen, newgate, newifindex, newmetric); + kernel_route_v4(1, pref, plen, newgate, newifindex, newmetric): + kernel_route_v6(1, pref, plen, newgate, newifindex, newmetric); return rc; break; @@ -154,8 +146,9 @@ kernel_route(int operation, const unsigned char *pref, unsigned short plen, } static int -kernel_route_add_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric) +kernel_route_v4(int add, + const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric) { struct zapi_ipv4 api; /* quagga's communication system */ struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ @@ -197,106 +190,16 @@ kernel_route_add_v4(const unsigned char *pref, unsigned short plen, api.metric = metric; } - debugf(BABEL_DEBUG_ROUTE, "adding route (ipv4) to zebra"); - return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, - &quagga_prefix, &api); -} - -static int -kernel_route_add_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, unsigned int metric) -{ - unsigned int tmp_ifindex = ifindex; /* (for typing) */ - struct zapi_ipv6 api; /* quagga's communication system */ - struct prefix_ipv6 quagga_prefix; /* quagga's prefix */ - struct in6_addr babel_prefix_addr; /* babeld's prefix addr */ - struct in6_addr nexthop; /* next router to go */ - struct in6_addr *nexthop_pointer = &nexthop; - - /* convert to be understandable by quagga */ - /* convert given addresses */ - uchar_to_in6addr(&babel_prefix_addr, pref); - uchar_to_in6addr(&nexthop, gate); - - /* make prefix structure */ - memset (&quagga_prefix, 0, sizeof(quagga_prefix)); - quagga_prefix.family = AF_INET6; - IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); - quagga_prefix.prefixlen = plen; - apply_mask_ipv6(&quagga_prefix); - - api.type = ZEBRA_ROUTE_BABEL; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - if(metric >= KERNEL_INFINITY) { - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.nexthop_num = 0; - api.ifindex_num = 0; - } else { - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &tmp_ifindex; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; - } - - debugf(BABEL_DEBUG_ROUTE, "adding route (ipv6) to zebra"); - return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, - &quagga_prefix, &api); -} - -static int -kernel_route_delete_v4(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric) -{ - struct zapi_ipv4 api; /* quagga's communication system */ - struct prefix_ipv4 quagga_prefix; /* quagga's prefix */ - struct in_addr babel_prefix_addr; /* babeld's prefix addr */ - struct in_addr nexthop; /* next router to go */ - struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */ - - /* convert to be understandable by quagga */ - /* convert given addresses */ - uchar_to_inaddr(&babel_prefix_addr, pref); - uchar_to_inaddr(&nexthop, gate); - - /* make prefix structure */ - memset (&quagga_prefix, 0, sizeof(quagga_prefix)); - quagga_prefix.family = AF_INET; - IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr); - quagga_prefix.prefixlen = plen - 96; - apply_mask_ipv4(&quagga_prefix); - - api.type = ZEBRA_ROUTE_BABEL; - api.flags = 0; - api.message = 0; - api.safi = SAFI_UNICAST; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); - api.ifindex_num = 0; - if(metric >= KERNEL_INFINITY) { - api.flags = ZEBRA_FLAG_BLACKHOLE; - api.nexthop_num = 0; - } else { - api.nexthop_num = 1; - api.nexthop = &nexthop_pointer; - SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); - api.metric = metric; - } - - debugf(BABEL_DEBUG_ROUTE, "removing route (ipv4) to zebra"); - return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, - &quagga_prefix, &api); + debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra", + add ? "adding" : "removing" ); + return zapi_ipv4_route (add ? ZEBRA_IPV4_ROUTE_ADD : + ZEBRA_IPV4_ROUTE_DELETE, + zclient, &quagga_prefix, &api); } static int -kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, - const unsigned char *gate, int ifindex, - unsigned int metric) +kernel_route_v6(int add, const unsigned char *pref, unsigned short plen, + const unsigned char *gate, int ifindex, unsigned int metric) { unsigned int tmp_ifindex = ifindex; /* (for typing) */ struct zapi_ipv6 api; /* quagga's communication system */ @@ -336,9 +239,11 @@ kernel_route_delete_v6(const unsigned char *pref, unsigned short plen, api.metric = metric; } - debugf(BABEL_DEBUG_ROUTE, "removing route (ipv6) to zebra"); - return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, - &quagga_prefix, &api); + debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra", + add ? "adding" : "removing" ); + return zapi_ipv6_route (add ? ZEBRA_IPV6_ROUTE_ADD : + ZEBRA_IPV6_ROUTE_DELETE, + zclient, &quagga_prefix, &api); } int -- cgit v1.2.1