Thanks Jeremie Dimino for the original patch.
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.
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");
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
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;
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_ADDTO(dynamic_attr, KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SOURCE); })
+
CF_CODE
CF_END
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;
{
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;
}
#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 */
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);