On Sat, Nov 03, 2018 at 09:51:33PM +0100, Michael Schwartzkopff wrote:
> hi,
> 
> 
> I want to export a route learned from BGP to the kernel. but I want to
> modify the route while exporting because I want to use a VTI instead of
> the next hop route.
> 
> 
> So instead of 192.168.0.0/24  via 10.0.0.1 I want to export
> 
> 192.168.0.0/24 dev vti0 to the kernel.
> 
> 
> Is this possible with bird? If yes, how can I acchieve this?

Hi

Attached patch (one for BIRD 1.6, one for BIRD 2.0) will allow
that by making route attribute ifname read/write. So it could
be done by

  ifname = "vti0";

in filters.

Compared to setting gateway it may be slower if there are plenty
of interfaces as the lookup is not cached.

-- 
Elen sila lumenn' omentielvo

Ondrej 'Santiago' Zajicek (email: [email protected])
OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net)
"To err is human -- to blame it on a computer is even more so."
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));
diff --git a/filter/config.Y b/filter/config.Y
index 93ad8d8b..d865d11f 100644
--- a/filter/config.Y
+++ b/filter/config.Y
@@ -852,7 +852,7 @@ static_attr:
  | SOURCE  { $$ = f_new_static_attr(T_ENUM_RTS,   SA_SOURCE,	0); }
  | SCOPE   { $$ = f_new_static_attr(T_ENUM_SCOPE, SA_SCOPE,	1); }
  | 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 edf54ec0..f308e7fd 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -1002,6 +1002,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_UNICAST;
+	  rta->nh.gw = IPA_NONE;
+	  rta->nh.iface = ifa;
+	  rta->nh.next = 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 9462b634..23a82ac5 100644
--- a/nest/iface.c
+++ b/nest/iface.c
@@ -449,7 +449,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;
 }
@@ -459,8 +459,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));

Reply via email to