Filter: Add MPLS label route attribute

Add support to set or read outgoing MPLS labels using filters. Currently
this supports the addition of one label per route for the first next hop.

Minor changes by committer.
This commit is contained in:
Trisha Biswas 2021-05-17 17:50:04 +02:00 committed by Ondrej Zajicek (work)
parent d114959e3a
commit e5468d1685
5 changed files with 33 additions and 1 deletions

View file

@ -1716,6 +1716,15 @@ Common route attributes are:
are merged to one ECMP route during export to the Kernel protocol are merged to one ECMP route during export to the Kernel protocol
(with active <ref id="krt-merge-paths" name="marge paths"> option). (with active <ref id="krt-merge-paths" name="marge paths"> option).
<tag><label id="rta-gw-mpls"><m/int/ gw_mpls</tag>
Outgoing MPLS label attached to route (i.e., incoming MPLS label on the
next hop router for this label-switched path). Reading returns the label
value and setting it sets it to the start of the label stack. Setting
implicit-NULL label (3) disables the MPLS label stack. Only the first
next hop and only one label in the label stack supported right now. This
is experimental option, will be likely changed in the future to handle
full MPLS label stack.
<tag><label id="rta-igp-metric"><m/int/ igp_metric</tag> <tag><label id="rta-igp-metric"><m/int/ igp_metric</tag>
The optional attribute that can be used to specify a distance to the The optional attribute that can be used to specify a distance to the
network for routes that do not have a native protocol metric attribute network for routes that do not have a native protocol metric attribute

View file

@ -278,7 +278,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST, SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
IF, THEN, ELSE, CASE, IF, THEN, ELSE, CASE,
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC, TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS,
PREFERENCE, PREFERENCE,
ROA_CHECK, ASN, SRC, DST, ROA_CHECK, ASN, SRC, DST,
IS_V4, IS_V6, IS_V4, IS_V6,
@ -751,6 +751,7 @@ static_attr:
| IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); } | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); }
| IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); }
| WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); } | WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
| GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); }
; ;
term: term:

View file

@ -100,6 +100,7 @@ enum f_sa_code {
SA_IFNAME, SA_IFNAME,
SA_IFINDEX, SA_IFINDEX,
SA_WEIGHT, SA_WEIGHT,
SA_GW_MPLS,
} PACKED; } PACKED;
/* Static attribute definition (members of struct rta) */ /* Static attribute definition (members of struct rta) */

View file

@ -533,6 +533,7 @@
case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break; case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break;
case SA_IFINDEX: RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break; case SA_IFINDEX: RESULT(sa.f_type, i, rta->nh.iface ? rta->nh.iface->index : 0); break;
case SA_WEIGHT: RESULT(sa.f_type, i, rta->nh.weight + 1); break; case SA_WEIGHT: RESULT(sa.f_type, i, rta->nh.weight + 1); break;
case SA_GW_MPLS: RESULT(sa.f_type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break;
default: default:
bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code); bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code);
@ -569,6 +570,7 @@
rta->nh.iface = n->iface; rta->nh.iface = n->iface;
rta->nh.next = NULL; rta->nh.next = NULL;
rta->hostentry = NULL; rta->hostentry = NULL;
rta->nh.labels = 0;
} }
break; break;
@ -587,6 +589,7 @@
rta->nh.iface = NULL; rta->nh.iface = NULL;
rta->nh.next = NULL; rta->nh.next = NULL;
rta->hostentry = NULL; rta->hostentry = NULL;
rta->nh.labels = 0;
} }
break; break;
@ -601,6 +604,22 @@
rta->nh.iface = ifa; rta->nh.iface = ifa;
rta->nh.next = NULL; rta->nh.next = NULL;
rta->hostentry = NULL; rta->hostentry = NULL;
rta->nh.labels = 0;
}
break;
case SA_GW_MPLS:
{
if (v1.val.i >= 0x100000)
runtime( "Invalid MPLS label" );
if (v1.val.i != MPLS_NULL)
{
rta->nh.label[0] = v1.val.i;
rta->nh.labels = 1;
}
else
rta->nh.labels = 0;
} }
break; break;

View file

@ -47,6 +47,8 @@
#define IP6_HEADER_LENGTH 40 #define IP6_HEADER_LENGTH 40
#define UDP_HEADER_LENGTH 8 #define UDP_HEADER_LENGTH 8
#define MPLS_NULL 3
/* IANA Address Family Numbers */ /* IANA Address Family Numbers */
/* https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml */ /* https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml */