Commit 2918e610 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

Fixes for OSPF NSSA handling.

parent b1b19433
Loading
Loading
Loading
Loading
+23 −9
Original line number Diff line number Diff line
@@ -1655,10 +1655,12 @@ protocol ospf <name> {
	tick <num>;
	ecmp <switch> [limit <num>];
	area <id> {
		stub <switch>;
		nssa <switch>;
		stub;
		nssa;
		summary <switch>;
		stub cost <num>;
		default nssa <switch>;
		default cost <num>;
		default cost2 <num>;
		translator <switch>;
		translator stability <num>;

@@ -1747,20 +1749,20 @@ protocol ospf <name> {
	 address, similarly to a router ID). The most important area is
	 the backbone (ID 0) to which every other area must be connected.

	<tag>stub <M>switch</M></tag>
	<tag>stub</tag>
	 This option configures the area to be a stub area. External
	 routes are not flooded into stub areas. Also summary LSAs can be
	 limited in stub areas (see option <cf/summary/). Default
	 value is no. (Area is not stub.)
	 limited in stub areas (see option <cf/summary/).
	 By default, the area is not a stub area.

	<tag>nssa <M>switch</M></tag>
	<tag>nssa</tag>
	 This option configures the area to be a NSSA (Not-So-Stubby
	 Area). NSSA is a variant of a stub area which allows a
	 limited way of external route propagation. Global external
	 routes are not propagated into a NSSA, but an external route
	 can be imported into NSSA as a (area-wide) NSSA-LSA (and
	 possibly translated and/or aggregated on area boundary).
	 Default value is no. (Area is not NSSA.)
	 By default, the area is not NSSA.

	<tag>summary <M>switch</M></tag>
	 This option controls propagation of summary LSAs into stub or
@@ -1771,10 +1773,22 @@ protocol ospf &lt;name&gt; {
	 summary LSAs could lead to more efficient routing at the cost
	 of larger link state database. Default value is no.

	<tag>stub cost <M>num</M></tag>
	<tag>default nssa <M>switch</M></tag>
 	 When <cf/summary/ option is enabled, default summary route is
	 no longer propagated to the NSSA. In that case, this option
	 allows to originate default route as NSSA-LSA to the NSSA.
	 Default value is no.

	<tag>default cost <M>num</M></tag>
	 This option controls the cost of a default route propagated to
	 stub and NSSA areas. Default value is 1000.

	<tag>default cost2 <M>num</M></tag>
	 When a default route is originated as NSSA-LSA, its cost
	 can use either type 1 or type 2 metric. This option allows
	 to specify the cost of a default route in type 2 metric.
	 By default, type 1 metric (option <cf/default cost/) is used.

	<tag>translator <M>switch</M></tag>
	 This option controls translation of NSSA-LSAs into external
	 LSAs. By default, one translator per NSSA is automatically
+24 −5
Original line number Diff line number Diff line
@@ -59,6 +59,15 @@ ospf_area_finish(void)
{
  if ((this_area->areaid == 0) && (this_area->type != OPT_E))
    cf_error("Backbone area cannot be stub/NSSA");

  if (this_area->summary && (this_area->type == OPT_E))
    cf_error("Only Stub/NSSA areas can use summary propagation");

  if (this_area->default_nssa && ((this_area->type != OPT_N) || ! this_area->summary))
    cf_error("Only NSSA areas with summary propagation can use NSSA default route");

  if ((this_area->default_cost & LSA_EXT_EBIT) && ! this_area->default_nssa)
    cf_error("Only NSSA default route can use type 2 metric");
}

static void
@@ -94,10 +103,17 @@ ospf_proto_finish(void)
    cf_error( "Vlinks cannot be used on single area router");
}

static inline void
check_defcost(int cost)
{
  if ((cost <= 0) || (cost >= LSINFINITY))
   cf_error("Default cost must be in range 1-%d", LSINFINITY);
}

CF_DECLS

CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, COST2, RETRANSMIT)
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST)
CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
@@ -139,7 +155,7 @@ ospf_area_start: AREA idval {
  this_area = cfg_allocz(sizeof(struct ospf_area_config));
  add_tail(&OSPF_CFG->area_list, NODE this_area);
  this_area->areaid = $2;
  this_area->stub_cost = DEFAULT_STUB_COST;
  this_area->default_cost = DEFAULT_STUB_COST;
  this_area->type = OPT_E;
  this_area->transint = DEFAULT_TRANSINT;

@@ -159,10 +175,13 @@ ospf_area_opts:
 ;

ospf_area_item:
   STUB COST expr { this_area->stub_cost = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
 | STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
   STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
 | NSSA { this_area->type = OPT_N; }
 | SUMMARY bool { this_area->summary = $2; }
 | DEFAULT NSSA bool { this_area->default_nssa = $3; }
 | DEFAULT COST expr { this_area->default_cost = $3; check_defcost($3); }
 | DEFAULT COST2 expr { this_area->default_cost = $3 | LSA_EXT_EBIT; check_defcost($3); }
 | STUB COST expr { this_area->default_cost = $3;  check_defcost($3); }
 | TRANSLATOR bool { this_area->translator = $2; }
 | TRANSLATOR STABILITY expr { this_area->transint = $3; }
 | NETWORKS { this_nets = &this_area->net_list; } '{' pref_list '}'
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i
    case LSA_SCOPE_AS:
      if (ifa->type == OSPF_IT_VLINK)
	return 0;
      if (ifa->oa->stub)
      if (!oa_is_ext(ifa->oa))
	return 0;
      return 1;

+21 −3
Original line number Diff line number Diff line
@@ -170,6 +170,14 @@ ospf_area_add(struct proto_ospf *po, struct ospf_area_config *ac, int reconf)
  oa->options = OPT_R | ac->type | OPT_V6;
#endif

  /*
   * Set E-bit for NSSA ABR routers. No need to explicitly call
   * schedule_rt_lsa() for other areas, will be done anyway.
   * We use cf->abr because po->areano is not yet complete.
   */
  if (oa_is_nssa(oa) && ((struct ospf_config *) (p->cf))->abr)
    po->ebit = 1;

  if (reconf)
    ospf_ifaces_reconfigure(oa, ac);
}
@@ -453,7 +461,7 @@ area_disp(struct ospf_area *oa)
}

