Cleaned up handling of interface patterns:

o  Parsing of interface patterns moved to generic code,
      introduced this_ipatt which works similarly to this_iface.
   o  Interface patterns now support selection by both interface
      names and primary IP addresses.
   o  Proto `direct' updated.
   o  RIP updated as well, it also seems the memory corruption
      bug there is gone.
This commit is contained in:
Martin Mares 1999-08-03 19:30:49 +00:00
parent 9273035403
commit 8edf2361f9
5 changed files with 66 additions and 68 deletions

View file

@ -9,12 +9,11 @@
CF_HDR CF_HDR
static struct proto_config *this_proto; static struct proto_config *this_proto;
static struct iface_patt *this_ipatt;
#include "nest/rt-dev.h" #include "nest/rt-dev.h"
#include "nest/password.h" #include "nest/password.h"
void rt_dev_add_iface(char *);
CF_DECLS CF_DECLS
CF_KEYWORDS(ROUTER, ID, PROTOCOL, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT) 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 */ /* Direct device route protocol */
CF_ADDTO(proto, dev_proto '}') CF_ADDTO(proto, dev_proto '}')
dev_proto_start: proto_start DIRECT { dev_proto_start: proto_start DIRECT {
struct rt_dev_config *p = proto_config_new(&proto_device, sizeof(struct rt_dev_config)); 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; this_proto = &p->c;
p->c.preference = DEF_PREF_DIRECT; p->c.preference = DEF_PREF_DIRECT;
init_list(&p->iface_list); 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_proto dev_iface_list ';'
; ;
dev_iface_list: dev_iface_entry_init:
INTERFACE TEXT { /* EMPTY */ {
/* FIXME: Beware of obscure semantics. */ struct rt_dev_config *p = (void *) this_proto;
init_list(&((struct rt_dev_config *) this_proto)->iface_list); struct iface_patt *k = cfg_allocz(sizeof(struct iface_patt));
rt_dev_add_iface($2); 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_begin:
PASSWORD TEXT { PASSWORD TEXT {
last_password_item = cfg_alloc(sizeof (struct password_item)); last_password_item = cfg_alloc(sizeof (struct password_item));
@ -162,14 +177,4 @@ password_list:
CF_CODE 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 CF_END

View file

@ -588,13 +588,19 @@ iface_patt_match(list *l, struct iface *i)
{ {
char *t = p->pattern; char *t = p->pattern;
int ok = 1; int ok = 1;
if (*t == '-') if (t)
{ {
t++; if (*t == '-')
ok = 0; {
t++;
ok = 0;
}
if (!patmatch(t, i->name))
continue;
} }
if (patmatch(t, i->name)) if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
return ok ? p : NULL; continue;
return ok ? p : NULL;
} }
return NULL; return NULL;
} }
@ -608,7 +614,10 @@ iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct ifac
y = HEAD(*b); y = HEAD(*b);
while (x->n.next && y->n.next) 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; return 0;
x = (void *) x->n.next; x = (void *) x->n.next;
y = (void *) y->n.next; y = (void *) y->n.next;

View file

@ -122,13 +122,10 @@ void neigh_prune(void);
struct iface_patt { struct iface_patt {
node n; node n;
byte *pattern; /* Interface name pattern */ byte *pattern; /* Interface name pattern */
ip_addr prefix; /* Interface prefix */
int pxlen;
/* Protocol-specific data follow, but keep them like this: /* Protocol-specific data follow after this structure */
struct rip_iface_patt {
struct iface_patt i;
whatever you (need);
}
*/
}; };
struct iface_patt *iface_patt_match(list *, struct iface *); struct iface_patt *iface_patt_match(list *, struct iface *);

View file

@ -23,7 +23,9 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
{ {
struct rt_dev_config *P = (void *) p->cf; 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; return;
if (c & IF_CHANGE_DOWN) if (c & IF_CHANGE_DOWN)
{ {

View file

@ -17,10 +17,8 @@ CF_HDR
#include "proto/rip/rip.h" #include "proto/rip/rip.h"
#include "nest/iface.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_CFG ((struct rip_proto_config *) this_proto)
#define RIP_IPATT ((struct rip_patt *) this_ipatt)
CF_DECLS CF_DECLS
@ -58,7 +56,6 @@ rip_auth:
| NONE { $$=AT_NONE; } | NONE { $$=AT_NONE; }
; ;
/* FIXME FIXME this corrupts memory */
rip_mode: rip_mode:
BROADCAST { $$=IM_BROADCAST; } BROADCAST { $$=IM_BROADCAST; }
| QUIET { $$=IM_QUIET; } | QUIET { $$=IM_QUIET; }
@ -67,14 +64,8 @@ rip_mode:
; ;
rip_iface_item: rip_iface_item:
| METRIC expr { | METRIC expr { RIP_IPATT->metric = $2; }
struct rip_patt *k = rip_get_iface(); | MODE rip_mode { RIP_IPATT->mode |= $2; }
k->metric = $2;
}
| MODE rip_mode {
struct rip_patt *k = rip_get_iface();
k->mode |= $2;
}
; ;
rip_iface_opts: rip_iface_opts:
@ -82,32 +73,26 @@ rip_iface_opts:
| rip_iface_opts rip_iface_item ';' | rip_iface_opts rip_iface_item ';'
; ;
rip_iface_empty: /* EMPTY */ | rip_iface_opts '}' ; rip_iface_opt_list: /* EMPTY */ | rip_iface_opts '}' ;
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;
}
;
rip_iface:
rip_iface_init iface_patt rip_iface_opt_list
;
rip_iface_list: rip_iface_list:
INTERFACE TEXT rip_iface_empty { rip_dev_add_iface($2); } INTERFACE rip_iface
| dev_iface_list ',' TEXT rip_iface_empty { rip_dev_add_iface($3); } | rip_iface_list ',' rip_iface
; ;
CF_CODE CF_CODE
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;
}
CF_END CF_END