summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2018-09-28 01:03:42 +0200
committerMikael Magnusson <mikma@users.sourceforge.net>2019-03-08 00:15:45 +0100
commit8bb0b0d7575a7f7701c44d8907381f546c001331 (patch)
treeaa540ede9cb2828aa729a4114fae1cd9f171bcdd
parentc8d22fe91cc7d13cabf4b0f625dda137fc835321 (diff)
WIP tlv
-rw-r--r--filter/config.Y81
-rw-r--r--filter/filter.c10
-rw-r--r--filter/filter.h2
-rw-r--r--nest/attrs.h18
-rw-r--r--nest/route.h1
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) */