Re: interfaces and priorities for relayd routers

2015-06-24 Thread Stuart Henderson
On 2015/06/22 10:20, Reyk Floeter wrote:
 The router code was mostly done for something like link balancing,
 you have two or more uplink gateways and want to select the route
 based on their availability.

I've never really understood how this is meant to work, in real life
the usual case is where the gateway is up but the attached circuit is
down so there's no routing beyond it, am I missing a non-obvious way
where relayd can check for this?



Re: interfaces and priorities for relayd routers

2015-06-24 Thread David Gwynne

 On 24 Jun 2015, at 10:38 am, David Gwynne da...@gwynne.id.au wrote:
 
 
 On 22 Jun 2015, at 18:20, Reyk Floeter r...@openbsd.org wrote:
 
 Hi,
 
 On Thu, May 14, 2015 at 09:44:22PM +1000, David Gwynne wrote:
 i want relayd to check teh availability of some services and inject
 routes when the service is available. if it is available, i want
 to advertise the routes using ospfd, but i also want the local
 machine to be able to contact the service even if it isnt the carp
 master.
 
 to do that i need to inject the routes twice, once on my real
 interface and again on my carp interfaces. the route on the real
 interface needs to be a higher priority than the carp route.
 
 this shuffles relayd to accomodate this.
 
 it mostly adds stuff to the route statements in routers, but i also
 take priorities away from hosts in tables so i can specify them on
 routes.
 
 
 I'm generally ok with extending the use cases of router, but it seems
 that you're replacing one narrow use case with another one.
 
 The router code was mostly done for something like link balancing,
 you have two or more uplink gateways and want to select the route
 based on their availability.  I'm afraid that moving the priority from
 hosts to routes, and changing the semantics, breaks this original use
 case somehow.
 
  table gateways {
  $gw1 ip ttl 1 priority 8,
  $gw2 ip ttl 1 priority 52
  }
  router uplinks {
  route 0.0.0.0/0
  forward to gateways check icmp
  }
 
 But maybe even multiple routes for something internal:
 
  router srvlan {
  route 10.10.0.0/16
  route 10.40.0.0/16
  forward to srvgateways check icmp
  }
 
 Sometimes different gateways can even be connected via the same interface!
 (e.g. with an intermediate switch and a single cable to the OpenBSD box)
 
 this is an example config:
 
 rns_nogal=130.102.71.227
 rns_neem=130.102.71.229
 
 table rns { $rns_nogal ip ttl 1, $rns_neem ip ttl 1 } 
 
 router rns { 
 route 130.102.71.160/31 interface vlan888 priority 8
 route 130.102.71.160/31 interface carp40888 priority 16
 forward to rns check icmp 
 }
 
 
 I'm wondering, how would you translate my examples above?
 
 hrm.
 
 we could allow priorities on both the route statements and on the host 
 statements in the table and combine them somehow when the actual routes are 
 inserted into the kernel. or allow a relative priorities to be specified with 
 a + or - prefix. eg:
 
 table gateways {
  $gw1 priority +1,
  $gw2
 }
 
 router uplinks {
  route 0.0.0.0/0 priority 16
  forward to gateways check icmp
 }
 
 if you add increase the priority of a route, should its numeric value get 
 higher or lower?
 
 anyway, allowing priorities in both tables and router blocks would cover both 
 use cases i think.

another option could be

table gw1 { $gw1 }
table gw2 { $gw2 }

router hipri-uplink {
  route 0.0.0.0/0 priority 8
  forward to gw1 check icmp
}

router lopri-uplink {
  route 0.0.0.0/0 priority 52
  forward to gw2 check icmp
}

