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.
This commit is contained in:
Juliusz Chroboczek 2012-02-09 14:06:11 +01:00 committed by Paul Jakma
parent 578ce371d1
commit 31e2a19fd2
3 changed files with 56 additions and 166 deletions

View File

@ -45,144 +45,80 @@ THE SOFTWARE.
#include "distribute.h" #include "distribute.h"
#include "util.h" #include "util.h"
int 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 distribute *dist;
struct access_list *alist; struct access_list *alist;
struct prefix_list *plist; struct prefix_list *plist;
int filter = output ? BABEL_FILTER_OUT : BABEL_FILTER_IN;
int distribute = output ? DISTRIBUTE_OUT : DISTRIBUTE_IN;
/* Input distribute-list filtering. */ p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
if (babel_ifp != NULL && babel_ifp->list[BABEL_FILTER_IN]) { p.prefixlen = v4mapped(prefix) ? plen - 96 : plen;
if (access_list_apply (babel_ifp->list[BABEL_FILTER_IN], p) if (p.family == AF_INET)
uchar_to_inaddr(&p.u.prefix4, prefix);
else
uchar_to_in6addr(&p.u.prefix6, prefix);
if (babel_ifp != NULL && babel_ifp->list[filter]) {
if (access_list_apply (babel_ifp->list[filter], &p)
== FILTER_DENY) { == FILTER_DENY) {
debugf(BABEL_DEBUG_FILTER, debugf(BABEL_DEBUG_FILTER,
"%s/%d filtered by distribute in", "%s/%d filtered by distribute in",
p->family == AF_INET ? p.family == AF_INET ?
inet_ntoa(p->u.prefix4) : inet_ntoa(p.u.prefix4) :
inet6_ntoa (p->u.prefix6), inet6_ntoa (p.u.prefix6),
p->prefixlen); p.prefixlen);
return -1; return INFINITY;
} }
} }
if (babel_ifp != NULL && babel_ifp->prefix[BABEL_FILTER_IN]) { if (babel_ifp != NULL && babel_ifp->prefix[filter]) {
if (prefix_list_apply (babel_ifp->prefix[BABEL_FILTER_IN], p) if (prefix_list_apply (babel_ifp->prefix[filter], &p)
== PREFIX_DENY) { == PREFIX_DENY) {
debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p->family == AF_INET ? p.family == AF_INET ?
inet_ntoa(p->u.prefix4) : inet_ntoa(p.u.prefix4) :
inet6_ntoa (p->u.prefix6), inet6_ntoa (p.u.prefix6),
p->prefixlen); p.prefixlen);
return -1; return INFINITY;
} }
} }
/* All interface filter check. */ /* All interface filter check. */
dist = distribute_lookup (NULL); dist = distribute_lookup (NULL);
if (dist) { if (dist) {
if (dist->list[DISTRIBUTE_IN]) { if (dist->list[distribute]) {
alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]); alist = access_list_lookup (AFI_IP6, dist->list[distribute]);
if (alist) { 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", debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p->family == AF_INET ? p.family == AF_INET ?
inet_ntoa(p->u.prefix4) : inet_ntoa(p.u.prefix4) :
inet6_ntoa (p->u.prefix6), inet6_ntoa (p.u.prefix6),
p->prefixlen); p.prefixlen);
return -1; return INFINITY;
} }
} }
} }
if (dist->prefix[DISTRIBUTE_IN]) { if (dist->prefix[distribute]) {
plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]); plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]);
if (plist) { 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", debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in",
p->family == AF_INET ? p.family == AF_INET ?
inet_ntoa(p->u.prefix4) : inet_ntoa(p.u.prefix4) :
inet6_ntoa (p->u.prefix6), inet6_ntoa (p.u.prefix6),
p->prefixlen); p.prefixlen);
return -1; return INFINITY;
} }
} }
} }
} }
return 0; 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 */
}

View File

@ -43,12 +43,7 @@ THE SOFTWARE.
#include "prefix.h" #include "prefix.h"
#include "babel_interface.h" #include "babel_interface.h"
/* filter route coming from other worlds */ int babel_filter(int output, const unsigned char *prefix, unsigned short plen,
int babel_filter_in (struct prefix *, babel_interface_nfo *); unsigned int index);
/* 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 *);
#endif /* BABELD_BABEL_FILTER_H */ #endif /* BABELD_BABEL_FILTER_H */

View File

@ -705,71 +705,30 @@ babeld_quagga_init(void)
distribute_list_delete_hook (babel_distribute_update); 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, input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen, const unsigned char *prefix, unsigned short plen,
const unsigned char *neigh, unsigned int ifindex) const unsigned char *neigh, unsigned int ifindex)
{ {
struct interface *ifp = NULL; return babel_filter(0, prefix, plen, ifindex);
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);
} }
int /* DEPRECATED: for compatibility with old babeld */ int
output_filter(const unsigned char *id, const unsigned char *prefix, output_filter(const unsigned char *id, const unsigned char *prefix,
unsigned short plen, unsigned int ifindex) unsigned short plen, unsigned int ifindex)
{ {
struct interface *ifp = NULL; return babel_filter(1, prefix, plen, ifindex);
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);
} }
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, redistribute_filter(const unsigned char *prefix, unsigned short plen,
unsigned int ifindex, int proto) unsigned int ifindex, int proto)
{ {
struct interface *ifp = NULL; return 0;
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);
} }
void void