From patchwork Tue Feb 27 10:04:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ahmed Abdelsalam X-Patchwork-Id: 879061 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="o5bqZ3ER"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zrst75P4Nz9s3G for ; Wed, 28 Feb 2018 21:55:43 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752312AbeB1Kzm (ORCPT ); Wed, 28 Feb 2018 05:55:42 -0500 Received: from mail-wr0-f193.google.com ([209.85.128.193]:37906 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752474AbeB1Kzl (ORCPT ); Wed, 28 Feb 2018 05:55:41 -0500 Received: by mail-wr0-f193.google.com with SMTP id n7so1908380wrn.5 for ; Wed, 28 Feb 2018 02:55:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=dN3Ghu0zAD+elgcZE/IbD+ZCLsXjyOLKKp5gpI47Rtg=; b=o5bqZ3ERcorZE+nI9y8XTNuK20HjzVH1XRFPUWl9ZZUOq+sOGJLGut7bsEVteVYbc0 Faea1NiefgA7epicJ3dwOlZ7SfGDJKfcPm0m6I3cTsEf9w7kTKylNFG8920NKZDbrTLy NQY41VIlAXv28AqKgeBZVg/rTfDnpllkwCzdGTY59jWDb186PS3Mv3YctD/Gje6dLlC2 BVmNN23dLkx2xteyXzo+L+HYWHCwCq7spRL8NnBMKQfpmtnytoRKg1IaqV2BSegAq85/ nZ/8Ptp6qAmLXz2c28sKLNEGX6BGUD/2LtE5KDD6HVAqiTWvvx9lyKJvB0rqrhx2KwHs XJkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=dN3Ghu0zAD+elgcZE/IbD+ZCLsXjyOLKKp5gpI47Rtg=; b=O3/lGpCW2qwHWTHI8F64DnbFxoYiV/N4aT1JPLvHiAfmMvWvSbDjWANEUj2Lys+Exa 2PfdoNUwaw9stZzrljYRN/QtwHUiIk8J1TAD6u1j0xrESbrJv8hpfCqmQOZQ7aWNMkUp gciHg2eukMApI+hRbL8uvqLsLtNbFLH+w5gqxEeR52KtkBLk2bTtqUhHP6nDa50GXvLK 556FRxE0XMbUSluM/sbiXT+kAS+re91ftRrNIYdFi2MF/3j+skvWGgC43864UDp/PEFT /vQ0U5SqKL8wsH7V1BJ8AwcjUz7zG2/S68bKI53f0BjgWq2OsVlMjVXjxQTnxYrh3iHm pZ5A== X-Gm-Message-State: APf1xPDpa06sxUpPdI0qjdBpJ91QQQApCt0geSFbUzf2PSODit5FfwTg P2lR16HXqZpBn6mgDYpC7EQ= X-Google-Smtp-Source: AH8x226ZSZvDyuGnO8H1bbGtpYhy/pquiskVd5DK2o2CP0ovNWY7YDkRdZi77+GDxLRfI4T1bvREKQ== X-Received: by 10.223.163.85 with SMTP id d21mr15547347wrb.105.1519815340095; Wed, 28 Feb 2018 02:55:40 -0800 (PST) Received: from sr6.gssi.infn.it (wifi-guest-target.gssi.infn.it. [192.135.27.147]) by smtp.gmail.com with ESMTPSA id p104sm2556434wrb.47.2018.02.28.02.55.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 28 Feb 2018 02:55:39 -0800 (PST) From: Ahmed Abdelsalam To: pablo@netfilter.org, fw@strlen.de, netfilter-devel@vger.kernel.org Cc: davem@davemloft.net, coreteam@netfilter.org, amsalam20@gmail.com Subject: [nft] nftables: Adding support for segment routing header 'srh' Date: Tue, 27 Feb 2018 11:04:14 +0100 Message-Id: <1519725854-23059-1-git-send-email-amsalam20@gmail.com> X-Mailer: git-send-email 2.1.4 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- This patch should be applied after those two patches http://patchwork.ozlabs.org/patch/878674/ http://patchwork.ozlabs.org/patch/878675/ include/exthdr.h | 9 +++++++++ include/headers.h | 12 ++++++++++++ src/exthdr.c | 23 +++++++++++++++++++++++ src/parser_bison.y | 26 +++++++++++++++++++++++--- src/scanner.l | 4 ++++ 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/include/exthdr.h b/include/exthdr.h index 06bf628..32f99c9 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 469d674..3d564de 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 3757f33..cbe0da8 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 df672b1..5fad274 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -357,8 +357,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" @@ -664,9 +668,9 @@ int nft_lex(void *, void *, void *); %type hbh_hdr_expr frag_hdr_expr dst_hdr_expr %destructor { expr_free($$); } hbh_hdr_expr frag_hdr_expr dst_hdr_expr %type hbh_hdr_field frag_hdr_field dst_hdr_field -%type rt_hdr_expr rt0_hdr_expr rt2_hdr_expr -%destructor { expr_free($$); } rt_hdr_expr rt0_hdr_expr rt2_hdr_expr -%type rt_hdr_field rt0_hdr_field rt2_hdr_field +%type 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 rt_hdr_field rt0_hdr_field rt2_hdr_field rt4_hdr_field %type mh_hdr_expr %destructor { expr_free($$); } mh_hdr_expr %type mh_hdr_field @@ -3737,6 +3741,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 @@ -3785,6 +3790,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 05c70af..15e6641 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -450,8 +450,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; }