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 +++++++++++++++----------------------------------- babeld/babel_filter.h | 9 +-- babeld/babeld.c | 61 ++++---------------- 3 files changed, 56 insertions(+), 166 deletions(-) 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 */ -} diff --git a/babeld/babel_filter.h b/babeld/babel_filter.h index 52b72f60..73722e0a 100644 --- a/babeld/babel_filter.h +++ b/babeld/babel_filter.h @@ -43,12 +43,7 @@ THE SOFTWARE. #include "prefix.h" #include "babel_interface.h" -/* filter route coming from other worlds */ -int babel_filter_in (struct prefix *, babel_interface_nfo *); -/* filter route sending to other worlds */ -int babel_filter_out (struct prefix *, babel_interface_nfo *); -/* filter route coming from our friend zebra */ -int babel_filter_redistribute - (struct prefix *, babel_interface_nfo *); +int babel_filter(int output, const unsigned char *prefix, unsigned short plen, + unsigned int index); #endif /* BABELD_BABEL_FILTER_H */ diff --git a/babeld/babeld.c b/babeld/babeld.c index da074349..14990a68 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -705,71 +705,30 @@ babeld_quagga_init(void) distribute_list_delete_hook (babel_distribute_update); } -int /* DEPRECATED: for compatibility with old babeld (configuration.{c,h})*/ +/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */ + +int input_filter(const unsigned char *id, const unsigned char *prefix, unsigned short plen, const unsigned char *neigh, unsigned int ifindex) { - struct interface *ifp = NULL; - struct prefix p; - 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); - } - - ifp = if_lookup_by_index(ifindex); - if (ifp != NULL) { - return babel_filter_in(&p, babel_get_if_nfo(ifp)); - } - - return babel_filter_in(&p, NULL); + return babel_filter(0, prefix, plen, ifindex); } -int /* DEPRECATED: for compatibility with old babeld */ +int output_filter(const unsigned char *id, const unsigned char *prefix, unsigned short plen, unsigned int ifindex) { - struct interface *ifp = NULL; - struct prefix p; - 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); - } - - ifp = if_lookup_by_index(ifindex); - if (ifp != NULL) { - return babel_filter_out(&p, babel_get_if_nfo(ifp)); - } - - return babel_filter_out(&p, NULL); + return babel_filter(1, prefix, plen, ifindex); } -int /* DEPRECATED: for compatibility with old babeld */ +/* There's no redistribute filter in Quagga -- the zebra daemon does its + own filtering. */ +int redistribute_filter(const unsigned char *prefix, unsigned short plen, unsigned int ifindex, int proto) { - struct interface *ifp = NULL; - struct prefix p; - 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); - } - - ifp = if_lookup_by_index(ifindex); - if (ifp != NULL) { - return babel_filter_redistribute(&p,babel_get_if_nfo(ifp)); - } - - return babel_filter_redistribute(&p, NULL); + return 0; } void -- cgit v1.2.1