summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/exthdr.c23
-rw-r--r--src/parser_bison.y26
-rw-r--r--src/scanner.l4
3 files changed, 50 insertions, 3 deletions
diff --git a/src/exthdr.c b/src/exthdr.c
index 3757f335..cbe0da86 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -101,6 +101,9 @@ struct expr *exthdr_expr_alloc(const struct location *loc,
case 2:
expr->exthdr.op = NFT_EXTHDR_OP_RT2;
break;
+ case 4:
+ expr->exthdr.op = NFT_EXTHDR_OP_RT4;
+ break;
}
}
return expr;
@@ -165,6 +168,8 @@ void exthdr_init_raw(struct expr *expr, uint8_t type,
expr->exthdr.desc = &exthdr_rt0;
else if (op == NFT_EXTHDR_OP_RT2)
expr->exthdr.desc = &exthdr_rt2;
+ else if (op == NFT_EXTHDR_OP_RT4)
+ expr->exthdr.desc = &exthdr_rt4;
else if (type < array_size(exthdr_protocols))
expr->exthdr.desc = exthdr_protocols[type];
@@ -274,6 +279,24 @@ const struct exthdr_desc exthdr_rt0 = {
},
};
+#define RT4_FIELD(__name, __member, __dtype) \
+ HDR_TEMPLATE(__name, __dtype, struct ip6_rt4, __member)
+
+const struct exthdr_desc exthdr_rt4 = {
+ .name = "srh",
+ .type = IPPROTO_ROUTING,
+ .proto_key = 4,
+ .templates = {
+ [RT4HDR_LASTENT] = RT4_FIELD("last-entry", ip6r4_last_entry, &integer_type),
+ [RT4HDR_FLAGS] = RT4_FIELD("flags", ip6r4_flags, &integer_type),
+ [RT4HDR_TAG] = RT4_FIELD("tag", ip6r4_tag, &integer_type),
+ [RT4HDR_SID_1] = RT4_FIELD("sid[1]", ip6r4_segments[0], &ip6addr_type),
+ [RT4HDR_SID_1 + 1] = RT4_FIELD("sid[1]", ip6r4_segments[0], &ip6addr_type),
+ // ...
+ },
+};
+
+
#define RT_FIELD(__name, __member, __dtype) \
HDR_TEMPLATE(__name, __dtype, struct ip6_rthdr, __member)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 2ccaf9ab..5f84d794 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -364,8 +364,12 @@ int nft_lex(void *, void *, void *);
%token RT "rt"
%token RT0 "rt0"
%token RT2 "rt2"
+%token RT4 "srh"
%token SEG_LEFT "seg-left"
%token ADDR "addr"
+%token LAST_ENT "last-entry"
+%token TAG "tag"
+%token SID "sid"
%token HBH "hbh"
@@ -674,9 +678,9 @@ int nft_lex(void *, void *, void *);
%type <expr> hbh_hdr_expr frag_hdr_expr dst_hdr_expr
%destructor { expr_free($$); } hbh_hdr_expr frag_hdr_expr dst_hdr_expr
%type <val> hbh_hdr_field frag_hdr_field dst_hdr_field
-%type <expr> rt_hdr_expr rt0_hdr_expr rt2_hdr_expr
-%destructor { expr_free($$); } rt_hdr_expr rt0_hdr_expr rt2_hdr_expr
-%type <val> rt_hdr_field rt0_hdr_field rt2_hdr_field
+%type <expr> rt_hdr_expr rt0_hdr_expr rt2_hdr_expr rt4_hdr_expr
+%destructor { expr_free($$); } rt_hdr_expr rt0_hdr_expr rt2_hdr_expr rt4_hdr_expr
+%type <val> rt_hdr_field rt0_hdr_field rt2_hdr_field rt4_hdr_field
%type <expr> mh_hdr_expr
%destructor { expr_free($$); } mh_hdr_expr
%type <val> mh_hdr_field
@@ -3921,6 +3925,7 @@ exthdr_expr : hbh_hdr_expr
| rt_hdr_expr
| rt0_hdr_expr
| rt2_hdr_expr
+ | rt4_hdr_expr
| frag_hdr_expr
| dst_hdr_expr
| mh_hdr_expr
@@ -3969,6 +3974,21 @@ rt2_hdr_expr : RT2 rt2_hdr_field
rt2_hdr_field : ADDR { $$ = RT2HDR_ADDR; }
;
+rt4_hdr_expr : RT4 rt4_hdr_field
+ {
+ $$ = exthdr_expr_alloc(&@$, &exthdr_rt4, $2);
+ }
+ ;
+
+rt4_hdr_field : LAST_ENT { $$ = RT4HDR_LASTENT; }
+ | FLAGS { $$ = RT4HDR_FLAGS; }
+ | TAG { $$ = RT4HDR_TAG; }
+ | SID '[' NUM ']'
+ {
+ $$ = RT4HDR_SID_1 + $3 - 1;
+ }
+ ;
+
frag_hdr_expr : FRAG frag_hdr_field
{
$$ = exthdr_expr_alloc(&@$, &exthdr_frag, $2);
diff --git a/src/scanner.l b/src/scanner.l
index ab10738b..1d8e8ba0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -456,8 +456,12 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"rt" { return RT; }
"rt0" { return RT0; }
"rt2" { return RT2; }
+"srh" { return RT4; }
"seg-left" { return SEG_LEFT; }
"addr" { return ADDR; }
+"last-entry" { return LAST_ENT; }
+"tag" { return TAG; }
+"sid" { return SID; }
"hbh" { return HBH; }