/**
 * ospf_disp - invokes routing table calctulation, aging and also area_disp()
 * ospf_disp - invokes routing table calculation, aging and also area_disp()
 * @timer: timer usually called every @proto_ospf->tick second, @timer->data
 * point to @proto_ospf
 */
@@ -572,6 +580,8 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol
    /* Old external route might blocked some NSSA translation */
    if (po->areano > 1)
      schedule_rtcalc(po);

    return;
  }

  /* Get route attributes */
@@ -587,7 +597,7 @@ ospf_rt_notify(struct proto *p, rtable *tbl UNUSED, net * n, rte * new, rte * ol
      (ospf_iface_find((struct proto_ospf *) p, new->attrs->iface) != NULL))
    gw = new->attrs->gw;

  originate_ext_lsa(oa, fn, EXT_EXPORT, metric, gw, tag);
  originate_ext_lsa(oa, fn, EXT_EXPORT, metric, gw, tag, 1);
}

static void
@@ -674,7 +684,15 @@ static void
ospf_area_reconfigure(struct ospf_area *oa, struct ospf_area_config *nac)
{
  oa->ac = nac;
  // FIXME NSSA check type

  // FIXME better area type reconfiguration
#ifdef OSPFv2
  oa->options = nac->type;
#else /* OSPFv3 */
  oa->options = OPT_R | nac->type | OPT_V6;
#endif
  if (oa_is_nssa(oa) && (oa->po->areano > 1))
    oa->po->ebit = 1;

  ospf_ifaces_reconfigure(oa, nac);

+2 −1
Original line number Diff line number Diff line
@@ -126,10 +126,11 @@ struct ospf_area_config
{
  node n;
  u32 areaid;
  u32 stub_cost;		/* Cost of default route for stub areas */
  u32 default_cost;		/* Cost of default route for stub areas */
  u8 type;			/* Area type (standard, stub, NSSA), represented
				   by option flags (OPT_E, OPT_N) */
  u8 summary;			/* Import summaries to this stub/NSSA area, valid for ABR */
  u8 default_nssa;		/* Generate default NSSA route for NSSA+summary area */
  u8 translator;		/* Translator role, for NSSA ABR */
  u32 transint;			/* Translator stability interval */
  list patt_list;
Loading