]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Route attributes for OSPF.
authorMartin Mares <mj@ucw.cz>
Tue, 30 May 2000 21:25:32 +0000 (21:25 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 30 May 2000 21:25:32 +0000 (21:25 +0000)
nest/route.h
proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/ospf.h
proto/ospf/topology.c
proto/ospf/topology.h

index 640cd490d9e803e2f37e8100b2f50633d870ade0..bc8f35111dae9c300d58b88a8ccacc2b7247e33e 100644 (file)
@@ -287,7 +287,8 @@ typedef struct eattr {
 #define EAP_GENERIC 0                  /* Generic attributes */
 #define EAP_BGP 1                      /* BGP attributes */
 #define EAP_RIP 2                      /* RIP */
-#define EAP_MAX 3
+#define EAP_OSPF 3                     /* OSPF */
+#define EAP_MAX 4
 
 #define EA_CODE(proto,id) (((proto) << 8) | (id))
 #define EA_PROTO(ea) ((ea) >> 8)
index dcd7500efa4ae03db16ea62a4d21a470a988bab8..95741410f0731378ed4b77e3f97fe13578029398 100644 (file)
@@ -12,7 +12,7 @@ CF_HDR
 
 CF_DECLS
 
-CF_KEYWORDS(OSPF, AREA)
+CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG)
 
 CF_GRAMMAR
 
@@ -35,6 +35,10 @@ ospf_area: AREA idval {
  }
  ;
 
+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_CODE
 
 CF_END
index 49e02333e4ad275edf5e6e627f2a3c44542f4e29..b385a4820d86f447ceae6ccb9d5a14a2bcfc9051 100644 (file)
@@ -63,12 +63,13 @@ ospf_init(struct proto_config *c)
   struct proto_ospf *po=(struct proto_ospf *)p;
 
   debug("OSPF: Init requested.\n");
-  p->neigh_notify = NULL;
   p->import_control = ospf_import_control;
+  p->make_tmp_attrs = ospf_make_tmp_attrs;
+  p->store_tmp_attrs = ospf_store_tmp_attrs;
   p->rt_notify = ospf_rt_notify;
   p->if_notify = ospf_if_notify;
-  p->rte_better=ospf_rte_better;
-  p->rte_same=ospf_rte_same;
+  p->rte_better = ospf_rte_better;
+  p->rte_same = ospf_rte_same;
 
   return p;
 }
@@ -104,12 +105,34 @@ ospf_rte_better(struct rte *new, struct rte *old)
 static int
 ospf_rte_same(struct rte *new, struct rte *old)
 {
-  struct proto *p = new->attrs->proto;
+  /* new->attrs == old->attrs always */
+  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;
+}
 
-  if(new->attrs->source!=old->attrs->source) return 0;
-  if(new->u.ospf.metric1!=old->u.ospf.metric1) return 0;
-  if(new->u.ospf.metric2!=old->u.ospf.metric2) return 0;
-  return 1;
+static ea_list *
+ospf_build_attrs(ea_list *next, struct linpool *pool, u32 m1, u32 m2, u32 tag)
+{
+  struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 3*sizeof(eattr));
+
+  l->next = next;
+  l->flags = EALF_SORTED;
+  l->count = 3;
+  l->attrs[0].id = EA_OSPF_METRIC1;
+  l->attrs[0].flags = 0;
+  l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
+  l->attrs[0].u.data = m1;
+  l->attrs[1].id = EA_OSPF_METRIC2;
+  l->attrs[1].flags = 0;
+  l->attrs[1].type = EAF_TYPE_INT | EAF_TEMP;
+  l->attrs[1].u.data = m2;
+  l->attrs[2].id = EA_OSPF_TAG;
+  l->attrs[2].flags = 0;
+  l->attrs[2].type = EAF_TYPE_INT | EAF_TEMP;
+  l->attrs[2].u.data = tag;
+  return l;
 }
 
 int
@@ -118,9 +141,23 @@ ospf_import_control(struct proto *p, rte **new, ea_list **attrs, struct linpool
   rte *e=*new;
   struct proto_ospf *po=(struct proto_ospf *)p;
 
-  if(p==e->attrs->proto) return -1;
+  if(p==e->attrs->proto) return -1;    /* Reject our own routes */
+  *attrs = ospf_build_attrs(*attrs, pool, 0, 0, 0); /* FIXME: Use better defaults? */
+  return 0;                            /* Leave decision to the filters */
+}
 
-  return 0;
+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);
+}
+
+void
+ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs)
+{
+  rt->u.ospf.metric1 = ea_get_int(attrs, EA_OSPF_METRIC1, 0);
+  rt->u.ospf.metric2 = ea_get_int(attrs, EA_OSPF_METRIC2, 0);
+  rt->u.ospf.tag     = ea_get_int(attrs, EA_OSPF_TAG,     0);
 }
 
 static int
@@ -152,7 +189,7 @@ ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old, ea_list *attrs)
 
   if(new)              /* Got some new route */
   {
-    originate_ext_lsa(n, new, po);
+    originate_ext_lsa(n, new, po, attrs);
   }
   else
   {
@@ -210,13 +247,27 @@ ospf_get_route_info(rte *rte, byte *buf, ea_list *attrs)
     (rte->u.ospf.metric2==0) ? rte->u.ospf.metric1 : rte->u.ospf.metric2);
 }
 
+static int
+ospf_get_attr(eattr *a, byte *buf)
+{
+  switch (a->id)
+    {
+    case EA_OSPF_METRIC1: bsprintf(buf, "metric1"); return GA_NAME;
+    case EA_OSPF_METRIC2: bsprintf(buf, "metric2"); return GA_NAME;
+    case EA_OSPF_TAG: bsprintf(buf, "tag: %08x", a->u.data); return GA_FULL;
+    default: return GA_UNKNOWN;
+    }
+}
+
 struct protocol proto_ospf = {
   name:                "OSPF",
   template:            "ospf%d",
+  attr_class:          EAP_OSPF,
   init:                        ospf_init,
   dump:                        ospf_dump,
   start:               ospf_start,
   shutdown:            ospf_shutdown,
   get_route_info:      ospf_get_route_info,
+  get_attr:            ospf_get_attr,
   get_status:          ospf_get_status
 };
index 0eaf98bc7d69f0c5b1ae2029cb576be5fc810246..63c4fc2219fce7bbfb22ad59cb1803ea3e9534ab 100644 (file)
@@ -353,8 +353,14 @@ static int ospf_rte_better(struct rte *new, struct rte *old);
 static int ospf_rte_same(struct rte *new, struct rte *old);
 int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,
   struct linpool *pool);
+struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
+void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
 void ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old,ea_list *attrs);
 
+#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)
+
 #include "proto/ospf/hello.h"
 #include "proto/ospf/packet.h"
 #include "proto/ospf/iface.h"
index 053ea4bc42f59906b978aaf86b2f6268174df286..bb3cb062a04e20dddd8b74dd1fe4b442c94bcfcb 100644 (file)
@@ -319,38 +319,42 @@ originate_net_lsa(struct ospf_iface *ifa, struct proto_ospf *po)
   flood_lsa(NULL,NULL,&ifa->nlsa->lsa,po,NULL,ifa->oa,1);
 }
 
-void *
-originate_ext_lsa_body(net *n, rte *e, struct proto_ospf *po)
+static void *
+originate_ext_lsa_body(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs)
 {
   struct proto *p=&po->proto;
   struct ospf_lsa_ext *ext;
   struct ospf_lsa_ext_tos *et;
   neighbor *nn;
+  u32 m1 = ea_get_int(attrs, EA_OSPF_METRIC1, 0);
+  u32 m2 = ea_get_int(attrs, EA_OSPF_METRIC2, 0);
+  u32 tag = ea_get_int(attrs, EA_OSPF_TAG, 0);
 
   ext=mb_alloc(p->pool,sizeof(struct ospf_lsa_ext)+
     sizeof(struct ospf_lsa_ext_tos));
   ext->netmask=ipa_mkmask(n->n.pxlen);
 
   et=(struct ospf_lsa_ext_tos *)(ext+1);
-  if(e->u.ospf.metric2!=0)
-  {
-    et->etos=0;
-    et->metric=e->u.ospf.metric1;
-  }
+
+  if(!m2)
+    {
+      et->etos=0;
+      et->metric=m1;
+    }
   else
-  {
-    et->etos=1;
-    et->metric=e->u.ospf.metric2;
-  }
+    {
+      et->etos=0x80;
+      et->metric=m2;
+    }
   et->padding=0;
-  et->tag=e->u.ospf.tag;
+  et->tag=tag;
   if(1) et->fwaddr= ipa_from_u32(0); /* FIXME if e->attrs->iface is not in my AS*/
   else et->fwaddr=e->attrs->gw;
   return ext;
 }
 
 void
-originate_ext_lsa(net *n, rte *e, struct proto_ospf *po)
+originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs)
 {
   struct ospf_lsa_header lsa;
   u32 rtid=po->proto.cf->global->router_id;
@@ -366,7 +370,7 @@ originate_ext_lsa(net *n, rte *e, struct proto_ospf *po)
   lsa.type=LSA_T_EXT;
   lsa.rt=rtid;
   lsa.sn=LSA_INITSEQNO;
-  body=originate_ext_lsa_body(n, e, po);
+  body=originate_ext_lsa_body(n, e, po, attrs);
   lsa.length=sizeof(struct ospf_lsa_ext)+sizeof(struct ospf_lsa_ext_tos)+
     sizeof(struct ospf_lsa_header);
   lsasum_calculate(&lsa,body,po);
index 23620b8150fa05bf44c889dddc0d41fd781ae15b..fe0d86ea7ed85b5e98a672d5a7c864cb1fdd4b10 100644 (file)
@@ -49,6 +49,6 @@ void addifa_rtlsa(struct ospf_iface *ifa);
 void originate_rt_lsa(struct ospf_area *oa,struct proto_ospf *po);
 void originate_net_lsa(struct ospf_iface *ifa,struct proto_ospf *po);
 int can_flush_lsa(struct ospf_area *oa);
-void originate_ext_lsa(net *n, rte *e, struct proto_ospf *po);
+void originate_ext_lsa(net *n, rte *e, struct proto_ospf *po, struct ea_list *attrs);
 
 #endif /* _BIRD_OSPF_TOPOLOGY_H_ */