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

Unified attribute and filter types

This commit removes the EAF_TYPE_* namespace completely and also for
route attributes, filter-based types T_* are used. This simplifies
fetching and setting route attributes from filters.

Also, there is now union bval which serves as an universal value holder
instead of private unions held separately by eattr and filter code.
This commit is contained in:
Maria Matejka 2022-03-26 11:56:02 +01:00
parent 80272d4b64
commit 0d0f6554a5
28 changed files with 299 additions and 2517 deletions

View File

@ -163,26 +163,11 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
static inline struct f_inst * static inline struct f_inst *
f_generate_empty(struct f_dynamic_attr dyn) f_generate_empty(struct f_dynamic_attr dyn)
{ {
struct f_val empty; const struct f_val *empty = f_get_empty(dyn.type);
if (!empty)
cf_error("Can't empty that attribute");
switch (dyn.type) { return f_new_inst(FI_EA_SET, f_new_inst(FI_CONSTANT, *empty), dyn);
case EAF_TYPE_AS_PATH:
empty = f_const_empty_path;
break;
case EAF_TYPE_INT_SET:
empty = f_const_empty_clist;
break;
case EAF_TYPE_EC_SET:
empty = f_const_empty_eclist;
break;
case EAF_TYPE_LC_SET:
empty = f_const_empty_lclist;
break;
default:
cf_error("Can't empty that attribute");
}
return f_new_inst(FI_EA_SET, f_new_inst(FI_CONSTANT, empty), dyn);
} }
#define BA_AS_PATH 0x02 #define BA_AS_PATH 0x02
@ -190,7 +175,7 @@ f_generate_empty(struct f_dynamic_attr dyn)
static inline struct f_inst * static inline struct f_inst *
f_implicit_roa_check(struct rtable_config *tab) f_implicit_roa_check(struct rtable_config *tab)
{ {
struct f_dynamic_attr fda = f_new_dynamic_attr(EAF_TYPE_AS_PATH, T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); struct f_dynamic_attr fda = f_new_dynamic_attr(T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH));
struct f_static_attr fsa = f_new_static_attr(T_NET, SA_NET, 1); struct f_static_attr fsa = f_new_static_attr(T_NET, SA_NET, 1);

View File

@ -27,6 +27,8 @@
static const char * const f_type_str[] = { static const char * const f_type_str[] = {
[T_VOID] = "void", [T_VOID] = "void",
[T_OPAQUE] = "opaque byte string",
[T_IFACE] = "interface",
[T_INT] = "int", [T_INT] = "int",
[T_BOOL] = "bool", [T_BOOL] = "bool",
@ -47,6 +49,7 @@ static const char * const f_type_str[] = {
[T_NET] = "prefix", [T_NET] = "prefix",
[T_STRING] = "string", [T_STRING] = "string",
[T_PATH_MASK] = "bgpmask", [T_PATH_MASK] = "bgpmask",
[T_PATH_MASK_ITEM] = "bgpmask item",
[T_PATH] = "bgppath", [T_PATH] = "bgppath",
[T_CLIST] = "clist", [T_CLIST] = "clist",
[T_EC] = "ec", [T_EC] = "ec",
@ -54,22 +57,19 @@ static const char * const f_type_str[] = {
[T_LC] = "lc", [T_LC] = "lc",
[T_LCLIST] = "lclist", [T_LCLIST] = "lclist",
[T_RD] = "rd", [T_RD] = "rd",
[T_SET] = "set",
[T_PREFIX_SET] = "prefix set",
}; };
const char * const char *
f_type_name(enum f_type t) f_type_name(btype t)
{ {
if (t < ARRAY_SIZE(f_type_str)) return (t < ARRAY_SIZE(f_type_str)) ? (f_type_str[t] ?: "?") : "?";
return f_type_str[t] ?: "?";
if ((t == T_SET) || (t == T_PREFIX_SET))
return "set";
return "?";
} }
enum f_type btype
f_type_element_type(enum f_type t) f_type_element_type(btype t)
{ {
switch(t) { switch(t) {
case T_CLIST: return T_PAIR; case T_CLIST: return T_PAIR;

View File

@ -11,65 +11,15 @@
#define _BIRD_FILTER_DATA_H_ #define _BIRD_FILTER_DATA_H_
#include "nest/bird.h" #include "nest/bird.h"
#include "lib/type.h"
/* Type numbers must be in 0..0xff range */
#define T_MASK 0xff
/* Internal types */
enum f_type {
/* Nothing. Simply nothing. */
T_VOID = 0,
/* Something but inaccessible. */
T_OPAQUE = 0xee,
/* User visible types, which fit in int */
T_INT = 0x10,
T_BOOL = 0x11,
T_PAIR = 0x12, /* Notice that pair is stored as integer: first << 16 | second */
T_QUAD = 0x13,
/* Put enumerational types in 0x30..0x3f range */
T_ENUM_LO = 0x30,
T_ENUM_HI = 0x3f,
T_ENUM_RTS = 0x30,
T_ENUM_BGP_ORIGIN = 0x31,
T_ENUM_SCOPE = 0x32,
T_ENUM_RTC = 0x33,
T_ENUM_RTD = 0x34,
T_ENUM_ROA = 0x35,
T_ENUM_NETTYPE = 0x36,
T_ENUM_RA_PREFERENCE = 0x37,
T_ENUM_AF = 0x38,
/* new enums go here */
#define T_ENUM T_ENUM_LO ... T_ENUM_HI
/* Bigger ones */
T_IP = 0x20,
T_NET = 0x21,
T_STRING = 0x22,
T_PATH_MASK = 0x23, /* mask for BGP path */
T_PATH = 0x24, /* BGP path */
T_CLIST = 0x25, /* Community list */
T_EC = 0x26, /* Extended community value, u64 */
T_ECLIST = 0x27, /* Extended community list */
T_LC = 0x28, /* Large community value, lcomm */
T_LCLIST = 0x29, /* Large community list */
T_RD = 0x2a, /* Route distinguisher for VPN addresses */
T_PATH_MASK_ITEM = 0x2b, /* Path mask item for path mask constructors */
T_SET = 0x80,
T_PREFIX_SET = 0x81,
} PACKED;
/* Filter value; size of this affects filter memory consumption */ /* Filter value; size of this affects filter memory consumption */
struct f_val { struct f_val {
enum f_type type; /* T_* */ btype type; /* T_* */
union { union {
uint i; union bval bval;
BVAL_ITEMS;
u64 ec; u64 ec;
lcomm lc; lcomm lc;
ip_addr ip; ip_addr ip;
@ -77,17 +27,17 @@ struct f_val {
const char *s; const char *s;
const struct f_tree *t; const struct f_tree *t;
const struct f_trie *ti; const struct f_trie *ti;
const struct adata *ad;
const struct f_path_mask *path_mask; const struct f_path_mask *path_mask;
struct f_path_mask_item pmi; struct f_path_mask_item pmi;
} val; } val;
}; };
#define fputip(a) ({ ip_addr *ax = falloc(sizeof(*ax)); *ax = (a); ax; })
/* Dynamic attribute definition (eattrs) */ /* Dynamic attribute definition (eattrs) */
struct f_dynamic_attr { struct f_dynamic_attr {
u8 type; /* EA type (EAF_*) */ btype type; /* EA type (EAF_*) */
u8 bit; /* For bitfield accessors */ u8 bit; /* For bitfield accessors */
enum f_type f_type; /* Filter type */
uint ea_code; /* EA code */ uint ea_code; /* EA code */
}; };
@ -108,9 +58,9 @@ enum f_sa_code {
/* Static attribute definition (members of struct rta) */ /* Static attribute definition (members of struct rta) */
struct f_static_attr { struct f_static_attr {
enum f_type f_type; /* Filter type */ btype type; /* Data type */
enum f_sa_code sa_code; /* Static attribute id */ enum f_sa_code sa_code; /* Static attribute id */
int readonly:1; /* Don't allow writing */ int readonly:1; /* Don't allow writing */
}; };
/* Filter l-value type */ /* Filter l-value type */
@ -266,9 +216,9 @@ trie_match_next_longest_ip6(net_addr_ip6 *n, ip6_addr *found)
#define F_CMP_ERROR 999 #define F_CMP_ERROR 999
const char *f_type_name(enum f_type t); const char *f_type_name(btype t);
enum f_type f_type_element_type(enum f_type t); enum btype f_type_element_type(btype t);
int val_same(const struct f_val *v1, const struct f_val *v2); int val_same(const struct f_val *v1, const struct f_val *v2);
int val_compare(const struct f_val *v1, const struct f_val *v2); int val_compare(const struct f_val *v1, const struct f_val *v2);
@ -301,6 +251,16 @@ undef_value(struct f_val v)
} }
extern const struct f_val f_const_empty_path, f_const_empty_clist, f_const_empty_eclist, f_const_empty_lclist; extern const struct f_val f_const_empty_path, f_const_empty_clist, f_const_empty_eclist, f_const_empty_lclist;
static inline const struct f_val *f_get_empty(btype t)
{
switch (t) {
case T_PATH: return &f_const_empty_path;
case T_CLIST: return &f_const_empty_clist;
case T_ECLIST: return &f_const_empty_eclist;
case T_LCLIST: return &f_const_empty_lclist;
default: return NULL;
}
}
enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres); enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);

View File

@ -490,7 +490,7 @@ fi_constant(struct f_inst *what, struct f_val val)
} }
static int static int
f_const_promotion(struct f_inst *arg, enum f_type want) f_const_promotion(struct f_inst *arg, btype want)
{ {
if (arg->fi_code != FI_CONSTANT) if (arg->fi_code != FI_CONSTANT)
return 0; return 0;
@ -640,7 +640,7 @@ FID_WR_PUT(4)m4_dnl
struct f_inst { struct f_inst {
struct f_inst *next; /* Next instruction */ struct f_inst *next; /* Next instruction */
enum f_instruction_code fi_code; /* Instruction code */ enum f_instruction_code fi_code; /* Instruction code */
enum f_type type; /* Type of returned value, if known */ btype type; /* Type of returned value, if known */
int size; /* How many instructions are underneath */ int size; /* How many instructions are underneath */
int lineno; /* Line number */ int lineno; /* Line number */
union { union {

View File

@ -533,21 +533,21 @@
switch (sa.sa_code) switch (sa.sa_code)
{ {
case SA_FROM: RESULT(sa.f_type, ip, rta->from); break; case SA_FROM: RESULT(sa.type, ip, rta->from); break;
case SA_GW: RESULT(sa.f_type, ip, rta->nh.gw); break; case SA_GW: RESULT(sa.type, ip, rta->nh.gw); break;
case SA_NET: RESULT(sa.f_type, net, (*fs->rte)->net->n.addr); break; case SA_NET: RESULT(sa.type, net, (*fs->rte)->net->n.addr); break;
case SA_PROTO: RESULT(sa.f_type, s, (*fs->rte)->src->proto->name); break; case SA_PROTO: RESULT(sa.type, s, (*fs->rte)->src->proto->name); break;
case SA_SOURCE: RESULT(sa.f_type, i, rta->source); break; case SA_SOURCE: RESULT(sa.type, i, rta->source); break;
case SA_SCOPE: RESULT(sa.f_type, i, rta->scope); break; case SA_SCOPE: RESULT(sa.type, i, rta->scope); break;
case SA_DEST: RESULT(sa.f_type, i, rta->dest); break; case SA_DEST: RESULT(sa.type, i, rta->dest); break;
case SA_IFNAME: RESULT(sa.f_type, s, rta->nh.iface ? rta->nh.iface->name : ""); break; case SA_IFNAME: RESULT(sa.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.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.type, i, rta->nh.weight + 1); break;
case SA_PREF: RESULT(sa.f_type, i, rta->pref); break; case SA_PREF: RESULT(sa.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.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.type, sa.sa_code);
} }
} }
} }
@ -556,7 +556,7 @@
ACCESS_RTE; ACCESS_RTE;
ARG_ANY(1); ARG_ANY(1);
STATIC_ATTR; STATIC_ATTR;
ARG_TYPE(1, sa.f_type); ARG_TYPE(1, sa.type);
f_rta_cow(fs); f_rta_cow(fs);
{ {
@ -653,7 +653,7 @@
break; break;
default: default:
bug("Invalid static attribute access (%u/%u)", sa.f_type, sa.sa_code); bug("Invalid static attribute access (%u/%u)", sa.type, sa.sa_code);
} }
} }
} }
@ -662,68 +662,30 @@
DYNAMIC_ATTR; DYNAMIC_ATTR;
ACCESS_RTE; ACCESS_RTE;
ACCESS_EATTRS; ACCESS_EATTRS;
RESULT_TYPE(da.f_type); RESULT_TYPE(da.type);
{ {
const struct f_val *empty;
eattr *e = ea_find(*fs->eattrs, da.ea_code); eattr *e = ea_find(*fs->eattrs, da.ea_code);
if (!e) { if (e)
/* A special case: undefined as_path looks like empty as_path */ {
if (da.type == EAF_TYPE_AS_PATH) { ASSERT_DIE(e->type == da.type);
RESULT_(T_PATH, ad, &null_adata);
break;
}
/* The same special case for int_set */ switch (e->type) {
if (da.type == EAF_TYPE_INT_SET) { case T_IP:
RESULT_(T_CLIST, ad, &null_adata); RESULT_(T_IP, ip, *((const ip_addr *) e->u.ptr->data));
break; break;
default:
RESULT_VAL([[(struct f_val) {
.type = e->type,
.val.bval = e->u,
}]]);
} }
}
/* The same special case for ec_set */ else if (empty = f_get_empty(da.type))
if (da.type == EAF_TYPE_EC_SET) { RESULT_VAL(*empty);
RESULT_(T_ECLIST, ad, &null_adata); else
break;
}
/* The same special case for lc_set */
if (da.type == EAF_TYPE_LC_SET) {
RESULT_(T_LCLIST, ad, &null_adata);
break;
}
/* Undefined value */
RESULT_VOID; RESULT_VOID;
break;
}
switch (e->type) {
case EAF_TYPE_INT:
RESULT_(da.f_type, i, e->u.data);
break;
case EAF_TYPE_ROUTER_ID:
RESULT_(T_QUAD, i, e->u.data);
break;
case EAF_TYPE_OPAQUE:
RESULT_(T_OPAQUE, ad, e->u.ptr);
break;
case EAF_TYPE_IP_ADDRESS:
RESULT_(T_IP, ip, *((ip_addr *) e->u.ptr->data));
break;
case EAF_TYPE_AS_PATH:
RESULT_(T_PATH, ad, e->u.ptr);
break;
case EAF_TYPE_INT_SET:
RESULT_(T_CLIST, ad, e->u.ptr);
break;
case EAF_TYPE_EC_SET:
RESULT_(T_ECLIST, ad, e->u.ptr);
break;
case EAF_TYPE_LC_SET:
RESULT_(T_LCLIST, ad, e->u.ptr);
break;
default:
bug("Unknown dynamic attribute type");
}
} }
} }
@ -732,7 +694,7 @@
ACCESS_EATTRS; ACCESS_EATTRS;
ARG_ANY(1); ARG_ANY(1);
DYNAMIC_ATTR; DYNAMIC_ATTR;
ARG_TYPE(1, da.f_type); ARG_TYPE(1, da.type);
{ {
struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr)); struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr));
@ -746,17 +708,16 @@
l->attrs[0].fresh = 1; l->attrs[0].fresh = 1;
l->attrs[0].undef = 0; l->attrs[0].undef = 0;
switch (da.type) { if (da.type >= EAF_TYPE__MAX)
case EAF_TYPE_INT: bug("Unsupported attribute type");
case EAF_TYPE_ROUTER_ID:
l->attrs[0].u.data = v1.val.i;
break;
case EAF_TYPE_OPAQUE: switch (da.type) {
case T_OPAQUE:
case T_IFACE:
runtime( "Setting opaque attribute is not allowed" ); runtime( "Setting opaque attribute is not allowed" );
break; break;
case EAF_TYPE_IP_ADDRESS:; case T_IP:;
int len = sizeof(ip_addr); int len = sizeof(ip_addr);
struct adata *ad = lp_alloc(fs->pool, sizeof(struct adata) + len); struct adata *ad = lp_alloc(fs->pool, sizeof(struct adata) + len);
ad->length = len; ad->length = len;
@ -764,15 +725,10 @@
l->attrs[0].u.ptr = ad; l->attrs[0].u.ptr = ad;
break; break;
case EAF_TYPE_AS_PATH: default:
case EAF_TYPE_INT_SET: l->attrs[0].u = v1.val.bval;
case EAF_TYPE_EC_SET:
case EAF_TYPE_LC_SET:
l->attrs[0].u.ptr = v1.val.ad;
break; break;
default:
bug("Unknown dynamic attribute type");
} }
f_rta_cow(fs); f_rta_cow(fs);