dlg

 
 
 redirect dns {
 listen on 130.102.71.160 tcp port 53
 listen on 130.102.71.160 udp port 53
 listen on 130.102.71.161 tcp port 53
 listen on 130.102.71.161 udp port 53
 
 match pftag rns
 forward to rns port 53 check icmp
 }
 
 i wish redirects took a prefix. maybe thats a diff for another day.
 
 
 Would make sense.
 
 anyway, here's the diff.
 
 thoughts? tweaks? ok?
 
 
 In addition to my general concern, see comments inline below.
 
 Reyk
 
 Index: parse.y
 ===
 RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
 retrieving revision 1.204
 diff -u -p -r1.204 parse.y
 --- parse.y 2 May 2015 13:15:24 -   1.204
 +++ parse.y 14 May 2015 11:30:28 -
 @@ -173,6 +173,7 @@ typedef struct {
 %token  ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL 
 RTABLE
 %token  MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
 PASSWORD ECDH
 %token  EDH CURVE
 +%token NONE LOCAL CONNECTED STATIC OSPF ISIS RIP BGP DEFAULT
 
 A lot of keywords for basically an enum.  See below.
 
 %token  v.string  STRING
 %token  v.number  NUMBER
 %type   v.string  hostname interface table value optstring
 @@ -182,6 +183,7 @@ typedef struct {
 %type   v.number  redirect_proto relay_proto match
 %type   v.number  action ruleaf key_option
 %type   v.number  tlsdhparams tlsecdhcurve
 +%type  v.number  rtprio
 %type   v.portport
 %type   v.hosthost
 %type   v.addraddress
 @@ -1864,8 +1866,8 @@ router: ROUTER STRING {
 router = rt;
 
 tableport = -1;
 -   } '{' optnl routeopts_l '}' {
 -   if (!router-rt_conf.nroutes) {
 

Re: interfaces and priorities for relayd routers

2015-06-24 Thread Reyk Floeter
On Wed, Jun 24, 2015 at 10:35:26AM +0100, Stuart Henderson wrote:
 On 2015/06/22 10:20, Reyk Floeter wrote:
  The router code was mostly done for something like link balancing,
  you have two or more uplink gateways and want to select the route
  based on their availability.
 
 I've never really understood how this is meant to work, in real life
 the usual case is where the gateway is up but the attached circuit is
 down so there's no routing beyond it, am I missing a non-obvious way
 where relayd can check for this?
 

What do you mean with real life?  Is mine not real?  That reminds me
of fobser's signature: I'm not entirely sure you are real. ;-)

So it is basically a cheap alternative for sites that want uplink
redundancy without speaking BGP.  You have to assume that you are the
next hop that is connected to some layer 2 uplink, without a local 3rd
party router in between:

+-+- Line 1 - [ gateway @ISP-A ]
| OpenBSD |
+-+- Line 2 - [ gateway @ISP-B ]

The ttl 1 makes sure that you're not accidentally testing ISP-A's
gateway address all the way over ISP-B.

table gateways {
$ispgwa ip ttl 1 
$ispgwb ip ttl 1
}

I never tried, but you could theoretically use the parent option to
inherit the status from a different hop behind your local gateway.

+-+-[ local 1 ]- Line 1 - [ gateway @ISP-A ]
| OpenBSD | 
+-+-[ local 2 ]- Line 2 - [ gateway @ISP-B ]

table nexthops {
$ispgwa ip ttl 2 
$ispgwb ip ttl 2
}

table gateways {
$local1 parent 1
$local2 parent 2
}

You'd have to define a fake check somewhere to run health checks on
the gateway IPs behind the nexthops (eg. an unused relay or redirect).

But, as I said, router can be extened, just don't break it ;)

Reyk



Re: interfaces and priorities for relayd routers

2015-06-23 Thread David Gwynne

 On 22 Jun 2015, at 18:20, Reyk Floeter r...@openbsd.org wrote:
 
 Hi,
 
 On Thu, May 14, 2015 at 09:44:22PM +1000, David Gwynne wrote:
 i want relayd to check teh availability of some services and inject
 routes when the service is available. if it is available, i want
 to advertise the routes using ospfd, but i also want the local
 machine to be able to contact the service even if it isnt the carp
 master.
 
 to do that i need to inject the routes twice, once on my real
 interface and again on my carp interfaces. the route on the real
 interface needs to be a higher priority than the carp route.
 
 this shuffles relayd to accomodate this.
 
 it mostly adds stuff to the route statements in routers, but i also
 take priorities away from hosts in tables so i can specify them on
 routes.
 
 
 I'm generally ok with extending the use cases of router, but it seems
 that you're replacing one narrow use case with another one.
 
 The router code was mostly done for something like link balancing,
 you have two or more uplink gateways and want to select the route
 based on their availability.  I'm afraid that moving the priority from
 hosts to routes, and changing the semantics, breaks this original use
 case somehow.
 
   table gateways {
   $gw1 ip ttl 1 priority 8,
   $gw2 ip ttl 1 priority 52
   }
   router uplinks {
   route 0.0.0.0/0
   forward to gateways check icmp
   }
 
 But maybe even multiple routes for something internal:
 
   router srvlan {
   route 10.10.0.0/16
   route 10.40.0.0/16
   forward to srvgateways check icmp
   }
 
 Sometimes different gateways can even be connected via the same interface!
 (e.g. with an intermediate switch and a single cable to the OpenBSD box)
 
 this is an example config:
 
  rns_nogal=130.102.71.227
  rns_neem=130.102.71.229
 
  table rns { $rns_nogal ip ttl 1, $rns_neem ip ttl 1 } 
 
  router rns { 
  route 130.102.71.160/31 interface vlan888 priority 8
  route 130.102.71.160/31 interface carp40888 priority 16
  forward to rns check icmp 
  }
 
 
 I'm wondering, how would you translate my examples above?

hrm.

we could allow priorities on both the route statements and on the host 
statements in the table and combine them somehow when the actual routes are 
inserted into the kernel. or allow a relative priorities to be specified with a 
+ or - prefix. eg:

table gateways {
  $gw1 priority +1,
  $gw2
}

router uplinks {
  route 0.0.0.0/0 priority 16
  forward to gateways check icmp
}

if you add increase the priority of a route, should its numeric value get 
higher or lower?

anyway, allowing priorities in both tables and router blocks would cover both 
use cases i think.

 
  redirect dns {
  listen on 130.102.71.160 tcp port 53
  listen on 130.102.71.160 udp port 53
  listen on 130.102.71.161 tcp port 53
  listen on 130.102.71.161 udp port 53
 
  match pftag rns
  forward to rns port 53 check icmp
  }
 
 i wish redirects took a prefix. maybe thats a diff for another day.
 
 
 Would make sense.
 
 anyway, here's the diff.
 
 thoughts? tweaks? ok?
 
 
 In addition to my general concern, see comments inline below.
 
 Reyk
 
 Index: parse.y
 ===
 RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
 retrieving revision 1.204
 diff -u -p -r1.204 parse.y
 --- parse.y  2 May 2015 13:15:24 -   1.204
 +++ parse.y  14 May 2015 11:30:28 -
 @@ -173,6 +173,7 @@ typedef struct {
 %token   ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL 
 RTABLE
 %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
 PASSWORD ECDH
 %token   EDH CURVE
 +%token  NONE LOCAL CONNECTED STATIC OSPF ISIS RIP BGP DEFAULT
 
 A lot of keywords for basically an enum.  See below.
 
 %token   v.string  STRING
 %token  v.number   NUMBER
 %typev.string  hostname interface table value optstring
 @@ -182,6 +183,7 @@ typedef struct {
 %typev.number  redirect_proto relay_proto match
 %typev.number  action ruleaf key_option
 %typev.number  tlsdhparams tlsecdhcurve
 +%type   v.number  rtprio
 %typev.portport
 %typev.hosthost
 %typev.addraddress
 @@ -1864,8 +1866,8 @@ router : ROUTER STRING {
  router = rt;
 
  tableport = -1;
 -} '{' optnl routeopts_l '}' {
 -if (!router-rt_conf.nroutes) {
 +} '{' optnl routeropts_l '}'{
 +if (TAILQ_EMPTY(router-rt_netroutes)) {
  yyerror(router %s without routes,
  router-rt_conf.name);
  free(router);
 @@ -1881,11 

Re: interfaces and priorities for relayd routers

2015-06-22 Thread Reyk Floeter
Hi,

On Thu, May 14, 2015 at 09:44:22PM +1000, David Gwynne wrote:
 i want relayd to check teh availability of some services and inject
 routes when the service is available. if it is available, i want
 to advertise the routes using ospfd, but i also want the local
 machine to be able to contact the service even if it isnt the carp
 master.
 
 to do that i need to inject the routes twice, once on my real
 interface and again on my carp interfaces. the route on the real
 interface needs to be a higher priority than the carp route.
 
 this shuffles relayd to accomodate this.
 
 it mostly adds stuff to the route statements in routers, but i also
 take priorities away from hosts in tables so i can specify them on
 routes.
 

I'm generally ok with extending the use cases of router, but it seems
that you're replacing one narrow use case with another one.

The router code was mostly done for something like link balancing,
you have two or more uplink gateways and want to select the route
based on their availability.  I'm afraid that moving the priority from
hosts to routes, and changing the semantics, breaks this original use
case somehow.

table gateways {
$gw1 ip ttl 1 priority 8,
$gw2 ip ttl 1 priority 52
}
router uplinks {
route 0.0.0.0/0
forward to gateways check icmp
}

But maybe even multiple routes for something internal:

router srvlan {
route 10.10.0.0/16
route 10.40.0.0/16
forward to srvgateways check icmp
}

Sometimes different gateways can even be connected via the same interface!
(e.g. with an intermediate switch and a single cable to the OpenBSD box)

 this is an example config:
 
   rns_nogal=130.102.71.227
   rns_neem=130.102.71.229
 
   table rns { $rns_nogal ip ttl 1, $rns_neem ip ttl 1 } 
 
   router rns { 
   route 130.102.71.160/31 interface vlan888 priority 8
   route 130.102.71.160/31 interface carp40888 priority 16
   forward to rns check icmp 
   }
 

I'm wondering, how would you translate my examples above?

   redirect dns {
   listen on 130.102.71.160 tcp port 53
   listen on 130.102.71.160 udp port 53
   listen on 130.102.71.161 tcp port 53
   listen on 130.102.71.161 udp port 53
 
   match pftag rns
   forward to rns port 53 check icmp
   }
 
 i wish redirects took a prefix. maybe thats a diff for another day.


Would make sense.

 anyway, here's the diff.
 
 thoughts? tweaks? ok?
 

In addition to my general concern, see comments inline below.

Reyk

 Index: parse.y
 ===
 RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
 retrieving revision 1.204
 diff -u -p -r1.204 parse.y
 --- parse.y   2 May 2015 13:15:24 -   1.204
 +++ parse.y   14 May 2015 11:30:28 -
 @@ -173,6 +173,7 @@ typedef struct {
  %token   ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL 
 RTABLE
  %token   MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE 
 PASSWORD ECDH
  %token   EDH CURVE
 +%token   NONE LOCAL CONNECTED STATIC OSPF ISIS RIP BGP DEFAULT

A lot of keywords for basically an enum.  See below.

  %token   v.string  STRING
  %token  v.number   NUMBER
  %typev.string  hostname interface table value optstring
 @@ -182,6 +183,7 @@ typedef struct {
  %typev.number  redirect_proto relay_proto match
  %typev.number  action ruleaf key_option
  %typev.number  tlsdhparams tlsecdhcurve
 +%typev.number  rtprio
  %typev.portport
  %typev.hosthost
  %typev.addraddress
 @@ -1864,8 +1866,8 @@ router  : ROUTER STRING {
   router = rt;
  
   tableport = -1;
 - } '{' optnl routeopts_l '}' {
 - if (!router-rt_conf.nroutes) {
 + } '{' optnl routeropts_l '}'{
 + if (TAILQ_EMPTY(router-rt_netroutes)) {
   yyerror(router %s without routes,
   router-rt_conf.name);
   free(router);
 @@ -1881,11 +1883,11 @@ router: ROUTER STRING {
   }
   ;
  
 -routeopts_l  : routeopts_l routeoptsl nl
 - | routeoptsl optnl
 +routeropts_l : routeropts_l routeroptsl nl
 + | routeroptsl optnl
   ;
  
 -routeoptsl   : ROUTE address '/' NUMBER {
 +routeroptsl  : ROUTE address '/' NUMBER {
   struct netroute *nr;
  
   if (router-rt_conf.af == AF_UNSPEC)
 @@ -1914,15 +1916,15 @@ routeoptsl: ROUTE address '/' NUMBER {
   YYERROR;
   }
   

interfaces and priorities for relayd routers

2015-05-14 Thread David Gwynne
i want relayd to check teh availability of some services and inject
routes when the service is available. if it is available, i want
to advertise the routes using ospfd, but i also want the local
machine to be able to contact the service even if it isnt the carp
master.

to do that i need to inject the routes twice, once on my real
interface and again on my carp interfaces. the route on the real
interface needs to be a higher priority than the carp route.

this shuffles relayd to accomodate this.

it mostly adds stuff to the route statements in routers, but i also
take priorities away from hosts in tables so i can specify them on
routes.

this is an example config:

rns_nogal=130.102.71.227
rns_neem=130.102.71.229

table rns { $rns_nogal ip ttl 1, $rns_neem ip ttl 1 } 

router rns { 
route 130.102.71.160/31 interface vlan888 priority 8
route 130.102.71.160/31 interface carp40888 priority 16
forward to rns check icmp 
}

redirect dns {
listen on 130.102.71.160 tcp port 53
listen on 130.102.71.160 udp port 53
listen on 130.102.71.161 tcp port 53
listen on 130.102.71.161 udp port 53

match pftag rns
forward to rns port 53 check icmp
}

i wish redirects took a prefix. maybe thats a diff for another day.

anyway, here's the diff.

thoughts? tweaks? ok?

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.204
diff -u -p -r1.204 parse.y
--- parse.y 2 May 2015 13:15:24 -   1.204
+++ parse.y 14 May 2015 11:30:28 -
@@ -173,6 +173,7 @@ typedef struct {
 %token ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDH
 %token EDH CURVE
+%token NONE LOCAL CONNECTED STATIC OSPF ISIS RIP BGP DEFAULT
 %token v.string  STRING
 %token  v.number NUMBER
 %type  v.string  hostname interface table value optstring
@@ -182,6 +183,7 @@ typedef struct {
 %type  v.number  redirect_proto relay_proto match
 %type  v.number  action ruleaf key_option
 %type  v.number  tlsdhparams tlsecdhcurve
+%type  v.number  rtprio
 %type  v.portport
 %type  v.hosthost
 %type  v.addraddress
@@ -1864,8 +1866,8 @@ router: ROUTER STRING {
router = rt;
 
tableport = -1;
-   } '{' optnl routeopts_l '}' {
-   if (!router-rt_conf.nroutes) {
+   } '{' optnl routeropts_l '}'{
+   if (TAILQ_EMPTY(router-rt_netroutes)) {
yyerror(router %s without routes,
router-rt_conf.name);
free(router);
@@ -1881,11 +1883,11 @@ router  : ROUTER STRING {
}
;
 
-routeopts_l: routeopts_l routeoptsl nl
-   | routeoptsl optnl
+routeropts_l   : routeropts_l routeroptsl nl
+   | routeroptsl optnl
;
 
-routeoptsl : ROUTE address '/' NUMBER {
+routeroptsl: ROUTE address '/' NUMBER {
struct netroute *nr;
 
if (router-rt_conf.af == AF_UNSPEC)
@@ -1914,15 +1916,15 @@ routeoptsl  : ROUTE address '/' NUMBER {
YYERROR;
}
nr-nr_conf.prefixlen = $4;
+   nr-nr_conf.priority = RTP_DEFAULT;
nr-nr_conf.routerid = router-rt_conf.id;
nr-nr_router = router;
bcopy($2.ss, nr-nr_conf.ss, sizeof($2.ss));
 
-   router-rt_conf.nroutes++;
-   conf-sc_routecount++;
TAILQ_INSERT_TAIL(router-rt_netroutes, nr, nr_entry);
+   conf-sc_routecount++;
TAILQ_INSERT_TAIL(conf-sc_routes, nr, nr_route);
-   }
+   } routeopts_l
| FORWARD TO tablespec {
free(hashkey);
hashkey = NULL;
@@ -1950,18 +1952,74 @@ routeoptsl  : ROUTE address '/' NUMBER {
}
router-rt_conf.rtable = $2;
}
-   | RTLABEL STRING {
-   if (strlcpy(router-rt_conf.label, $2,
-   sizeof(router-rt_conf.label)) =
-   sizeof(router-rt_conf.label)) {
-   yyerror(route label truncated);
+   | DISABLE   { rlay-rl_conf.flags |= F_DISABLE; }
+   | include
+   ;
+
+routeopts_l: routeopts_l routeoptsl
+   | routeoptsl
+