Hi all,
Here is a patch to add two new functions to OpenOSPF6d.
The first function is the new keyword fib-routing-priority. This keyword allows to choose a custom routing priority. this function is useful when you use ospf6d with BGPd or ripd, to decrease ospf6d routes priority to use routes obtained from another protocol (bgpd for example).
The second function is the new chain fib-ignore-update nexthop . This new feature allows to prevent insertion of a specific route into the kernel routing table. This function is useful when you have two border routers with BGP + OSPF and a redistribute default on OSPF. OSPF is prior than BGP by default, and will cause a routing loop for outgoing packets. With this function you can refuse to insert a route obtained from your first/second border router and then, break the routing loop.
Comments are welcome, thanks !
--- OpenBSD-ORIG/usr.sbin/ospf6d/kroute.c 2013-02-16 04:03:41.000000000 +0100
+++ OpenBSD/usr.sbin/ospf6d/kroute.c 2013-07-10 18:25:33.809401325 +0200
@@ -1,6 +1,7 @@
-/* $OpenBSD: kroute.c,v 1.41 2013/01/14 14:39:38 florian Exp $ */
+/* $OpenBSD: kroute.c,v 1.42 2013/07/10 14:39:38 florian Exp $ */
/*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
* Copyright (c) 2004 Esben Norby <norby@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
@@ -928,12 +929,15 @@
if (kr_state.fib_sync == 0)
return (0);
+ if (kr_filter_do(kroute) != 0)
+ return (0);
+
/* initialize header */
bzero(&hdr, sizeof(hdr));
hdr.rtm_version = RTM_VERSION;
hdr.rtm_type = action;
hdr.rtm_flags = RTF_UP;
- hdr.rtm_priority = RTP_OSPF;
+ hdr.rtm_priority = get_fibrtprio();
if (action == RTM_CHANGE)
hdr.rtm_fmask = RTF_REJECT|RTF_BLACKHOLE;
hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */
@@ -1496,3 +1500,28 @@
}
return (0);
}
+
+struct kroute_filter *
+kr_filter_new(struct in6_addr nexthop, struct in6_addr prefix,
+ u_int8_t prefixlen)
+{
+ struct kroute_filter *kroute_filter;
+
+ if ((kroute_filter = calloc(1, sizeof(*kroute_filter))) == NULL)
+ err(1, "kr_filter_new: calloc");
+
+ kroute_filter->prefix = prefix;
+ kroute_filter->nexthop = nexthop;
+ kroute_filter->prefixlen = prefixlen;
+
+ return (kroute_filter);
+}
+
+void
+kr_filter_del(struct kroute_filter *kroute_filter)
+{
+ LIST_REMOVE(kroute_filter, entry);
+
+ free(kroute_filter);
+}
+
diff: OpenBSD-ORIG/usr.sbin/ospf6d/obj: Aucun fichier ou dossier de ce type
diff: OpenBSD/usr.sbin/ospf6d/obj: Aucun fichier ou dossier de ce type
diff -u OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.c OpenBSD/usr.sbin/ospf6d/ospf6d.c
--- OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.c 2011-11-15 05:17:45.000000000 +0100
+++ OpenBSD/usr.sbin/ospf6d/ospf6d.c 2013-07-10 17:51:18.920541838 +0200
@@ -1,6 +1,7 @@
-/* $OpenBSD: ospf6d.c,v 1.22 2011/08/20 19:02:28 sthen Exp $ */
+/* $OpenBSD: ospf6d.c,v 1.23 2013/07/10 19:02:28 sthen Exp $ */
/*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2004, 2007 Esben Norby <norby@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -632,12 +633,16 @@
struct area *a, *xa, *na;
struct iface *iface;
struct redistribute *r;
+ struct kroute_filter *rf, *nrf;
/* change of rtr_id needs a restart */
conf->flags = xconf->flags;
conf->spf_delay = xconf->spf_delay;
conf->spf_hold_time = xconf->spf_hold_time;
conf->redistribute = xconf->redistribute;
+
+ /* change of fib routing priority needs a restart */
+ conf->routing_priority = xconf->routing_priority;
if (ospfd_process == PROC_MAIN) {
/* main process does neither use areas nor interfaces */
@@ -649,6 +654,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;
}
@@ -799,3 +812,31 @@
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 (memcmp(&i->prefix,&kr->prefix, sizeof(&i->prefix)) == 0 &&
+ i->prefixlen == kr->prefixlen &&
+ memcmp(&i->nexthop, &kr->nexthop, sizeof(&i->nexthop)) == 0) {
+ log_info("kr_filter_do: filtering route %s/%u for nexthop %s",
+ log_in6addr(&i->prefix), i->prefixlen,
+ log_in6addr(&i->nexthop));
+
+ return (1);
+ }
+ }
+ return (0);
+}
+
+u_int8_t
+get_fibrtprio(void)
+{
+ return (ospfd_conf->routing_priority);
+}
diff -u OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.conf.5 OpenBSD/usr.sbin/ospf6d/ospf6d.conf.5
--- OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.conf.5 2012-06-19 20:05:26.000000000 +0200
+++ OpenBSD/usr.sbin/ospf6d/ospf6d.conf.5 2013-07-10 18:24:03.088407528 +0200
@@ -102,6 +102,32 @@
option to ensure that no traffic tries to transit via this router.
.Pp
.It Xo
+.Ic fib-routing-priority Ar 9-62
+.Xc
+Setting the routing priority permit to ajust the kernel route choice
+when multiple protocols are used (for example a BGP plus OSPF router).
+The routing priority is contained between
+.Ic RTP_STATIC
+(8) and
+.Ic RTP_MAX
+(63)
+.Ic Warning!
+Be sure the ospf6d priority
+.Ic isn't same as
+another used protocol on this machine (except ospfd daemon).
+.Pp
+.It Xo
+.Ic fib-ignore-route Ar prefix
+.Ic nexthop Ar hop
+.Xc
+Block some kernel route insertions based on an discovered
+.Ar prefix
+and it's
+.Ar nexthop .
+This function permit to break some routing loops
+caused by mutiple protocol use.
+.Pp
+.It Xo
.Op Ic no
.Ic redistribute
.Sm off
diff -u OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.h OpenBSD/usr.sbin/ospf6d/ospf6d.h
--- OpenBSD-ORIG/usr.sbin/ospf6d/ospf6d.h 2013-02-16 04:03:41.000000000 +0100
+++ OpenBSD/usr.sbin/ospf6d/ospf6d.h 2013-07-10 17:59:07.577509792 +0200
@@ -1,6 +1,7 @@
/* $OpenBSD: ospf6d.h,v 1.26 2013/01/14 14:39:38 florian Exp $ */
/*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
* Copyright (c) 2004, 2007 Esben Norby <norby@openbsd.org>
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
*
@@ -375,6 +376,8 @@
int flags;
u_int8_t border;
u_int8_t redistribute;
+ LIST_HEAD(, kroute_filter) kroute_filter_list;
+ u_int8_t routing_priority;
};
/* kroute */
@@ -494,6 +497,14 @@
int level;
};
+/* kernel route filtering */
+struct kroute_filter {
+ LIST_ENTRY(kroute_filter) entry;
+ struct in6_addr prefix;
+ struct in6_addr nexthop;
+ u_int8_t prefixlen;
+};
+
/* area.c */
struct area *area_new(void);
int area_del(struct area *);
@@ -537,6 +548,9 @@
void kr_show_route(struct imsg *);
void kr_reload(void);
+struct kroute_filter *kr_filter_new(struct in6_addr, struct in6_addr, u_int8_t);
+void kr_filter_del(struct kroute_filter *);
+
void embedscope(struct sockaddr_in6 *);
void recoverscope(struct sockaddr_in6 *);
void addscope(struct sockaddr_in6 *, u_int32_t);
@@ -570,6 +584,8 @@
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 *);
+u_int8_t get_fibrtprio(void);
/* printconf.c */
void print_config(struct ospfd_conf *);
diff -u OpenBSD-ORIG/usr.sbin/ospf6d/parse.y OpenBSD/usr.sbin/ospf6d/parse.y
--- OpenBSD-ORIG/usr.sbin/ospf6d/parse.y 2011-06-27 20:55:28.000000000 +0200
+++ OpenBSD/usr.sbin/ospf6d/parse.y 2013-07-10 17:59:23.398508710 +0200
@@ -1,6 +1,7 @@
/* $OpenBSD: parse.y,v 1.21 2011/06/27 03:07:26 dlg Exp $ */
/*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
* Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -27,6 +28,7 @@
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <net/route.h>
#include <ctype.h>
#include <err.h>
@@ -118,6 +120,7 @@
%token METRIC PASSIVE
%token HELLOINTERVAL TRANSMITDELAY
%token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY
+%token FIBIGNOREROUTE NEXTHOP FIBROUTEPRIORITY
%token SET TYPE
%token YES NO
%token DEMOTE
@@ -330,7 +333,44 @@
}
;
-defaults : METRIC NUMBER {
+defaults : FIBIGNOREROUTE STRING NEXTHOP STRING {
+ struct kroute_filter* kroute_filter;
+ struct in6_addr rt_prefix;
+ struct in6_addr rt_nexthop;
+ u_int8_t rt_prefixlen;
+ u_int8_t rt_nexthoplen;
+
+ if (prefix($2,&rt_prefix,&rt_prefixlen) == 0) {
+ yyerror("bad route: %s", $2);
+ free($2);
+ YYERROR;
+ }
+
+ if (prefix($4, &rt_nexthop,&rt_nexthoplen) == 0) {
+ yyerror("bad nexthop: %s", $4);
+ free($4);
+ YYERROR;
+ }
+
+ kroute_filter = kr_filter_new(rt_nexthop,rt_prefix,rt_prefixlen);
+ LIST_INSERT_HEAD(&conf->kroute_filter_list, kroute_filter, entry);
+
+ free($2);
+ free($4);
+ }
+ | FIBROUTEPRIORITY NUMBER {
+ /*
+ * OSPF routing priority neither be less or equal than static routes
+ * nor be greater or equal than RTP_MAX
+ */
+ if ($2 <= RTP_STATIC || $2 >= RTP_MAX) {
+ yyerror("fib-route-priority out of range (must be > 8 and < 63)");
+ YYERROR;
+ }
+
+ conf->routing_priority = $2;
+ }
+ | METRIC NUMBER {
if ($2 < MIN_METRIC || $2 > MAX_METRIC) {
yyerror("metric out of range (%d-%d)",
MIN_METRIC, MAX_METRIC);
@@ -541,11 +581,14 @@
{"area", AREA},
{"demote", DEMOTE},
{"external-tag", EXTTAG},
+ {"fib-ignore-route", FIBIGNOREROUTE},
+ {"fib-routing-priority", FIBROUTEPRIORITY},
{"fib-update", FIBUPDATE},
{"hello-interval", HELLOINTERVAL},
{"include", INCLUDE},
{"interface", INTERFACE},
{"metric", METRIC},
+ {"nexthop", NEXTHOP},
{"no", NO},
{"passive", PASSIVE},
{"redistribute", REDISTRIBUTE},
@@ -902,6 +945,7 @@
defs->priority = DEFAULT_PRIORITY;
conf->spf_delay = DEFAULT_SPF_DELAY;
+ conf->routing_priority = RTP_OSPF;
conf->spf_hold_time = DEFAULT_SPF_HOLDTIME;
conf->spf_state = SPF_IDLE;
@@ -914,6 +958,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;
diff -u OpenBSD-ORIG/usr.sbin/ospf6d/printconf.c OpenBSD/usr.sbin/ospf6d/printconf.c
--- OpenBSD-ORIG/usr.sbin/ospf6d/printconf.c 2010-11-29 21:57:30.000000000 +0100
+++ OpenBSD/usr.sbin/ospf6d/printconf.c 2013-07-10 18:00:07.638505685 +0200
@@ -1,6 +1,7 @@
/* $OpenBSD: printconf.c,v 1.4 2010/08/22 21:15:25 bluhm Exp $ */
/*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -33,6 +34,7 @@
const char *print_no(u_int16_t);
void print_redistribute(struct ospfd_conf *);
void print_rtlabel(struct ospfd_conf *);
+void print_kroute_filter(struct ospfd_conf *);
void print_iface(struct iface *);
void
@@ -50,9 +52,11 @@
print_redistribute(conf);
print_rtlabel(conf);
+ print_kroute_filter(conf);
printf("spf-delay %u\n", conf->spf_delay);
printf("spf-holdtime %u\n", conf->spf_hold_time);
+ printf("fib-routing-priority %u\n", conf->routing_priority);
}
const char *
@@ -105,6 +109,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/%u",
+ log_in6addr(&kroute_filter->prefix),kroute_filter->prefixlen);
+ printf(" nexthop %s\n",
+ log_in6addr(&kroute_filter->nexthop));
+ }
+}
+
+void
print_iface(struct iface *iface)
{
printf("\tinterface %s {\n", iface->name);