diff options
-rw-r--r-- | doc/bird.sgml | 9 | ||||
-rw-r--r-- | filter/config.Y | 3 | ||||
-rw-r--r-- | filter/data.h | 1 | ||||
-rw-r--r-- | filter/f-inst.c | 19 | ||||
-rw-r--r-- | lib/ip.h | 2 |
5 files changed, 33 insertions, 1 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index c4d2c49b..51a92ce9 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1716,6 +1716,15 @@ Common route attributes are: are merged to one ECMP route during export to the Kernel protocol (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> 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 diff --git a/filter/config.Y b/filter/config.Y index 5cd52e40..7820e719 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -278,7 +278,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST, IF, THEN, ELSE, CASE, 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, ROA_CHECK, ASN, SRC, DST, IS_V4, IS_V6, @@ -751,6 +751,7 @@ static_attr: | IFNAME { $$ = f_new_static_attr(T_STRING, SA_IFNAME, 0); } | IFINDEX { $$ = f_new_static_attr(T_INT, SA_IFINDEX, 1); } | WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); } + | GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); } ; term: diff --git a/filter/data.h b/filter/data.h index 61cdb43e..d296776d 100644 --- a/filter/data.h +++ b/filter/data.h @@ -100,6 +100,7 @@ enum f_sa_code { SA_IFNAME, SA_IFINDEX, SA_WEIGHT, + SA_GW_MPLS, } PACKED; /* Static attribute definition (members of struct rta) */ diff --git a/filter/f-inst.c b/filter/f-inst.c index 1378fe4a..b876a937 100644 --- a/filter/f-inst.c +++ b/filter/f-inst.c @@ -533,6 +533,7 @@ 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_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: bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code); @@ -569,6 +570,7 @@ rta->nh.iface = n->iface; rta->nh.next = NULL; rta->hostentry = NULL; + rta->nh.labels = 0; } break; @@ -587,6 +589,7 @@ rta->nh.iface = NULL; rta->nh.next = NULL; rta->hostentry = NULL; + rta->nh.labels = 0; } break; @@ -601,6 +604,22 @@ rta->nh.iface = ifa; rta->nh.next = 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; @@ -47,6 +47,8 @@ #define IP6_HEADER_LENGTH 40 #define UDP_HEADER_LENGTH 8 +#define MPLS_NULL 3 + /* IANA Address Family Numbers */ /* https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml */ |