mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-30 22:25:41 +00:00
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:
parent
578ce371d1
commit
31e2a19fd2
@ -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 */
|
|
||||||
}
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user