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:
parent
9273035403
commit
8edf2361f9
5 changed files with 66 additions and 68 deletions
|
@ -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
|
||||||
|
|
21
nest/iface.c
21
nest/iface.c
|
@ -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;
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue