]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Adds krt_metric linux route attribute.
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 23 Mar 2012 00:17:02 +0000 (01:17 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 23 Mar 2012 16:22:13 +0000 (17:22 +0100)
doc/bird.sgml
sysdep/linux/netlink/netlink.c
sysdep/unix/krt.Y
sysdep/unix/krt.c
sysdep/unix/krt.h

index 5f478066432d1a902a61c958bd3335f9c029821d..5244fc393762f574e255fd6235ae9a96352a5852 100644 (file)
@@ -1653,12 +1653,16 @@ are translated to appropriate system (and OS-specific) route attributes.
 We support these attributes:
 
 <descrip>
-       <tag>int <cf/krt_source/</tag> The source of the imported
+       <tag>int <cf/krt_source/</tag> The original source of the imported
        kernel route.  The value is system-dependent. On Linux, it is
        a value of the protocol field of the route. See
        /etc/iproute2/rt_protos for common values.  On BSD, it is
        based on STATIC and PROTOx flags. The attribute is read-only.
 
+       <tag>int <cf/krt_metric/</tag> The kernel metric of
+       the route.  When multiple same routes are in a kernel routing
+       table, the Linux kernel chooses one with lower metric.
+
        <tag>ip <cf/krt_prefsrc/</tag> (Linux) The preferred source address.
        Used in source address selection for outgoing packets. Have to
        be one of IP addresses of the router.
index 17c369ea8dd42360bcb7027bb76994a788c4a080..a0743da7b769390fed163832470686555217401d 100644 (file)
@@ -639,6 +639,9 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
   r.r.rtm_scope = RT_SCOPE_UNIVERSE;
   nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix);
 
+  if (ea = ea_find(a->eattrs, EA_KRT_METRIC))
+    nl_add_attr_u32(&r.h, sizeof(r), RTA_PRIORITY, ea->u.data);
+
   if (ea = ea_find(a->eattrs, EA_KRT_PREFSRC))
     nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
 
@@ -886,7 +889,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
   e->u.krt.type = i->rtm_type;
 
   if (a[RTA_PRIORITY])
-    memcpy(&e->u.krt.metric, RTA_DATA(a[RTA_PRIORITY]), sizeof(e->u.krt.metric));
+    memcpy(&e->u.krt.metric, RTA_DATA(a[RTA_PRIORITY]), sizeof(e->u.krt.metric)); 
   else
     e->u.krt.metric = 0;
 
index 2c45c5fec5a2b5769850053634873ad80717d0a1..c0141f574b629b2b209336b781e03bef1625357c 100644 (file)
@@ -17,7 +17,7 @@ CF_DEFINES
 
 CF_DECLS
 
-CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, KRT_SOURCE)
+CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, KRT_SOURCE, KRT_METRIC)
 
 CF_GRAMMAR
 
@@ -90,7 +90,8 @@ kif_item:
    }
  ;
 
-CF_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SOURCE); })
+CF_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_KRT_SOURCE); })
+CF_ADDTO(dynamic_attr, KRT_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_KRT_METRIC); })
 
 CF_CODE
 
index de1188a137cffe44bee31ef0aa1cf1bb9259742c..f4bfca784b93a59050f547ec674ce59d7b6cda4c 100644 (file)
@@ -907,22 +907,36 @@ krt_shutdown(struct proto *P)
   return PS_DOWN;
 }
 
-struct ea_list *
+static struct ea_list *
 krt_make_tmp_attrs(struct rte *rt, struct linpool *pool)
 {
-  struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 1 * sizeof(eattr));
+  struct ea_list *l = lp_alloc(pool, sizeof(struct ea_list) + 2 * sizeof(eattr));
 
   l->next = NULL;
   l->flags = EALF_SORTED;
-  l->count = 1;
+  l->count = 2;
+
   l->attrs[0].id = EA_KRT_SOURCE;
   l->attrs[0].flags = 0;
   l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
   l->attrs[0].u.data = rt->u.krt.proto;
 
+  l->attrs[1].id = EA_KRT_METRIC;
+  l->attrs[1].flags = 0;
+  l->attrs[1].type = EAF_TYPE_INT | EAF_TEMP;
+  l->attrs[1].u.data = rt->u.krt.metric;
+
   return l;
 }
 
+static void
+krt_store_tmp_attrs(struct rte *rt, struct ea_list *attrs)
+{
+  /* EA_KRT_SOURCE is read-only */
+  rt->u.krt.metric = ea_get_int(attrs, EA_KRT_METRIC, 0);
+}
+
+
 static struct proto *
 krt_init(struct proto_config *c)
 {
@@ -930,6 +944,7 @@ krt_init(struct proto_config *c)
 
   p->p.accept_ra_types = RA_OPTIMAL;
   p->p.make_tmp_attrs = krt_make_tmp_attrs;
+  p->p.store_tmp_attrs = krt_store_tmp_attrs;
   p->p.import_control = krt_import_control;
   p->p.rt_notify = krt_notify;
 
@@ -973,6 +988,10 @@ krt_get_attr(eattr * a, byte * buf, int buflen UNUSED)
     bsprintf(buf, "source");
     return GA_NAME;
 
+  case EA_KRT_METRIC:
+    bsprintf(buf, "metric");
+    return GA_NAME;
+
   case EA_KRT_PREFSRC:
     bsprintf(buf, "prefsrc");
     return GA_NAME;
index aa1eccaaa6ddaa8773c1017fb1b9121e31c44176..d859c5b8cb70fe376bb9e86e1da07d9471db58ce 100644 (file)
@@ -29,8 +29,9 @@ struct kif_proto;
 #define KRF_IGNORE 4                   /* To be ignored */
 
 #define EA_KRT_SOURCE  EA_CODE(EAP_KRT, 0)
-#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 1)
-#define EA_KRT_REALM   EA_CODE(EAP_KRT, 2)
+#define EA_KRT_METRIC  EA_CODE(EAP_KRT, 1)
+#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 2)
+#define EA_KRT_REALM   EA_CODE(EAP_KRT, 3)
 
 /* Whenever we recognize our own routes, we allow learing of foreign routes */