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/babel_filter.c | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 babeld/babel_filter.c (limited to 'babeld/babel_filter.c') diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c new file mode 100644 index 00000000..5c93d13a --- /dev/null +++ b/babeld/babel_filter.c @@ -0,0 +1,188 @@ +/* + * 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 "babel_filter.h" +#include "vty.h" +#include "filter.h" +#include "log.h" +#include "plist.h" +#include "distribute.h" +#include "util.h" + + +int +babel_filter_in (struct prefix *p, babel_interface_nfo *babel_ifp) +{ + struct distribute *dist; + struct access_list *alist; + struct prefix_list *plist; + + /* Input distribute-list filtering. */ + if (babel_ifp != NULL && babel_ifp->list[BABEL_FILTER_IN]) { + if (access_list_apply (babel_ifp->list[BABEL_FILTER_IN], p) + == FILTER_DENY) { + debugf(BABEL_DEBUG_FILTER, + "%s/%d filtered by distribute in", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + if (babel_ifp != NULL && babel_ifp->prefix[BABEL_FILTER_IN]) { + if (prefix_list_apply (babel_ifp->prefix[BABEL_FILTER_IN], p) + == PREFIX_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + + /* All interface filter check. */ + dist = distribute_lookup (NULL); + if (dist) { + if (dist->list[DISTRIBUTE_IN]) { + alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]); + + if (alist) { + if (access_list_apply (alist, p) == FILTER_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + } + if (dist->prefix[DISTRIBUTE_IN]) { + plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]); + if (plist) { + if (prefix_list_apply (plist, p) == PREFIX_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + } + } + return 0; +} + +int +babel_filter_out (struct prefix *p, babel_interface_nfo *babel_ifp) +{ + struct distribute *dist; + struct access_list *alist; + struct prefix_list *plist; + + if (babel_ifp != NULL && babel_ifp->list[BABEL_FILTER_OUT]) { + if (access_list_apply (babel_ifp->list[BABEL_FILTER_OUT], p) + == FILTER_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + if (babel_ifp != NULL && babel_ifp->prefix[BABEL_FILTER_OUT]) { + if (prefix_list_apply (babel_ifp->prefix[BABEL_FILTER_OUT], p) + == PREFIX_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + + /* All interface filter check. */ + dist = distribute_lookup (NULL); + if (dist) { + if (dist->list[DISTRIBUTE_OUT]) { + alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]); + if (alist) { + if (access_list_apply (alist, p) == FILTER_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + } + if (dist->prefix[DISTRIBUTE_OUT]) { + plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]); + if (plist) { + if (prefix_list_apply (plist, p) == PREFIX_DENY) { + debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return -1; + } + } + } + } + return 0; +} + +int +babel_filter_redistribute (struct prefix *p, + babel_interface_nfo *babel_ifp) +{ + debugf(BABEL_DEBUG_FILTER, "%s/%d WARNING: no redistribute filter implemented !!!!", + p->family == AF_INET ? + inet_ntoa(p->u.prefix4) : + inet6_ntoa (p->u.prefix6), + p->prefixlen); + return 0; /* TODO: it redistributes always */ +} -- cgit v1.2.1 From 31e2a19fd2b4aca34b1d2f5e2eb8c9a44b9ea6c9 Mon Sep 17 00:00:00 2001 From: Juliusz Chroboczek Date: Thu, 9 Feb 2012 14:06:11 +0100 Subject: babeld: refactor filtering stubs. Factorise the common parts of the in/out filtering functions. This also fixes a bug with filtered out routes, which in babeld are signalled by a filter returing INFINITY, not -1. --- babeld/babel_filter.c | 152 +++++++++++++++----------------------------------- 1 file changed, 44 insertions(+), 108 deletions(-) (limited to 'babeld/babel_filter.c') diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c index 5c93d13a..191a9f77 100644 --- a/babeld/babel_filter.c +++ b/babeld/babel_filter.c @@ -45,144 +45,80 @@ THE SOFTWARE. #include "distribute.h" #include "util.h" - int -babel_filter_in (struct prefix *p, babel_interface_nfo *babel_ifp) +babel_filter(int output, const unsigned char *prefix, unsigned short plen, + unsigned int ifindex) { + struct interface *ifp = if_lookup_by_index(ifindex); + babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL; + struct prefix p; struct distribute *dist; struct access_list *alist; struct prefix_list *plist; + int filter = output ? BABEL_FILTER_OUT : BABEL_FILTER_IN; + int distribute = output ? DISTRIBUTE_OUT : DISTRIBUTE_IN; + + p.family = v4mapped(prefix) ? AF_INET : AF_INET6; + p.prefixlen = v4mapped(prefix) ? plen - 96 : plen; + if (p.family == AF_INET) + uchar_to_inaddr(&p.u.prefix4, prefix); + else + uchar_to_in6addr(&p.u.prefix6, prefix); - /* Input distribute-list filtering. */ - if (babel_ifp != NULL && babel_ifp->list[BABEL_FILTER_IN]) { - if (access_list_apply (babel_ifp->list[BABEL_FILTER_IN], p) + if (babel_ifp != NULL && babel_ifp->list[filter]) { + if (access_list_apply (babel_ifp->list[filter], &p) == FILTER_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; + p.family == AF_INET ? + inet_ntoa(p.u.prefix4) : + inet6_ntoa (p.u.prefix6), + p.prefixlen); + return INFINITY; } } - if (babel_ifp != NULL && babel_ifp->prefix[BABEL_FILTER_IN]) { - if (prefix_list_apply (babel_ifp->prefix[BABEL_FILTER_IN], p) + if (babel_ifp != NULL && babel_ifp->prefix[filter]) { + if (prefix_list_apply (babel_ifp->prefix[filter], &p) == PREFIX_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; + p.family == AF_INET ? + inet_ntoa(p.u.prefix4) : + inet6_ntoa (p.u.prefix6), + p.prefixlen); + return INFINITY; } } /* All interface filter check. */ dist = distribute_lookup (NULL); if (dist) { - if (dist->list[DISTRIBUTE_IN]) { - alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]); + if (dist->list[distribute]) { + alist = access_list_lookup (AFI_IP6, dist->list[distribute]); if (alist) { - if (access_list_apply (alist, p) == FILTER_DENY) { + if (access_list_apply (alist, &p) == FILTER_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; + p.family == AF_INET ? + inet_ntoa(p.u.prefix4) : + inet6_ntoa (p.u.prefix6), + p.prefixlen); + return INFINITY; } } } - if (dist->prefix[DISTRIBUTE_IN]) { - plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]); + if (dist->prefix[distribute]) { + plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]); if (plist) { - if (prefix_list_apply (plist, p) == PREFIX_DENY) { + if (prefix_list_apply (plist, &p) == PREFIX_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; - } - } - } - } - return 0; -} - -int -babel_filter_out (struct prefix *p, babel_interface_nfo *babel_ifp) -{ - struct distribute *dist; - struct access_list *alist; - struct prefix_list *plist; - - if (babel_ifp != NULL && babel_ifp->list[BABEL_FILTER_OUT]) { - if (access_list_apply (babel_ifp->list[BABEL_FILTER_OUT], p) - == FILTER_DENY) { - debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; - } - } - if (babel_ifp != NULL && babel_ifp->prefix[BABEL_FILTER_OUT]) { - if (prefix_list_apply (babel_ifp->prefix[BABEL_FILTER_OUT], p) - == PREFIX_DENY) { - debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; - } - } - - /* All interface filter check. */ - dist = distribute_lookup (NULL); - if (dist) { - if (dist->list[DISTRIBUTE_OUT]) { - alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]); - if (alist) { - if (access_list_apply (alist, p) == FILTER_DENY) { - debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; - } - } - } - if (dist->prefix[DISTRIBUTE_OUT]) { - plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]); - if (plist) { - if (prefix_list_apply (plist, p) == PREFIX_DENY) { - debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute out", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return -1; + p.family == AF_INET ? + inet_ntoa(p.u.prefix4) : + inet6_ntoa (p.u.prefix6), + p.prefixlen); + return INFINITY; } } } } return 0; } - -int -babel_filter_redistribute (struct prefix *p, - babel_interface_nfo *babel_ifp) -{ - debugf(BABEL_DEBUG_FILTER, "%s/%d WARNING: no redistribute filter implemented !!!!", - p->family == AF_INET ? - inet_ntoa(p->u.prefix4) : - inet6_ntoa (p->u.prefix6), - p->prefixlen); - return 0; /* TODO: it redistributes always */ -} -- cgit v1.2.1