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