0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-18 09:08:42 +00:00

Merge commit '80272d4b64a38ee6f04a1c4e8566cac3a2293176' into haugesund

This commit is contained in:
Maria Matejka 2022-05-30 15:39:32 +02:00
commit 3752654852
14 changed files with 77 additions and 52 deletions

View File

@ -347,7 +347,7 @@ else: {
return DDOT; return DDOT;
} }
[={}:;,.()+*/%<>~\[\]?!\|-] { [={}:;,.()+*/%<>~\[\]?!\|&-] {
return yytext[0]; return yytext[0];
} }

View File

@ -120,6 +120,7 @@ CF_DECLS
%nonassoc PREFIX_DUMMY %nonassoc PREFIX_DUMMY
%left AND OR %left AND OR
%nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC %nonassoc '=' '<' '>' '~' GEQ LEQ NEQ NMA PO PC
%left '|' '&'
%left '+' '-' %left '+' '-'
%left '*' '/' '%' %left '*' '/' '%'
%left '!' %left '!'

View File

@ -165,7 +165,7 @@ f_generate_empty(struct f_dynamic_attr dyn)
{ {
struct f_val empty; struct f_val empty;
switch (dyn.type & EAF_TYPE_MASK) { switch (dyn.type) {
case EAF_TYPE_AS_PATH: case EAF_TYPE_AS_PATH:
empty = f_const_empty_path; empty = f_const_empty_path;
break; break;
@ -308,7 +308,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
%type <xp> cmds_int cmd_prep %type <xp> cmds_int cmd_prep
%type <x> term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail %type <x> term block cmd cmds constant constructor print_list var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
%type <fda> dynamic_attr %type <fda> dynamic_attr attr_bit
%type <fsa> static_attr %type <fsa> static_attr
%type <f> filter where_filter %type <f> filter where_filter
%type <fl> filter_body function_body %type <fl> filter_body function_body
@ -780,6 +780,8 @@ term:
| term '-' term { $$ = f_new_inst(FI_SUBTRACT, $1, $3); } | term '-' term { $$ = f_new_inst(FI_SUBTRACT, $1, $3); }
| term '*' term { $$ = f_new_inst(FI_MULTIPLY, $1, $3); } | term '*' term { $$ = f_new_inst(FI_MULTIPLY, $1, $3); }
| term '/' term { $$ = f_new_inst(FI_DIVIDE, $1, $3); } | term '/' term { $$ = f_new_inst(FI_DIVIDE, $1, $3); }
| term '&' term { $$ = f_new_inst(FI_BITAND, $1, $3); }
| term '|' term { $$ = f_new_inst(FI_BITOR, $1, $3); }
| term AND term { $$ = f_new_inst(FI_AND, $1, $3); } | term AND term { $$ = f_new_inst(FI_AND, $1, $3); }
| term OR term { $$ = f_new_inst(FI_OR, $1, $3); } | term OR term { $$ = f_new_inst(FI_OR, $1, $3); }
| term '=' term { $$ = f_new_inst(FI_EQ, $1, $3); } | term '=' term { $$ = f_new_inst(FI_EQ, $1, $3); }
@ -800,6 +802,10 @@ term:
| static_attr { $$ = f_new_inst(FI_RTA_GET, $1); } | static_attr { $$ = f_new_inst(FI_RTA_GET, $1); }
| dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); } | dynamic_attr { $$ = f_new_inst(FI_EA_GET, $1); }
| attr_bit {
struct f_inst *c = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)});
$$ = f_new_inst(FI_EQ, c, f_new_inst(FI_BITAND, f_new_inst(FI_EA_GET, $1), c));
}
| term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); } | term '.' IS_V4 { $$ = f_new_inst(FI_IS_V4, $1); }
| term '.' TYPE { $$ = f_new_inst(FI_TYPE, $1); } | term '.' TYPE { $$ = f_new_inst(FI_TYPE, $1); }
@ -897,6 +903,14 @@ cmd:
| UNSET '(' dynamic_attr ')' ';' { | UNSET '(' dynamic_attr ')' ';' {
$$ = f_new_inst(FI_EA_UNSET, $3); $$ = f_new_inst(FI_EA_UNSET, $3);
} }
| attr_bit '=' term ';' {
$$ = f_new_inst(FI_CONDITION, $3,
f_generate_complex(FI_BITOR, $1,
f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = (1U << $1.bit)})),
f_generate_complex(FI_BITAND, $1,
f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = ~(1U << $1.bit)}))
);
}
| break_command print_list ';' { | break_command print_list ';' {
struct f_inst *breaker = f_new_inst(FI_DIE, $1); struct f_inst *breaker = f_new_inst(FI_DIE, $1);
if ($2) { if ($2) {

View File

@ -20,6 +20,9 @@ enum f_type {
/* Nothing. Simply nothing. */ /* Nothing. Simply nothing. */
T_VOID = 0, T_VOID = 0,
/* Something but inaccessible. */
T_OPAQUE = 0xee,
/* User visible types, which fit in int */ /* User visible types, which fit in int */
T_INT = 0x10, T_INT = 0x10,
T_BOOL = 0x11, T_BOOL = 0x11,
@ -41,7 +44,6 @@ enum f_type {
T_ENUM_AF = 0x38, T_ENUM_AF = 0x38,
/* new enums go here */ /* new enums go here */
T_ENUM_EMPTY = 0x3f, /* Special hack for atomic_aggr */
#define T_ENUM T_ENUM_LO ... T_ENUM_HI #define T_ENUM T_ENUM_LO ... T_ENUM_HI

View File

@ -240,6 +240,16 @@
if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" ); if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" );
RESULT(T_INT, i, v1.val.i / v2.val.i); RESULT(T_INT, i, v1.val.i / v2.val.i);
} }
INST(FI_BITOR, 2, 1) {
ARG(1,T_INT);
ARG(2,T_INT);
RESULT(T_INT, i, v1.val.i | v2.val.i);
}
INST(FI_BITAND, 2, 1) {
ARG(1,T_INT);
ARG(2,T_INT);
RESULT(T_INT, i, v1.val.i & v2.val.i);
}
INST(FI_AND, 1, 1) { INST(FI_AND, 1, 1) {
ARG(1,T_BOOL); ARG(1,T_BOOL);
ARG_TYPE_STATIC(2,T_BOOL); ARG_TYPE_STATIC(2,T_BOOL);
@ -686,7 +696,7 @@
break; break;
} }
switch (e->type & EAF_TYPE_MASK) { switch (e->type) {
case EAF_TYPE_INT: case EAF_TYPE_INT:
RESULT_(da.f_type, i, e->u.data); RESULT_(da.f_type, i, e->u.data);
break; break;
@ -694,7 +704,7 @@
RESULT_(T_QUAD, i, e->u.data); RESULT_(T_QUAD, i, e->u.data);
break; break;
case EAF_TYPE_OPAQUE: case EAF_TYPE_OPAQUE:
RESULT_(T_ENUM_EMPTY, i, 0); RESULT_(T_OPAQUE, ad, e->u.ptr);
break; break;
case EAF_TYPE_IP_ADDRESS: case EAF_TYPE_IP_ADDRESS:
RESULT_(T_IP, ip, *((ip_addr *) e->u.ptr->data)); RESULT_(T_IP, ip, *((ip_addr *) e->u.ptr->data));
@ -702,9 +712,6 @@
case EAF_TYPE_AS_PATH: case EAF_TYPE_AS_PATH:
RESULT_(T_PATH, ad, e->u.ptr); RESULT_(T_PATH, ad, e->u.ptr);
break; break;
case EAF_TYPE_BITFIELD:
RESULT_(T_BOOL, i, !!(e->u.data & (1u << da.bit)));
break;
case EAF_TYPE_INT_SET: case EAF_TYPE_INT_SET:
RESULT_(T_CLIST, ad, e->u.ptr); RESULT_(T_CLIST, ad, e->u.ptr);
break; break;
@ -764,19 +771,6 @@
l->attrs[0].u.ptr = v1.val.ad; l->attrs[0].u.ptr = v1.val.ad;
break; break;
case EAF_TYPE_BITFIELD:
{
/* First, we have to find the old value */
eattr *e = ea_find(*fs->eattrs, da.ea_code);
u32 data = e ? e->u.data : 0;
if (v1.val.i)
l->attrs[0].u.data = data | (1u << da.bit);
else
l->attrs[0].u.data = data & ~(1u << da.bit);
}
break;
default: default:
bug("Unknown dynamic attribute type"); bug("Unknown dynamic attribute type");
} }

View File

@ -89,8 +89,8 @@ void f_add_lines(const struct f_line_item *what, struct filter_iterator *fit);
struct filter *f_new_where(struct f_inst *); struct filter *f_new_where(struct f_inst *);
static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ static inline struct f_dynamic_attr f_new_dynamic_attr(u8 type, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ { return (struct f_dynamic_attr) { .type = type, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */
static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, enum f_type f_type, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */ static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, uint code) /* Type as core knows it, type as filters know it, and code of dynamic attribute */
{ return (struct f_dynamic_attr) { .type = EAF_TYPE_BITFIELD, .bit = bit, .f_type = f_type, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */ { return (struct f_dynamic_attr) { .type = EAF_TYPE_INT, .bit = bit, .f_type = T_INT, .ea_code = code }; } /* f_type currently unused; will be handy for static type checking */
static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly) static inline struct f_static_attr f_new_static_attr(int f_type, int code, int readonly)
{ return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; } { return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; }
struct f_inst *f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument); struct f_inst *f_generate_complex(enum f_instruction_code fi_code, struct f_dynamic_attr da, struct f_inst *argument);

View File

@ -111,6 +111,14 @@ int i;
bt_assert(!(i = 4)); bt_assert(!(i = 4));
bt_assert(1 <= 1); bt_assert(1 <= 1);
bt_assert(!(1234 < 1234)); bt_assert(!(1234 < 1234));
bt_assert(10 - 5 = 5);
bt_assert(4294967295 + 1 = 0);
bt_assert(6*9=54);
bt_assert(984/41 = 24);
bt_assert(123/45 = 2);
bt_assert(0xfee1a | 0xbeef = 0xffeff);
bt_assert(0xfee1a & 0xbeef = 0xae0a);
} }
bt_test_suite(t_int, "Testing integers"); bt_test_suite(t_int, "Testing integers");
@ -1334,6 +1342,10 @@ int j;
rip_metric = 14; rip_metric = 14;
unset(rip_metric); unset(rip_metric);
# krt_lock_mtu = false;
# krt_lock_window = true;
# krt_lock_rtt = krt_lock_rttvar && krt_lock_sstresh || krt_lock_cwnd;
accept "ok I take that"; accept "ok I take that";
} }

View File

@ -698,13 +698,15 @@ const char *ea_custom_name(uint ea);
#define EAF_TYPE_IP_ADDRESS 0x04 /* IP address */ #define EAF_TYPE_IP_ADDRESS 0x04 /* IP address */
#define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */ #define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */
#define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */ #define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */
#define EAF_TYPE_BITFIELD 0x09 /* 32-bit embedded bitfield */
#define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */ #define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */
#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */ #define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */
#define EAF_TYPE_LC_SET 0x12 /* Set of triplets of u32's - large community list */ #define EAF_TYPE_LC_SET 0x08 /* Set of triplets of u32's - large community list */
#define EAF_TYPE_IFACE 0x16 /* Interface pointer stored in adata */ #define EAF_TYPE_IFACE 0x0c /* Interface pointer stored in adata */
#define EAF_TYPE_BGP_ORIGIN 0x11 /* BGP Origin enum */
#define EAF_TYPE_RA_PREFERENCE 0x13 /* RA Preference enum */
#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ #define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */
#define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */ /* Otherwise, attribute data is adata */
typedef struct adata { typedef struct adata {
uint length; /* Length of data */ uint length; /* Length of data */

View File

@ -948,7 +948,7 @@ ea_show(struct cli *c, const eattr *e)
if (e->undef) if (e->undef)
bsprintf(pos, "undefined"); bsprintf(pos, "undefined");
else else
switch (e->type & EAF_TYPE_MASK) switch (e->type)
{ {
case EAF_TYPE_INT: case EAF_TYPE_INT:
bsprintf(pos, "%u", e->u.data); bsprintf(pos, "%u", e->u.data);
@ -965,9 +965,6 @@ ea_show(struct cli *c, const eattr *e)
case EAF_TYPE_AS_PATH: case EAF_TYPE_AS_PATH:
as_path_format(ad, pos, end - pos); as_path_format(ad, pos, end - pos);
break; break;
case EAF_TYPE_BITFIELD:
bsprintf(pos, "%08x", e->u.data);
break;
case EAF_TYPE_INT_SET: case EAF_TYPE_INT_SET:
ea_show_int_set(c, ad, 1, pos, buf, end); ea_show_int_set(c, ad, 1, pos, buf, end);
return; return;
@ -1011,7 +1008,10 @@ ea_dump(ea_list *e)
{ {
eattr *a = &e->attrs[i]; eattr *a = &e->attrs[i];
debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags); debug(" %02x:%02x.%02x", EA_PROTO(a->id), EA_ID(a->id), a->flags);
debug("=%c", "?iO?I?P???S?????" [a->type & EAF_TYPE_MASK]); debug("=%c",
"?iO?IRP???S??pE?"
"??L???N?????????"
"?o???r??????????" [a->type]);
if (a->originated) if (a->originated)
debug("o"); debug("o");
if (a->type & EAF_EMBEDDED) if (a->type & EAF_EMBEDDED)

View File

@ -987,7 +987,7 @@ bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data,
static const struct bgp_attr_desc bgp_attr_table[] = { static const struct bgp_attr_desc bgp_attr_table[] = {
[BA_ORIGIN] = { [BA_ORIGIN] = {
.name = "origin", .name = "origin",
.type = EAF_TYPE_INT, .type = EAF_TYPE_BGP_ORIGIN,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.export = bgp_export_origin, .export = bgp_export_origin,
.encode = bgp_encode_u8, .encode = bgp_encode_u8,

View File

@ -318,7 +318,7 @@ bgp_proto_channel: bgp_channel_start bgp_channel_opt_list bgp_channel_end;
dynamic_attr: BGP_ORIGIN dynamic_attr: BGP_ORIGIN
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_BGP_ORIGIN, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); } ;
dynamic_attr: BGP_PATH dynamic_attr: BGP_PATH
{ $$ = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); } ;
dynamic_attr: BGP_NEXT_HOP dynamic_attr: BGP_NEXT_HOP
@ -328,9 +328,9 @@ dynamic_attr: BGP_MED
dynamic_attr: BGP_LOCAL_PREF dynamic_attr: BGP_LOCAL_PREF
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_LOCAL_PREF)); } ;
dynamic_attr: BGP_ATOMIC_AGGR dynamic_attr: BGP_ATOMIC_AGGR
{ $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); } ;
dynamic_attr: BGP_AGGREGATOR dynamic_attr: BGP_AGGREGATOR
{ $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); } ;
dynamic_attr: BGP_COMMUNITY dynamic_attr: BGP_COMMUNITY
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); } ;
dynamic_attr: BGP_ORIGINATOR_ID dynamic_attr: BGP_ORIGINATOR_ID
@ -340,7 +340,7 @@ dynamic_attr: BGP_CLUSTER_LIST
dynamic_attr: BGP_EXT_COMMUNITY dynamic_attr: BGP_EXT_COMMUNITY
{ $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(PROTOCOL_BGP, BA_EXT_COMMUNITY)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(PROTOCOL_BGP, BA_EXT_COMMUNITY)); } ;
dynamic_attr: BGP_AIGP dynamic_attr: BGP_AIGP
{ $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_ENUM_EMPTY, EA_CODE(PROTOCOL_BGP, BA_AIGP)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_OPAQUE, T_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AIGP)); } ;
dynamic_attr: BGP_LARGE_COMMUNITY dynamic_attr: BGP_LARGE_COMMUNITY
{ $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); } ; { $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); } ;

