summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAhmed Abdelsalam <amsalam20@gmail.com>2018-02-27 11:04:14 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-11 22:59:46 +0100
commita7e02fe7984a721ae1240c415ec7d1e73ccc5dbd (patch)
tree29aabe95725a2f29543044bdaf81efe5da6f05f1 /src
parent1400288f6d39d9839748c44216171e84c6d47d66 (diff)
src: Adding support for segment routing header 'srh'
Segment Routing Header "SRH" is new type of IPv6 Routing extension header (type 4). SRH contains a list of segments (each is represented as an IPv6 address) to be visited by packets during the journey from source to destination. The SRH specification are defined in the below IETF SRH draft. https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-07 Signed-off-by: Ahmed Abdelsalam <amsalam20@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
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; }