]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Adds krt_source route attribute.
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 22 Mar 2012 23:26:26 +0000 (00:26 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 22 Mar 2012 23:26:26 +0000 (00:26 +0100)
Thanks Jeremie Dimino for the original patch.

doc/bird.sgml
sysdep/bsd/krt-sock.c
sysdep/unix/krt.Y
sysdep/unix/krt.c
sysdep/unix/krt.h
sysdep/unix/main.c

index 4024f137d0c1f0dfa4c7406e44af6e8996479a22..5f478066432d1a902a61c958bd3335f9c029821d 100644 (file)
@@ -1653,6 +1653,12 @@ 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
+       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>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 4ee5495f1e238a06c57e37924a2ed484c9a3c351..eb92d908bc23b55c79ff66e7e9a660d3e92dd40d 100644 (file)
@@ -255,10 +255,11 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
   ip_addr idst, igate, imask;
   void *body = (char *)msg->buf;
   int new = (msg->rtm.rtm_type == RTM_ADD);
-  int src;
   char *errmsg = "KRT: Invalid route received";
   int flags = msg->rtm.rtm_flags;
   int addrs = msg->rtm.rtm_addrs;
+  int src;
+  byte src2;
 
   if (!(flags & RTF_UP) && scan)
     SKIP("not up in scan\n");
@@ -302,12 +303,17 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
   u32 self_mask = RTF_PROTO1;
   u32 alien_mask = RTF_STATIC | RTF_PROTO1 | RTF_GATEWAY;
 
+  src2 = (flags & RTF_STATIC) ? 1 : 0;
+  src2 |= (flags & RTF_PROTO1) ? 2 : 0;
+
 #ifdef RTF_PROTO2
   alien_mask |= RTF_PROTO2;
+  src2 |= (flags & RTF_PROTO2) ? 4 : 0;
 #endif
 
 #ifdef RTF_PROTO3
   alien_mask |= RTF_PROTO3;
+  src2 |= (flags & RTF_PROTO3) ? 8 : 0;
 #endif
 
 #ifdef RTF_REJECT
@@ -397,9 +403,9 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
   e = rte_get_temp(&a);
   e->net = net;
   e->u.krt.src = src;
+  e->u.krt.proto = src2;
 
   /* These are probably too Linux-specific */
-  e->u.krt.proto = 0;
   e->u.krt.type = 0;
   e->u.krt.metric = 0;
 
index 18e1e52ddd57a32631a64bca490ffbecb9945473..2c45c5fec5a2b5769850053634873ad80717d0a1 100644 (file)
@@ -17,7 +17,7 @@ CF_DEFINES
 
 CF_DECLS
 
-CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES)
+CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, KRT_SOURCE)
 
 CF_GRAMMAR
 
@@ -90,6 +90,8 @@ kif_item:
    }
  ;
 
+CF_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SOURCE); })
+
 CF_CODE
 
 CF_END
index 0fb8c4f9363d13dacf88d9c70bd7dc5acfae0fff..de1188a137cffe44bee31ef0aa1cf1bb9259742c 100644 (file)
@@ -907,12 +907,29 @@ krt_shutdown(struct proto *P)
   return PS_DOWN;
 }
 
+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));
+
+  l->next = NULL;
+  l->flags = EALF_SORTED;
+  l->count = 1;
+  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;
+
+  return l;
+}
+
 static struct proto *
 krt_init(struct proto_config *c)
 {
   struct krt_proto *p = proto_new(c, sizeof(struct krt_proto));
 
   p->p.accept_ra_types = RA_OPTIMAL;
+  p->p.make_tmp_attrs = krt_make_tmp_attrs;
   p->p.import_control = krt_import_control;
   p->p.rt_notify = krt_notify;
 
@@ -952,12 +969,18 @@ krt_get_attr(eattr * a, byte * buf, int buflen UNUSED)
 {
   switch (a->id)
   {
+  case EA_KRT_SOURCE:
+    bsprintf(buf, "source");
+    return GA_NAME;
+
   case EA_KRT_PREFSRC:
     bsprintf(buf, "prefsrc");
     return GA_NAME;
+
   case EA_KRT_REALM:
     bsprintf(buf, "realm");
     return GA_NAME;
+
   default:
     return GA_UNKNOWN;
   }
index b0c4dc5e5c8a92060ebcd0f17aa6b9839dd5cce2..aa1eccaaa6ddaa8773c1017fb1b9121e31c44176 100644 (file)
@@ -28,8 +28,9 @@ struct kif_proto;
 #define KRF_DELETE 3                   /* Should be deleted */
 #define KRF_IGNORE 4                   /* To be ignored */
 
-#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 0)
-#define EA_KRT_REALM EA_CODE(EAP_KRT, 1)
+#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)
 
 /* Whenever we recognize our own routes, we allow learing of foreign routes */
 
index a4e80154650bd3c27e9acdd14b56573a49b1f077..9219da9b6d68c679c034063cab1d79e00c292ff3 100644 (file)
@@ -191,7 +191,7 @@ sysdep_preconfig(struct config *c)
   init_list(&c->logfiles);
 
 #ifdef PATH_IPROUTE_DIR
-  // read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 256);
+  read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 256);
   read_iproute_table(PATH_IPROUTE_DIR "/rt_realms", "ipr_", 256);
   read_iproute_table(PATH_IPROUTE_DIR "/rt_scopes", "ips_", 256);
   read_iproute_table(PATH_IPROUTE_DIR "/rt_tables", "ipt_", 256);