Revision c27b2449

View differences:

doc/bird.sgml
1578 1578

  
1579 1579
<sect1>Attributes
1580 1580

  
1581
<p>OSPF defines three route attributes. Each internal route has a <cf/metric/
1581
<p>OSPF defines four route attributes. Each internal route has a <cf/metric/.
1582 1582
Metric is ranging from 1 to infinity (65535).
1583 1583
External routes use <cf/metric type 1/ or <cf/metric type 2/.
1584 1584
A <cf/metric of type 1/ is comparable with internal <cf/metric/, a
......
1588 1588
Each external route can also carry a <cf/tag/ which is a 32-bit
1589 1589
integer which is used when exporting routes to other protocols;
1590 1590
otherwise, it doesn't affect routing inside the OSPF domain at all.
1591
The fourth attribute is a <cf/router_id/ of the router advertising
1592
that route/network. This attribute is read-only.
1591 1593
Default is <cf/metric of type 2 = 10000/ and <cf/tag = 0/.
1592 1594

  
1593 1595
<sect1>Example
nest/route.h
166 166
    struct {
167 167
      u32 metric1, metric2;		/* OSPF Type 1 and Type 2 metrics */
168 168
      u32 tag;				/* External route tag */
169
      u32 router_id;			/* Router that originated this route */
169 170
    } ospf;
170 171
#endif
171 172
    struct {				/* Routes generated by krt sync (both temporary and inherited ones) */
proto/ospf/config.Y
45 45

  
46 46
CF_DECLS
47 47

  
48
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, BROADCAST)
49
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
48
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
49
CF_KEYWORDS(BROADCAST, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
50 50
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
51 51
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
52 52
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
......
304 304
CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); })
305 305
CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); })
306 306
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
307
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_ROUTER_ID); })
307 308

  
308 309
CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
309 310
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
proto/ospf/ospf.c
278 278
  return
279 279
    new->u.ospf.metric1 == old->u.ospf.metric1 &&
280 280
    new->u.ospf.metric2 == old->u.ospf.metric2 &&
281
    new->u.ospf.tag == old->u.ospf.tag;
281
    new->u.ospf.tag == old->u.ospf.tag &&
282
    new->u.ospf.router_id == old->u.ospf.router_id;
282 283
}
283 284

  
284 285
static ea_list *
285 286
ospf_build_attrs(ea_list * next, struct linpool *pool, u32 m1, u32 m2,
286
		 u32 tag)
287
		 u32 tag, u32 rid)
287 288
{
288 289
  struct ea_list *l =
289
    lp_alloc(pool, sizeof(struct ea_list) + 3 * sizeof(eattr));
290
    lp_alloc(pool, sizeof(struct ea_list) + 4 * sizeof(eattr));
290 291

  
291 292
  l->next = next;
292 293
  l->flags = EALF_SORTED;
293
  l->count = 3;
294
  l->count = 4;
294 295
  l->attrs[0].id = EA_OSPF_METRIC1;
295 296
  l->attrs[0].flags = 0;
296 297
  l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
......
303 304
  l->attrs[2].flags = 0;
304 305
  l->attrs[2].type = EAF_TYPE_INT | EAF_TEMP;
305 306
  l->attrs[2].u.data = tag;
307
  l->attrs[3].id = EA_OSPF_ROUTER_ID;
308
  l->attrs[3].flags = 0;
309
  l->attrs[3].type = EAF_TYPE_INT | EAF_TEMP;
310
  l->attrs[3].u.data = rid;
306 311
  return l;
307 312
}
308 313

  
......
435 440

  
436 441
  if (p == e->attrs->proto)
437 442
    return -1;			/* Reject our own routes */
438
  *attrs = ospf_build_attrs(*attrs, pool, LSINFINITY, 10000, 0);
443
  *attrs = ospf_build_attrs(*attrs, pool, LSINFINITY, 10000, 0, 0);
439 444
  return 0;			/* Leave decision to the filters */
440 445
}
441 446

  
......
443 448
ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool)
444 449
{
445 450
  return ospf_build_attrs(NULL, pool, rt->u.ospf.metric1, rt->u.ospf.metric2,
446
			  rt->u.ospf.tag);
451
			  rt->u.ospf.tag, rt->u.ospf.router_id);
447 452
}
448 453

  
449 454
void
......
452 457
  rt->u.ospf.metric1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY);
453 458
  rt->u.ospf.metric2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000);
454 459
  rt->u.ospf.tag = ea_get_int(attrs, EA_OSPF_TAG, 0);
460
  rt->u.ospf.router_id = ea_get_int(attrs, EA_OSPF_ROUTER_ID, 0);
