Commit a5fc5958 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

Rewrites static attribute filter code and adds ifname/ifindex attributes.

Thanks to Sergey Popovich for the original ifname/ifindex patch.
parent 4df2019e
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -928,10 +928,16 @@ incompatible with each other (that is to prevent you from shooting in the foot).
	  from 0 to 255. Literals of this type are written like IPv4
	  addresses.

	<tag/string/ This is a string of characters. There are no ways to modify strings in
	  filters. You can pass them between functions, assign them to variables of type <cf/string/, print
	  such variables, but you can't concatenate two strings. String literals
	  are written as <cf/"This is a string constant"/.
	<tag/string/ This is a string of characters. There are no ways
	  to modify strings in filters. You can pass them between
	  functions, assign them to variables of type <cf/string/,
	  print such variables, use standard string comparison
	  operations (e.g. <cf/=, !=, &lt;, &gt;, &lt;=, &gt;=/), but
	  you can't concatenate two strings. String literals are
	  written as <cf/"This is a string constant"/. Additionaly
	  matching <cf/&tilde;/ operator could be used to match a
	  string value against a shell pattern (represented also as a
	  string).

	<tag/ip/ This type can hold a single IP address. Depending on the compile-time configuration of BIRD you are using, it
	  is either an IPv4 or IPv6 address. IP addresses are written in the standard notation (<cf/10.20.30.40/ or <cf/fec0:3:4::1/). You can apply special operator <cf>.mask(<M>num</M>)</cf>
@@ -1194,7 +1200,6 @@ undefined value is regarded as empty clist for most purposes.
	what protocol has told me about this route. Possible values: <cf/RTS_DUMMY/, <cf/RTS_STATIC/, <cf/RTS_INHERIT/, <cf/RTS_DEVICE/, <cf/RTS_STATIC_DEVICE/, <cf/RTS_REDIRECT/, <cf/RTS_RIP/, <cf/RTS_OSPF/, <cf/RTS_OSPF_IA/, <cf/RTS_OSPF_EXT1/, <cf/RTS_OSPF_EXT2/, <cf/RTS_BGP/, <cf/RTS_PIPE/.

	<tag><m/enum/ cast</tag>

	Route type (Currently <cf/RTC_UNICAST/ for normal routes,
	<cf/RTC_BROADCAST/, <cf/RTC_MULTICAST/, <cf/RTC_ANYCAST/ will
	be used in the future for broadcast, multicast and anycast
@@ -1212,6 +1217,19 @@ undefined value is regarded as empty clist for most purposes.
	only to <cf/RTD_BLACKHOLE/, <cf/RTD_UNREACHABLE/ or
	<cf/RTD_PROHIBIT/.

	<tag><m/string/ ifname</tag>
	Name of the outgoing interface. Sink routes (like blackhole,
	unreachable or prohibit) and multipath routes have no interface
	associated with them, so <cf/ifname/ returns an empty string for
	such routes. Read-only.

	<tag><m/int/ ifindex</tag>
	Index of the outgoing interface. System wide index of the
	interface. May be used for interface matching, however
	indexes might change on interface creation/removal. Zero is
	returned for routes with undefined outgoing
	interfaces. Read-only.

	<tag><m/int/ igp_metric</tag>
	The optional attribute that can be used to specify a distance
	to the network for routes that do not have a native protocol
+12 −9
Original line number Diff line number Diff line
@@ -261,7 +261,8 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
	SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST,
	IF, THEN, ELSE, CASE,
	TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
	FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, PREFERENCE,
	FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, IFNAME, IFINDEX,
	PREFERENCE,
	LEN,
	DEFINED,
	ADD, DELETE, CONTAINS, RESET,
@@ -680,14 +681,16 @@ symbol:
   }

static_attr:
   FROM    { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = OFFSETOF(struct rta, from);   $$->a1.i = 1; }
 | GW      { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = OFFSETOF(struct rta, gw);     $$->a1.i = 1; }
 | NET     { $$ = f_new_inst(); $$->aux = T_PREFIX;     $$->a2.i = 0x12345678; /* This is actually ok - T_PREFIX is special-cased. */ }
 | PROTO   { $$ = f_new_inst(); $$->aux = T_STRING;     $$->a2.i = 0x12345678; /* T_STRING is also special-cased. */ }
 | SOURCE  { $$ = f_new_inst(); $$->aux = T_ENUM_RTS;   $$->a2.i = OFFSETOF(struct rta, source); }
 | SCOPE   { $$ = f_new_inst(); $$->aux = T_ENUM_SCOPE; $$->a2.i = OFFSETOF(struct rta, scope);  $$->a1.i = 1; }
 | CAST    { $$ = f_new_inst(); $$->aux = T_ENUM_RTC;   $$->a2.i = OFFSETOF(struct rta, cast); }
 | DEST    { $$ = f_new_inst(); $$->aux = T_ENUM_RTD;   $$->a2.i = OFFSETOF(struct rta, dest);   $$->a1.i = 1; }
   FROM    { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = SA_FROM;	$$->a1.i = 1; }
 | GW      { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = SA_GW;	$$->a1.i = 1; }
 | NET     { $$ = f_new_inst(); $$->aux = T_PREFIX;     $$->a2.i = SA_NET; }
 | PROTO   { $$ = f_new_inst(); $$->aux = T_STRING;     $$->a2.i = SA_PROTO; }
 | SOURCE  { $$ = f_new_inst(); $$->aux = T_ENUM_RTS;   $$->a2.i = SA_SOURCE; }
 | SCOPE   { $$ = f_new_inst(); $$->aux = T_ENUM_SCOPE; $$->a2.i = SA_SCOPE;	$$->a1.i = 1; }
 | CAST    { $$ = f_new_inst(); $$->aux = T_ENUM_RTC;   $$->a2.i = SA_CAST; }
 | DEST    { $$ = f_new_inst(); $$->aux = T_ENUM_RTD;   $$->a2.i = SA_DEST;	$$->a1.i = 1; }
 | IFNAME  { $$ = f_new_inst(); $$->aux = T_STRING;     $$->a2.i = SA_IFNAME; }
 | IFINDEX { $$ = f_new_inst(); $$->aux = T_INT;        $$->a2.i = SA_IFINDEX; }
 ;

