]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Shows source (Router ID) for OSPF routes and adds such attribute.
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 8 Feb 2010 15:01:03 +0000 (16:01 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 8 Feb 2010 15:01:03 +0000 (16:01 +0100)
A sad thing is that we does not have a 'router_id' filter type,
so it must be given as decimal number in filters.

doc/bird.sgml
nest/route.h
proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/ospf/rt.c
proto/ospf/rt.h

index 799972cc1bc64b4b3a2db6985a695035f1ac7844..3d82e45bd9e35025978ae23757b1175b78e65963 100644 (file)
@@ -1578,7 +1578,7 @@ protocol ospf &lt;name&gt; {
 
 <sect1>Attributes
 
-<p>OSPF defines three route attributes. Each internal route has a <cf/metric/
+<p>OSPF defines four route attributes. Each internal route has a <cf/metric/.
 Metric is ranging from 1 to infinity (65535).
 External routes use <cf/metric type 1/ or <cf/metric type 2/.
 A <cf/metric of type 1/ is comparable with internal <cf/metric/, a
@@ -1588,6 +1588,8 @@ If you specify both metrics only metric1 is used.
 Each external route can also carry a <cf/tag/ which is a 32-bit
 integer which is used when exporting routes to other protocols;
 otherwise, it doesn't affect routing inside the OSPF domain at all.
+The fourth attribute is a <cf/router_id/ of the router advertising
+that route/network. This attribute is read-only.
 Default is <cf/metric of type 2 = 10000/ and <cf/tag = 0/.
 
 <sect1>Example
index e45a8c62219db5142d8d394ea4406920ee51f865..99803e7cdf2b033e1ff8cac5cd3157104f7a773e 100644 (file)
@@ -166,6 +166,7 @@ typedef struct rte {
     struct {
       u32 metric1, metric2;            /* OSPF Type 1 and Type 2 metrics */
       u32 tag;                         /* External route tag */
+      u32 router_id;                   /* Router that originated this route */
     } ospf;
 #endif
     struct {                           /* Routes generated by krt sync (both temporary and inherited ones) */
index e809baf9192f7b09d67ee237886ae3337037bef9..aeb8a0dfe05091411c69a754c9100eccc850cf58 100644 (file)
@@ -45,8 +45,8 @@ finish_iface_config(struct ospf_iface_patt *ip)
 
 CF_DECLS
 
-CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, BROADCAST)
-CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
+CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
+CF_KEYWORDS(BROADCAST, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
 CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
 CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
 CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
@@ -304,6 +304,7 @@ opttext:
 CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); })
 CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); })
 CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
+CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_ROUTER_ID); })
 
 CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
 { ospf_sh(proto_get_named($3, &proto_ospf)); };
index 232803d7d1f2065596bc70bf2e1ab3b92dfdc307..d2ceab25a7040cd01ecf62f41a3214766ab55eb3 100644 (file)
@@ -278,19 +278,20 @@ ospf_rte_same(struct rte *new, struct rte *old)
   return
     new->u.ospf.metric1 == old->u.ospf.metric1 &&
     new->u.ospf.metric2 == old->u.ospf.metric2 &&
-    new->u.ospf.tag == old->u.ospf.tag;
+    new->u.ospf.tag == old->u.ospf.tag &&
+    new->u.ospf.router_id == old->u.ospf.router_id;
 }
 
 static ea_list *
 ospf_build_attrs(ea_list * next, struct linpool *pool, u32 m1, u32 m2,
-                u32 tag)
+                u32 tag, u32 rid)
 {
   struct ea_list *l =
-    lp_alloc(pool, sizeof(struct ea_list) + 3 * sizeof(eattr));
+    lp_alloc(pool, sizeof(struct ea_list) + 4 * sizeof(eattr));
 
   l->next = next;
   l->flags = EALF_SORTED;
-  l->count = 3;
+  l->count = 4;
   l->attrs[0].id = EA_OSPF_METRIC1;
   l->attrs[0].flags = 0;
   l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
@@ -303,6 +304,10 @@ ospf_build_attrs(ea_list * next, struct linpool *pool, u32 m1, u32 m2,
   l->attrs[2].flags = 0;
   l->attrs[2].type = EAF_TYPE_INT | EAF_TEMP;
   l->attrs[2].u.data = tag;
+  l->attrs[3].id = EA_OSPF_ROUTER_ID;
+  l->attrs[3].flags = 0;
+  l->attrs[3].type = EAF_TYPE_INT | EAF_TEMP;
+  l->attrs[3].u.data = rid;
   return l;
 }
 
@@ -435,7 +440,7 @@ ospf_import_control(struct proto *p, rte ** new, ea_list ** attrs,
 
   if (p == e->attrs->proto)
     return -1;                 /* Reject our own routes */
-  *attrs = ospf_build_attrs(*attrs, pool, LSINFINITY, 10000, 0);
+  *attrs = ospf_build_attrs(*attrs, pool, LSINFINITY, 10000, 0, 0);
   return 0;                    /* Leave decision to the filters */
 }
 
@@ -443,7 +448,7 @@ struct ea_list *
 ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool)
 {
   return ospf_build_attrs(NULL, pool, rt->u.ospf.metric1, rt->u.ospf.metric2,
-                         rt->u.ospf.tag);
+                         rt->u.ospf.tag, rt->u.ospf.router_id);
 }
 
 void
@@ -452,6 +457,7 @@ ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs)
   rt->u.ospf.metric1 = ea_get_int(attrs, EA_OSPF_METRIC1, LSINFINITY);
   rt->u.ospf.metric2 = ea_get_int(attrs, EA_OSPF_METRIC2, 10000);
   rt->u.ospf.tag = ea_get_int(attrs, EA_OSPF_TAG, 0);
+  rt->u.ospf.router_id = ea_get_int(attrs, EA_OSPF_ROUTER_ID, 0);
 }
 
 /**
@@ -569,6 +575,8 @@ ospf_get_route_info(rte * rte, byte * buf, ea_list * attrs UNUSED)
   {
     buf += bsprintf(buf, " [%x]", rte->u.ospf.tag);
   }
+  if (rte->u.ospf.router_id)
+    buf += bsprintf(buf, " [%R]", rte->u.ospf.router_id);
 }
 
 static int
@@ -583,7 +591,10 @@ ospf_get_attr(eattr * a, byte * buf, int buflen UNUSED)
     bsprintf(buf, "metric2");
     return GA_NAME;
   case EA_OSPF_TAG:
-    bsprintf(buf, "tag: %08x", a->u.data);
+    bsprintf(buf, "tag: %08x (%u)", a->u.data, a->u.data);
+    return GA_FULL;
+ case EA_OSPF_ROUTER_ID:
+   bsprintf(buf, "router_id: %R (%u)", a->u.data, a->u.data);
     return GA_FULL;
   default:
     return GA_UNKNOWN;
index d1ad9f292fa5d1e805047239e0176b9931761cde..17dc15215c48e2ede010e1b8db3bda1487a9a0d0 100644 (file)
@@ -793,6 +793,7 @@ void ospf_sh_state(struct proto *p, int verbose);
 #define EA_OSPF_METRIC1        EA_CODE(EAP_OSPF, 0)
 #define EA_OSPF_METRIC2        EA_CODE(EAP_OSPF, 1)
 #define EA_OSPF_TAG    EA_CODE(EAP_OSPF, 2)
+#define EA_OSPF_ROUTER_ID EA_CODE(EAP_OSPF, 3)
 
 #include "proto/ospf/rt.h"
 #include "proto/ospf/hello.h"
index 8b88d6638cd0dbf20cde3c8b21fedb4dfe3c241e..c3ed19f891c768f6a60163cf9f894c64ae009800 100644 (file)
@@ -38,6 +38,7 @@ fill_ri(orta * orta)
   orta->ifa = NULL;
   orta->ar = NULL;
   orta->tag = 0;
+  orta->rid = 0;
 }
 
 void
@@ -158,6 +159,7 @@ add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_
   nf.ar = en;
   nf.nh = en->nh;
   nf.ifa = en->nhi;
+  nf.rid = en->lsa.rt;
 
   /* FIXME check nf.ifa on stubs */
   ri_install(oa->po, px, pxlen, ORT_NET, &nf, NULL);
@@ -256,6 +258,7 @@ ospf_rt_spfa_rtlinks(struct ospf_area *oa, struct top_hash_entry *act, struct to
          nf.ar = act;
          nf.nh = act->nh;
          nf.ifa = act->nhi;
+         nf.rid = act->lsa.rt;
 
          if (act == oa->rt)
            {
@@ -373,6 +376,7 @@ ospf_rt_spfa(struct ospf_area *oa)
       nf.ar = act;
       nf.nh = act->nh;
       nf.ifa = act->nhi;
+      nf.rid = act->lsa.rt;
       ri_install(po, ipa_from_rid(act->lsa.rt), MAX_PREFIX_LENGTH, ORT_ROUTER, &nf, NULL);
 
 #ifdef OSPFv2
@@ -610,6 +614,7 @@ ospf_rt_sum_tr(struct ospf_area *oa)
     nf.ar = abr->n.ar;
     nf.nh = abr->n.nh;
     nf.ifa = abr->n.ifa;
+    nf.rid = en->lsa.rt; /* ABR ID */
     ri_install(po, ip, pxlen, type, &nf, NULL);
   }
 }
@@ -719,6 +724,7 @@ ospf_rt_sum(struct ospf_area *oa)
     nf.ar = abr->n.ar;
     nf.nh = abr->n.nh;
     nf.ifa = abr->n.ifa;
+    nf.rid = en->lsa.rt; /* ABR ID */
     ri_install(po, ip, pxlen, type, &nf, NULL);
   }
 }
@@ -961,6 +967,7 @@ ospf_ext_spf(struct proto_ospf *po)
     nfa.ar = nf1->n.ar;
     nfa.nh = nh;
     nfa.ifa = nhi;
+    nfa.rid = en->lsa.rt;
     ri_install(po, ip, pxlen, ORT_NET, &nfa, nfh);
   }
 
@@ -1212,6 +1219,7 @@ again1:
         e->u.ospf.metric1 = nf->n.metric1;
         e->u.ospf.metric2 = nf->n.metric2;
         e->u.ospf.tag = nf->n.tag;
+        e->u.ospf.router_id = nf->n.rid;
         e->pflags = 0;
         e->net = ne;
         e->pref = p->preference;
index 5020b473896ff68c2650c9a25bde4ba480b62643..559fa5c6e4f3eb386ace29539010eaf6cc0460fb 100644 (file)
@@ -28,8 +28,11 @@ typedef struct orta
   u32 metric2;
   ip_addr nh;                  /* Next hop */
   struct ospf_iface *ifa;      /* Outgoing interface */
-  struct top_hash_entry *ar;   /* Advertising router */
+  struct top_hash_entry *ar;   /* Advertising router (or ABR) */
   u32 tag;
+  u32 rid;                     /* Router ID of real advertising router */
+  /* For ext-LSA from different area, 'ar' is a type 1 LSA of ABR.
+     Router ID of real advertising router is stored in 'rid'. */
 }
 orta;