455 461
}
456 462

  
457 463
/**
......
569 575
  {
570 576
    buf += bsprintf(buf, " [%x]", rte->u.ospf.tag);
571 577
  }
578
  if (rte->u.ospf.router_id)
579
    buf += bsprintf(buf, " [%R]", rte->u.ospf.router_id);
572 580
}
573 581

  
574 582
static int
......
583 591
    bsprintf(buf, "metric2");
584 592
    return GA_NAME;
585 593
  case EA_OSPF_TAG:
586
    bsprintf(buf, "tag: %08x", a->u.data);
594
    bsprintf(buf, "tag: %08x (%u)", a->u.data, a->u.data);
595
    return GA_FULL;
596
 case EA_OSPF_ROUTER_ID:
597
   bsprintf(buf, "router_id: %R (%u)", a->u.data, a->u.data);
587 598
    return GA_FULL;
588 599
  default:
589 600
    return GA_UNKNOWN;
proto/ospf/ospf.h
793 793
#define EA_OSPF_METRIC1	EA_CODE(EAP_OSPF, 0)
794 794
#define EA_OSPF_METRIC2	EA_CODE(EAP_OSPF, 1)
795 795
#define EA_OSPF_TAG	EA_CODE(EAP_OSPF, 2)
796
#define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3)
796 797

  
797 798
#include "proto/ospf/rt.h"
798 799
#include "proto/ospf/hello.h"
proto/ospf/rt.c
38 38
  orta->ifa = NULL;
39 39
  orta->ar = NULL;
40 40
  orta->tag = 0;
41
  orta->rid = 0;
41 42
}
42 43

  
43 44
void
......
158 159
  nf.ar = en;
159 160
  nf.nh = en->nh;
160 161
  nf.ifa = en->nhi;
162
  nf.rid = en->lsa.rt;
161 163

  
162 164
  /* FIXME check nf.ifa on stubs */
163 165
  ri_install(oa->po, px, pxlen, ORT_NET, &nf, NULL);
......
256 258
	  nf.ar = act;
257 259
	  nf.nh = act->nh;
258 260
	  nf.ifa = act->nhi;
261
	  nf.rid = act->lsa.rt;
259 262

  
260 263
	  if (act == oa->rt)
261 264
	    {
......
373 376
      nf.ar = act;
374 377
      nf.nh = act->nh;
375 378
      nf.ifa = act->nhi;
379
      nf.rid = act->lsa.rt;
376 380
      ri_install(po, ipa_from_rid(act->lsa.rt), MAX_PREFIX_LENGTH, ORT_ROUTER, &nf, NULL);
377 381

  
378 382
#ifdef OSPFv2
......
610 614
    nf.ar = abr->n.ar;
611 615
    nf.nh = abr->n.nh;
612 616
    nf.ifa = abr->n.ifa;
617
    nf.rid = en->lsa.rt; /* ABR ID */
613 618
    ri_install(po, ip, pxlen, type, &nf, NULL);
614 619
  }
615 620
}
......
719 724
    nf.ar = abr->n.ar;
720 725
    nf.nh = abr->n.nh;
721 726
    nf.ifa = abr->n.ifa;
727
    nf.rid = en->lsa.rt; /* ABR ID */
722 728
    ri_install(po, ip, pxlen, type, &nf, NULL);
723 729
  }
724 730
}
......
961 967
    nfa.ar = nf1->n.ar;
962 968
    nfa.nh = nh;
963 969
    nfa.ifa = nhi;
970
    nfa.rid = en->lsa.rt;
964 971
    ri_install(po, ip, pxlen, ORT_NET, &nfa, nfh);
965 972
  }
966 973

  
......
1212 1219
        e->u.ospf.metric1 = nf->n.metric1;
1213 1220
        e->u.ospf.metric2 = nf->n.metric2;
1214 1221
        e->u.ospf.tag = nf->n.tag;
1222
        e->u.ospf.router_id = nf->n.rid;
1215 1223
        e->pflags = 0;
1216 1224
        e->net = ne;
1217 1225
        e->pref = p->preference;
proto/ospf/rt.h
28 28
  u32 metric2;
29 29
  ip_addr nh;			/* Next hop */
30 30
  struct ospf_iface *ifa;	/* Outgoing interface */
31
  struct top_hash_entry *ar;	/* Advertising router */
31
  struct top_hash_entry *ar;	/* Advertising router (or ABR) */
32 32
  u32 tag;
33
  u32 rid;			/* Router ID of real advertising router */
34
  /* For ext-LSA from different area, 'ar' is a type 1 LSA of ABR.
35
     Router ID of real advertising router is stored in 'rid'. */
33 36
}
34 37
orta;
35 38

  

Also available in: Unified diff