<tag>int <cf/krt_realm/</tag> (Linux)
The realm of the route. Can be used for traffic classification.
+
+ <tag>int <cf/krt_scope/</tag> (Linux IPv4)
+ The scope of the route. Valid values are 0-254, although Linux kernel
+ may reject some values depending on route type and nexthop. It is
+ supposed to represent `indirectness' of the route, where nexthops of
+ routes are resolved through routes with a higher scope, but in current
+ kernels anything below <it/link/ (253) is treated as <it/global/ (0).
+ When not present, global scope is implied for all routes except device
+ routes, where link scope is used by default.
</descrip>
<p>In Linux, there is also a plenty of obscure route attributes mostly focused
#define EA_KRT_PREFSRC EA_CODE(EAP_KRT, 0x10)
#define EA_KRT_REALM EA_CODE(EAP_KRT, 0x11)
+#define EA_KRT_SCOPE EA_CODE(EAP_KRT, 0x12)
#define KRT_METRICS_MAX 0x10 /* RTAX_QUICKACK+1 */
CF_DECLS
-CF_KEYWORDS(KERNEL, TABLE, METRIC, KRT_PREFSRC, KRT_REALM, KRT_MTU, KRT_WINDOW,
+CF_KEYWORDS(KERNEL, TABLE, METRIC, KRT_PREFSRC, KRT_REALM, KRT_SCOPE, KRT_MTU, KRT_WINDOW,
KRT_RTT, KRT_RTTVAR, KRT_SSTRESH, KRT_CWND, KRT_ADVMSS, KRT_REORDERING,
KRT_HOPLIMIT, KRT_INITCWND, KRT_RTO_MIN, KRT_INITRWND, KRT_QUICKACK,
KRT_LOCK_MTU, KRT_LOCK_WINDOW, KRT_LOCK_RTT, KRT_LOCK_RTTVAR,
CF_ADDTO(dynamic_attr, KRT_PREFSRC { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_KRT_PREFSRC); })
CF_ADDTO(dynamic_attr, KRT_REALM { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_REALM); })
+CF_ADDTO(dynamic_attr, KRT_SCOPE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SCOPE); })
CF_ADDTO(dynamic_attr, KRT_MTU { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_MTU); })
CF_ADDTO(dynamic_attr, KRT_WINDOW { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_WINDOW); })
r.r.rtm_family = BIRD_AF;
r.r.rtm_dst_len = net->n.pxlen;
r.r.rtm_protocol = RTPROT_BIRD;
- r.r.rtm_scope = RT_SCOPE_UNIVERSE;
+ r.r.rtm_scope = RT_SCOPE_NOWHERE;
nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix);
/*
if (op == NL_OP_DELETE)
goto dest;
+ /* Default scope is LINK for device routes, UNIVERSE otherwise */
+ if (ea = ea_find(eattrs, EA_KRT_SCOPE))
+ r.r.rtm_scope = ea->u.data;
+ else
+ r.r.rtm_scope = (dest == RTD_DEVICE) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE;
+
if (ea = ea_find(eattrs, EA_KRT_PREFSRC))
nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
u32 oif = ~0;
u32 table;
u32 priority = 0;
+ u32 def_scope = RT_SCOPE_UNIVERSE;
int src;
if (!(i = nl_checkin(h, sizeof(*i))))
return;
}
-
if (a[RTA_DST])
{
memcpy(&dst, RTA_DATA(a[RTA_DST]), sizeof(dst));
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
SKIP("strange class/scope\n");
- // ignore rtm_scope, it is not a real scope
- // if (i->rtm_scope != RT_SCOPE_UNIVERSE)
- // SKIP("scope %u\n", i->rtm_scope);
-
-
switch (i->rtm_protocol)
{
case RTPROT_UNSPEC:
else
{
ra->dest = RTD_DEVICE;
+ def_scope = RT_SCOPE_LINK;
}
break;
return;
}
+ if (i->rtm_scope != def_scope)
+ {
+ ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + sizeof(eattr));
+ ea->next = ra->eattrs;
+ ra->eattrs = ea;
+ ea->flags = EALF_SORTED;
+ ea->count = 1;
+ ea->attrs[0].id = EA_KRT_SCOPE;
+ ea->attrs[0].flags = 0;
+ ea->attrs[0].type = EAF_TYPE_INT;
+ ea->attrs[0].u.data = i->rtm_scope;
+ }
+
if (a[RTA_PREFSRC])
{
ip_addr ps;
bsprintf(buf, "realm");
return GA_NAME;
+ case EA_KRT_SCOPE:
+ bsprintf(buf, "scope");
+ return GA_NAME;
+
case EA_KRT_LOCK:
buf += bsprintf(buf, "lock:");
ea_format_bitfield(a, buf, buflen, krt_metrics_names, 2, KRT_METRICS_MAX);