View File

@ -87,12 +87,12 @@ 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, uint code)
{ 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, .ea_code = code }; }
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 */ static inline struct f_dynamic_attr f_new_dynamic_attr_bit(u8 bit, uint code)
{ 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 */ { return (struct f_dynamic_attr) { .type = T_INT, .bit = bit, .ea_code = code }; }
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(btype type, int code, int readonly)
{ return (struct f_static_attr) { .f_type = f_type, .sa_code = code, .readonly = readonly }; } { return (struct f_static_attr) { .type = 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);
struct f_inst *f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct f_inst *asn); struct f_inst *f_generate_roa_check(struct rtable_config *table, struct f_inst *prefix, struct f_inst *asn);

View File

@ -82,8 +82,8 @@ static void
ca_dump(resource *r) ca_dump(resource *r)
{ {
struct custom_attribute *ca = (void *) r; struct custom_attribute *ca = (void *) r;
debug("name \"%s\" id 0x%04x ea_type 0x%02x f_type 0x%02x\n", debug("name \"%s\" id 0x%04x ea_type 0x%02x\n",
ca->name, ca->fda->ea_code, ca->fda->type, ca->fda->f_type); ca->name, ca->fda->ea_code, ca->fda->type);
} }
static struct resclass ca_class = { static struct resclass ca_class = {
@ -96,31 +96,16 @@ static struct resclass ca_class = {
}; };
struct custom_attribute * struct custom_attribute *
ca_lookup(pool *p, const char *name, int f_type) ca_lookup(pool *p, const char *name, btype type)
{ {
int ea_type; switch (type) {
switch (f_type) {
case T_INT: case T_INT:
ea_type = EAF_TYPE_INT;
break;
case T_IP: case T_IP:
ea_type = EAF_TYPE_IP_ADDRESS;
break;
case T_QUAD: case T_QUAD:
ea_type = EAF_TYPE_ROUTER_ID;
break;
case T_PATH: case T_PATH:
ea_type = EAF_TYPE_AS_PATH;
break;
case T_CLIST: case T_CLIST:
ea_type = EAF_TYPE_INT_SET;
break;
case T_ECLIST: case T_ECLIST:
ea_type = EAF_TYPE_EC_SET;
break;
case T_LCLIST: case T_LCLIST:
ea_type = EAF_TYPE_LC_SET;
break; break;
default: default:
cf_error("Custom route attribute of unsupported type"); cf_error("Custom route attribute of unsupported type");
@ -137,7 +122,7 @@ ca_lookup(pool *p, const char *name, int f_type)
inited++; inited++;
} }
struct ca_storage *cas = HASH_FIND(ca_hash, CA, name, ea_type); struct ca_storage *cas = HASH_FIND(ca_hash, CA, name, type);
if (cas) { if (cas) {
cas->uc++; cas->uc++;
} else { } else {
@ -153,7 +138,7 @@ ca_lookup(pool *p, const char *name, int f_type)
} }
cas = mb_allocz(&root_pool, sizeof(struct ca_storage) + strlen(name) + 1); cas = mb_allocz(&root_pool, sizeof(struct ca_storage) + strlen(name) + 1);
cas->fda = f_new_dynamic_attr(ea_type, f_type, EA_CUSTOM(id)); cas->fda = f_new_dynamic_attr(type, EA_CUSTOM(id));
cas->uc = 1; cas->uc = 1;
strcpy(cas->name, name); strcpy(cas->name, name);

View File

@ -77,6 +77,6 @@ struct custom_attribute {
const char *name; const char *name;
}; };
struct custom_attribute *ca_lookup(pool *p, const char *name, int ea_type); struct custom_attribute *ca_lookup(pool *p, const char *name, btype type);
#endif #endif

View File

@ -406,9 +406,9 @@ bt_test_suite(t_ip_set, "Testing sets of ip address");
function t_enum() function t_enum()
{ {
bt_assert(format(RTS_STATIC) = "(enum 30)1"); bt_assert(format(RTS_STATIC) = "(enum 31)1");
bt_assert(format(NET_IP4) = "(enum 36)1"); bt_assert(format(NET_IP4) = "(enum 3b)1");
bt_assert(format(NET_VPN6) = "(enum 36)4"); bt_assert(format(NET_VPN6) = "(enum 3b)4");
bt_assert(RTS_STATIC ~ [RTS_STATIC, RTS_DEVICE]); bt_assert(RTS_STATIC ~ [RTS_STATIC, RTS_DEVICE]);
bt_assert(RTS_BGP !~ [RTS_STATIC, RTS_DEVICE]); bt_assert(RTS_BGP !~ [RTS_STATIC, RTS_DEVICE]);

87
lib/type.h Normal file
View File

@ -0,0 +1,87 @@
/*
* BIRD Internet Routing Daemon -- Internal Data Types
*
* (c) 2022 Maria Matejka <mq@jmq.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_TYPE_H_
#define _BIRD_TYPE_H_
#include "lib/birdlib.h"
union bval {
#define BVAL_ITEMS \
u32 data; /* Integer type inherited from eattrs */ \
u32 i; /* Integer type inherited from filters */ \
const struct adata *ptr; /* Generic attribute data inherited from eattrs */ \
const struct adata *ad; /* Generic attribute data inherited from filters */ \
BVAL_ITEMS
};
/* Internal types */
enum btype {
/* Nothing. Simply nothing. */
T_VOID = 0,
/* Something but inaccessible. */
T_OPAQUE = 0x02, /* Opaque byte string (not filterable) */
T_IFACE = 0x0c, /* Pointer to an interface (inside adata) */
/* Types shared with eattrs */
T_INT = 0x01, /* 32-bit unsigned integer number */
T_IP = 0x04, /* IP address */
T_QUAD = 0x05, /* Router ID (IPv4 address) */
T_PATH = 0x06, /* BGP AS path (encoding per RFC 1771:4.3) */
T_CLIST = 0x0a, /* Set of u32's (e.g., a community list) */
T_ECLIST = 0x0e, /* Set of pairs of u32's - ext. community list */
T_LCLIST = 0x08, /* Set of triplets of u32's - large community list */
T_ENUM_BGP_ORIGIN = 0x11, /* BGP Origin enum */
T_ENUM_RA_PREFERENCE = 0x13, /* RA Preference enum */
#define EAF_TYPE__MAX 0x1f
#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */
/* Otherwise, attribute data is adata */
/* Other user visible types which fit in int */
T_BOOL = 0xa0,
T_PAIR = 0xa4, /* Notice that pair is stored as integer: first << 16 | second */
/* Put enumerational types in 0x20..0x3f range */
T_ENUM_LO = 0x10,
T_ENUM_HI = 0x3f,
T_ENUM_RTS = 0x31,
T_ENUM_SCOPE = 0x33,
T_ENUM_RTC = 0x35,
T_ENUM_RTD = 0x37,
T_ENUM_ROA = 0x39,
T_ENUM_NETTYPE = 0x3b,
T_ENUM_AF = 0x3d,
/* new enums go here */
#define T_ENUM T_ENUM_LO ... T_ENUM_HI
/* Bigger ones */
T_NET = 0xb0,
T_STRING = 0xb4,
T_PATH_MASK = 0xb8, /* mask for BGP path */
T_EC = 0xbc, /* Extended community value, u64 */
T_LC = 0xc0, /* Large community value, lcomm */
T_RD = 0xc4, /* Route distinguisher for VPN addresses */
T_PATH_MASK_ITEM = 0xc8, /* Path mask item for path mask constructors */
T_SET = 0x80,
T_PREFIX_SET = 0x84,
} PACKED;
typedef enum btype btype;
STATIC_ASSERT(sizeof(btype) == sizeof(byte));
#endif

View File

@ -921,7 +921,7 @@ proto_patt2:
| TEXT { $$.ptr = $1; $$.patt = 1; } | TEXT { $$.ptr = $1; $$.patt = 1; }
; ;
dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); } ; dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_GEN_IGP_METRIC); } ;
CF_CODE CF_CODE

