Commit 20e94fb8 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

A change in OSPF and RIP interface patterns.

Allows to add more interface patterns to one common 'options'
section like:

interface "eth3", "eth4" { options common to eth3 and eth4 };

Also removes undocumented and unnecessary ability to specify
more interface patterns with different 'options' sections:

interface "eth3" { options ... }, "eth4" { options ... };
parent 10ab65a8
Loading
Loading
Loading
Loading
+36 −16
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ CF_DEFINES

static struct proto_config *this_proto;
static struct iface_patt *this_ipatt;
static struct iface_patt_node *this_ipn;
static list *this_p_list;
static struct password_item *this_p_item;
static int password_id;
@@ -146,12 +147,36 @@ debug_default:

/* Interface patterns */

iface_patt:
   TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; }
 | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; }
 | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; }
iface_patt_node_init:
   /* EMPTY */ {
     struct iface_patt_node *ipn = cfg_allocz(sizeof(struct iface_patt_node));
     add_tail(&this_ipatt->ipn_list, NODE ipn);
     this_ipn = ipn;
   }
 ;

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; }
 ;

iface_negate:
       { this_ipn->positive = 1; }
 | '-' { this_ipn->positive = 0; }
 ;

iface_patt_node:
   iface_patt_node_init iface_negate iface_patt_node_body 
 ;


iface_patt_list:
   iface_patt_node
 | iface_patt_list ',' iface_patt_node
 ;


/* Direct device route protocol */

CF_ADDTO(proto, dev_proto '}')
@@ -167,25 +192,20 @@ dev_proto_start: proto_start DIRECT {
dev_proto:
   dev_proto_start proto_name '{'
 | dev_proto proto_item ';'
 | dev_proto dev_iface_list ';'
 | dev_proto dev_iface_patt ';'
 ;

dev_iface_entry_init:
dev_iface_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;
     this_ipatt = cfg_allocz(sizeof(struct iface_patt));
     add_tail(&p->iface_list, NODE this_ipatt);
     init_list(&this_ipatt->ipn_list);
   }
 ;

dev_iface_entry:
   dev_iface_entry_init iface_patt
 ;

dev_iface_list:
   INTERFACE dev_iface_entry
 | dev_iface_list ',' dev_iface_entry
dev_iface_patt:
   INTERFACE dev_iface_init iface_patt_list
 ;

/* Debug flags */
+51 −16
Original line number Diff line number Diff line
@@ -543,32 +543,72 @@ if_init(void)
 *	Interface Pattern Lists
 */

struct iface_patt *
iface_patt_match(list *l, struct iface *i)
static int
iface_patt_match(struct iface_patt *ifp, struct iface *i)
{
  struct iface_patt *p;
  struct iface_patt_node *p;

  WALK_LIST(p, *l)
  WALK_LIST(p, ifp->ipn_list)
    {
      char *t = p->pattern;
      int ok = 1;
      int pos = p->positive;

      if (t)
	{
	  if (*t == '-')
	    {
	      t++;
	      ok = 0;
	      pos = !pos;
	    }

	  if (!patmatch(t, i->name))
	    continue;
	}

      if (p->pxlen)
	if (!i->addr || !ipa_in_net(i->addr->ip, p->prefix, p->pxlen))
	  continue;
      return ok ? p : NULL;

      return pos;
    }

  return 0;
}

struct iface_patt *
iface_patt_find(list *l, struct iface *i)
{
  struct iface_patt *p;

  WALK_LIST(p, *l)
    if (iface_patt_match(p, i))
      return p;

  return NULL;
}

static int
iface_plists_equal(struct iface_patt *pa, struct iface_patt *pb)
{
  struct iface_patt_node *x, *y;

  x = HEAD(pa->ipn_list);
  y = HEAD(pb->ipn_list);
  while (x->n.next && y->n.next)
    {
      if ((x->positive != y->positive) ||
	  (!x->pattern && y->pattern) ||	/* This nasty lines where written by me... :-( Feela */
	  (!y->pattern && x->pattern) ||
	  ((x->pattern != y->pattern) && strcmp(x->pattern, y->pattern)) ||
	  !ipa_equal(x->prefix, y->prefix) ||
	  (x->pxlen != y->pxlen))
	return 0;
      x = (void *) x->n.next;
      y = (void *) y->n.next;
    }
  return (!x->n.next && !y->n.next);
}

