mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Filter: Add route attribute gw_mpls_stack
Add route attribute gw_mpls_stack to make MPLS stack of route nexthop accessible from filters. Its type is T_CLIST, which is really not correct (as it is a list, while T_CLIST is a set). Therefore, we keep this attribute *undocumented* and it will be *changed* without further notice. Based on a patch from Trisha Biswas <tbiswas@fastly.com>, thanks!
This commit is contained in:
parent
26dd61ee7f
commit
114be2af28
@ -362,7 +362,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
|||||||
IF, THEN, ELSE, CASE,
|
IF, THEN, ELSE, CASE,
|
||||||
FOR, DO,
|
FOR, DO,
|
||||||
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
|
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
|
||||||
FROM, GW, NET, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
|
FROM, GW, NET, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, GW_MPLS_STACK, ONLINK,
|
||||||
PREFERENCE,
|
PREFERENCE,
|
||||||
ROA_CHECK,
|
ROA_CHECK,
|
||||||
DEFINED,
|
DEFINED,
|
||||||
@ -879,6 +879,7 @@ static_attr:
|
|||||||
| WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
|
| WEIGHT { $$ = f_new_static_attr(T_INT, SA_WEIGHT, 0); }
|
||||||
| PREFERENCE { $$ = f_new_static_attr(T_INT, SA_PREF, 0); }
|
| PREFERENCE { $$ = f_new_static_attr(T_INT, SA_PREF, 0); }
|
||||||
| GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); }
|
| GW_MPLS { $$ = f_new_static_attr(T_INT, SA_GW_MPLS, 0); }
|
||||||
|
| GW_MPLS_STACK { $$ = f_new_static_attr(T_CLIST, SA_GW_MPLS_STACK, 0); }
|
||||||
| ONLINK { $$ = f_new_static_attr(T_BOOL, SA_ONLINK, 0); }
|
| ONLINK { $$ = f_new_static_attr(T_BOOL, SA_ONLINK, 0); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ enum f_sa_code {
|
|||||||
SA_WEIGHT,
|
SA_WEIGHT,
|
||||||
SA_PREF,
|
SA_PREF,
|
||||||
SA_GW_MPLS,
|
SA_GW_MPLS,
|
||||||
|
SA_GW_MPLS_STACK,
|
||||||
SA_ONLINK,
|
SA_ONLINK,
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
@ -692,6 +692,16 @@
|
|||||||
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_PREF: RESULT(sa.f_type, i, rta->pref); break;
|
case SA_PREF: RESULT(sa.f_type, i, rta->pref); break;
|
||||||
case SA_GW_MPLS: RESULT(sa.f_type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break;
|
case SA_GW_MPLS: RESULT(sa.f_type, i, rta->nh.labels ? rta->nh.label[0] : MPLS_NULL); break;
|
||||||
|
case SA_GW_MPLS_STACK:
|
||||||
|
{
|
||||||
|
uint len = rta->nh.labels * sizeof(u32);
|
||||||
|
struct adata *list = falloc(sizeof(struct adata) + len);
|
||||||
|
list->length = len;
|
||||||
|
memcpy(list->data, rta->nh.label, len);
|
||||||
|
RESULT(sa.f_type, ad, list);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SA_ONLINK: RESULT(sa.f_type, i, rta->nh.flags & RNF_ONLINK ? 1 : 0); break;
|
case SA_ONLINK: RESULT(sa.f_type, i, rta->nh.flags & RNF_ONLINK ? 1 : 0); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -779,6 +789,36 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
rta->nh.labels = 0;
|
rta->nh.labels = 0;
|
||||||
|
|
||||||
|
rta->nh.labels_orig = rta->hostentry ? rta->nh.labels : 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SA_GW_MPLS_STACK:
|
||||||
|
{
|
||||||
|
int len = int_set_get_size(v1.val.ad);
|
||||||
|
u32 *l = int_set_get_data(v1.val.ad);
|
||||||
|
|
||||||
|
if (len > MPLS_MAX_LABEL_STACK)
|
||||||
|
runtime("Too many MPLS labels in stack (%d)", len);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
u32 label = l[i];
|
||||||
|
|
||||||
|
if (label >= 0x100000)
|
||||||
|
runtime("Invalid MPLS label (%u)", label);
|
||||||
|
|
||||||
|
/* Ignore rest of label stack if implicit-NULL label (3) is set */
|
||||||
|
if (label == MPLS_NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rta->nh.label[i] = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
rta->nh.labels = i;
|
||||||
|
rta->nh.labels_orig = rta->hostentry ? i : 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1262,6 +1302,14 @@
|
|||||||
RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, v2.val.i) ]]);
|
RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, v2.val.i) ]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hack for gw_mpls_list */
|
||||||
|
INST(FI_CLIST_ADD_INT, 2, 1) {
|
||||||
|
ARG(1, T_CLIST);
|
||||||
|
ARG(2, T_INT);
|
||||||
|
METHOD_CONSTRUCTOR("add");
|
||||||
|
RESULT(T_CLIST, ad, [[ int_set_add(fpool, v1.val.ad, v2.val.i) ]]);
|
||||||
|
}
|
||||||
|
|
||||||
INST(FI_CLIST_ADD_IP, 2, 1) {
|
INST(FI_CLIST_ADD_IP, 2, 1) {
|
||||||
ARG(1, T_CLIST);
|
ARG(1, T_CLIST);
|
||||||
ARG(2, T_IP);
|
ARG(2, T_IP);
|
||||||
@ -1344,6 +1392,14 @@
|
|||||||
RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, v2.val.i) ]]);
|
RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, v2.val.i) ]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hack for gw_mpls_list */
|
||||||
|
INST(FI_CLIST_DELETE_INT, 2, 1) {
|
||||||
|
ARG(1, T_CLIST);
|
||||||
|
ARG(2, T_INT);
|
||||||
|
METHOD_CONSTRUCTOR("delete");
|
||||||
|
RESULT(T_CLIST, ad, [[ int_set_del(fpool, v1.val.ad, v2.val.i) ]]);
|
||||||
|
}
|
||||||
|
|
||||||
INST(FI_CLIST_DELETE_IP, 2, 1) {
|
INST(FI_CLIST_DELETE_IP, 2, 1) {
|
||||||
ARG(1, T_CLIST);
|
ARG(1, T_CLIST);
|
||||||
ARG(2, T_IP);
|
ARG(2, T_IP);
|
||||||
|
1
lib/ip.h
1
lib/ip.h
@ -392,6 +392,7 @@ static inline ip6_addr ip6_ntoh(ip6_addr a)
|
|||||||
#define MPLS_MAX_LABEL 0x100000
|
#define MPLS_MAX_LABEL 0x100000
|
||||||
|
|
||||||
#define MPLS_MAX_LABEL_STACK 8
|
#define MPLS_MAX_LABEL_STACK 8
|
||||||
|
#define MPLS_MAX_LABEL_STRING MPLS_MAX_LABEL_STACK*12 + 5
|
||||||
typedef struct mpls_label_stack {
|
typedef struct mpls_label_stack {
|
||||||
uint len;
|
uint len;
|
||||||
u32 stack[MPLS_MAX_LABEL_STACK];
|
u32 stack[MPLS_MAX_LABEL_STACK];
|
||||||
|
@ -72,7 +72,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary
|
|||||||
if (a->dest == RTD_UNICAST)
|
if (a->dest == RTD_UNICAST)
|
||||||
for (nh = &(a->nh); nh; nh = nh->next)
|
for (nh = &(a->nh); nh; nh = nh->next)
|
||||||
{
|
{
|
||||||
char mpls[MPLS_MAX_LABEL_STACK*12 + 5], *lsp = mpls;
|
char mpls[MPLS_MAX_LABEL_STRING], *lsp = mpls;
|
||||||
char *onlink = (nh->flags & RNF_ONLINK) ? " onlink" : "";
|
char *onlink = (nh->flags & RNF_ONLINK) ? " onlink" : "";
|
||||||
char weight[16] = "";
|
char weight[16] = "";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user