summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-11-05 21:55:18 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-11-05 21:55:18 +0100
commit716b904f4eb14349cdf66656eea0d90b040d51e5 (patch)
tree73efc901c3c66996255ec4807639b81314b6b876
parentfff79b1c1e0577f487b4fb67f79a74b054d734b6 (diff)
Filter: Make ifname attribute modifiable
Allow to change an interface associated with a route by setting ifname attribute. It will also change the route to a direct one.
-rw-r--r--doc/bird.sgml3
-rw-r--r--filter/config.Y2
-rw-r--r--filter/filter.c14
-rw-r--r--nest/iface.c7
4 files changed, 21 insertions, 5 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 7cbb4de6..46a93655 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1405,7 +1405,8 @@ clist for most purposes.
<tag><label id="rta-ifname"><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.
+ them, so <cf/ifname/ returns an empty string for such routes. Setting it
+ would also change route to a direct one (remove gateway).
<tag><label id="rta-ifindex"><m/int/ ifindex</tag>
Index of the outgoing interface. System wide index of the interface. May
diff --git a/filter/config.Y b/filter/config.Y
index 6328ba09..3b7f9004 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -792,7 +792,7 @@ static_attr:
| SCOPE { $$ = f_new_static_attr(T_ENUM_SCOPE, SA_SCOPE, 1); }
| CAST { $$ = f_new_static_attr(T_ENUM_RTC, SA_CAST, 0); }
| DEST { $$ = f_new_static_attr(T_ENUM_RTD, SA_DEST, 1); }
- | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); }
+ | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 1); }
| IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 0); }
;
diff --git a/filter/filter.c b/filter/filter.c
index 8b66b57e..02d3b960 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -1000,6 +1000,20 @@ interpret(struct f_inst *what)
rta->hostentry = NULL;
break;
+ case SA_IFNAME:
+ {
+ struct iface *ifa = if_find_by_name(v1.val.s);
+ if (!ifa)
+ runtime( "Invalid iface name" );
+
+ rta->dest = RTD_DEVICE;
+ rta->gw = IPA_NONE;
+ rta->iface = ifa;
+ rta->nexthops = NULL;
+ rta->hostentry = NULL;
+ }
+ break;
+
default:
bug("Invalid static attribute access (%x)", res.type);
}
diff --git a/nest/iface.c b/nest/iface.c
index 3dd45065..56de1f5c 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -441,7 +441,7 @@ if_find_by_name(char *name)
struct iface *i;
WALK_LIST(i, iface_list)
- if (!strcmp(i->name, name))
+ if (!strcmp(i->name, name) && !(i->flags & IF_SHUTDOWN))
return i;
return NULL;
}
@@ -451,8 +451,9 @@ if_get_by_name(char *name)
{
struct iface *i;
- if (i = if_find_by_name(name))
- return i;
+ WALK_LIST(i, iface_list)
+ if (!strcmp(i->name, name))
+ return i;
/* No active iface, create a dummy */
i = mb_allocz(if_pool, sizeof(struct iface));