Commit 145368f5 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Extends multipath support for OSPF.

Fixes cases where the same network or external route are propagated by
several OSPF routes and some other corner cases in next hop construction
and ECMP. Allows to specify whether external routes should be merged.

Thanks to Peter Christensen for the original patch.
parent 4dd24f05
......@@ -2291,6 +2291,7 @@ protocol ospf <name> {
stub router <switch>;
tick <num>;
ecmp <switch> [limit <num>];
merge external <switch>;
area <id> {
stub;
nssa;
......@@ -2396,6 +2397,14 @@ protocol ospf <name> {
nexthops in one route. By default, ECMP is disabled. If enabled,
default value of the limit is 16.
<tag>merge external <M>switch</M></tag>
This option specifies whether OSPF should merge external routes from
different routers/LSAs for the same destination. When enabled together
with <cf/ecmp/, equal-cost external routes will be combined to multipath
routes in the same way as regular routes. When disabled, external routes
from different LSAs are treated as separate even if they represents the
same destination. Default value is no.
<tag>area <M>id</M></tag>
This defines an OSPF area with given area ID (an integer or an IPv4
address, similarly to a router ID). The most important area is the
......
......@@ -132,7 +132,7 @@ CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK, ONLY, BFD)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH)
CF_KEYWORDS(SECONDARY)
CF_KEYWORDS(SECONDARY, MERGE)
%type <t> opttext
%type <ld> lsadb_args
......@@ -162,6 +162,7 @@ ospf_proto_item:
| STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
| ECMP bool { OSPF_CFG->ecmp = $2 ? DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); }
| MERGE EXTERNAL bool { OSPF_CFG->merge_external = $3; }
| TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); }
| ospf_area
;
......
......@@ -234,6 +234,7 @@ ospf_start(struct proto *p)
po->router_id = proto_get_router_id(p->cf);
po->rfc1583 = c->rfc1583;
po->stub_router = c->stub_router;
po->merge_external = c->merge_external;
po->ebit = 0;
po->ecmp = c->ecmp;
po->tick = c->tick;
......@@ -742,6 +743,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
return 0;
po->stub_router = new->stub_router;
po->merge_external = new->merge_external;
po->ecmp = new->ecmp;
po->tick = new->tick;
po->disp_timer->recurrent = po->tick;
......
......@@ -81,6 +81,7 @@ struct ospf_config
unsigned tick;
byte rfc1583;
byte stub_router;
byte merge_external;
byte abr;
int ecmp;
list area_list; /* list of struct ospf_area_config */
......@@ -777,6 +778,7 @@ struct proto_ospf
struct fib rtf; /* Routing table */
byte rfc1583; /* RFC1583 compatibility */
byte stub_router; /* Do not forward transit traffic */
byte merge_external; /* Should i merge external routes? */
byte ebit; /* Did I originate any ext lsa? */
byte ecmp; /* Maximal number of nexthops in ECMP route, or 0 */
struct ospf_area *backbone; /* If exists */
......
This diff is collapsed.
......@@ -16,7 +16,8 @@
typedef struct orta
{
int type;
u8 type; /* RTS_OSPF_* */
u8 nhs_reuse; /* Whether nhs nodes can be reused during merging */
u32 options;
/*
* For ORT_ROUTER routes, options field are router-LSA style
......@@ -93,16 +94,24 @@ static inline int rt_is_nssa(ort *nf)
* - n.metric1 may be at most a small multiple of LSINFINITY,
* therefore sums do not overflow
* - n.oa is always non-NULL
* - n.nhs is always non-NULL with one exception - configured stubnet
* nodes (in po->rtf).
* - n.nhs is always non-NULL unless it is configured stubnet
* - n.en is non-NULL for external routes, NULL for intra/inter area routes.
* - oa->rtr does not contain calculating router itself
*
* There are three types of nexthops in nhs fields:
* There are four types of nexthops in nhs fields:
* - gateway nexthops (non-NULL iface, gw != IPA_NONE)
* - device nexthops (non-NULL iface, gw == IPA_NONE)
* - dummy vlink nexthops (NULL iface, gw == IPA_NONE)
* These three types don't mix, nhs field contains either
* one device, one vlink node, or one/more gateway nodes.
* - configured stubnets (nhs is NULL, only RTS_OSPF orta nodes in po->rtf)
*
* Dummy vlink nexthops and configured stubnets cannot be mixed with
* regular ones, nhs field contains either list of gateway+device nodes,
* one vlink node, or NULL for configured stubnet.
*
* Dummy vlink nexthops can appear in both network (rtf) and backbone area router
* (rtr) tables for regular and inter-area routes, but only if areano > 1. They are
* replaced in ospf_rt_sum_tr() and removed in ospf_rt_abr1(), therefore cannot
* appear in ASBR pre-selection and external routes processing.
*/
void ospf_rt_spf(struct proto_ospf *po);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment