Commit 4a3f5b36 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

OSPF: Basic support for DN-bit handling (RFC 4576)

External LSAs originated by OSPF routers with VPN-PE behavior enabled are
marked by DN flag and they are ignored by other OSPF routers with VPN-PE
enabled.
parent 1e958e52
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -199,7 +199,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(MERGE, LSA, SUPPRESSION, MULTICAST, RFC5838)
CF_KEYWORDS(MERGE, LSA, SUPPRESSION, MULTICAST, RFC5838, VPN, PE)

%type <ld> lsadb_args
%type <i> ospf_variant ospf_af_mc nbma_eligible
@@ -256,6 +256,7 @@ ospf_proto_item:
 | ospf_channel { this_proto->net_type = $1->net_type; }
 | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
 | RFC5838 bool { OSPF_CFG->af_ext = $2; if (!ospf_cfg_is_v3()) cf_error("RFC5838 option requires OSPFv3"); }
 | VPN PE bool { OSPF_CFG->vpn_pe = $3; }
 | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
 | ECMP bool { OSPF_CFG->ecmp = $2 ? OSPF_DEFAULT_ECMP_LIMIT : 0; }
 | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; }
+4 −1
Original line number Diff line number Diff line
@@ -336,9 +336,10 @@ lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, int af, net_addr *net, u
{
  if (ospf2)
  {
    uint opts = lsa_get_options(&en->lsa);
    struct ospf_lsa_sum2 *ls = en->lsa_body;
    net_fill_ip4(net, ip4_from_u32(en->lsa.id & ls->netmask), u32_masklen(ls->netmask));
    *pxopts = 0;
    *pxopts = (opts & OPT_DN) ? OPT_PX_DN : 0;
    *metric = ls->metric & LSA_METRIC_MASK;
  }
  else
@@ -386,6 +387,7 @@ lsa_parse_ext(struct top_hash_entry *en, int ospf2, int af, struct ospf_lsa_ext_

    rt->tag = ext->tag;
    rt->propagate = lsa_get_options(&en->lsa) & OPT_P;
    rt->downwards = lsa_get_options(&en->lsa) & OPT_DN;
  }
  else
  {
@@ -402,6 +404,7 @@ lsa_parse_ext(struct top_hash_entry *en, int ospf2, int af, struct ospf_lsa_ext_

    rt->tag = (ext->metric & LSA_EXT3_TBIT) ? *buf++ : 0;
    rt->propagate = rt->pxopts & OPT_PX_P;
    rt->downwards = rt->pxopts & OPT_PX_DN;
  }
}

+5 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@
 * - RFC 2328 - main OSPFv2 standard
 * - RFC 5340 - main OSPFv3 standard
 * - RFC 3101 - OSPFv2 NSSA areas
 * - RFC 4576 - OSPFv2 VPN loop prevention
 * - RFC 5250 - OSPFv2 Opaque LSAs
 * - RFC 5709 - OSPFv2 HMAC-SHA Cryptographic Authentication
 * - RFC 5838 - OSPFv3 Support of Address Families
@@ -243,6 +244,7 @@ ospf_start(struct proto *P)
  p->merge_external = c->merge_external;
  p->instance_id = c->instance_id;
  p->asbr = c->asbr;
  p->vpn_pe = c->vpn_pe;
  p->ecmp = c->ecmp;
  p->tick = c->tick;
  p->disp_timer = tm_new_init(P->pool, ospf_disp, p, p->tick S, 0);
@@ -657,6 +659,9 @@ ospf_reconfigure(struct proto *P, struct proto_config *CF)
  if (old->abr != new->abr)
    return 0;

  if (old->vpn_pe != new->vpn_pe)
    return 0;

  if ((p->af_ext != new->af_ext) || (p->af_mc != new->af_mc))
    return 0;

+4 −1
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ struct ospf_config
  u8 instance_id_set;
  u8 abr;
  u8 asbr;
  u8 vpn_pe;
  int ecmp;
  list area_list;		/* list of area configs (struct ospf_area_config) */
  list vlink_list;		/* list of configured vlinks (struct ospf_iface_patt) */
@@ -225,6 +226,7 @@ struct ospf_proto
  u8 merge_external;		/* Should i merge external routes? */
  u8 instance_id;		/* Differentiate between more OSPF instances */
  u8 asbr;			/* May i originate any ext/NSSA lsa? */
  u8 vpn_pe;			/* Should we do VPN PE specific behavior (RFC 4577)? */
  u8 ecmp;			/* Maximal number of nexthops in ECMP route, or 0 */
  u64 csn64;			/* Last used cryptographic sequence number */
  struct ospf_area *backbone;	/* If exists */
@@ -467,6 +469,7 @@ struct ospf_neighbor
#define OPT_R		0x0010	/* OSPFv3, originator is active router */
#define OPT_DC		0x0020	/* Related to demand circuits, not used */
#define OPT_O		0x0040	/* OSPFv2 Opaque LSA (RFC 5250) */
#define OPT_DN		0x0080	/* OSPFv2 VPN loop prevention (RFC 4576)*/
#define OPT_AF		0x0100	/* OSPFv3 Address Families (RFC 5838) */
#define OPT_L_V3	0x0200	/* OSPFv3, link-local signaling */
#define OPT_AT          0x0400	/* OSPFv3, authentication trailer */
@@ -736,7 +739,7 @@ struct ospf_lsa_ext_local
{
  net_addr net;
  ip_addr fwaddr;
  u32 metric, ebit, fbit, tag, propagate;
  u32 metric, ebit, fbit, tag, propagate, downwards;
  u8 pxopts;
};

+15 −3
Original line number Diff line number Diff line
@@ -782,6 +782,10 @@ ospf_rt_sum(struct ospf_area *oa)
      if (pxopts & OPT_PX_NU)
	continue;

      /* RFC 4576 4 - do not use LSAs with DN-bit on PE-routers */
      if (p->vpn_pe && (pxopts & OPT_PX_DN))
	continue;

      options = 0;
      type = ORT_NET;
    }
