diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2018-09-28 01:03:42 +0200 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-03-08 00:15:45 +0100 |
commit | 8bb0b0d7575a7f7701c44d8907381f546c001331 (patch) | |
tree | aa540ede9cb2828aa729a4114fae1cd9f171bcdd | |
parent | c8d22fe91cc7d13cabf4b0f625dda137fc835321 (diff) |
WIP tlv
-rw-r--r-- | filter/config.Y | 81 | ||||
-rw-r--r-- | filter/filter.c | 10 | ||||
-rw-r--r-- | filter/filter.h | 2 | ||||
-rw-r--r-- | nest/attrs.h | 18 | ||||
-rw-r--r-- | nest/route.h | 1 |
5 files changed, 110 insertions, 2 deletions
diff --git a/filter/config.Y b/filter/config.Y index c1e74531..84644370 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -107,6 +107,18 @@ f_new_pair_set(int fa, int ta, int fb, int tb) #define LC_ALL 0xFFFFFFFF static struct f_tree * +f_new_tlv_item(u32 type, u32 v1) +{ + debug("f_new_tlv_item\n"); + struct f_tree *t = f_new_tree(); + t->right = t; + t->from.type = t->to.type = T_TLV; + // t->from.val.tlv = v1; + // t->to.val.tlv = v1; + return t; +} + +static struct f_tree * f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt) { u64 fm, to; @@ -315,6 +327,62 @@ f_generate_lc(struct f_inst *t1, struct f_inst *t2, struct f_inst *t3) } static inline struct f_inst * +f_generate_tlv(u16 kind, struct f_inst *tv) +{ + struct f_inst *rv = NULL; + struct tlv tlv; + struct f_val *val; + u32 type; + + debug("f_generate_tlv\n"); + + if (tv->fi_code != FI_CONSTANT_INDIRECT) + cf_error("Can't operate with value of non-constant type in TLV: %d", tv->fi_code); + + val = tv->a1.p; + type = val->type; + + switch (kind) { + case TLV_WIREGUARD: { + if (type == T_STRING) { + tlv.u.peer = val->val.s; + } + else + cf_error("Can't operate with value of non-string type in TLV wireguard constructor"); + break; + } + case TLV_REMOTE_ENDPOINT: { + if (type == T_IP) { + tlv.u.remote_endpoint.ip = val->val.ip; + } + else + cf_error("Can't operate with value of non-IP type in TLV remote endpoint constructor"); + break; + } + case TLV_UDP_DEST_PORT: { + if (type == T_INT) { + tlv.u.udp_dest_port = val->val.i; + } + else + cf_error("Can't operate with value of non-integer type in TLV udp dest port constructor"); + break; + } + default: + cf_error("Invalid TLV kind in constructor"); + }; + + { + NEW_F_VAL; + rv = f_new_inst(FI_CONSTANT_INDIRECT); + rv->a1.p = val; + val->type = T_TLV; + val->val.tlv = tlv; + + return rv; + } +} + +static inline struct f_inst * f_generate_path_mask(struct f_path_mask *t) { for (struct f_path_mask *tt = t; tt; tt = tt->next) { @@ -427,9 +495,9 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %type <fda> dynamic_attr %type <fsa> static_attr %type <f> filter filter_body where_filter -%type <i> type break_command ec_kind +%type <i> type break_command ec_kind tlv_kind %type <i32> cnum -%type <e> pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body +%type <e> pair_item ec_item lc_item set_item switch_item set_items switch_items switch_body tlv_item %type <trie> fprefix_set %type <v> set_atom switch_atom fipa %type <px> fprefix @@ -712,6 +780,14 @@ lc_item: { $$ = f_new_lc_item($2, $10, $4, $12, $6, $14); } ; +tlv_kind: + WIREGUARD { $$ = TLV_WIREGUARD; } + +tlv_item: + '(' tlv_kind ',' term ')' { $$ = f_new_tlv_item($2, $4); } + +// | tlv_item + set_item: pair_item | ec_item @@ -808,6 +884,7 @@ constructor: '(' term ',' term ')' { $$ = f_generate_dpair($2, $4); } | '(' ec_kind ',' term ',' term ')' { $$ = f_generate_ec($2, $4, $6); } | '(' term ',' term ',' term ')' { $$ = f_generate_lc($2, $4, $6); } + | '(' tlv_kind ',' term ')' { $$ = f_generate_tlv($2, $4); } | bgp_path { $$ = f_generate_path_mask($1); } ; diff --git a/filter/filter.c b/filter/filter.c index 37cf16a3..299e616e 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -1104,6 +1104,10 @@ interpret(struct f_inst *what) case EAF_TYPE_UNDEF: res.type = T_VOID; break; + case EAF_TYPE_TUNNEL_ENCAP: + res.type = T_TLV; + runtime("FIXME Tunnel Encapsulation in e,a"); + break; default: bug("Unknown type in e,a"); } @@ -1195,6 +1199,12 @@ interpret(struct f_inst *what) runtime( "Setting void attribute to non-void value" ); l->attrs[0].u.data = 0; break; + case EAF_TYPE_TUNNEL_ENCAP: + if (v1.type != T_TLV) + runtime( "Setting tunnel encap attribute to non-tlv value" ); + debug( "FIXME tunnel encapsulation in e,S" ); + l->attrs[0].u.ptr = v1.val.ad; + break; default: bug("Unknown type in e,S"); } diff --git a/filter/filter.h b/filter/filter.h index a8c33287..dc9715a0 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -129,6 +129,7 @@ struct f_val { struct f_trie *ti; struct adata *ad; struct f_path_mask *path_mask; + struct tlv tlv; } val; }; @@ -245,6 +246,7 @@ void val_format(struct f_val v, buffer *buf); #define T_LC 0x28 /* Large community value, lcomm */ #define T_LCLIST 0x29 /* Large community list */ #define T_RD 0x2a /* Route distinguisher for VPN addresses */ +#define T_TLV 0x2b /* Tunnel encapsulation TLV */ #define T_RETURN 0x40 #define T_SET 0x80 diff --git a/nest/attrs.h b/nest/attrs.h index 102f378a..8f76695d 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -199,4 +199,22 @@ struct adata *lc_set_sort(struct linpool *pool, struct adata *src); void ec_set_sort_x(struct adata *set); /* Sort in place */ +/* Tunnel Encapsulation TLV types */ +#define TLV_WIREGUARD 0xffff +#define TLV_REMOTE_ENDPOINT 0x06 +#define TLV_UDP_DEST_PORT 0x08 + +/* Tunnel Encapsulation TLV */ +struct tlv { + union { + const char *peer; + struct { + u32 asn; + ip_addr ip; + } remote_endpoint; + u16 udp_dest_port; + u32 color; + } u; +}; + #endif diff --git a/nest/route.h b/nest/route.h index 8dfbb376..5b7085bf 100644 --- a/nest/route.h +++ b/nest/route.h @@ -504,6 +504,7 @@ const char *ea_custom_name(uint ea); #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 0x12 /* Set of triplets of u32's - large community list */ +#define EAF_TYPE_TUNNEL_ENCAP 0x13 /* Tunnel Encapsulation (encoding per draft-ietf-idr-tunnel-encaps-10) */ #define EAF_TYPE_UNDEF 0x1f /* `force undefined' entry */ #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) */ |