diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/exthdr.c | 23 | ||||
-rw-r--r-- | src/parser_bison.y | 26 | ||||
-rw-r--r-- | src/scanner.l | 4 |
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; } |