View File

@ -13,6 +13,7 @@
#include "lib/bitmap.h" #include "lib/bitmap.h"
#include "lib/resource.h" #include "lib/resource.h"
#include "lib/net.h" #include "lib/net.h"
#include "lib/type.h"
struct ea_list; struct ea_list;
struct protocol; struct protocol;
@ -506,10 +507,8 @@ typedef struct eattr {
byte originated:1; /* The attribute has originated locally */ byte originated:1; /* The attribute has originated locally */
byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */ byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */
byte undef:1; /* Explicitly undefined */ byte undef:1; /* Explicitly undefined */
union {
uintptr_t data; union bval u;
const struct adata *ptr; /* Attribute data elsewhere */
} u;
} eattr; } eattr;
@ -530,22 +529,6 @@ const char *ea_custom_name(uint ea);
#define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */ #define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */
#define EA_BIT_GET(ea) ((ea) >> 24) #define EA_BIT_GET(ea) ((ea) >> 24)
#define EAF_TYPE_MASK 0x1f /* Mask with this to get type */
#define EAF_TYPE_INT 0x01 /* 32-bit unsigned integer number */
#define EAF_TYPE_OPAQUE 0x02 /* Opaque byte string (not filterable) */
#define EAF_TYPE_IP_ADDRESS 0x04 /* IP 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_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_LC_SET 0x08 /* Set of triplets of u32's - large community list */
#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) */
/* Otherwise, attribute data is adata */
typedef struct adata { typedef struct adata {
uint length; /* Length of data */ uint length; /* Length of data */
byte data[0]; byte data[0];
@ -591,7 +574,7 @@ struct ea_walk_state {
eattr *ea_find(ea_list *, unsigned ea); eattr *ea_find(ea_list *, unsigned ea);
eattr *ea_walk(struct ea_walk_state *s, uint id, uint max); eattr *ea_walk(struct ea_walk_state *s, uint id, uint max);
uintptr_t ea_get_int(ea_list *, unsigned ea, uintptr_t def); u32 ea_get_int(ea_list *, unsigned ea, u32 def);
void ea_dump(ea_list *); void ea_dump(ea_list *);
void ea_sort(ea_list *); /* Sort entries in all sub-lists */ void ea_sort(ea_list *); /* Sort entries in all sub-lists */
unsigned ea_scan(ea_list *); /* How many bytes do we need for merged ea_list */ unsigned ea_scan(ea_list *); /* How many bytes do we need for merged ea_list */
@ -618,7 +601,7 @@ struct ea_one_attr_list {
}; };
static inline eattr * static inline eattr *
ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val) ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, union bval val)
{ {
struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea)); struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea));
*ea = (struct ea_one_attr_list) { *ea = (struct ea_one_attr_list) {
@ -631,11 +614,7 @@ ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type,
.a.flags = flags, .a.flags = flags,
}; };
if (type & EAF_EMBEDDED) ea->a.u = val;
ea->a.u.data = val;
else
ea->a.u.ptr = (struct adata *) val;
*to = &ea->l; *to = &ea->l;
return &ea->a; return &ea->a;
@ -659,19 +638,19 @@ ea_unset_attr(ea_list **to, struct linpool *pool, _Bool local, uint code)
} }
static inline void static inline void
ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 val) ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 data)
{ ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); } {
union bval bv = { .data = data };
static inline void ea_set_attr(to, pool, id, flags, type, bv);
ea_set_attr_ptr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, struct adata *val) }
{ ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); }
static inline void static inline void
ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint len) ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint len)
{ {
struct adata *a = lp_alloc_adata(pool, len); struct adata *a = lp_alloc_adata(pool, len);
memcpy(a->data, data, len); memcpy(a->data, data, len);
ea_set_attr(to, pool, id, flags, type, (uintptr_t) a); union bval bv = { .ptr = a, };
ea_set_attr(to, pool, id, flags, type, bv);
} }

