Hi misc, i have wrote some C code to resolve my OSPF+BGP default route problem, and now the problem is resolved by the following ospfd patch.
I have added the kroute-ignore-insert option to ospfd. This options block kernel route insertion with a prefix, prefixlen and nexthop option Example: kroute-ignore-insert 0.0.0.0 prefixlen 0 nexthop 10.0.0.2 This rule block the default route obtained which nexthop is 10.0.0.2. The block rule is applied to kernel route insertion, then FIB and RIB are not affected by this filter. I give you the patch, reviews are accepted, and i hope Claudio like it and accept it (with little modifications maybe) for OpenBSD 5.4 :). ================================================================= --- /root/ospfd/ospfd.c 2011-11-15 05:17:46.000000000 +0100 +++ /usr/src/usr.sbin/ospfd/ospfd.c 2013-05-31 22:38:22.202030731 +0200 @@ -1,6 +1,7 @@ -/* $OpenBSD: ospfd.c,v 1.78 2011/08/20 11:16:09 sthen Exp $ */ +/* $OpenBSD: ospfd.c,v 1.79 2013/05/31 22:35:17 sthen Exp $ */ /* + * Copyright (c) 2013 Loic Blot <loic.b...@unix-experience.fr> * Copyright (c) 2005 Claudio Jeker <clau...@openbsd.org> * Copyright (c) 2004 Esben Norby <no...@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henn...@openbsd.org> @@ -680,6 +681,7 @@ struct area *a, *xa, *na; struct iface *iface; struct redistribute *r; + struct kroute_filter *rf, *nrf; int rchange = 0; /* change of rtr_id needs a restart */ @@ -701,6 +703,14 @@ SIMPLEQ_REMOVE_HEAD(&xconf->redist_list, entry); SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry); } + for (rf = LIST_FIRST(&conf->kroute_filter_list); rf != NULL; rf = nrf) { + nrf = LIST_NEXT(rf, entry); + kr_filter_del(rf); + } + for (rf = LIST_FIRST(&xconf->kroute_filter_list); rf != NULL; rf = nrf) { + nrf = LIST_NEXT(rf, entry); + LIST_INSERT_HEAD(&conf->kroute_filter_list, rf, entry); + } goto done; } @@ -891,3 +901,26 @@ return (i); return (NULL); } + +int +kr_filter_do(struct kroute *kr) +{ + struct kroute_filter *i; + + LIST_FOREACH(i, &ospfd_conf->kroute_filter_list, entry) { + /* + * TODO: filter all routes for one nexthop + */ + if (i->prefix.s_addr == kr->prefix.s_addr && + i->prefixlen == kr->prefixlen && + (i->nexthop.s_addr == kr->nexthop.s_addr || + i->nexthop.s_addr == INADDR_ANY)) { + log_info("ospfd_filternexthop: filtering route %s/%u", + inet_ntoa(i->prefix), i->prefixlen); + log_info("ospfd_filternexthop: nexthop is %s", + inet_ntoa(i->nexthop)); + return (1); + } + } + return (0); +} --- /root/ospfd/ospfd.h 2013-02-16 04:03:42.000000000 +0100 +++ /usr/src/usr.sbin/ospfd/ospfd.h 2013-05-31 22:38:44.768029188 +0200 @@ -1,6 +1,7 @@ -/* $OpenBSD: ospfd.h,v 1.91 2013/01/17 10:07:56 markus Exp $ */ +/* $OpenBSD: ospfd.h,v 1.92 2013/05/31 22:38:56 markus Exp $ */ /* + * Copyright (c) 2013 Loic Blot <loic.b...@unix-experience.fr> * Copyright (c) 2004 Esben Norby <no...@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henn...@openbsd.org> * @@ -387,6 +388,7 @@ u_int8_t border; u_int8_t redistribute; u_int rdomain; + LIST_HEAD(, kroute_filter) kroute_filter_list; char *csock; }; @@ -526,6 +528,14 @@ int level; }; +/* kernel route filtering */ +struct kroute_filter { + LIST_ENTRY(kroute_filter) entry; + struct in_addr prefix; + struct in_addr nexthop; + u_int8_t prefixlen; +}; + /* area.c */ struct area *area_new(void); int area_del(struct area *); @@ -564,6 +574,9 @@ void kr_ifinfo(char *, pid_t); struct kif *kif_findname(char *, struct in_addr, struct kif_addr **); void kr_reload(void); +struct kroute_filter *kr_filter_new(struct in_addr, struct in_addr, u_int8_t); +void kr_filter_del(struct kroute_filter *); +struct kroute_filter *kr_filter_find(struct ospfd_conf *, struct in_addr, struct in_addr, u_int8_t); u_int8_t mask2prefixlen(in_addr_t); in_addr_t prefixlen2mask(u_int8_t); @@ -592,6 +605,7 @@ void imsg_event_add(struct imsgev *); int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, pid_t, int, void *, u_int16_t); +int kr_filter_do(struct kroute *); /* printconf.c */ void print_config(struct ospfd_conf *); --- /root/ospfd/parse.y 2010-12-20 19:09:24.000000000 +0100 +++ /usr/src/usr.sbin/ospfd/parse.y 2013-05-31 22:39:09.098027524 +0200 @@ -1,6 +1,7 @@ -/* $OpenBSD: parse.y,v 1.73 2010/12/13 13:43:37 bluhm Exp $ */ +/* $OpenBSD: parse.y,v 1.74 2013/05/31 22:12:08 bluhm Exp $ */ /* + * Copyright (c) 2013 Loic Blot <loic.b...@unix-experience.fr> * Copyright (c) 2004, 2005 Esben Norby <no...@openbsd.org> * Copyright (c) 2004 Ryan McBride <mcbr...@openbsd.org> * Copyright (c) 2002, 2003, 2004 Henning Brauer <henn...@openbsd.org> @@ -116,12 +117,14 @@ %} -%token AREA INTERFACE ROUTERID FIBUPDATE REDISTRIBUTE RTLABEL RDOMAIN -%token RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG +%token AREA INTERFACE ROUTERID FIBUPDATE +%token REDISTRIBUTE RTLABEL RDOMAIN RFC1583COMPAT STUB ROUTER SPFDELAY +%token SPFHOLDTIME EXTTAG %token AUTHKEY AUTHTYPE AUTHMD AUTHMDKEYID %token METRIC PASSIVE %token HELLOINTERVAL FASTHELLOINTERVAL TRANSMITDELAY %token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY +%token KROUTEIGNOREINSERT PREFIXLEN NEXTHOP %token SET TYPE %token YES NO %token MSEC MINIMAL @@ -435,7 +438,32 @@ } ; -defaults : METRIC NUMBER { +defaults : KROUTEIGNOREINSERT STRING PREFIXLEN NUMBER NEXTHOP STRING { + struct kroute_filter* kroute_filter; + struct in_addr prefix; + struct in_addr nexthop; + u_int8_t prefixlen; + + if (!inet_aton($2, &prefix)) { + yyerror("bad network: %llu/%llu", $2, $4); + free($2); + YYERROR; + } + + if (!inet_aton($6, &nexthop)) { + yyerror("bad network: %llu/%llu", $2, $4); + free($2); + YYERROR; + } + + prefixlen = $4; + + kroute_filter = kr_filter_new(nexthop,prefix,prefixlen); + LIST_INSERT_HEAD(&conf->kroute_filter_list, kroute_filter, entry); + + free($2); + } + | METRIC NUMBER { if ($2 < MIN_METRIC || $2 > MAX_METRIC) { yyerror("metric out of range (%d-%d)", MIN_METRIC, MAX_METRIC); @@ -508,7 +536,6 @@ | MINIMAL { $$ = FAST_RTR_DEAD_TIME; } - optnl : '\n' optnl | ; @@ -726,11 +753,14 @@ {"hello-interval", HELLOINTERVAL}, {"include", INCLUDE}, {"interface", INTERFACE}, + {"kroute-ignore-insert", KROUTEIGNOREINSERT}, {"metric", METRIC}, {"minimal", MINIMAL}, {"msec", MSEC}, + {"nexthop", NEXTHOP}, {"no", NO}, {"passive", PASSIVE}, + {"prefixlen", PREFIXLEN}, {"rdomain", RDOMAIN}, {"redistribute", REDISTRIBUTE}, {"retransmit-interval", RETRANSMITINTERVAL}, @@ -1101,6 +1131,7 @@ LIST_INIT(&conf->area_list); LIST_INIT(&conf->cand_list); SIMPLEQ_INIT(&conf->redist_list); + LIST_INIT(&conf->kroute_filter_list); yyparse(); errors = file->errors; --- /root/ospfd/printconf.c 2010-02-20 19:02:25.000000000 +0100 +++ /usr/src/usr.sbin/ospfd/printconf.c 2013-05-31 22:39:27.174026288 +0200 @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.15 2010/02/16 08:39:05 dlg Exp $ */ +/* $OpenBSD: printconf.c,v 1.16 2013/05/31 21:59:48 dlg Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <no...@openbsd.org> @@ -32,6 +32,7 @@ const char *print_no(u_int16_t); void print_redistribute(struct redist_list *); void print_rtlabel(struct ospfd_conf *); +void print_kroute_filter(struct ospfd_conf *); void print_iface(struct iface *); void @@ -54,6 +55,7 @@ print_redistribute(&conf->redist_list); print_rtlabel(conf); + print_kroute_filter(conf); printf("spf-delay msec %u\n", conf->spf_delay); printf("spf-holdtime msec %u\n", conf->spf_hold_time); @@ -109,6 +111,19 @@ } void +print_kroute_filter(struct ospfd_conf *conf) +{ + struct kroute_filter *kroute_filter; + + LIST_FOREACH(kroute_filter, &conf->kroute_filter_list, entry) { + printf("kroute-ignore-insert %s prefixlen %u", + inet_ntoa(kroute_filter->prefix),kroute_filter->prefixlen); + printf(" nexthop %s\n", + inet_ntoa(kroute_filter->nexthop)); + } +} + +void print_iface(struct iface *iface) { struct auth_md *md; ================================================================= Have a nice day ! -- Best regards, Loïc BLOT, UNIX systems, security and network expert http://www.unix-experience.fr Le mercredi 01 mai 2013 à 23:45 +0200, Loïc BLOT a écrit : > My border routers obtain a default route in fact, and OSPF must > redistribute this route to LAN Routers. Here is a scheme > > > |-------------- R1 site 1------------ R3 Site 1 > | BGP AS 650XX | OSPF a3 | > |-------------- R2 site 1------------ R4 Site 1 > | | > WAN | GRE (OSPF a3) > | | > |-------------- R1 site 2 ------------ R3 Site 2 > | BGP AS 650YY | OSPF a3 | > |-------------- R2 site 2------------- R4 Site 2 > > Each BGP AS redistribute a default route. > you are right, OSPF should redistribute default route (it's the case) > for R3/R4 routers on each site. The problem is between between the two > border routers and on GRE. > Please note R1 and R2 are full mesh GRE (R1S1 -> R1S2 / R1S1 -> R2S2 / > R2S1 -> R2S1 -> R2S1 / R2S1 -> R2S2). > When i said priority it's not route priority but protocol priority (BGP: > 48/OSPF: 40) > > Any idea ? I think the only and the best solution is to filter installed > routes > > -- > Best regards, > Loc BLOT, > UNIX systems, security and network expert > http://www.unix-experience.fr > > > > > Le mercredi 01 mai 2013 23:26 +0200, Claudio Jeker a crit : > > On Wed, May 01, 2013 at 10:00:55PM +0200, Loc BLOT wrote: > > > In fact, this isn't really an interarea problem but a inter protocol > > > problem. > > > > > > Next month i'll have two border routers which are connecter to MAN by > > > BGP. In my LAN and on my tunnels i'm in a "LAN backbone" area. > > > > > > Because of the priority of OSPF and the default route redistribution, > > > the default route will be redistributed on my GRE tunnel and also > > > between the two border routers and those routes are prior to BGP routes. > > > A problem is also redistribute default is a global function, then the > > > default route will be redistributed (and also taken) everywhere) . > > > If we could configure redistribute default/static/connected on area, i > > > could split my "LAN backbone" area into 3 areas (1 per site + 1 for > > > GRE), and do not redistribute default route on GRE, but the > > > redistribution between the two border routers is not fixed. Then the > > > only way to resolve this issue is to filter entries to kernel routing > > > table, you are right. > > > > > > > Hmm. I don't know your network setup but you should redistribute the > > default route from your border routers. Also the routing priority only > > matters for equal prefixes so the more specifc bgp routes from a full feed > > will still be considered. Last but not least on border routers I also > > normaly install a default blackhole route which again would prevent the > > ospf default route to take precedence (if the prio is set right of course). > > > > -- > > :wq Claudio > > [demime 1.01d removed an attachment of type application/pgp-signature which > had a name of signature.asc]