int
iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct iface_patt *))
{
@@ -578,13 +618,8 @@ 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 ((!x->pattern && y->pattern) ||	/* This nasty lines where written by me... :-( Feela */
          (!y->pattern && x->pattern) ||
          (!(x->pattern==y->pattern) &&
          strcmp(x->pattern, y->pattern)) ||
	  !ipa_equal(x->prefix, y->prefix) ||
	  x->pxlen != y->pxlen ||
	  comp && !comp(x, y))
      if (!iface_plists_equal(x, y) ||
	  (comp && !comp(x, y)))
	return 0;
      x = (void *) x->n.next;
      y = (void *) y->n.next;
+10 −4
Original line number Diff line number Diff line
@@ -116,16 +116,22 @@ void neigh_init(struct pool *);
 *	Interface Pattern Lists
 */

struct iface_patt {
struct iface_patt_node {
  node n;
  byte *pattern;			/* Interface name pattern */
  ip_addr prefix;			/* Interface prefix */
  int positive;
  byte *pattern;
  ip_addr prefix;
  int pxlen;
};

struct iface_patt {
  node n;
  list ipn_list;			/* A list of struct iface_patt_node */

  /* Protocol-specific data follow after this structure */
};

struct iface_patt *iface_patt_match(list *, struct iface *);
struct iface_patt *iface_patt_find(list *, struct iface *);
int iface_patts_equal(list *, list *, int (*)(struct iface_patt *, struct iface_patt *));

#endif
+1 −1
Original line number Diff line number Diff line
@@ -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_match(&P->iface_list, ad->iface))
      !iface_patt_find(&P->iface_list, ad->iface))
    /* Empty list is automagically treated as "*" */
    return;
  if (c & IF_CHANGE_DOWN)
+6 −9
Original line number Diff line number Diff line
@@ -13,9 +13,9 @@ CF_HDR
CF_DEFINES

#define OSPF_CFG ((struct ospf_config *) this_proto)
static struct ospf_area_config *this_area;
static struct iface_patt *this_ipatt;
#define OSPF_PATT ((struct ospf_iface_patt *) this_ipatt)

static struct ospf_area_config *this_area;
static struct nbma_node *this_nbma;
static struct area_net_config *this_pref;

@@ -90,7 +90,7 @@ ospf_area_item:
   STUB COST expr { this_area->stub = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
 | STUB bool {if($2) { if(!this_area->stub) this_area->stub=DEFAULT_STUB_COST;}else{ this_area->stub=0;}}
 | NETWORKS '{' pref_list '}'
 | INTERFACE ospf_iface_list
 | INTERFACE ospf_iface
 | ospf_vlink
 ;

@@ -122,6 +122,7 @@ ospf_vlink_start: VIRTUAL LINK idval
  if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
  add_tail(&this_area->vlink_list, NODE this_ipatt);
  init_list(&this_ipatt->ipn_list);
  OSPF_PATT->vid = $3;
  OSPF_PATT->cost = COST_D;
  OSPF_PATT->helloint = HELLOINT_D;
@@ -222,6 +223,7 @@ ospf_iface_start:
 {
  this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
  add_tail(&this_area->patt_list, NODE this_ipatt);
  init_list(&this_ipatt->ipn_list);
  OSPF_PATT->cost = COST_D;
  OSPF_PATT->helloint = HELLOINT_D;
  OSPF_PATT->pollint = POLLINT_D;
@@ -251,12 +253,7 @@ ospf_iface_opt_list:
 ;

ospf_iface:
  ospf_iface_start iface_patt ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
 ;

ospf_iface_list:
   ospf_iface
 | ospf_iface_list ',' ospf_iface
  ospf_iface_start iface_patt_list ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
 ;

opttext:
Loading