View File

@ -539,8 +539,8 @@ ea_walk(struct ea_walk_state *s, uint id, uint max)
* by calling ea_find() to find the attribute, extracting its value or returning * by calling ea_find() to find the attribute, extracting its value or returning
* a provided default if no such attribute is present. * a provided default if no such attribute is present.
*/ */
uintptr_t u32
ea_get_int(ea_list *e, unsigned id, uintptr_t def) ea_get_int(ea_list *e, unsigned id, u32 def)
{ {
eattr *a = ea_find(e, id); eattr *a = ea_find(e, id);
if (!a) if (!a)
@ -950,30 +950,33 @@ ea_show(struct cli *c, const eattr *e)
else else
switch (e->type) switch (e->type)
{ {
case EAF_TYPE_INT: case T_INT:
bsprintf(pos, "%u", e->u.data); bsprintf(pos, "%u", e->u.data);
break; break;
case EAF_TYPE_OPAQUE: case T_OPAQUE:
opaque_format(ad, pos, end - pos); opaque_format(ad, pos, end - pos);
break; break;
case EAF_TYPE_IP_ADDRESS: case T_IP:
bsprintf(pos, "%I", *(ip_addr *) ad->data); bsprintf(pos, "%I", *(ip_addr *) ad->data);
break; break;
case EAF_TYPE_ROUTER_ID: case T_QUAD:
bsprintf(pos, "%R", e->u.data); bsprintf(pos, "%R", e->u.data);
break; break;
case EAF_TYPE_AS_PATH: case T_PATH:
as_path_format(ad, pos, end - pos); as_path_format(ad, pos, end - pos);
break; break;
case EAF_TYPE_INT_SET: case T_CLIST:
ea_show_int_set(c, ad, 1, pos, buf, end); ea_show_int_set(c, ad, 1, pos, buf, end);
return; return;
case EAF_TYPE_EC_SET: case T_ECLIST:
ea_show_ec_set(c, ad, pos, buf, end); ea_show_ec_set(c, ad, pos, buf, end);
return; return;
case EAF_TYPE_LC_SET: case T_LCLIST:
ea_show_lc_set(c, ad, pos, buf, end); ea_show_lc_set(c, ad, pos, buf, end);
return; return;
case T_IFACE:
bsprintf(pos, "%s", ((struct iface *) e->u.ptr)->name);
return;
default: default:
bsprintf(pos, "<type %02x>", e->type); bsprintf(pos, "<type %02x>", e->type);
} }

View File

@ -654,7 +654,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
*a0.eattrs = (ea_list) { .count = 3 }; *a0.eattrs = (ea_list) { .count = 3 };
a0.eattrs->attrs[0] = (eattr) { a0.eattrs->attrs[0] = (eattr) {
.id = EA_BABEL_METRIC, .id = EA_BABEL_METRIC,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = r->metric, .u.data = r->metric,
}; };
@ -663,13 +663,13 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
memcpy(ad->data, &(r->router_id), sizeof(u64)); memcpy(ad->data, &(r->router_id), sizeof(u64));
a0.eattrs->attrs[1] = (eattr) { a0.eattrs->attrs[1] = (eattr) {
.id = EA_BABEL_ROUTER_ID, .id = EA_BABEL_ROUTER_ID,
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.u.ptr = ad, .u.ptr = ad,
}; };
a0.eattrs->attrs[2] = (eattr) { a0.eattrs->attrs[2] = (eattr) {
.id = EA_BABEL_SEQNO, .id = EA_BABEL_SEQNO,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = r->seqno, .u.data = r->seqno,
}; };

View File

@ -163,7 +163,7 @@ babel_iface_opt_list:
babel_iface: babel_iface:
babel_iface_start iface_patt_list_nopx babel_iface_opt_list babel_iface_finish; babel_iface_start iface_patt_list_nopx babel_iface_opt_list babel_iface_finish;
dynamic_attr: BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_BABEL_METRIC); } ; dynamic_attr: BABEL_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_BABEL_METRIC); } ;
CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]); CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]);

View File

@ -80,7 +80,7 @@ static const struct bgp_attr_desc bgp_attr_table[];
static inline int bgp_attr_known(uint code); static inline int bgp_attr_known(uint code);
eattr * eattr *
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintptr_t val) bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val)
{ {
ASSERT(bgp_attr_known(code)); ASSERT(bgp_attr_known(code));
@ -976,7 +976,7 @@ static inline void
bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to) bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to)
{ {
/* Cannot use bgp_set_attr_data() as it works on known attributes only */ /* Cannot use bgp_set_attr_data() as it works on known attributes only */
ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, EAF_TYPE_OPAQUE, data, len); ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, T_OPAQUE, data, len);
} }
@ -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_BGP_ORIGIN, .type = T_ENUM_BGP_ORIGIN,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.export = bgp_export_origin, .export = bgp_export_origin,
.encode = bgp_encode_u8, .encode = bgp_encode_u8,
@ -996,14 +996,14 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_AS_PATH] = { [BA_AS_PATH] = {
.name = "as_path", .name = "as_path",
.type = EAF_TYPE_AS_PATH, .type = T_PATH,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.encode = bgp_encode_as_path, .encode = bgp_encode_as_path,
.decode = bgp_decode_as_path, .decode = bgp_decode_as_path,
}, },
[BA_NEXT_HOP] = { [BA_NEXT_HOP] = {
.name = "next_hop", .name = "next_hop",
.type = EAF_TYPE_IP_ADDRESS, .type = T_IP,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.encode = bgp_encode_next_hop, .encode = bgp_encode_next_hop,
.decode = bgp_decode_next_hop, .decode = bgp_decode_next_hop,
@ -1011,14 +1011,14 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_MULTI_EXIT_DISC] = { [BA_MULTI_EXIT_DISC] = {
.name = "med", .name = "med",
.type = EAF_TYPE_INT, .type = T_INT,
.flags = BAF_OPTIONAL, .flags = BAF_OPTIONAL,
.encode = bgp_encode_u32, .encode = bgp_encode_u32,
.decode = bgp_decode_med, .decode = bgp_decode_med,
}, },
[BA_LOCAL_PREF] = { [BA_LOCAL_PREF] = {
.name = "local_pref", .name = "local_pref",
.type = EAF_TYPE_INT, .type = T_INT,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.export = bgp_export_local_pref, .export = bgp_export_local_pref,
.encode = bgp_encode_u32, .encode = bgp_encode_u32,
@ -1026,14 +1026,14 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_ATOMIC_AGGR] = { [BA_ATOMIC_AGGR] = {
.name = "atomic_aggr", .name = "atomic_aggr",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_TRANSITIVE, .flags = BAF_TRANSITIVE,
.encode = bgp_encode_raw, .encode = bgp_encode_raw,
.decode = bgp_decode_atomic_aggr, .decode = bgp_decode_atomic_aggr,
}, },
[BA_AGGREGATOR] = { [BA_AGGREGATOR] = {
.name = "aggregator", .name = "aggregator",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.encode = bgp_encode_aggregator, .encode = bgp_encode_aggregator,
.decode = bgp_decode_aggregator, .decode = bgp_decode_aggregator,
@ -1041,7 +1041,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_COMMUNITY] = { [BA_COMMUNITY] = {
.name = "community", .name = "community",
.type = EAF_TYPE_INT_SET, .type = T_CLIST,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.export = bgp_export_community, .export = bgp_export_community,
.encode = bgp_encode_u32s, .encode = bgp_encode_u32s,
@ -1049,7 +1049,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_ORIGINATOR_ID] = { [BA_ORIGINATOR_ID] = {
.name = "originator_id", .name = "originator_id",
.type = EAF_TYPE_ROUTER_ID, .type = T_QUAD,
.flags = BAF_OPTIONAL, .flags = BAF_OPTIONAL,
.export = bgp_export_originator_id, .export = bgp_export_originator_id,
.encode = bgp_encode_u32, .encode = bgp_encode_u32,
@ -1057,7 +1057,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_CLUSTER_LIST] = { [BA_CLUSTER_LIST] = {
.name = "cluster_list", .name = "cluster_list",
.type = EAF_TYPE_INT_SET, .type = T_CLIST,
.flags = BAF_OPTIONAL, .flags = BAF_OPTIONAL,
.export = bgp_export_cluster_list, .export = bgp_export_cluster_list,
.encode = bgp_encode_u32s, .encode = bgp_encode_u32s,
@ -1066,19 +1066,19 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_MP_REACH_NLRI] = { [BA_MP_REACH_NLRI] = {
.name = "mp_reach_nlri", .name = "mp_reach_nlri",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_OPTIONAL, .flags = BAF_OPTIONAL,
.decode = bgp_decode_mp_reach_nlri, .decode = bgp_decode_mp_reach_nlri,
}, },
[BA_MP_UNREACH_NLRI] = { [BA_MP_UNREACH_NLRI] = {
.name = "mp_unreach_nlri", .name = "mp_unreach_nlri",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_OPTIONAL, .flags = BAF_OPTIONAL,
.decode = bgp_decode_mp_unreach_nlri, .decode = bgp_decode_mp_unreach_nlri,
}, },
[BA_EXT_COMMUNITY] = { [BA_EXT_COMMUNITY] = {
.name = "ext_community", .name = "ext_community",
.type = EAF_TYPE_EC_SET, .type = T_ECLIST,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.export = bgp_export_ext_community, .export = bgp_export_ext_community,
.encode = bgp_encode_u32s, .encode = bgp_encode_u32s,
@ -1086,14 +1086,14 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_AS4_PATH] = { [BA_AS4_PATH] = {
.name = "as4_path", .name = "as4_path",
.type = EAF_TYPE_AS_PATH, .type = T_PATH,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.encode = bgp_encode_raw, .encode = bgp_encode_raw,
.decode = bgp_decode_as4_path, .decode = bgp_decode_as4_path,
}, },
[BA_AS4_AGGREGATOR] = { [BA_AS4_AGGREGATOR] = {
.name = "as4_aggregator", .name = "as4_aggregator",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.encode = bgp_encode_raw, .encode = bgp_encode_raw,
.decode = bgp_decode_as4_aggregator, .decode = bgp_decode_as4_aggregator,
@ -1101,7 +1101,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_AIGP] = { [BA_AIGP] = {
.name = "aigp", .name = "aigp",
.type = EAF_TYPE_OPAQUE, .type = T_OPAQUE,
.flags = BAF_OPTIONAL | BAF_DECODE_FLAGS, .flags = BAF_OPTIONAL | BAF_DECODE_FLAGS,
.export = bgp_export_aigp, .export = bgp_export_aigp,
.encode = bgp_encode_raw, .encode = bgp_encode_raw,
@ -1110,7 +1110,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_LARGE_COMMUNITY] = { [BA_LARGE_COMMUNITY] = {
.name = "large_community", .name = "large_community",
.type = EAF_TYPE_LC_SET, .type = T_LCLIST,
.flags = BAF_OPTIONAL | BAF_TRANSITIVE, .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
.export = bgp_export_large_community, .export = bgp_export_large_community,
.encode = bgp_encode_u32s, .encode = bgp_encode_u32s,
@ -1118,7 +1118,7 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
}, },
[BA_MPLS_LABEL_STACK] = { [BA_MPLS_LABEL_STACK] = {
.name = "mpls_label_stack", .name = "mpls_label_stack",
.type = EAF_TYPE_INT_SET, .type = T_CLIST,
.export = bgp_export_mpls_label_stack, .export = bgp_export_mpls_label_stack,
.encode = bgp_encode_mpls_label_stack, .encode = bgp_encode_mpls_label_stack,
.decode = bgp_decode_mpls_label_stack, .decode = bgp_decode_mpls_label_stack,

View File

@ -545,22 +545,28 @@ bgp_find_attr(ea_list *attrs, uint code)
} }
eattr * eattr *
bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, uintptr_t val); bgp_set_attr(ea_list **attrs, struct linpool *pool, uint code, uint flags, union bval val);
static inline void static inline void
bgp_set_attr_u32(ea_list **to, struct linpool *pool, uint code, uint flags, u32 val) bgp_set_attr_u32(ea_list **to, struct linpool *pool, uint code, uint flags, u32 val)
{ bgp_set_attr(to, pool, code, flags, (uintptr_t) val); } {
union bval bv = { .data = val };
bgp_set_attr(to, pool, code, flags, bv);
}
static inline void static inline void
bgp_set_attr_ptr(ea_list **to, struct linpool *pool, uint code, uint flags, const struct adata *val) bgp_set_attr_ptr(ea_list **to, struct linpool *pool, uint code, uint flags, const struct adata *ad)
{ bgp_set_attr(to, pool, code, flags, (uintptr_t) val); } {
union bval bv = { .ptr = ad };
bgp_set_attr(to, pool, code, flags, bv);
}
static inline void static inline void
bgp_set_attr_data(ea_list **to, struct linpool *pool, uint code, uint flags, void *data, uint len) bgp_set_attr_data(ea_list **to, struct linpool *pool, uint code, uint flags, void *data, uint len)
{ {
struct adata *a = lp_alloc_adata(pool, len); struct adata *a = lp_alloc_adata(pool, len);
bmemcpy(a->data, data, len); bmemcpy(a->data, data, len);
bgp_set_attr(to, pool, code, flags, (uintptr_t) a); bgp_set_attr_ptr(to, pool, code, flags, a);
} }
#define bgp_unset_attr(to, pool, code) ea_unset_attr(to, pool, 0, code) #define bgp_unset_attr(to, pool, code) ea_unset_attr(to, pool, 0, code)

View File

@ -318,31 +318,31 @@ 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_BGP_ORIGIN, T_ENUM_BGP_ORIGIN, EA_CODE(PROTOCOL_BGP, BA_ORIGIN)); } ; { $$ = f_new_dynamic_attr(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(T_PATH, EA_CODE(PROTOCOL_BGP, BA_AS_PATH)); } ;
dynamic_attr: BGP_NEXT_HOP dynamic_attr: BGP_NEXT_HOP
{ $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_CODE(PROTOCOL_BGP, BA_NEXT_HOP)); } ; { $$ = f_new_dynamic_attr(T_IP, EA_CODE(PROTOCOL_BGP, BA_NEXT_HOP)); } ;
dynamic_attr: BGP_MED dynamic_attr: BGP_MED
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); } ; { $$ = f_new_dynamic_attr(T_INT, EA_CODE(PROTOCOL_BGP, BA_MULTI_EXIT_DISC)); } ;
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(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_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_ATOMIC_AGGR)); } ; { $$ = f_new_dynamic_attr(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_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AGGREGATOR)); } ; { $$ = f_new_dynamic_attr(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(T_CLIST, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); } ;
dynamic_attr: BGP_ORIGINATOR_ID dynamic_attr: BGP_ORIGINATOR_ID
{ $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUAD, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID)); } ; { $$ = f_new_dynamic_attr(T_QUAD, EA_CODE(PROTOCOL_BGP, BA_ORIGINATOR_ID)); } ;
dynamic_attr: BGP_CLUSTER_LIST dynamic_attr: BGP_CLUSTER_LIST
{ $$ = f_new_dynamic_attr(EAF_TYPE_INT_SET, T_CLIST, EA_CODE(PROTOCOL_BGP, BA_CLUSTER_LIST)); } ; { $$ = f_new_dynamic_attr(T_CLIST, EA_CODE(PROTOCOL_BGP, BA_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(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_OPAQUE, EA_CODE(PROTOCOL_BGP, BA_AIGP)); } ; { $$ = f_new_dynamic_attr(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(T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); } ;

View File

@ -505,10 +505,10 @@ ospf_iface:
ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); } ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
; ;
dynamic_attr: OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_METRIC1); } ; dynamic_attr: OSPF_METRIC1 { $$ = f_new_dynamic_attr(T_INT, EA_OSPF_METRIC1); } ;
dynamic_attr: OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_METRIC2); } ; dynamic_attr: OSPF_METRIC2 { $$ = f_new_dynamic_attr(T_INT, EA_OSPF_METRIC2); } ;
dynamic_attr: OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_OSPF_TAG); } ; dynamic_attr: OSPF_TAG { $$ = f_new_dynamic_attr(T_INT, EA_OSPF_TAG); } ;
dynamic_attr: OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID, T_QUAD, EA_OSPF_ROUTER_ID); } ; dynamic_attr: OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(T_QUAD, EA_OSPF_ROUTER_ID); } ;
CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]); CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
CF_CLI(SHOW OSPF, optproto, [<name>], [[Show information about OSPF protocol]]) CF_CLI(SHOW OSPF, optproto, [<name>], [[Show information about OSPF protocol]])

View File

@ -2072,27 +2072,27 @@ again1:
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) { a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
.id = EA_OSPF_METRIC1, .id = EA_OSPF_METRIC1,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = nf->n.metric1, .u.data = nf->n.metric1,
}; };
if (nf->n.type == RTS_OSPF_EXT2) if (nf->n.type == RTS_OSPF_EXT2)
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) { a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
.id = EA_OSPF_METRIC2, .id = EA_OSPF_METRIC2,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = nf->n.metric2, .u.data = nf->n.metric2,
}; };
if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2)) if ((nf->n.type == RTS_OSPF_EXT1) || (nf->n.type == RTS_OSPF_EXT2))
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) { a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
.id = EA_OSPF_TAG, .id = EA_OSPF_TAG,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = nf->n.tag, .u.data = nf->n.tag,
}; };
a0.eattrs->attrs[a0.eattrs->count++] = (eattr) { a0.eattrs->attrs[a0.eattrs->count++] = (eattr) {
.id = EA_OSPF_ROUTER_ID, .id = EA_OSPF_ROUTER_ID,
.type = EAF_TYPE_ROUTER_ID, .type = T_QUAD,
.u.data = nf->n.rid, .u.data = nf->n.rid,
}; };

View File

@ -336,8 +336,8 @@ radv_sensitive:
| SENSITIVE bool { $$ = $2; } | SENSITIVE bool { $$ = $2; }
; ;
dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(EAF_TYPE_RA_PREFERENCE, T_ENUM_RA_PREFERENCE, EA_RA_PREFERENCE); } ; dynamic_attr: RA_PREFERENCE { $$ = f_new_dynamic_attr(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(T_INT, EA_RA_LIFETIME); } ;
CF_CODE CF_CODE

View File

@ -190,8 +190,8 @@ rip_iface:
rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish; rip_iface_start iface_patt_list_nopx rip_iface_opt_list rip_iface_finish;
dynamic_attr: RIP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_METRIC); } ; dynamic_attr: RIP_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_RIP_METRIC); } ;
dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_RIP_TAG); } ; dynamic_attr: RIP_TAG { $$ = f_new_dynamic_attr(T_INT, EA_RIP_TAG); } ;
CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]); CF_CLI_HELP(SHOW RIP, ..., [[Show information about RIP protocol]]);

