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.
diff --git a/babeld/babel_filter.c b/babeld/babel_filter.c
index 5c93d13..191a9f7 100644
--- a/babeld/babel_filter.c
+++ b/babeld/babel_filter.c
@@ -45,144 +45,80 @@
#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 */
-}
diff --git a/babeld/babel_filter.h b/babeld/babel_filter.h
index 52b72f6..73722e0 100644
--- a/babeld/babel_filter.h
+++ b/babeld/babel_filter.h
@@ -43,12 +43,7 @@
#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 da07434..14990a6 100644
--- a/babeld/babeld.c
+++ b/babeld/babeld.c
@@ -705,71 +705,30 @@
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