Re: interfaces and priorities for relayd routers
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
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
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
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
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
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 +