Adds krt_metric linux route attribute.

This commit is contained in:
Ondrej Zajicek 2012-03-23 01:17:02 +01:00
parent 72aed1a00b
commit 9ba2798c65
5 changed files with 37 additions and 9 deletions

View file

@ -1653,12 +1653,16 @@ are translated to appropriate system (and OS-specific) route attributes.
We support these attributes: We support these attributes:
<descrip> <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 kernel route. The value is system-dependent. On Linux, it is
a value of the protocol field of the route. See a value of the protocol field of the route. See
/etc/iproute2/rt_protos for common values. On BSD, it is /etc/iproute2/rt_protos for common values. On BSD, it is
based on STATIC and PROTOx flags. The attribute is read-only. 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. <tag>ip <cf/krt_prefsrc/</tag> (Linux) The preferred source address.
Used in source address selection for outgoing packets. Have to Used in source address selection for outgoing packets. Have to
be one of IP addresses of the router. be one of IP addresses of the router.

View file

@ -639,6 +639,9 @@ nl_send_route(struct krt_proto *p, rte *e, int new)
r.r.rtm_scope = RT_SCOPE_UNIVERSE; r.r.rtm_scope = RT_SCOPE_UNIVERSE;
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix); 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)) 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); 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; e->u.krt.type = i->rtm_type;
if (a[RTA_PRIORITY]) 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 else
e->u.krt.metric = 0; e->u.krt.metric = 0;

View file

@ -17,7 +17,7 @@ CF_DEFINES
CF_DECLS 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 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 CF_CODE

View file

@ -907,22 +907,36 @@ krt_shutdown(struct proto *P)
return PS_DOWN; return PS_DOWN;
} }
struct ea_list * static struct ea_list *
krt_make_tmp_attrs(struct rte *rt, struct linpool *pool) 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->next = NULL;
l->flags = EALF_SORTED; l->flags = EALF_SORTED;
l->count = 1; l->count = 2;
l->attrs[0].id = EA_KRT_SOURCE; l->attrs[0].id = EA_KRT_SOURCE;
l->attrs[0].flags = 0; l->attrs[0].flags = 0;
l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP; l->attrs[0].type = EAF_TYPE_INT | EAF_TEMP;
l->attrs[0].u.data = rt->u.krt.proto; 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; 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 * static struct proto *
krt_init(struct proto_config *c) 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.accept_ra_types = RA_OPTIMAL;
p->p.make_tmp_attrs = krt_make_tmp_attrs; 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.import_control = krt_import_control;
p->p.rt_notify = krt_notify; p->p.rt_notify = krt_notify;
@ -973,6 +988,10 @@ krt_get_attr(eattr * a, byte * buf, int buflen UNUSED)
bsprintf(buf, "source"); bsprintf(buf, "source");
return GA_NAME; return GA_NAME;
case EA_KRT_METRIC:
bsprintf(buf, "metric");
return GA_NAME;
case EA_KRT_PREFSRC: case EA_KRT_PREFSRC:
bsprintf(buf, "prefsrc"); bsprintf(buf, "prefsrc");
return GA_NAME; return GA_NAME;

View file

@ -29,8 +29,9 @@ struct kif_proto;
#define KRF_IGNORE 4 /* To be ignored */ #define KRF_IGNORE 4 /* To be ignored */
#define EA_KRT_SOURCE EA_CODE(EAP_KRT, 0) #define EA_KRT_SOURCE EA_CODE(EAP_KRT, 0)
#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 1) #define EA_KRT_METRIC EA_CODE(EAP_KRT, 1)
#define EA_KRT_REALM EA_CODE(EAP_KRT, 2) #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 */ /* Whenever we recognize our own routes, we allow learing of foreign routes */