View File

@ -202,17 +202,17 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
.e = { .e = {
{ {
.id = EA_RIP_METRIC, .id = EA_RIP_METRIC,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = rt_metric, .u.data = rt_metric,
}, },
{ {
.id = EA_RIP_TAG, .id = EA_RIP_TAG,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = rt_tag, .u.data = rt_tag,
}, },
{ {
.id = EA_RIP_FROM, .id = EA_RIP_FROM,
.type = EAF_TYPE_IFACE, .type = T_IFACE,
.u.ptr = &ea_block.riad.ad, .u.ptr = &ea_block.riad.ad,
} }
}, },

View File

@ -589,7 +589,7 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
ea->attrs[0] = (eattr) { ea->attrs[0] = (eattr) {
.id = EA_KRT_SOURCE, .id = EA_KRT_SOURCE,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = src2, .u.data = src2,
}; };

View File

@ -28,23 +28,23 @@ kern_sys_item:
| NETLINK RX BUFFER expr { THIS_KRT->sys.netlink_rx_buffer = $4; } | NETLINK RX BUFFER expr { THIS_KRT->sys.netlink_rx_buffer = $4; }
; ;
dynamic_attr: KRT_PREFSRC { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_KRT_PREFSRC); } ; dynamic_attr: KRT_PREFSRC { $$ = f_new_dynamic_attr(T_IP, EA_KRT_PREFSRC); } ;
dynamic_attr: KRT_REALM { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_REALM); } ; dynamic_attr: KRT_REALM { $$ = f_new_dynamic_attr(T_INT, EA_KRT_REALM); } ;
dynamic_attr: KRT_SCOPE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SCOPE); } ; dynamic_attr: KRT_SCOPE { $$ = f_new_dynamic_attr(T_INT, EA_KRT_SCOPE); } ;
dynamic_attr: KRT_MTU { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_MTU); } ; dynamic_attr: KRT_MTU { $$ = f_new_dynamic_attr(T_INT, EA_KRT_MTU); } ;
dynamic_attr: KRT_WINDOW { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_WINDOW); } ; dynamic_attr: KRT_WINDOW { $$ = f_new_dynamic_attr(T_INT, EA_KRT_WINDOW); } ;
dynamic_attr: KRT_RTT { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_RTT); } ; dynamic_attr: KRT_RTT { $$ = f_new_dynamic_attr(T_INT, EA_KRT_RTT); } ;
dynamic_attr: KRT_RTTVAR { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_RTTVAR); } ; dynamic_attr: KRT_RTTVAR { $$ = f_new_dynamic_attr(T_INT, EA_KRT_RTTVAR); } ;
dynamic_attr: KRT_SSTRESH { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SSTRESH); } ; dynamic_attr: KRT_SSTRESH { $$ = f_new_dynamic_attr(T_INT, EA_KRT_SSTRESH); } ;
dynamic_attr: KRT_CWND { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_CWND); } ; dynamic_attr: KRT_CWND { $$ = f_new_dynamic_attr(T_INT, EA_KRT_CWND); } ;
dynamic_attr: KRT_ADVMSS { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_ADVMSS); } ; dynamic_attr: KRT_ADVMSS { $$ = f_new_dynamic_attr(T_INT, EA_KRT_ADVMSS); } ;
dynamic_attr: KRT_REORDERING { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_REORDERING); } ; dynamic_attr: KRT_REORDERING { $$ = f_new_dynamic_attr(T_INT, EA_KRT_REORDERING); } ;
dynamic_attr: KRT_HOPLIMIT { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_HOPLIMIT); } ; dynamic_attr: KRT_HOPLIMIT { $$ = f_new_dynamic_attr(T_INT, EA_KRT_HOPLIMIT); } ;
dynamic_attr: KRT_INITCWND { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_INITCWND); } ; dynamic_attr: KRT_INITCWND { $$ = f_new_dynamic_attr(T_INT, EA_KRT_INITCWND); } ;
dynamic_attr: KRT_RTO_MIN { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_RTO_MIN); } ; dynamic_attr: KRT_RTO_MIN { $$ = f_new_dynamic_attr(T_INT, EA_KRT_RTO_MIN); } ;
dynamic_attr: KRT_INITRWND { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_INITRWND); } ; dynamic_attr: KRT_INITRWND { $$ = f_new_dynamic_attr(T_INT, EA_KRT_INITRWND); } ;
dynamic_attr: KRT_QUICKACK { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_QUICKACK); } ; dynamic_attr: KRT_QUICKACK { $$ = f_new_dynamic_attr(T_INT, EA_KRT_QUICKACK); } ;
/* Bits of EA_KRT_LOCK, based on RTAX_* constants */ /* Bits of EA_KRT_LOCK, based on RTAX_* constants */

