From patchwork Fri Jun 3 05:11:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zong Kai LI X-Patchwork-Id: 629604 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rLXJM50QRz9sD5 for ; Fri, 3 Jun 2016 15:11:47 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=ZXZZnKJZ; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 0278C108B6; Thu, 2 Jun 2016 22:11:46 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 4AA17108B5 for ; Thu, 2 Jun 2016 22:11:44 -0700 (PDT) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id A2C6B42020B for ; Thu, 2 Jun 2016 23:11:43 -0600 (MDT) X-ASG-Debug-ID: 1464930702-09eadd4ab7b3100001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id WWmMXT5Np6uKHQgQ (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 02 Jun 2016 23:11:42 -0600 (MDT) X-Barracuda-Envelope-From: zealokii@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO mail-it0-f66.google.com) (209.85.214.66) by mx1-pf2.cudamail.com with ESMTPS (AES128-SHA encrypted); 3 Jun 2016 05:11:41 -0000 Received-SPF: pass (mx1-pf2.cudamail.com: SPF record at _netblocks.google.com designates 209.85.214.66 as permitted sender) X-Barracuda-Apparent-Source-IP: 209.85.214.66 X-Barracuda-RBL-IP: 209.85.214.66 Received: by mail-it0-f66.google.com with SMTP id i127so5311347ita.3 for ; Thu, 02 Jun 2016 22:11:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=Ao/QZ9EYDt7LxQrU298VinxgNi3Jy4iwcW1RTgl4PG8=; b=ZXZZnKJZJbiYO25mtZXvVBFfCYG3/LLaUNNBDHw9G85C0tDrCL6mtC9eONMIP33M0j VcsBghDZYKvWwIsF6JybChp0UIg7ugsaSVIRbXB8P5KGCCINbeFa1JiqBzCIkMUp1JhY VCcVp2nMdfGurXCyzwzYAIqkjsa4NxT1hCHHpObeQPP/XHS23r/hYTHZaXwkoGe+qfKy rILiyytaZAGTJ6zhwKFxGU0osKBfgM6QsZoZAgfpgOREbQ3vClbOQAwNq8xg/YK1srDk xDLD5A6831vo7KNQU/7CP303MqQ4ObTLhMOY2vjX31FugQT5/iJugs2M6hTviZD790g7 C3kQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Ao/QZ9EYDt7LxQrU298VinxgNi3Jy4iwcW1RTgl4PG8=; b=YxyUbY9qMABbElhr5GW+f0be9Tni8qnNQCijWM3WHVdvLDHgc7kfiJaoGURPpE1gqI Iy+j7sUQOS3OjD6DXxL170nLI/mLlGDKHBNjH4U4Rl4w7XY8vU2HNQPTcEPQ8mxO2Sq2 i2sULvBPiu+ggCrgkG41XXmaiUfgfrRDsBAV9u4t0QPqu19Kq7k8sk3I40sAvwDnegS6 EpSGnO2vFAYezu+sRfVj4Vv7Mb38R3EAnJTuV6tfWWoNDyNaoPLAAP2JIml74GHgPhoQ tVln9QZGw5xjgSiZzsLaOGtmd88JOJqhVsfuXb/NyMmpRTgAFM58WbyGaUQuhq6T2eO4 KHBA== X-Gm-Message-State: ALyK8tKauPLkTWLbrZP31I9aK82AO/Km5ZsQpcQevrPKj8vZC09T/744S3D5ckWCP85IaQ== X-Received: by 10.36.54.85 with SMTP id l82mr7769721itl.18.1464930700872; Thu, 02 Jun 2016 22:11:40 -0700 (PDT) Received: from localhost.localdomain ([106.38.0.70]) by smtp.gmail.com with ESMTPSA id 127sm2083386iov.34.2016.06.02.22.11.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Jun 2016 22:11:40 -0700 (PDT) X-CudaMail-Envelope-Sender: zealokii@gmail.com From: Zong Kai LI To: dev@openvswitch.org X-CudaMail-MID: CM-E2-601097648 X-CudaMail-DTE: 060216 X-CudaMail-Originating-IP: 209.85.214.66 Date: Fri, 3 Jun 2016 13:11:32 +0800 X-ASG-Orig-Subj: [##CM-E2-601097648##][PATCH] [PATCH v2 2/2] ovn: add lflows for 'na' action for ND Message-Id: <1464930692-23732-1-git-send-email-zealokii@gmail.com> X-Mailer: git-send-email 1.9.1 X-GBUdb-Analysis: 0, 209.85.214.66, Ugly c=0.377531 p=-0.384615 Source Normal X-MessageSniffer-Rules: 0-0-0-22193-c X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1464930702 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC5_MJ1963, DKIM_SIGNED, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.30133 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Cc: Zong Kai LI Subject: [ovs-dev] [PATCH] [PATCH v2 2/2] ovn: add lflows for 'na' action for ND X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" This patch adds some lflows for 'na' action to support ND versus ARP. For ovn-northd, it will generate lflows per each IPv6 address on echo lport, with lport mac and IPv6 addresss, with 'na' action. e.g. match=(ip6 && nd && icmp6.type == 135 && nd.target == fde3:f657:aac1:0:f816:3eff:fe13:8198), action=(na{fa:16:3e:13:81:98; reg0 = 0x1; outport = inport; inport = ""; output;};) And new lflows will be set in tabel ls_in_arp_nd_rsp, which is renamed from previous ls_in_arp_rsp. Setting reg0 = 0x1 to mention that such kind of NA packets are replied by ovn-controller, and for these packets, they dont need conntrack. So I also modfiy current table 32 and table 48, to make these packets output directly. (Will try to add test once I figure out what to test.) Signed-off-by: Zong Kai LI --- ovn/controller/physical.c | 17 +++++++++ ovn/northd/ovn-northd.c | 93 +++++++++++++++++++++++++++++++++++++++++++---- tutorial/OVN-Tutorial.md | 6 +-- 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 576c695..df19680 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -707,6 +707,23 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve, put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, &match, &ofpacts); + /* Table 32, Priority 100. + * ======================= + * + * Directly output NA packets replied by ovn-controller for NS packets + * come from local VMs. + * - match: ip6 && icmp6 && icmp6.type == 136 && reg0 == 0x1 + * - action: resubmit(,48) + */ + match_init_catchall(&match); + match_set_dl_type(&match, htons(0x86dd)); + match_set_nw_proto(&match, (uint8_t)58); + match_set_icmp_type(&match, (uint8_t)136); + match_set_reg(&match, 0, (uint32_t)1); + ofpbuf_clear(&ofpacts); + put_resubmit(OFTABLE_LOG_EGRESS_PIPELINE, &ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 100, &match, &ofpacts); + /* Table 34, Priority 0. * ======================= * diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index a8dd2bb..0263d5c 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -93,7 +93,7 @@ enum ovn_stage { PIPELINE_STAGE(SWITCH, IN, PORT_SEC_ND, 2, "ls_in_port_sec_nd") \ PIPELINE_STAGE(SWITCH, IN, PRE_ACL, 3, "ls_in_pre_acl") \ PIPELINE_STAGE(SWITCH, IN, ACL, 4, "ls_in_acl") \ - PIPELINE_STAGE(SWITCH, IN, ARP_RSP, 5, "ls_in_arp_rsp") \ + PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 5, "ls_in_arp_nd_rsp") \ PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 6, "ls_in_l2_lkup") \ \ /* Logical switch egress stages. */ \ @@ -1475,6 +1475,64 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, struct hmap *ports) acl->match, "drop;"); } } + + /* Egress Pre-ACL Table (Priority 110). + * + * Directly output RA packets replied by ovn-controller, they dont + * need go through conntrack. + */ + bool ra_allowed = false; + /* Consider the following cases are RA allowed: + * - has: + * match: "... ip6 && icmp6", + * action: "allow"/"allow-related". + * and has no: + * match: "... ip6 && icmp6 && icmp6.type == 136", + * action: "drop"/"reject". + * - has: + * match: "... ip6 && icmp6 && icmp6.type == 136", + * action: "allow"/"allow-related". + * and has no: + * match: "... ip6 && icmp6", + * action: "drop"/"reject". + */ + for (size_t i = 0; i < od->nbs->n_acls; i++) { + struct nbrec_acl *acl = od->nbs->acls[i]; + if (!strcmp(acl->direction, "from-lport")) { + continue; + } + char *icmp6 = strstr(acl->match, "ip6 && icmp6"); + if (!icmp6) { + continue; + } + /* strlen("ip6 && icmp6") == 12 */ + if (*(icmp6 + 12) == '\0') { + if (!strcmp(acl->action, "drop") + || !strcmp(acl->action, "reject")) { + ra_allowed = false; + break; + } else { + ra_allowed = true; + } + } else { + char *ra = strstr(icmp6 + 12, "icmp6.type == 136"); + /* strlen("icmp6.type == 136") == 17 */ + if (ra && *(ra + 17) == '\0') { + if (!strcmp(acl->action, "drop") + || !strcmp(acl->action, "reject")) { + ra_allowed = false; + break; + } else { + ra_allowed = true; + } + } + } + } + if (ra_allowed) { + ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110, + "ip6 && icmp6 && icmp6.type == 136 && reg0 == 0x1", + "output;"); + } } static void @@ -1566,13 +1624,13 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, if (!strcmp(op->nbs->type, "localnet")) { char *match = xasprintf("inport == %s", op->json_key); - ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_RSP, 100, + ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 100, match, "next;"); free(match); } } - /* Ingress table 5: ARP responder, reply for known IPs. + /* Ingress table 5: ARP/ND responder, reply for known IPs. * (priority 50). */ HMAP_FOR_EACH (op, key_node, ports) { if (!op->nbs) { @@ -1580,7 +1638,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, } /* - * Add ARP reply flows if either the + * Add ARP/ND reply flows if either the * - port is up or * - port type is router */ @@ -1591,7 +1649,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, for (size_t i = 0; i < op->nbs->n_addresses; i++) { struct lport_addresses laddrs; if (!extract_lport_addresses(op->nbs->addresses[i], &laddrs, - false)) { + true)) { continue; } for (size_t j = 0; j < laddrs.n_ipv4_addrs; j++) { @@ -1612,13 +1670,34 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, ETH_ADDR_ARGS(laddrs.ea), ETH_ADDR_ARGS(laddrs.ea), IP_ARGS(laddrs.ipv4_addrs[j].addr)); - ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_RSP, 50, + ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 50, match, actions); free(match); free(actions); } + char ip6_str[INET6_ADDRSTRLEN + 1]; + for (size_t j = 0; j < laddrs.n_ipv6_addrs; j++) { + ipv6_string_mapped(ip6_str, &(laddrs.ipv6_addrs[i].addr)); + + struct ds match = DS_EMPTY_INITIALIZER; + ds_put_cstr(&match, "ip6 && nd && icmp6.type == 135 " + "&& nd.target == "); + ds_put_format(&match, "%s", ip6_str); + struct ds actions = DS_EMPTY_INITIALIZER; + ds_put_cstr(&actions, "na{"); + ds_put_format(&actions, ETH_ADDR_FMT, ETH_ADDR_ARGS(laddrs.ea)); + ds_put_cstr(&actions, "; reg0 = 0x1; outport = inport; " + "inport = \"\"; output;};"); + + ovn_lflow_add(lflows, op->od, S_SWITCH_IN_ARP_ND_RSP, 50, + ds_cstr(&match), ds_cstr(&actions)); + + ds_destroy(&actions); + ds_destroy(&match); + } free(laddrs.ipv4_addrs); + free(laddrs.ipv6_addrs); } } @@ -1629,7 +1708,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, continue; } - ovn_lflow_add(lflows, od, S_SWITCH_IN_ARP_RSP, 0, "1", "next;"); + ovn_lflow_add(lflows, od, S_SWITCH_IN_ARP_ND_RSP, 0, "1", "next;"); } /* Ingress table 6: Destination lookup, broadcast and multicast handling diff --git a/tutorial/OVN-Tutorial.md b/tutorial/OVN-Tutorial.md index 7b31fe2..bb3cdae 100644 --- a/tutorial/OVN-Tutorial.md +++ b/tutorial/OVN-Tutorial.md @@ -104,7 +104,7 @@ show the logical flows. table=2(ls_in_port_sec_nd), priority= 0, match=(1), action=(next;) table=3( ls_in_pre_acl), priority= 0, match=(1), action=(next;) table=4( ls_in_acl), priority= 0, match=(1), action=(next;) - table=5( ls_in_arp_rsp), priority= 0, match=(1), action=(next;) + table=5(ls_in_arp_nd_rsp), priority= 0, match=(1), action=(next;) table=6( ls_in_l2_lkup), priority= 100, match=(eth.mcast), action=(outport = "_MC_flood"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:01), action=(outport = "sw0-port1"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:02), action=(outport = "sw0-port2"; output;) @@ -277,7 +277,7 @@ OVN creates separate logical flows for each logical switch. table=2(ls_in_port_sec_nd), priority= 0, match=(1), action=(next;) table=3( ls_in_pre_acl), priority= 0, match=(1), action=(next;) table=4( ls_in_acl), priority= 0, match=(1), action=(next;) - table=5( ls_in_arp_rsp), priority= 0, match=(1), action=(next;) + table=5(ls_in_arp_nd_rsp), priority= 0, match=(1), action=(next;) table=6( ls_in_l2_lkup), priority= 100, match=(eth.mcast), action=(outport = "_MC_flood"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:03), action=(outport = "sw1-port1"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:04), action=(outport = "sw1-port2"; output;) @@ -303,7 +303,7 @@ OVN creates separate logical flows for each logical switch. table=2(ls_in_port_sec_nd), priority= 0, match=(1), action=(next;) table=3( ls_in_pre_acl), priority= 0, match=(1), action=(next;) table=4( ls_in_acl), priority= 0, match=(1), action=(next;) - table=5( ls_in_arp_rsp), priority= 0, match=(1), action=(next;) + table=5(ls_in_arp_nd_rsp), priority= 0, match=(1), action=(next;) table=6( ls_in_l2_lkup), priority= 100, match=(eth.mcast), action=(outport = "_MC_flood"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:01), action=(outport = "sw0-port1"; output;) table=6( ls_in_l2_lkup), priority= 50, match=(eth.dst == 00:00:00:00:00:02), action=(outport = "sw0-port2"; output;)