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]

Reply via email to