term:
+27 −30
Original line number Diff line number Diff line
@@ -824,24 +824,23 @@ interpret(struct f_inst *what)
      ACCESS_RTE;
      struct rta *rta = (*f_rte)->attrs;
      res.type = what->aux;
      switch(res.type) {
      case T_IP:
	res.val.px.ip = * (ip_addr *) ((char *) rta + what->a2.i);
	break;
      case T_ENUM:
	res.val.i = * ((char *) rta + what->a2.i);
	break;
      case T_STRING:	/* Warning: this is a special case for proto attribute */
	res.val.s = rta->proto->name;
	break;
      case T_PREFIX:	/* Warning: this works only for prefix of network */

      switch (what->a2.i)
      {
	  res.val.px.ip = (*f_rte)->net->n.prefix;
	  res.val.px.len = (*f_rte)->net->n.pxlen;
	  break;
	}
      case SA_FROM:	res.val.px.ip = rta->from; break;
      case SA_GW:	res.val.px.ip = rta->gw; break;
      case SA_NET:	res.val.px.ip = (*f_rte)->net->n.prefix;
			res.val.px.len = (*f_rte)->net->n.pxlen; break;
      case SA_PROTO:	res.val.s = rta->proto->name; break;
      case SA_SOURCE:	res.val.i = rta->source; break;
      case SA_SCOPE:	res.val.i = rta->scope; break;
      case SA_CAST:	res.val.i = rta->cast; break;
      case SA_DEST:	res.val.i = rta->dest; break;
      case SA_IFNAME:	res.val.s = rta->iface ? rta->iface->name : ""; break;
      case SA_IFINDEX:	res.val.i = rta->iface ? rta->iface->index : 0; break;

      default:
	bug( "Invalid type for rta access (%x)", res.type );
	bug("Invalid static attribute access (%x)", res.type);
      }
    }
    break;
@@ -850,19 +849,20 @@ interpret(struct f_inst *what)
    ONEARG;
    if (what->aux != v1.type)
      runtime( "Attempt to set static attribute to incompatible type" );

    f_rta_cow();
    {
      struct rta *rta = (*f_rte)->attrs;
      ip_addr ip;

      switch (what->aux) {

      case T_IP:
	ip = v1.val.px.ip;
      switch (what->a2.i)
      {
      case SA_FROM:
	rta->from = v1.val.px.ip;
	break;

	/* "gw" attribute? */
	if (what->a2.i == OFFSETOF(struct rta, gw))
      case SA_GW:
	{
	  ip_addr ip = v1.val.px.ip;
	  neighbor *n = neigh_find(rta->proto, &ip, 0);
	  if (!n || (n->scope == SCOPE_HOST))
	    runtime( "Invalid gw address" );
@@ -873,16 +873,13 @@ interpret(struct f_inst *what)
	  rta->nexthops = NULL;
	  rta->hostentry = NULL;
	}
	else /* or "from" attribute? */
	  rta->from = ip;

	break;

      case T_ENUM_SCOPE:
      case SA_SCOPE:
	rta->scope = v1.val.i;
	break;

      case T_ENUM_RTD:
      case SA_DEST:
	i = v1.val.i;
	if ((i != RTD_BLACKHOLE) && (i != RTD_UNREACHABLE) && (i != RTD_PROHIBIT))
	  runtime( "Destination can be changed only to blackhole, unreachable or prohibit" );
@@ -895,7 +892,7 @@ interpret(struct f_inst *what)
	break;

      default:
	bug( "Unknown type in set of static attribute" );
	bug("Invalid static attribute access (%x)", res.type);
      }
    }
    break;
+13 −0
Original line number Diff line number Diff line
@@ -172,6 +172,19 @@ void val_print(struct f_val v);
#define T_SET 0x80
#define T_PREFIX_SET 0x81


#define SA_FROM		 1    
#define SA_GW		 2      
#define SA_NET		 3     
#define SA_PROTO	 4   
#define SA_SOURCE	 5  
#define SA_SCOPE	 6   
#define SA_CAST    	 7
#define SA_DEST    	 8
#define SA_IFNAME  	 9
#define SA_IFINDEX    	10


struct f_tree {
  struct f_tree *left, *right;
  struct f_val from, to;