mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
MPLS: RTA_ENCAP parsing in netlink interface
This commit is contained in:
parent
45f01fb32e
commit
ec11f99243
@ -194,7 +194,7 @@ net_classify(const net_addr *N)
|
|||||||
return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
|
return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
|
||||||
|
|
||||||
case NET_MPLS:
|
case NET_MPLS:
|
||||||
return IADDR_HOST | SCOPE_SITE;
|
return IADDR_HOST | SCOPE_UNIVERSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IADDR_INVALID;
|
return IADDR_INVALID;
|
||||||
|
@ -64,10 +64,6 @@
|
|||||||
#define RTA_ENCAP 22
|
#define RTA_ENCAP 22
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AF_MPLS
|
|
||||||
#define AF_MPLS 28
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Synchronous Netlink interface
|
* Synchronous Netlink interface
|
||||||
*/
|
*/
|
||||||
@ -283,6 +279,10 @@ static struct nl_want_attrs mpnh_attr_want4[BIRD_RTA_MAX] = {
|
|||||||
[RTA_GATEWAY] = { 1, 1, sizeof(ip4_addr) },
|
[RTA_GATEWAY] = { 1, 1, sizeof(ip4_addr) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct nl_want_attrs encap_mpls_want[BIRD_RTA_MAX] = {
|
||||||
|
[RTA_DST] = { 1, 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
static struct nl_want_attrs rtm_attr_want4[BIRD_RTA_MAX] = {
|
static struct nl_want_attrs rtm_attr_want4[BIRD_RTA_MAX] = {
|
||||||
[RTA_DST] = { 1, 1, sizeof(ip4_addr) },
|
[RTA_DST] = { 1, 1, sizeof(ip4_addr) },
|
||||||
[RTA_OIF] = { 1, 1, sizeof(u32) },
|
[RTA_OIF] = { 1, 1, sizeof(u32) },
|
||||||
@ -1027,6 +1027,21 @@ mpls_from_ea(struct adata *ad) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define mpls_to_ea(ms, oea) do { \
|
||||||
|
ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr)); \
|
||||||
|
ea->next = oea; \
|
||||||
|
oea = ea; \
|
||||||
|
ea->flags = EALF_SORTED; \
|
||||||
|
ea->count = 1; \
|
||||||
|
ea->attrs[0].id = EA_GEN_MPLS_STACK; \
|
||||||
|
ea->attrs[0].flags = 0; \
|
||||||
|
ea->attrs[0].type = EAF_TYPE_INT_SET; \
|
||||||
|
ea->attrs[0].u.ptr = alloca(sizeof(struct adata) + sizeof(u32)*ms.len); \
|
||||||
|
ea->attrs[0].u.ptr->length = sizeof(u32)*ms.len; \
|
||||||
|
for (int j = 0; j < ms.len; j++) \
|
||||||
|
((u32 *)ea->attrs[0].u.ptr->data)[j] = ms.label[j]; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
|
nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
|
||||||
{
|
{
|
||||||
@ -1235,7 +1250,7 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
|||||||
SKIP("RTM_DELROUTE in scan\n");
|
SKIP("RTM_DELROUTE in scan\n");
|
||||||
|
|
||||||
int c = net_classify(&dst);
|
int c = net_classify(&dst);
|
||||||
if (i->rtm_family != AF_MPLS && ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK)))
|
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||||
SKIP("strange class/scope\n");
|
SKIP("strange class/scope\n");
|
||||||
|
|
||||||
// ignore rtm_scope, it is not a real scope
|
// ignore rtm_scope, it is not a real scope
|
||||||
@ -1355,19 +1370,26 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
|||||||
if ((i->rtm_family == AF_MPLS) && a[RTA_NEWDST])
|
if ((i->rtm_family == AF_MPLS) && a[RTA_NEWDST])
|
||||||
{
|
{
|
||||||
mpls_stack ms = rta_get_mpls(a[RTA_NEWDST]);
|
mpls_stack ms = rta_get_mpls(a[RTA_NEWDST]);
|
||||||
|
mpls_to_ea(ms, ra.eattrs);
|
||||||
|
}
|
||||||
|
|
||||||
ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr));
|
if (a[RTA_ENCAP] && a[RTA_ENCAP_TYPE])
|
||||||
ea->next = ra.eattrs;
|
{
|
||||||
ra.eattrs = ea;
|
switch (*((u16*) RTA_DATA(a[RTA_ENCAP_TYPE])))
|
||||||
ea->flags = EALF_SORTED;
|
{
|
||||||
ea->count = 1;
|
case LWTUNNEL_ENCAP_MPLS:
|
||||||
ea->attrs[0].id = EA_KRT_PREFSRC;
|
{
|
||||||
ea->attrs[0].flags = 0;
|
struct rtattr *enca[BIRD_RTA_MAX];
|
||||||
ea->attrs[0].type = EAF_TYPE_INT_SET;
|
nl_attr_len = RTA_PAYLOAD(a[RTA_ENCAP]);
|
||||||
ea->attrs[0].u.ptr = alloca(sizeof(struct adata) + sizeof(u32)*ms.len);
|
nl_parse_attrs(RTA_DATA(a[RTA_ENCAP]), encap_mpls_want, enca, sizeof(enca));
|
||||||
ea->attrs[0].u.ptr->length = sizeof(u32)*ms.len;
|
mpls_stack ms = rta_get_mpls(enca[RTA_DST]);
|
||||||
for (int j = 0; j < ms.len; j++)
|
mpls_to_ea(ms, ra.eattrs);
|
||||||
((u32 *)ea->attrs[0].u.ptr->data)[j] = ms.label[j];
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
SKIP("unknown encapsulation method %d\n", *((u16*) RTA_DATA(a[RTA_ENCAP_TYPE])));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a[RTA_PREFSRC])
|
if (a[RTA_PREFSRC])
|
||||||
|
Loading…
Reference in New Issue
Block a user