diff options
-rw-r--r-- | include/exthdr.h | 9 | ||||
-rw-r--r-- | include/headers.h | 12 | ||||
-rw-r--r-- | src/exthdr.c | 23 | ||||
-rw-r--r-- | src/parser_bison.y | 26 | ||||
-rw-r--r-- | src/scanner.l | 4 |
5 files changed, 71 insertions, 3 deletions
diff --git a/include/exthdr.h b/include/exthdr.h index 06bf6285..32f99c9c 100644 --- a/include/exthdr.h +++ b/include/exthdr.h @@ -57,6 +57,14 @@ enum rt2_hdr_fields { RT2HDR_ADDR, }; +enum rt4_hdr_fields { + RT4HDR_INVALID, + RT4HDR_LASTENT, + RT4HDR_FLAGS, + RT4HDR_TAG, + RT4HDR_SID_1, +}; + enum frag_hdr_fields { FRAGHDR_INVALID, FRAGHDR_NEXTHDR, @@ -87,6 +95,7 @@ extern const struct exthdr_desc exthdr_hbh; extern const struct exthdr_desc exthdr_rt; extern const struct exthdr_desc exthdr_rt0; extern const struct exthdr_desc exthdr_rt2; +extern const struct exthdr_desc exthdr_rt4; extern const struct exthdr_desc exthdr_frag; extern const struct exthdr_desc exthdr_dst; extern const struct exthdr_desc exthdr_mh; diff --git a/include/headers.h b/include/headers.h index 469d6740..3d564deb 100644 --- a/include/headers.h +++ b/include/headers.h @@ -112,6 +112,18 @@ struct ip6_mh { uint8_t data[0]; }; +/* Type 4 Routing header - well known as srh */ +struct ip6_rt4 { + uint8_t ip6r4_nxt; /* next header */ + uint8_t ip6r4_len; /* length in units of 8 octets */ + uint8_t ip6r4_type; /* always zero */ + uint8_t ip6r4_segleft; /* segments left */ + uint8_t ip6r4_last_entry; /* last entry */ + uint8_t ip6r4_flags; /* flags */ + uint16_t ip6r4_tag; /* tag */ + struct in6_addr ip6r4_segments[0]; /* SID list */ +}; + /* RFC 3775 */ #define IP6_MH_TYPE_BRR 0 /* Binding Refresh Request */ #define IP6_MH_TYPE_HOTI 1 /* HOTI Message */ 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; } |