Revision f623ab98

View differences:

doc/bird.sgml
1904 1904
<code>
1905 1905
protocol ospf &lt;name&gt; {
1906 1906
	rfc1583compat &lt;switch&gt;;
1907
	stub router &lt;switch&gt;;
1907 1908
	tick &lt;num&gt;;
1908 1909
	ecmp &lt;switch&gt; [limit &lt;num&gt;];
1909 1910
	area &lt;id&gt; {
......
1983 1984
	 url="ftp://ftp.rfc-editor.org/in-notes/rfc1583.txt">. Default
1984 1985
	 value is no.
1985 1986

  
1987
	<tag>stub router <M>switch</M></tag>
1988
	 This option configures the router to be a stub router, i.e.,
1989
	 a router that participates in the OSPF topology but does not
1990
	 allow transit traffic. In OSPFv2, this is implemented by
1991
	 advertising maximum metric for outgoing links, as suggested
1992
	 by RFC 3137<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc3137.txt">.
1993
	 In OSPFv3, the stub router behavior is announced by clearing
1994
	 the R-bit in the router LSA. Default value is no.
1995

  
1986 1996
	<tag>tick <M>num</M></tag>
1987 1997
	 The routing table calculation and clean-up of areas' databases
1988 1998
         is not performed when a single link state
proto/ospf/config.Y
158 158
ospf_proto_item:
159 159
   proto_item
160 160
 | RFC1583COMPAT bool { OSPF_CFG->rfc1583 = $2; }
161
 | STUB ROUTER bool { OSPF_CFG->stub_router = $3; }
161 162
 | ECMP bool { OSPF_CFG->ecmp = $2 ? DEFAULT_ECMP_LIMIT : 0; }
162 163
 | ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); }
163 164
 | TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); }
proto/ospf/ospf.c
167 167
#ifdef OSPFv2
168 168
  oa->options = ac->type;
169 169
#else /* OSPFv3 */
170
  oa->options = OPT_R | ac->type | OPT_V6;
170
  oa->options = ac->type | OPT_V6 | (po->stub_router ? 0 : OPT_R);
171 171
#endif
172 172

  
173 173
  /*
......
234 234
  po->router_id = proto_get_router_id(p->cf);
235 235
  po->last_vlink_id = 0x80000000;
236 236
  po->rfc1583 = c->rfc1583;
237
  po->stub_router = c->stub_router;
237 238
  po->ebit = 0;
238 239
  po->ecmp = c->ecmp;
239 240
  po->tick = c->tick;
......
690 691
#ifdef OSPFv2
691 692
  oa->options = nac->type;
692 693
#else /* OSPFv3 */
693
  oa->options = OPT_R | nac->type | OPT_V6;
694
  oa->options = nac->type | OPT_V6 | (oa->po->stub_router ? 0 : OPT_R);
694 695
#endif
695 696
  if (oa_is_nssa(oa) && (oa->po->areano > 1))
696 697
    oa->po->ebit = 1;
......
738 739
  if (old->abr != new->abr)
739 740
    return 0;
740 741

  
742
  po->stub_router = new->stub_router;
741 743
  po->ecmp = new->ecmp;
742 744
  po->tick = new->tick;
743 745
  po->disp_timer->recurrent = po->tick;
......
831 833

  
832 834
  cli_msg(-1014, "%s:", p->name);
833 835
  cli_msg(-1014, "RFC1583 compatibility: %s", (po->rfc1583 ? "enable" : "disabled"));
836
  cli_msg(-1014, "Stub router: %s", (po->stub_router ? "Yes" : "No"));
834 837
  cli_msg(-1014, "RT scheduler tick: %d", po->tick);
835 838
  cli_msg(-1014, "Number of areas: %u", po->areano);
836 839
  cli_msg(-1014, "Number of LSAs in DB:\t%u", po->gr->hash_entries);
proto/ospf/ospf.h
83 83
  struct proto_config c;
84 84
  unsigned tick;
85 85
  byte rfc1583;
86
  byte stub_router;
86 87
  byte abr;
87 88
  int ecmp;
88 89
  list area_list;		/* list of struct ospf_area_config */
......
771 772
  int areano;			/* Number of area I belong to */
772 773
  struct fib rtf;		/* Routing table */
773 774
  byte rfc1583;			/* RFC1583 compatibility */
775
  byte stub_router;		/* Do not forward transit traffic */
774 776
  byte ebit;			/* Did I originate any ext lsa? */
775 777
  byte ecmp;			/* Maximal number of nexthops in ECMP route, or 0 */
776 778
  struct ospf_area *backbone;	/* If exists */
proto/ospf/rt.c
501 501
#ifdef OSPFv2
502 502
      ospf_rt_spfa_rtlinks(oa, act, act);
503 503
#else /* OSPFv3 */
504
      /* Errata 2078 to RFC 5340 4.8.1 - skip links from non-routing nodes */
505
      if ((act != oa->rt) && !(rt->options & OPT_R))
506
	break;
507

  
504 508
      for (tmp = ospf_hash_find_rt_first(po->gr, act->domain, act->lsa.rt);
505 509
	   tmp; tmp = ospf_hash_find_rt_next(tmp))
506 510
	ospf_rt_spfa_rtlinks(oa, act, tmp);
......
1839 1843
  if (en->lsa.type == LSA_T_RT)
1840 1844
    {
1841 1845
      struct ospf_lsa_rt *rt = en->lsa_body;
1842
      if (!(rt->options & OPT_V6) || !(rt->options & OPT_R))
1846
      if (!(rt->options & OPT_V6))
1843 1847
	return;
1844 1848
    }
1845 1849
#endif
proto/ospf/topology.c
233 233
  WALK_LIST(ifa, po->iface_list)
234 234
  {
235 235
    int net_lsa = 0;
236
    u32 link_cost = po->stub_router ? 0xffff : ifa->cost;
236 237

  
237 238
    if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
238 239
	(!EMPTY_LIST(ifa->neigh_list)))
......
268 269
	     * this address as a next-hop.
269 270
	     */
270 271
	    ln->data = ipa_to_u32(ifa->addr->ip);
271

  
272
	    ln->metric = ifa->cost;
272
	    ln->metric = link_cost;
273 273
	    ln->padding = 0;
274 274
	    i++;
275 275
	  }
......
283 283
	    ln->type = LSART_NET;
284 284
	    ln->id = ipa_to_u32(ifa->drip);
285 285
	    ln->data = ipa_to_u32(ifa->addr->ip);
286
	    ln->metric = ifa->cost;
286
	    ln->metric = link_cost;
287 287
	    ln->padding = 0;
288 288
	    i++;
289 289
	    net_lsa = 1;
......
298 298
	  ln->type = LSART_VLNK;
299 299
	  ln->id = neigh->rid;
300 300
	  ln->data = ipa_to_u32(ifa->addr->ip);
301
	  ln->metric = ifa->cost;
301
	  ln->metric = link_cost;
302 302
	  ln->padding = 0;
303 303
	  i++;
304 304
        }

Also available in: Unified diff