Commit 8edf2361 authored by Martin Mareš's avatar Martin Mareš

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.
parent 92730354
......@@ -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
......@@ -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;
......
......@@ -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 *);
......
......@@ -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)
{
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment