[PATCH 8/9] External LSAs work with SADR

Dean Luga dluga93 at gmail.com
Tue Mar 7 00:56:32 CET 2017


From: dean <dluga93 at gmail.com>

As with the previous LSAs, there won't be just simple destination
prefixes in the LSA, but pairs of (destination, source) prefixes
instead. The parsing and validation functions of external LSAs will
handle these changes.

The installation of the external routes in the OSPF routing table
now uses the addr_data structure to support SADR without needing to
change call syntax based on whether SADR is enabled. To facilitate
these calls, a new function was added that creates an addr_data
object based on an external LSA.
---
 proto/ospf/lsalib.c   | 21 ++++++++++++++++++++-
 proto/ospf/ospf.c     | 15 +++++++++++++++
 proto/ospf/ospf.h     |  8 ++++++++
 proto/ospf/rt.c       |  7 ++++---
 proto/ospf/topology.c |  7 +++++++
 5 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index eac9780..ac125a2 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -347,7 +347,17 @@ lsa_parse_ext(struct top_hash_entry *en, int ospf2, struct ospf_lsa_ext_local *r
   {
     struct ospf_lsa_ext3 *ext = en->lsa_body;
     u16 rest;
-    u32 *buf = lsa_get_ipv6_prefix(ext->rest, &rt->ip, &rt->pxlen, &rt->pxopts, &rest);
+    u32 *buf =
+      lsa_get_ipv6_prefix(ext->rest, &rt->ip, &rt->pxlen, &rt->pxopts, &rest);
+
+    #ifdef SADR_OSPF
+    // get src
+    u8 dummy_opts;
+    u16 dummy_rest;
+    buf = lsa_get_ipv6_prefix(buf, &rt->src_ip, &rt->src_pxlen,
+      &dummy_opts, &dummy_rest);
+    #endif
+
     rt->metric = ext->metric & LSA_METRIC_MASK;
     rt->ebit = ext->metric & LSA_EXT3_EBIT;
 
@@ -512,6 +522,15 @@ lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
     return 0;
 
   int len = IPV6_PREFIX_SPACE(pxl);
+
+  #ifdef SADR_OSPF
+  u32* src_start = body->rest + (len/4);
+  int src_pxlen = pxlen(src_start);
+
+  int slen = IPV6_PREFIX_SPACE(src_pxlen);
+  len += slen;
+  #endif
+
   if (body->metric & LSA_EXT3_FBIT) // forwardinf address
     len += 16;
   if (body->metric & LSA_EXT3_TBIT) // route tag
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 1fefb8d..2a630e2 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -107,6 +107,21 @@ static int ospf_rte_better(struct rte *new, struct rte *old);
 static int ospf_rte_same(struct rte *new, struct rte *old);
 static void ospf_disp(timer *timer);
 
+addr_data addr_data_extlsa_init(struct ospf_lsa_ext_local * lsa) {
+  addr_data addr = {
+    .prefix = &lsa->ip,
+    .pxlen = lsa->pxlen
+
+    #ifdef SADR_OSPF
+    ,
+    .src_prefix = &lsa->src_ip,
+    .src_pxlen = lsa->src_pxlen
+    #endif
+  };
+
+  return addr;
+}
+
 static void
 ospf_area_initfib(struct fib_node *fn)
 {
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index a4e525e..c8a5a51 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -683,10 +683,18 @@ struct ospf_lsa_ext_local
 {
   ip_addr ip, fwaddr;
   int pxlen;
+
+  #ifdef SADR_OSPF
+  ip_addr src_ip;
+  int src_pxlen;
+  #endif
+
   u32 metric, ebit, fbit, tag, propagate;
   u8 pxopts;
 };
 
+addr_data addr_data_extlsa_init(struct ospf_lsa_ext_local * lsa);
+
 struct ospf_lsa_link
 {
   u32 options;
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index c8eaa0f..ac21f6e 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -367,9 +367,9 @@ ri_install_asbr(struct ospf_proto *p, ip_addr *addr, const orta *new)
 }
 
 static inline void
-ri_install_ext(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
+ri_install_ext(struct ospf_proto *p, addr_data addr, const orta *new)
 {
-  ort *old = (ort *) fib_get(&p->rtf, &prefix, pxlen);
+  ort *old = (ort *) fib_get2(&p->rtf, addr);
   int cmp = orta_compare_ext(p, new, &old->n);
 
   if (cmp > 0)
@@ -1599,7 +1599,8 @@ ospf_ext_spf(struct ospf_proto *p)
     nfa.oa = atmp; /* undefined in RFC 2328 */
     nfa.en = en; /* store LSA for later (NSSA processing) */
 
-    ri_install_ext(p, rt.ip, rt.pxlen, &nfa);
+    addr_data addr = addr_data_extlsa_init(&rt);
+    ri_install_ext(p, addr, &nfa);
   }
 }
 
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index b1bfc48..55910bc 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -1094,6 +1094,9 @@ prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
   struct ospf_lsa_ext3 *ext;
   int bsize = sizeof(struct ospf_lsa_ext3)
     + IPV6_PREFIX_SPACE(nf->fn.pxlen)
+    #ifdef SADR_OSPF
+    + IPV6_PREFIX_SPACE(nf->fn.src_pxlen)
+    #endif
     + (ipa_nonzero(fwaddr) ? 16 : 0)
     + (tag ? 4 : 0);
 
@@ -1103,6 +1106,10 @@ prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
 
   buf = put_ipv6_prefix(buf, nf->fn.prefix, nf->fn.pxlen, pbit ? OPT_PX_P : 0, 0);
 
+  #ifdef SADR_OSPF
+  buf = put_ipv6_prefix(buf, nf->fn.src_prefix, nf->fn.src_pxlen, pbit ? OPT_PX_P : 0, 0);
+  #endif
+
   if (ebit)
     ext->metric |= LSA_EXT3_EBIT;
 
-- 
2.7.4



More information about the Bird-users mailing list