View File

@ -336,7 +336,7 @@ radv_sensitive:
| SENSITIVE bool { $$ = $2; } | SENSITIVE bool { $$ = $2; }
; ;
dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ; dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_RA_PREFERENCE, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ;
dynamic_attr: RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); } ; dynamic_attr: RA_LIFETIME { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RA_LIFETIME); } ;
CF_CODE CF_CODE

View File

@ -48,19 +48,19 @@ dynamic_attr: KRT_QUICKACK { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT
/* Bits of EA_KRT_LOCK, based on RTAX_* constants */ /* Bits of EA_KRT_LOCK, based on RTAX_* constants */
dynamic_attr: KRT_LOCK_MTU { $$ = f_new_dynamic_attr_bit(2, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_MTU { $$ = f_new_dynamic_attr_bit(2, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_WINDOW { $$ = f_new_dynamic_attr_bit(3, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_WINDOW { $$ = f_new_dynamic_attr_bit(3, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_RTT { $$ = f_new_dynamic_attr_bit(4, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_RTT { $$ = f_new_dynamic_attr_bit(4, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_RTTVAR { $$ = f_new_dynamic_attr_bit(5, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_RTTVAR { $$ = f_new_dynamic_attr_bit(5, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_SSTRESH { $$ = f_new_dynamic_attr_bit(6, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_SSTRESH { $$ = f_new_dynamic_attr_bit(6, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_CWND { $$ = f_new_dynamic_attr_bit(7, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_CWND { $$ = f_new_dynamic_attr_bit(7, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_ADVMSS { $$ = f_new_dynamic_attr_bit(8, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_ADVMSS { $$ = f_new_dynamic_attr_bit(8, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_REORDERING { $$ = f_new_dynamic_attr_bit(9, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_REORDERING { $$ = f_new_dynamic_attr_bit(9, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_HOPLIMIT { $$ = f_new_dynamic_attr_bit(10, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_HOPLIMIT { $$ = f_new_dynamic_attr_bit(10, EA_KRT_LOCK); } ;
dynamic_attr: KRT_LOCK_RTO_MIN { $$ = f_new_dynamic_attr_bit(13, T_BOOL, EA_KRT_LOCK); } ; attr_bit: KRT_LOCK_RTO_MIN { $$ = f_new_dynamic_attr_bit(13, EA_KRT_LOCK); } ;
dynamic_attr: KRT_FEATURE_ECN { $$ = f_new_dynamic_attr_bit(0, T_BOOL, EA_KRT_FEATURES); } ; attr_bit: KRT_FEATURE_ECN { $$ = f_new_dynamic_attr_bit(0, EA_KRT_FEATURES); } ;
dynamic_attr: KRT_FEATURE_ALLFRAG { $$ = f_new_dynamic_attr(3, T_BOOL, EA_KRT_FEATURES); } ; attr_bit: KRT_FEATURE_ALLFRAG { $$ = f_new_dynamic_attr_bit(3, EA_KRT_FEATURES); } ;
CF_CODE CF_CODE

View File

@ -1926,7 +1926,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
{ {
ea->attrs[n].id = EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t); ea->attrs[n].id = EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t);
ea->attrs[n].flags = 0; ea->attrs[n].flags = 0;
ea->attrs[n].type = EAF_TYPE_INT; /* FIXME: Some are EAF_TYPE_BITFIELD */ ea->attrs[n].type = EAF_TYPE_INT;
ea->attrs[n].u.data = metrics[t]; ea->attrs[n].u.data = metrics[t];
n++; n++;
} }