diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/config.Y | 6 | ||||
-rw-r--r-- | nest/iface.c | 25 | ||||
-rw-r--r-- | nest/iface.h | 12 | ||||
-rw-r--r-- | nest/rt-dev.c | 2 |
4 files changed, 32 insertions, 13 deletions
diff --git a/nest/config.Y b/nest/config.Y index 5a89505..7bb0525 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -181,8 +181,8 @@ iface_patt_node_init: iface_patt_node_body: TEXT { this_ipn->pattern = $1; this_ipn->prefix = IPA_NONE; this_ipn->pxlen = 0; } - | prefix { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; } - | TEXT prefix { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; } + | prefix_or_ipa { this_ipn->pattern = NULL; this_ipn->prefix = $1.addr; this_ipn->pxlen = $1.len; } + | TEXT prefix_or_ipa { this_ipn->pattern = $1; this_ipn->prefix = $2.addr; this_ipn->pxlen = $2.len; } ; iface_negate: @@ -472,7 +472,7 @@ CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protoc { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ; CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]]) -CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging via BIRD logs]]) +CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]]) { proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ; CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]]) diff --git a/nest/iface.c b/nest/iface.c index 82dead3..4d0cf04 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -566,8 +566,8 @@ if_init(void) * Interface Pattern Lists */ -static int -iface_patt_match(struct iface_patt *ifp, struct iface *i) +int +iface_patt_match(struct iface_patt *ifp, struct iface *i, struct ifa *a) { struct iface_patt_node *p; @@ -588,23 +588,32 @@ iface_patt_match(struct iface_patt *ifp, struct iface *i) continue; } - if (p->pxlen) - if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen)) - continue; + if (p->pxlen == 0) + return pos; + + if (!a) + continue; + + if (ipa_in_net(a->ip, p->prefix, p->pxlen)) + return pos; - return pos; + if ((a->flags & IA_UNNUMBERED) && + ipa_in_net(a->opposite, p->prefix, p->pxlen)) + return pos; + + continue; } return 0; } struct iface_patt * -iface_patt_find(list *l, struct iface *i) +iface_patt_find(list *l, struct iface *i, struct ifa *a) { struct iface_patt *p; WALK_LIST(p, *l) - if (iface_patt_match(p, i)) + if (iface_patt_match(p, i, a)) return p; return NULL; diff --git a/nest/iface.h b/nest/iface.h index 8fc2567..c116db8 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -83,6 +83,15 @@ struct iface *if_find_by_index(unsigned); struct iface *if_find_by_name(char *); void ifa_recalc_all_primary_addresses(void); +static inline int +ifa_match_addr(struct ifa *ifa, ip_addr addr) +{ + if (ifa->flags & IA_UNNUMBERED) + return ipa_equal(addr, ifa->opposite); + else + return ipa_in_net(addr, ifa->prefix, ifa->pxlen); +} + /* The Neighbor Cache */ typedef struct neighbor { @@ -135,7 +144,8 @@ struct iface_patt { /* Protocol-specific data follow after this structure */ }; -struct iface_patt *iface_patt_find(list *, struct iface *); +int iface_patt_match(struct iface_patt *ifp, struct iface *i, struct ifa *a); +struct iface_patt *iface_patt_find(list *l, struct iface *i, struct ifa *a); int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *)); #endif diff --git a/nest/rt-dev.c b/nest/rt-dev.c index bb8eb8e..239bd26 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -30,7 +30,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad) struct rt_dev_config *P = (void *) p->cf; if (!EMPTY_LIST(P->iface_list) && - !iface_patt_find(&P->iface_list, ad->iface)) + !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr)) /* Empty list is automagically treated as "*" */ return; |