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 "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;
/* 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)
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);
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;
p.family == AF_INET ?
inet_ntoa(p.u.prefix4) :
inet6_ntoa (p.u.prefix6),
p.prefixlen);
return INFINITY;
}
}
}
}
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 "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 */

View File

@ -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