summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nest/config.Y47
-rw-r--r--nest/iface.c21
-rw-r--r--nest/iface.h9
-rw-r--r--nest/rt-dev.c4
-rw-r--r--proto/rip/config.Y53
5 files changed, 66 insertions, 68 deletions
diff --git a/nest/config.Y b/nest/config.Y
index bb1328cc..0c653211 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -9,12 +9,11 @@
CF_HDR
static struct proto_config *this_proto;
+static struct iface_patt *this_ipatt;
#include "nest/rt-dev.h"
#include "nest/password.h"
-void rt_dev_add_iface(char *);
-
CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
@@ -102,18 +101,23 @@ rtable:
}
;
+/* Interface patterns */
+
+iface_patt:
+ TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; }
+ | IPA pxlen { this_ipatt->pattern = NULL; this_ipatt->prefix = $1; this_ipatt->pxlen = $2; }
+ | TEXT IPA pxlen { this_ipatt->pattern = $1; this_ipatt->prefix = $2; this_ipatt->pxlen = $3; }
+ ;
+
/* Direct device route protocol */
CF_ADDTO(proto, dev_proto '}')
dev_proto_start: proto_start DIRECT {
struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config));
- struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
this_proto = &p->c;
p->c.preference = DEF_PREF_DIRECT;
init_list(&p->iface_list);
- k->pattern = "*";
- add_tail(&p->iface_list, &k->n);
}
;
@@ -123,15 +127,26 @@ dev_proto:
| dev_proto dev_iface_list ';'
;
-dev_iface_list:
- INTERFACE TEXT {
- /* FIXME: Beware of obscure semantics. */
- init_list(&((struct rt_dev_config *) this_proto)->iface_list);
- rt_dev_add_iface($2);
+dev_iface_entry_init:
+ /* EMPTY */ {
+ struct rt_dev_config *p = (void *) this_proto;
+ struct iface_patt *k = cfg_allocz(sizeof(struct iface_patt));
+ add_tail(&p->iface_list, &k->n);
+ this_ipatt = k;
}
- | dev_iface_list ',' TEXT { rt_dev_add_iface($3); }
;
+dev_iface_entry:
+ dev_iface_entry_init iface_patt
+ ;
+
+dev_iface_list:
+ INTERFACE dev_iface_entry
+ | dev_iface_list ',' dev_iface_entry
+ ;
+
+/* Password lists */
+
password_begin:
PASSWORD TEXT {
last_password_item = cfg_alloc(sizeof (struct password_item));
@@ -162,14 +177,4 @@ password_list:
CF_CODE
-void
-rt_dev_add_iface(char *n)
-{
- struct rt_dev_config *p = (void *) this_proto;
- struct iface_patt *k = cfg_alloc(sizeof(struct iface_patt));
-
- k->pattern = cfg_strdup(n);
- add_tail(&p->iface_list, &k->n);
-}
-
CF_END
diff --git a/nest/iface.c b/nest/iface.c
index 19ed7fbd..3a5d9c6b 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -588,13 +588,19 @@ iface_patt_match(list *l, struct iface *i)
{
char *t = p->pattern;
int ok = 1;
- if (*t == '-')
+ if (t)
{
- t++;
- ok = 0;
+ if (*t == '-')
+ {
+ t++;
+ ok = 0;
+ }
+ if (!patmatch(t, i->name))
+ continue;
}
- if (patmatch(t, i->name))
- return ok ? p : NULL;
+ if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
+ continue;
+ return ok ? p : NULL;
}
return NULL;
}
@@ -608,7 +614,10 @@ iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct ifac
y = HEAD(*b);
while (x->n.next && y->n.next)
{
- if (strcmp(x->pattern, y->pattern) || comp && !comp(x, y))
+ if (strcmp(x->pattern, y->pattern) ||
+ !ipa_equal(x->prefix, y->prefix) ||
+ x->pxlen != y->pxlen ||
+ comp && !comp(x, y))
return 0;
x = (void *) x->n.next;
y = (void *) y->n.next;
diff --git a/nest/iface.h b/nest/iface.h
index 1d26e7b8..9f3a2395 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -122,13 +122,10 @@ void neigh_prune(void);
struct iface_patt {
node n;
byte *pattern; /* Interface name pattern */
+ ip_addr prefix; /* Interface prefix */
+ int pxlen;
- /* Protocol-specific data follow, but keep them like this:
- struct rip_iface_patt {
- struct iface_patt i;
- whatever you (need);
- }
- */
+ /* Protocol-specific data follow after this structure */
};
struct iface_patt *iface_patt_match(list *, struct iface *);
diff --git a/nest/rt-dev.c b/nest/rt-dev.c
index 63548fc7..c07b5de6 100644
--- a/nest/rt-dev.c
+++ b/nest/rt-dev.c
@@ -23,7 +23,9 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
{
struct rt_dev_config *P = (void *) p->cf;
- if (!iface_patt_match(&P->iface_list, ad->iface))
+ if (!EMPTY_LIST(P->iface_list) &&
+ !iface_patt_match(&P->iface_list, ad->iface))
+ /* Empty list is automagically treated as "*" */
return;
if (c & IF_CHANGE_DOWN)
{
diff --git a/proto/rip/config.Y b/proto/rip/config.Y
index 7443c44f..8590e57f 100644
--- a/proto/rip/config.Y
+++ b/proto/rip/config.Y
@@ -17,10 +17,8 @@ CF_HDR
#include "proto/rip/rip.h"
#include "nest/iface.h"
-void rip_dev_add_iface(char *);
-struct rip_patt *rip_get_iface(void);
-
#define RIP_CFG ((struct rip_proto_config *) this_proto)
+#define RIP_IPATT ((struct rip_patt *) this_ipatt)
CF_DECLS
@@ -58,7 +56,6 @@ rip_auth:
| NONE { $$=AT_NONE; }
;
-/* FIXME FIXME this corrupts memory */
rip_mode:
BROADCAST { $$=IM_BROADCAST; }
| QUIET { $$=IM_QUIET; }
@@ -67,14 +64,8 @@ rip_mode:
;
rip_iface_item:
- | METRIC expr {
- struct rip_patt *k = rip_get_iface();
- k->metric = $2;
- }
- | MODE rip_mode {
- struct rip_patt *k = rip_get_iface();
- k->mode |= $2;
- }
+ | METRIC expr { RIP_IPATT->metric = $2; }
+ | MODE rip_mode { RIP_IPATT->mode |= $2; }
;
rip_iface_opts:
@@ -82,32 +73,26 @@ rip_iface_opts:
| rip_iface_opts rip_iface_item ';'
;
-rip_iface_empty: /* EMPTY */ | rip_iface_opts '}' ;
+rip_iface_opt_list: /* EMPTY */ | rip_iface_opts '}' ;
-rip_iface_list:
- INTERFACE TEXT rip_iface_empty { rip_dev_add_iface($2); }
- | dev_iface_list ',' TEXT rip_iface_empty { rip_dev_add_iface($3); }
+rip_iface_init:
+ /* EMPTY */ {
+ struct rip_patt *k = cfg_allocz(sizeof(struct rip_patt));
+ k->metric = 1;
+ add_tail(&RIP_CFG->iface_list, &k->i.n);
+ this_ipatt = &k->i;
+ }
;
-CF_CODE
+rip_iface:
+ rip_iface_init iface_patt rip_iface_opt_list
+ ;
-void
-rip_dev_add_iface(char *n)
-{
- struct rip_patt *k = cfg_allocz(sizeof(struct rip_patt));
- k->metric = 1;
- k->i.pattern = cfg_strdup(n);
- add_tail(&RIP_CFG->iface_list, &k->i.n);
-}
-
-struct rip_patt *
-rip_get_iface(void)
-{
- struct rip_patt *k = TAIL(RIP_CFG->iface_list);
- if (!k)
- cf_error( "This cannot happen" );
- return k;
-}
+rip_iface_list:
+ INTERFACE rip_iface
+ | rip_iface_list ',' rip_iface
+ ;
+CF_CODE
CF_END