Adds krt_source route attribute.

Thanks Jeremie Dimino for the original patch.
This commit is contained in:
Ondrej Zajicek 2012-03-23 00:26:26 +01:00
parent 89647357af
commit 72aed1a00b
6 changed files with 44 additions and 6 deletions

View file

@ -1653,6 +1653,12 @@ 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
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. <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

@ -255,10 +255,11 @@ krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
ip_addr idst, igate, imask; ip_addr idst, igate, imask;
void *body = (char *)msg->buf; void *body = (char *)msg->buf;
int new = (msg->rtm.rtm_type == RTM_ADD); int new = (msg->rtm.rtm_type == RTM_ADD);
int src;
char *errmsg = "KRT: Invalid route received"; char *errmsg = "KRT: Invalid route received";
int flags = msg->rtm.rtm_flags; int flags = msg->rtm.rtm_flags;
int addrs = msg->rtm.rtm_addrs; int addrs = msg->rtm.rtm_addrs;
int src;
byte src2;
if (!(flags & RTF_UP) && scan) if (!(flags & RTF_UP) && scan)
SKIP("not up in scan\n"); 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 self_mask = RTF_PROTO1;
u32 alien_mask = RTF_STATIC | RTF_PROTO1 | RTF_GATEWAY; u32 alien_mask = RTF_STATIC | RTF_PROTO1 | RTF_GATEWAY;
src2 = (flags & RTF_STATIC) ? 1 : 0;
src2 |= (flags & RTF_PROTO1) ? 2 : 0;
#ifdef RTF_PROTO2 #ifdef RTF_PROTO2
alien_mask |= RTF_PROTO2; alien_mask |= RTF_PROTO2;
src2 |= (flags & RTF_PROTO2) ? 4 : 0;
#endif #endif
#ifdef RTF_PROTO3 #ifdef RTF_PROTO3
alien_mask |= RTF_PROTO3; alien_mask |= RTF_PROTO3;
src2 |= (flags & RTF_PROTO3) ? 8 : 0;
#endif #endif
#ifdef RTF_REJECT #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 = rte_get_temp(&a);
e->net = net; e->net = net;
e->u.krt.src = src; e->u.krt.src = src;
e->u.krt.proto = src2;
/* These are probably too Linux-specific */ /* These are probably too Linux-specific */
e->u.krt.proto = 0;
e->u.krt.type = 0; e->u.krt.type = 0;
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) CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, KRT_SOURCE)
CF_GRAMMAR 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_CODE
CF_END CF_END

View file

@ -907,12 +907,29 @@ krt_shutdown(struct proto *P)
return PS_DOWN; 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 * static struct proto *
krt_init(struct proto_config *c) krt_init(struct proto_config *c)
{ {
struct krt_proto *p = proto_new(c, sizeof(struct krt_proto)); struct krt_proto *p = proto_new(c, sizeof(struct krt_proto));
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.import_control = krt_import_control; p->p.import_control = krt_import_control;
p->p.rt_notify = krt_notify; p->p.rt_notify = krt_notify;
@ -952,12 +969,18 @@ krt_get_attr(eattr * a, byte * buf, int buflen UNUSED)
{ {
switch (a->id) switch (a->id)
{ {
case EA_KRT_SOURCE:
bsprintf(buf, "source");
return GA_NAME;
case EA_KRT_PREFSRC: case EA_KRT_PREFSRC:
bsprintf(buf, "prefsrc"); bsprintf(buf, "prefsrc");
return GA_NAME; return GA_NAME;
case EA_KRT_REALM: case EA_KRT_REALM:
bsprintf(buf, "realm"); bsprintf(buf, "realm");
return GA_NAME; return GA_NAME;
default: default:
return GA_UNKNOWN; return GA_UNKNOWN;
} }

View file

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

View file

@ -191,7 +191,7 @@ sysdep_preconfig(struct config *c)
init_list(&c->logfiles); init_list(&c->logfiles);
#ifdef PATH_IPROUTE_DIR #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_realms", "ipr_", 256);
read_iproute_table(PATH_IPROUTE_DIR "/rt_scopes", "ips_", 256); read_iproute_table(PATH_IPROUTE_DIR "/rt_scopes", "ips_", 256);
read_iproute_table(PATH_IPROUTE_DIR "/rt_tables", "ipt_", 256); read_iproute_table(PATH_IPROUTE_DIR "/rt_tables", "ipt_", 256);