View File

@ -1587,12 +1587,12 @@ nl_announce_route(struct nl_parse_state *s)
ea->attrs[0] = (eattr) { ea->attrs[0] = (eattr) {
.id = EA_KRT_SOURCE, .id = EA_KRT_SOURCE,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = s->krt_proto, .u.data = s->krt_proto,
}; };
ea->attrs[1] = (eattr) { ea->attrs[1] = (eattr) {
.id = EA_KRT_METRIC, .id = EA_KRT_METRIC,
.type = EAF_TYPE_INT, .type = T_INT,
.u.data = s->krt_metric, .u.data = s->krt_metric,
}; };
@ -1873,7 +1873,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
ea->count = 1; ea->count = 1;
ea->attrs[0].id = EA_KRT_SCOPE; ea->attrs[0].id = EA_KRT_SCOPE;
ea->attrs[0].flags = 0; ea->attrs[0].flags = 0;
ea->attrs[0].type = EAF_TYPE_INT; ea->attrs[0].type = T_INT;
ea->attrs[0].u.data = i->rtm_scope; ea->attrs[0].u.data = i->rtm_scope;
} }
@ -1888,7 +1888,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
ea->count = 1; ea->count = 1;
ea->attrs[0].id = EA_KRT_PREFSRC; ea->attrs[0].id = EA_KRT_PREFSRC;
ea->attrs[0].flags = 0; ea->attrs[0].flags = 0;
ea->attrs[0].type = EAF_TYPE_IP_ADDRESS; ea->attrs[0].type = T_IP;
struct adata *ad = lp_alloc(s->pool, sizeof(struct adata) + sizeof(ps)); struct adata *ad = lp_alloc(s->pool, sizeof(struct adata) + sizeof(ps));
ad->length = sizeof(ps); ad->length = sizeof(ps);
@ -1907,7 +1907,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
ea->count = 1; ea->count = 1;
ea->attrs[0].id = EA_KRT_REALM; ea->attrs[0].id = EA_KRT_REALM;
ea->attrs[0].flags = 0; ea->attrs[0].flags = 0;
ea->attrs[0].type = EAF_TYPE_INT; ea->attrs[0].type = T_INT;
ea->attrs[0].u.data = s->rta_flow; ea->attrs[0].u.data = s->rta_flow;
} }
@ -1928,7 +1928,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; ea->attrs[n].type = T_INT;
ea->attrs[n].u.data = metrics[t]; ea->attrs[n].u.data = metrics[t];
n++; n++;
} }

File diff suppressed because it is too large Load Diff

View File

@ -122,8 +122,8 @@ kif_iface:
kif_iface_start iface_patt_list_nopx kif_iface_opt_list; kif_iface_start iface_patt_list_nopx kif_iface_opt_list;
dynamic_attr: KRT_SOURCE { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_SOURCE); } ; dynamic_attr: KRT_SOURCE { $$ = f_new_dynamic_attr(T_INT, EA_KRT_SOURCE); } ;
dynamic_attr: KRT_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_METRIC); } ; dynamic_attr: KRT_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_KRT_METRIC); } ;
CF_CODE CF_CODE