/* Determine whether a given request should be forwarded. */ int request_redundant(struct interface *ifp, const unsigned char *prefix, unsigned char plen, unsigned short seqno, const unsigned char *id) { struct resend *request; request = find_request(prefix, plen, NULL); if(request == NULL || resend_expired(request)) return 0; if(memcmp(request->id, id, 8) == 0 && seqno_compare(request->seqno, seqno) > 0) return 0; if(request->ifp != NULL && request->ifp != ifp) return 0; if(request->max > 0) /* Will be resent. */ return 1; if(timeval_minus_msec(&babel_now, &request->time) < (ifp ? MIN(babel_get_if_nfo(ifp)->hello_interval, 1000) : 1000)) /* Fairly recent. */ return 1; return 0; }
int 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; 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); #ifdef HAVE_IPV6 else uchar_to_in6addr(&p.u.prefix6, prefix); #endif 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", #ifdef HAVE_IPV6 p.family == AF_INET ? inet_ntoa(p.u.prefix4) : inet6_ntoa (p.u.prefix6), #else inet_ntoa(p.u.prefix4), #endif p.prefixlen); return INFINITY; } } 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", #ifdef HAVE_IPV6 p.family == AF_INET ? inet_ntoa(p.u.prefix4) : inet6_ntoa (p.u.prefix6), #else inet_ntoa(p.u.prefix4), #endif p.prefixlen); return INFINITY; } } /* All interface filter check. */ dist = distribute_lookup (NULL); if (dist) { if (dist->list[distribute]) { alist = access_list_lookup (AFI_IP6, dist->list[distribute]); if (alist) { if (access_list_apply (alist, &p) == FILTER_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", #ifdef HAVE_IPV6 p.family == AF_INET ? inet_ntoa(p.u.prefix4) : inet6_ntoa (p.u.prefix6), #else inet_ntoa(p.u.prefix4), #endif p.prefixlen); return INFINITY; } } } if (dist->prefix[distribute]) { plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]); if (plist) { if (prefix_list_apply (plist, &p) == PREFIX_DENY) { debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute in", #ifdef HAVE_IPV6 p.family == AF_INET ? inet_ntoa(p.u.prefix4) : inet6_ntoa (p.u.prefix6), #else inet_ntoa(p.u.prefix4), #endif p.prefixlen); return INFINITY; } } } } return 0; }