@@ -879,6 +883,10 @@ ospf_rt_sum_tr(struct ospf_area *oa)
      if (pxopts & OPT_PX_NU)
	continue;

      /* RFC 4576 4 - do not use LSAs with DN-bit on PE-routers */
      if (p->vpn_pe && (pxopts & OPT_PX_DN))
	continue;

      re = fib_find(&p->rtf, &net);
    }
    else // en->lsa_type == LSA_T_SUM_RT
@@ -1104,11 +1112,11 @@ check_nssa_lsa(struct ospf_proto *p, ort *nf)
  /* RFC 3101 3.2 (3) - originate the aggregated address range */
  if (anet && anet->active && !anet->hidden && oa->translate)
    ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, anet->metric,
			   (anet->metric & LSA_EXT3_EBIT), IPA_NONE, anet->tag, 0);
			   (anet->metric & LSA_EXT3_EBIT), IPA_NONE, anet->tag, 0, 0);

  /* RFC 3101 3.2 (2) - originate the same network */
  else if (decide_nssa_lsa(p, nf, &rt))
    ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, rt.metric, rt.ebit, rt.fwaddr, rt.tag, 0);
    ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, rt.metric, rt.ebit, rt.fwaddr, rt.tag, 0, 0);
}

/* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
@@ -1238,7 +1246,7 @@ ospf_rt_abr1(struct ospf_proto *p)

    if (oa_is_nssa(oa) && oa->ac->default_nssa)
      ospf_originate_ext_lsa(p, oa, default_nf, LSA_M_RTCALC, oa->ac->default_cost,
			     (oa->ac->default_cost & LSA_EXT3_EBIT), IPA_NONE, 0, 0);
			     (oa->ac->default_cost & LSA_EXT3_EBIT), IPA_NONE, 0, 0, 0);

    /* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
    if (oa_is_ext(oa))
@@ -1474,6 +1482,10 @@ ospf_ext_spf(struct ospf_proto *p)
    if (rt.pxopts & OPT_PX_NU)
      continue;

    /* RFC 4576 4 - do not use LSAs with DN-bit on PE-routers */
    if (p->vpn_pe && rt.downwards)
      continue;

    /* 16.4. (3) */
    /* If there are more areas, we already precomputed preferred ASBR
       entries in ospf_rt_abr1() and stored them in the backbone
Loading