From patchwork Mon Apr 9 10:00:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 896220 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40KQmm5NdNz9s1p for ; Mon, 9 Apr 2018 20:01:12 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 9A9F3D8A; Mon, 9 Apr 2018 10:00:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id D8F34D7E for ; Mon, 9 Apr 2018 10:00:41 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-it0-f68.google.com (mail-it0-f68.google.com [209.85.214.68]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 03BDC628 for ; Mon, 9 Apr 2018 10:00:40 +0000 (UTC) Received: by mail-it0-f68.google.com with SMTP id e98-v6so9523874itd.4 for ; Mon, 09 Apr 2018 03:00:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=1aIn5Ya5Jqyd+BSkHTUUwq7NjZTrjqSZvUbiYYp7xK0=; b=JL55/N+EukCEsg6hdB8EQ7RO1KN/XyNxMyxTo2bowdBgij8N1fnzP0+xKqWZqu5+mb s3f/z7cEBY9cBdj7FGH8QSOok8Ew76g4NQjLI6u2eGUknhCfdsNt4tKl4RlpD/yHgv6r SNtjQFnMF5q7gapacv4PU3RmnLjMcVq+JczkT/wZPAoN7MVyXtsVqks81rFhT1ffmEUU Yeq0GzcHYurxirM/QirphT8/GqEiCKPc94HWl88JFz5fJBMJSxq1I2kwBrYBGTclReYd tB8ri83XBY6NwYwgvCWHeRxzxpBQSaE7yJpD3uR5cXUiEySIjHVKAimfqvxxUzzfBkFM 78DQ== X-Gm-Message-State: AElRT7HZ5/8hmQHfXcn6l0GDmQu6DrpT3YgIxO5Ezr6umC88ZguuAGhG gaDlOT2BKV7IEI3X5xbSCYZEQJoYoBs= X-Google-Smtp-Source: AIpwx48sgtAegisEo8NqO2linYPWFBQSsGoCIDvP2EDE18kR1WGP/Mkh3nQmK07A2fguXjmKgh9GcQ== X-Received: by 2002:a24:530f:: with SMTP id n15-v6mr26771373itb.123.1523268040045; Mon, 09 Apr 2018 03:00:40 -0700 (PDT) Received: from localhost.localdomain.com (nat-pool-mxp-t.redhat.com. [149.6.153.186]) by smtp.gmail.com with ESMTPSA id u66-v6sm282735itd.9.2018.04.09.03.00.37 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 09 Apr 2018 03:00:39 -0700 (PDT) From: Lorenzo Bianconi To: dev@openvswitch.org Date: Mon, 9 Apr 2018 12:00:24 +0200 Message-Id: X-Mailer: git-send-email 2.14.3 In-Reply-To: References: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v2 1/2] OVN: add icmp6{} action support X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org icmp6 action is used to replace the IPv6 packet been processed with an ICMPv6 packet initialized based on incoming IPv6 one. Ethernet and IPv6 fields not listed are not changed: - ip.proto = 58 (ICMPv6) - ip.ttl = 255 - icmp6.type = 1 (destination unreachable) - icmp6.code = 1 (communication administratively prohibited) Prerequisite: ip6 Signed-off-by: Lorenzo Bianconi --- include/ovn/actions.h | 5 ++-- ovn/controller/pinctrl.c | 73 +++++++++++++++++++++++++++++++++-------------- ovn/lib/actions.c | 24 +++++++++++++++- ovn/ovn-sb.xml | 26 +++++++++++++++++ ovn/utilities/ovn-trace.c | 30 +++++++++++++++++++ tests/ovn.at | 10 +++++++ 6 files changed, 144 insertions(+), 24 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 086ab19e0..3f58b72f8 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -65,6 +65,7 @@ struct ovn_extend_table; OVNACT(CLONE, ovnact_nest) \ OVNACT(ARP, ovnact_nest) \ OVNACT(ICMP4, ovnact_nest) \ + OVNACT(ICMP6, ovnact_nest) \ OVNACT(TCP_RESET, ovnact_nest) \ OVNACT(ND_NA, ovnact_nest) \ OVNACT(GET_ARP, ovnact_get_mac_bind) \ @@ -432,11 +433,11 @@ enum action_opcode { */ ACTION_OPCODE_ND_NS, - /* "icmp4 { ...actions... }". + /* "icmp4 { ...actions... } and icmp6 { ...actions... }". * * The actions, in OpenFlow 1.3 format, follow the action_header. */ - ACTION_OPCODE_ICMP4, + ACTION_OPCODE_ICMP, /* "tcp_reset { ...actions... }". * diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index c816b2dd6..2f130994a 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -220,15 +220,16 @@ pinctrl_handle_arp(const struct flow *ip_flow, const struct match *md, } static void -pinctrl_handle_icmp4(const struct flow *ip_flow, const struct match *md, - struct ofpbuf *userdata) +pinctrl_handle_icmp(const struct flow *ip_flow, struct dp_packet *pkt_in, + const struct match *md, struct ofpbuf *userdata) { /* This action only works for IP packets, and the switch should only send * us IP packets this way, but check here just to be sure. */ - if (ip_flow->dl_type != htons(ETH_TYPE_IP)) { + if (ip_flow->dl_type != htons(ETH_TYPE_IP) && + ip_flow->dl_type != htons(ETH_TYPE_IPV6)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); VLOG_WARN_RL(&rl, - "ICMP4 action on non-IP packet (eth_type 0x%"PRIx16")", + "ICMP action on non-IP packet (eth_type 0x%"PRIx16")", ntohs(ip_flow->dl_type)); return; } @@ -243,21 +244,50 @@ pinctrl_handle_icmp4(const struct flow *ip_flow, const struct match *md, struct eth_header *eh = dp_packet_put_zeros(&packet, sizeof *eh); eh->eth_dst = ip_flow->dl_dst; eh->eth_src = ip_flow->dl_src; - eh->eth_type = htons(ETH_TYPE_IP); - - struct ip_header *nh = dp_packet_put_zeros(&packet, sizeof *nh); - dp_packet_set_l3(&packet, nh); - nh->ip_ihl_ver = IP_IHL_VER(5, 4); - nh->ip_tot_len = htons(sizeof(struct ip_header) + - sizeof(struct icmp_header)); - nh->ip_proto = IPPROTO_ICMP; - nh->ip_frag_off = htons(IP_DF); - packet_set_ipv4(&packet, ip_flow->nw_src, ip_flow->nw_dst, - ip_flow->nw_tos, 255); - - struct icmp_header *ih = dp_packet_put_zeros(&packet, sizeof *ih); - dp_packet_set_l4(&packet, ih); - packet_set_icmp(&packet, ICMP4_DST_UNREACH, 1); + + if (get_dl_type(ip_flow) == htons(ETH_TYPE_IP)) { + struct ip_header *nh = dp_packet_put_zeros(&packet, sizeof *nh); + + eh->eth_type = htons(ETH_TYPE_IP); + dp_packet_set_l3(&packet, nh); + nh->ip_ihl_ver = IP_IHL_VER(5, 4); + nh->ip_tot_len = htons(sizeof(struct ip_header) + + sizeof(struct icmp_header)); + nh->ip_proto = IPPROTO_ICMP; + nh->ip_frag_off = htons(IP_DF); + packet_set_ipv4(&packet, ip_flow->nw_src, ip_flow->nw_dst, + ip_flow->nw_tos, 255); + + struct icmp_header *ih = dp_packet_put_zeros(&packet, sizeof *ih); + dp_packet_set_l4(&packet, ih); + packet_set_icmp(&packet, ICMP4_DST_UNREACH, 1); + } else { + struct ip6_hdr *nh = dp_packet_put_zeros(&packet, sizeof *nh); + struct icmp6_error_header *ih; + uint32_t icmpv6_csum; + + eh->eth_type = htons(ETH_TYPE_IPV6); + dp_packet_set_l3(&packet, nh); + nh->ip6_vfc = 0x60; + nh->ip6_nxt = IPPROTO_ICMPV6; + nh->ip6_plen = htons(sizeof(*nh) + ICMP6_ERROR_HEADER_LEN); + packet_set_ipv6(&packet, &ip_flow->ipv6_src, &ip_flow->ipv6_dst, + ip_flow->nw_tos, ip_flow->ipv6_label, 255); + + ih = dp_packet_put_zeros(&packet, sizeof *ih); + dp_packet_set_l4(&packet, ih); + ih->icmp6_base.icmp6_type = ICMP6_DST_UNREACH; + ih->icmp6_base.icmp6_code = 1; + ih->icmp6_base.icmp6_cksum = 0; + + uint8_t *data = dp_packet_put_zeros(&packet, sizeof *nh); + memcpy(data, dp_packet_l3(pkt_in), sizeof(*nh)); + + icmpv6_csum = packet_csum_pseudoheader6(dp_packet_l3(&packet)); + ih->icmp6_base.icmp6_cksum = csum_finish( + csum_continue(icmpv6_csum, ih, + sizeof(*nh) + ICMP6_ERROR_HEADER_LEN)); + } if (ip_flow->vlans[0].tci & htons(VLAN_CFI)) { eth_push_vlan(&packet, htons(ETH_TYPE_VLAN_8021Q), @@ -1154,8 +1184,9 @@ process_packet_in(const struct ofp_header *msg, struct controller_ctx *ctx) pinctrl_handle_nd_ns(&headers, &pin.flow_metadata, &userdata); break; - case ACTION_OPCODE_ICMP4: - pinctrl_handle_icmp4(&headers, &pin.flow_metadata, &userdata); + case ACTION_OPCODE_ICMP: + pinctrl_handle_icmp(&headers, &packet, &pin.flow_metadata, + &userdata); break; case ACTION_OPCODE_TCP_RESET: diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 1e0bcb7b7..a8dbb6b8c 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -1147,6 +1147,12 @@ parse_ICMP4(struct action_context *ctx) parse_nested_action(ctx, OVNACT_ICMP4, "ip4"); } +static void +parse_ICMP6(struct action_context *ctx) +{ + parse_nested_action(ctx, OVNACT_ICMP6, "ip6"); +} + static void parse_TCP_RESET(struct action_context *ctx) { @@ -1192,6 +1198,12 @@ format_ICMP4(const struct ovnact_nest *nest, struct ds *s) format_nested_action(nest, "icmp4", s); } +static void +format_ICMP6(const struct ovnact_nest *nest, struct ds *s) +{ + format_nested_action(nest, "icmp6", s); +} + static void format_TCP_RESET(const struct ovnact_nest *nest, struct ds *s) { @@ -1253,7 +1265,15 @@ encode_ICMP4(const struct ovnact_nest *on, const struct ovnact_encode_params *ep, struct ofpbuf *ofpacts) { - encode_nested_actions(on, ep, ACTION_OPCODE_ICMP4, ofpacts); + encode_nested_actions(on, ep, ACTION_OPCODE_ICMP, ofpacts); +} + +static void +encode_ICMP6(const struct ovnact_nest *on, + const struct ovnact_encode_params *ep, + struct ofpbuf *ofpacts) +{ + encode_nested_actions(on, ep, ACTION_OPCODE_ICMP, ofpacts); } static void @@ -2289,6 +2309,8 @@ parse_action(struct action_context *ctx) parse_ARP(ctx); } else if (lexer_match_id(ctx->lexer, "icmp4")) { parse_ICMP4(ctx); + } else if (lexer_match_id(ctx->lexer, "icmp6")) { + parse_ICMP6(ctx); } else if (lexer_match_id(ctx->lexer, "tcp_reset")) { parse_TCP_RESET(ctx); } else if (lexer_match_id(ctx->lexer, "nd_na")) { diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml index 23dcfb9cf..52750e192 100644 --- a/ovn/ovn-sb.xml +++ b/ovn/ovn-sb.xml @@ -1733,6 +1733,32 @@

Prerequisite: ip4

+
icmp6 { action; ... };
+
+

+ Temporarily replaces the IPv6 packet being processed by an ICMPv6 + packet and executes each nested action on the ICMPv6 + packet. Actions following the icmp6 action, if any, + apply to the original, unmodified packet. +

+ +

+ The ICMPv6 packet that this action operates on is initialized based + on the IPv6 packet being processed, as follows. These are default + values that the nested actions will probably want to change. + Ethernet and IPv6 fields not listed here are not changed: +

+ +
    +
  • ip.proto = 58 (ICMPv6)
  • +
  • ip.ttl = 255
  • +
  • icmp6.type = 1 (destination unreachable)
  • +
  • icmp6.code = 1 (administratively prohibited)
  • +
+ +

Prerequisite: ip6

+
+
tcp_reset;

diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index 4db6f24f2..ac15d4e9e 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -1560,6 +1560,31 @@ execute_icmp4(const struct ovnact_nest *on, table_id, pipeline, &node->subs); } +static void +execute_icmp6(const struct ovnact_nest *on, + const struct ovntrace_datapath *dp, + const struct flow *uflow, uint8_t table_id, + enum ovnact_pipeline pipeline, struct ovs_list *super) +{ + struct flow icmp6_flow = *uflow; + + /* Update fields for ICMPv6. */ + icmp6_flow.dl_dst = uflow->dl_dst; + icmp6_flow.dl_src = uflow->dl_src; + icmp6_flow.ipv6_dst = uflow->ipv6_dst; + icmp6_flow.ipv6_src = uflow->ipv6_src; + icmp6_flow.nw_proto = IPPROTO_ICMPV6; + icmp6_flow.nw_ttl = 255; + icmp6_flow.tp_src = htons(ICMP6_DST_UNREACH); /* icmp type */ + icmp6_flow.tp_dst = htons(1); /* icmp code */ + + struct ovntrace_node *node = ovntrace_node_append( + super, OVNTRACE_NODE_TRANSFORMATION, "icmp6"); + + trace_actions(on->nested, on->nested_len, dp, &icmp6_flow, + table_id, pipeline, &node->subs); +} + static void execute_tcp_reset(const struct ovnact_nest *on, const struct ovntrace_datapath *dp, @@ -1950,6 +1975,11 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len, super); break; + case OVNACT_ICMP6: + execute_icmp6(ovnact_get_ICMP6(a), dp, uflow, table_id, pipeline, + super); + break; + case OVNACT_TCP_RESET: execute_tcp_reset(ovnact_get_TCP_RESET(a), dp, uflow, table_id, pipeline, super); diff --git a/tests/ovn.at b/tests/ovn.at index b872a1b7e..423c73c26 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1135,6 +1135,16 @@ icmp4 { }; encodes as controller(userdata=00.00.00.0a.00.00.00.00) has prereqs ip4 +# icmp6 +icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output; + encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64) + has prereqs ip6 + +icmp6 { }; + formats as icmp6 { drop; }; + encodes as controller(userdata=00.00.00.0a.00.00.00.00) + has prereqs ip6 + # tcp_reset tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output; encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64) From patchwork Mon Apr 9 10:00:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 896221 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40KQnP4q2lz9s1p for ; Mon, 9 Apr 2018 20:01:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 73DDADA3; Mon, 9 Apr 2018 10:00:46 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 5B633D97 for ; Mon, 9 Apr 2018 10:00:45 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-io0-f194.google.com (mail-io0-f194.google.com [209.85.223.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 40E71636 for ; Mon, 9 Apr 2018 10:00:44 +0000 (UTC) Received: by mail-io0-f194.google.com with SMTP id y128so8940852iod.4 for ; Mon, 09 Apr 2018 03:00:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=6nxqx6YG2gwFnOreZm4b9cd9jZpr/IXOC4qkR6/1upw=; b=LkgmuBhr1GJizwab/35GlpzsbOnK7hlFtzqiW3+ynb/NkVuvdM7pcRYp/sMZC8i/14 YEB3NkFuenBLLvBAJ7hZCEDAy5CrTzBOLHulwmmWBjgwdCM+U00H/XUsZGJ1js+XPg88 pjUAraKYjBiNwsQn86NcSqbc2edRo+QCh2HemsdAn7g0K710H46HvWeXe6vYcvURhh0a +qb8/LGtYw6YNb8iwnSufAGKk8n0GK+Przgwwh5A1bonTbYVRiArEQqbt9/AC7ctEW2Y wvw8CBgSxnswcytV7lflf+i14V89ectKkkLoNTUz+ZGgS1PxR4SZjZec76UmbdibOtqw kLIA== X-Gm-Message-State: ALQs6tBy95HyxD+yXBHwPuSzvzv4uw3/sOjAy0T+KgGxbAf4LK81r+o2 n62xySwiF1o+FBIpvxUPGIiq1XSuaH0= X-Google-Smtp-Source: AIpwx48clniWpfe96c4K7afehj0RjNG6T8aRb7mpfQIerLuezYCvpvBtnN8UCH8IUv6S7H90aTWSUA== X-Received: by 10.107.79.18 with SMTP id d18mr33107638iob.286.1523268043327; Mon, 09 Apr 2018 03:00:43 -0700 (PDT) Received: from localhost.localdomain.com (nat-pool-mxp-t.redhat.com. [149.6.153.186]) by smtp.gmail.com with ESMTPSA id u66-v6sm282735itd.9.2018.04.09.03.00.41 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 09 Apr 2018 03:00:42 -0700 (PDT) From: Lorenzo Bianconi To: dev@openvswitch.org Date: Mon, 9 Apr 2018 12:00:25 +0200 Message-Id: X-Mailer: git-send-email 2.14.3 In-Reply-To: References: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v2 2/2] OVN: add icmp6 action to ovn acl reject support X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Whenever the acl reject rule is hit by an IPv6 packet send back an ICMPv6 destination unreachable packet using the icmp6 action Signed-off-by: Lorenzo Bianconi --- NEWS | 4 ++++ ovn/northd/ovn-northd.c | 25 ++++++++++++++++++++++--- ovn/ovn-nb.xml | 3 ++- tests/ovn.at | 20 ++++++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 0cfcac54f..757d648a1 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ Post-v2.9.0 * OFPT_ROLE_STATUS is now available in OpenFlow 1.3. - Linux kernel 4.14 * Add support for compiling OVS with the latest Linux 4.14 kernel + - ovn: + * implemented icmp4/icmp6/tcp_reset actions in order to drop the packet + and reply with a RST for TCP or ICMPv4/ICMPv6 unreachable message for + other IPv4/IPv6-based protocols whenever a reject ACL rule is hit. v2.9.0 - 19 Feb 2018 -------------------- diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 9ca15bc2f..845faba86 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -2912,10 +2912,12 @@ build_pre_acls(struct ovn_datapath *od, struct hmap *lflows) * unreachable packets. */ ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 110, "nd || nd_rs || nd_ra || icmp4.type == 3 || " - "(tcp && tcp.flags == 4)", "next;"); + "icmp6.type == 1 || (tcp && tcp.flags == 4)", + "next;"); ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110, "nd || nd_rs || nd_ra || icmp4.type == 3 || " - "(tcp && tcp.flags == 4)", "next;"); + "icmp6.type == 1 || (tcp && tcp.flags == 4)", + "next;"); /* Ingress and Egress Pre-ACL Table (Priority 100). * @@ -3131,7 +3133,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET + 10, ds_cstr(&match), ds_cstr(&actions)); - /* IPv4 traffic */ + /* IP traffic */ ds_clear(&match); ds_clear(&actions); build_acl_log(&actions, acl); @@ -3148,6 +3150,23 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ingress ? "output;" : "next(pipeline=ingress,table=0);"); ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, ds_cstr(&match), ds_cstr(&actions)); + ds_clear(&match); + ds_clear(&actions); + build_acl_log(&actions, acl); + if (extra_match->length > 0) { + ds_put_format(&match, "(%s) && ", extra_match->string); + } + ds_put_format(&match, "ip6 && (%s)", acl->match); + if (extra_actions->length > 0) { + ds_put_format(&actions, "%s ", extra_actions->string); + } + ds_put_format(&actions, "reg0 = 0; icmp6 { " + "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " + "outport <-> inport; %s };", + ingress ? "output;" : "next(pipeline=ingress,table=0);"); + ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET, + ds_cstr(&match), ds_cstr(&actions)); + ds_destroy(&match); ds_destroy(&actions); } diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index 2ebaac561..1f6e69e2d 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -1061,7 +1061,8 @@

  • reject: Drop the packet, replying with a RST for TCP or - ICMP unreachable message for other IP-based protocols. + ICMPv4/ICMPv6 unreachable message for other IPv4/IPv6-based + protocols.
  • diff --git a/tests/ovn.at b/tests/ovn.at index 423c73c26..3bb9932f2 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -9412,6 +9412,24 @@ test_ip_packet() { as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet } +# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM +# +# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with +# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified. +# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit +test_ipv6_packet() { + local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7 + shift 7 + + local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst} + local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000 + + local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr} + echo $reply >> vif$inport.expected + + as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet +} + # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM # # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with @@ -9486,6 +9504,8 @@ test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_ test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe +test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183 + test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486 test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486 test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486