From patchwork Tue Jan 14 11:07:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Bianconi X-Patchwork-Id: 1222690 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=hemlock.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=LpM9DUVi; dkim-atps=neutral Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47xnk93mvDz9sPW for ; Tue, 14 Jan 2020 22:08:00 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 11BE6877E2; Tue, 14 Jan 2020 11:07:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ab8PwShViLVg; Tue, 14 Jan 2020 11:07:53 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by hemlock.osuosl.org (Postfix) with ESMTP id AF4D886CD7; Tue, 14 Jan 2020 11:07:49 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9628CC1D83; Tue, 14 Jan 2020 11:07:49 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 35CB8C077D for ; Tue, 14 Jan 2020 11:07:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 2CFF4846F4 for ; Tue, 14 Jan 2020 11:07:48 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id wjZCvpSE4ev8 for ; Tue, 14 Jan 2020 11:07:43 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from us-smtp-delivery-1.mimecast.com (us-smtp-2.mimecast.com [205.139.110.61]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 3E8DB8592F for ; Tue, 14 Jan 2020 11:07:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579000055; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TabWFR4gy88z+tPAQ1io3Jz2B3jqkzddfUVxhz5fbik=; b=LpM9DUViyrqOnl4m2MIAatIzRYabYWA1y77WL+SlQ6XxezVwIxjlu9AvZXpGWjWB5p0GU6 DYWHxm36dsPxwm7KjvdRV9r3IAIx9dsCZpJL3m9mcKOBgSBYfSlrMw7KMs+BFMSHip2xJo c5v/b5EaOAPS4bTiUWpHvMh2DXysJi8= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-192-jVjco_HGNNu8Ioj5AxC-VA-1; Tue, 14 Jan 2020 06:07:28 -0500 Received: by mail-wr1-f70.google.com with SMTP id i9so6337998wru.1 for ; Tue, 14 Jan 2020 03:07:28 -0800 (PST) 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:in-reply-to :references:mime-version:content-transfer-encoding; bh=vX7l3NP7+hL1dUdSe9PwlDOGMCG+2rPiaBCYO5LAjQM=; b=QeA/mQxBHdS3carw2ItveexwjCyrICWrPL5SzSN5A40POlsmFFpsOF8ziyuMdETEq4 EHdB2aLWsv6P+syK1V2Fir93S28/FYRBANn9uVnMnoBWVxgk7APKx64W76OWJMJoMUxE hwqoiNgvyipz4RWitzqKBLmJA2aY+caANMDqtZe+QL6G4CG93RsYFEotFeerPPBiLdzN 9UBl3ZHzLvNzmP9Ojqj4gWFKmJKYf5Uekhf2qUXYXwss5MrU5d0whWYPeTVeAKNUwNTd fe9YEryL+V2ci0Em1JOm3T6spMg4M/pLWKuGkmj6SVGl7gzVfaXHDMR7eORlSn2pwg7f wpZA== X-Gm-Message-State: APjAAAVGqCtw48fXv/uGh7VeEjD7Aq09JzkaETxqT/egikaJn6MhT3K6 jBAoYxJr0LOXFKK8+NB9sNkNub7Wwl+rUUQsus9HdvVbybaHRc8QiYRRpeXrYh8QFMqAaDEsnIn lOgilpABGsyZF X-Received: by 2002:a5d:6a88:: with SMTP id s8mr23601264wru.173.1579000047169; Tue, 14 Jan 2020 03:07:27 -0800 (PST) X-Google-Smtp-Source: APXvYqxgCmqskgheadXAYAIAy3DjPhPnQ1JmqjoOITtaZlFInY2L5TQjCAuQ+/2IXauhyFL4TicJFA== X-Received: by 2002:a5d:6a88:: with SMTP id s8mr23601218wru.173.1579000046651; Tue, 14 Jan 2020 03:07:26 -0800 (PST) Received: from localhost.localdomain.com (nat-pool-mxp-t.redhat.com. [149.6.153.186]) by smtp.gmail.com with ESMTPSA id y6sm18853729wrl.17.2020.01.14.03.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jan 2020 03:07:26 -0800 (PST) From: Lorenzo Bianconi To: dev@openvswitch.org Date: Tue, 14 Jan 2020 12:07:14 +0100 Message-Id: <26f0f27705f95c11630fa3b0900be6ab9efe8d49.1578999694.git.lorenzo.bianconi@redhat.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: References: MIME-Version: 1.0 X-MC-Unique: jVjco_HGNNu8Ioj5AxC-VA-1 X-Mimecast-Spam-Score: 0 Subject: [ovs-dev] [PATCH v6 ovn 2/2] northd: add logical flows for dhcpv6 pfd parsing X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Introduce logical flows in ovn router pipeline in order to parse dhcpv6 advertise/reply from IPv6 prefix delegation router. Do not overwrite ipv6_ra_pd_list info in options column of SB port_binding table written by ovn-controller Introduce ipv6_prefix column in NB Logical_router_port table to report IPv6 prefix received from delegation router to the CMS Signed-off-by: Lorenzo Bianconi --- northd/ovn-northd.c | 99 +++++++++++++++++++++++++++++++++- ovn-nb.ovsschema | 5 +- ovn-nb.xml | 22 ++++++++ tests/atlocal.in | 5 +- tests/system-ovn.at | 127 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 255 insertions(+), 3 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index b6dc809d7..031792706 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -2645,6 +2645,41 @@ copy_gw_chassis_from_nbrp_to_sbpb( free(sb_ha_chassis); } +static void +ovn_port_update_ipv6_prefix(struct northd_context *ctx, + const struct ovn_port *op, + struct smap *sb_option) +{ + const char *ipv6_pd_list = smap_get(&op->sb->options, "ipv6_ra_pd_list"); + if (!ipv6_pd_list) { + return; + } + + smap_add(sb_option, "ipv6_ra_pd_list", ipv6_pd_list); + + const struct nbrec_logical_router_port *lrp = NULL, *iter; + /* update logical_router_port table */ + NBREC_LOGICAL_ROUTER_PORT_FOR_EACH (iter, ctx->ovnnb_idl) { + if (!strcmp(iter->name, op->sb->logical_port)) { + lrp = iter; + break; + } + } + if (!lrp) { + return; + } + + struct sset ipv6_prefix_set = SSET_INITIALIZER(&ipv6_prefix_set); + sset_add_array(&ipv6_prefix_set, lrp->ipv6_prefix, lrp->n_ipv6_prefix); + if (!sset_contains(&ipv6_prefix_set, ipv6_pd_list)) { + sset_add(&ipv6_prefix_set, ipv6_pd_list); + nbrec_logical_router_port_set_ipv6_prefix(lrp, + sset_array(&ipv6_prefix_set), + sset_count(&ipv6_prefix_set)); + } + sset_destroy(&ipv6_prefix_set); +} + static void ovn_port_update_sbrec(struct northd_context *ctx, struct ovsdb_idl_index *sbrec_chassis_by_name, @@ -2653,6 +2688,7 @@ ovn_port_update_sbrec(struct northd_context *ctx, struct sset *active_ha_chassis_grps) { sbrec_port_binding_set_datapath(op->sb, op->od->sb); + if (op->nbrp) { /* If the router is for l3 gateway, it resides on a chassis * and its port type is "l3gateway". */ @@ -2775,6 +2811,9 @@ ovn_port_update_sbrec(struct northd_context *ctx, smap_add(&new, "l3gateway-chassis", chassis_name); } } + + ovn_port_update_ipv6_prefix(ctx, op, &new); + sbrec_port_binding_set_options(op->sb, &new); smap_destroy(&new); @@ -2824,6 +2863,9 @@ ovn_port_update_sbrec(struct northd_context *ctx, smap_add_format(&options, "qdisc_queue_id", "%d", queue_id); } + + ovn_port_update_ipv6_prefix(ctx, op, &options); + sbrec_port_binding_set_options(op->sb, &options); smap_destroy(&options); if (ovn_is_known_nb_lsp_type(op->nbsp->type)) { @@ -2873,6 +2915,9 @@ ovn_port_update_sbrec(struct northd_context *ctx, if (chassis) { smap_add(&new, "l3gateway-chassis", chassis); } + + ovn_port_update_ipv6_prefix(ctx, op, &new); + sbrec_port_binding_set_options(op->sb, &new); smap_destroy(&new); } else { @@ -7129,6 +7174,11 @@ copy_ra_to_sb(struct ovn_port *op, const char *address_mode) } ds_put_format(&s, "%s/%u ", addrs->network_s, addrs->plen); } + + const char *ra_pd_list = smap_get(&op->sb->options, "ipv6_ra_pd_list"); + if (ra_pd_list) { + ds_put_cstr(&s, ra_pd_list); + } /* Remove trailing space */ ds_chomp(&s, ' '); smap_add(&options, "ipv6_ra_prefixes", ds_cstr(&s)); @@ -7851,7 +7901,36 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, free(snat_ips); } - /* Logical router ingress table 3: IP Input for IPv6. */ + /* DHCPv6 reply handling */ + HMAP_FOR_EACH (op, key_node, ports) { + if (!op->nbrp) { + continue; + } + + if (op->derived) { + continue; + } + + struct lport_addresses lrp_networks; + if (!extract_lrp_networks(op->nbrp, &lrp_networks)) { + continue; + } + + for (size_t i = 0; i < lrp_networks.n_ipv6_addrs; i++) { + ds_clear(&actions); + ds_clear(&match); + ds_put_format(&match, "ip6.dst == %s && udp.src == 547 &&" + " udp.dst == 546", + lrp_networks.ipv6_addrs[i].addr_s); + ds_put_format(&actions, "reg0 = 0; handle_dhcpv6_reply { " + "eth.dst <-> eth.src; ip6.dst <-> ip6.src; " + "outport <-> inport; output; };"); + ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 100, + ds_cstr(&match), ds_cstr(&actions)); + } + } + + /* Logical router ingress table 1: IP Input for IPv6. */ HMAP_FOR_EACH (op, key_node, ports) { if (!op->nbrp) { continue; @@ -8652,6 +8731,24 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } + struct smap options; + /* enable IPv6 prefix delegation */ + bool prefix_delegation = smap_get_bool(&op->nbrp->options, + "prefix_delegation", false); + if (prefix_delegation) { + smap_clone(&options, &op->sb->options); + smap_add(&options, "ipv6_prefix_delegation", "true"); + sbrec_port_binding_set_options(op->sb, &options); + smap_destroy(&options); + } + + if (smap_get_bool(&op->nbrp->options, "prefix", false)) { + smap_clone(&options, &op->sb->options); + smap_add(&options, "ipv6_prefix", "true"); + sbrec_port_binding_set_options(op->sb, &options); + smap_destroy(&options); + } + const char *address_mode = smap_get( &op->nbrp->ipv6_ra_configs, "address_mode"); diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index 12999a466..8e9d1517f 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", "version": "5.18.0", - "cksum": "2806349485 24196", + "cksum": "4171338172 24362", "tables": { "NB_Global": { "columns": { @@ -324,6 +324,9 @@ "ipv6_ra_configs": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, + "ipv6_prefix": {"type": {"key": "string", + "min": 0, + "max": "unlimited"}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, diff --git a/ovn-nb.xml b/ovn-nb.xml index 5ae52bbde..55faca3b1 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -1896,6 +1896,11 @@ port has all ingress and egress traffic dropped. + + This column contains IPv6 prefix obtained by prefix delegation + router according to RFC 3633 + +

This column defines the IPv6 ND RA address mode and ND MTU Option to be @@ -2142,6 +2147,23 @@ to true.

+ + +

+ If set to true, enable IPv6 prefix delegation state + machine on this logical router port (RFC3633). IPv6 prefix + delegation is available just on a gateway router or on a gateway + router port. +

+
+ + +

+ If set to true, this interface will receive an IPv6 + prefix according to RFC3663 +

+
diff --git a/tests/atlocal.in b/tests/atlocal.in index 5f14c3da0..8f3ff03b9 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -157,7 +157,7 @@ find_command() { which $1 > /dev/null 2>&1 status=$? - var=HAVE_`echo "$1" | tr '[a-z]' '[A-Z]'` + var=HAVE_`echo "$1" | tr '-' '_' | tr '[a-z]' '[A-Z]'` if test "$status" = "0"; then eval ${var}="yes" else @@ -192,6 +192,9 @@ else DIFF_SUPPORTS_NORMAL_FORMAT=no fi +# Set HAVE_DIBBLER-SERVER +find_command dibbler-server + # Turn off proxies. unset http_proxy unset https_proxy diff --git a/tests/system-ovn.at b/tests/system-ovn.at index a56d358ea..bb7d8e420 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -3426,3 +3426,130 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d /connection dropped.*/d"]) AT_CLEANUP + +AT_SETUP([ovn -- IPv6 prefix delegation]) +AT_SKIP_IF([test $HAVE_DIBBLER_SERVER = no]) +AT_KEYWORDS([ovn-ipv6-prefix_d]) + +ovn_start +OVS_TRAFFIC_VSWITCHD_START() + +ADD_BR([br-int]) +ADD_BR([br-ext]) + +ovs-ofctl add-flow br-ext action=normal +# Set external-ids in br-int needed for ovn-controller +ovs-vsctl \ + -- set Open_vSwitch . external-ids:system-id=hv1 \ + -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ + -- set bridge br-int fail-mode=secure other-config:disable-in-band=true + +# Start ovn-controller +start_daemon ovn-controller + +ovn-nbctl lr-add R1 + +ovn-nbctl ls-add sw0 +ovn-nbctl ls-add sw1 +ovn-nbctl ls-add public + +ovn-nbctl lrp-add R1 rp-sw0 00:00:01:01:02:03 192.168.1.1/24 +ovn-nbctl lrp-add R1 rp-sw1 00:00:03:01:02:03 192.168.2.1/24 +ovn-nbctl lrp-add R1 rp-public 00:00:02:01:02:03 172.16.1.1/24 \ + -- set Logical_Router_Port rp-public options:redirect-chassis=hv1 + +ovn-nbctl lsp-add sw0 sw0-rp -- set Logical_Switch_Port sw0-rp \ + type=router options:router-port=rp-sw0 \ + -- lsp-set-addresses sw0-rp router +ovn-nbctl lsp-add sw1 sw1-rp -- set Logical_Switch_Port sw1-rp \ + type=router options:router-port=rp-sw1 \ + -- lsp-set-addresses sw1-rp router + +ovn-nbctl lsp-add public public-rp -- set Logical_Switch_Port public-rp \ + type=router options:router-port=rp-public \ + -- lsp-set-addresses public-rp router + +ADD_NAMESPACES(sw01) +ADD_VETH(sw01, sw01, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \ + "192.168.1.1") +ovn-nbctl lsp-add sw0 sw01 \ + -- lsp-set-addresses sw01 "f0:00:00:01:02:03 192.168.1.2" + +ADD_NAMESPACES(sw11) +ADD_VETH(sw11, sw11, br-int, "192.168.2.2/24", "f0:00:00:02:02:03", \ + "192.168.2.1") +ovn-nbctl lsp-add sw1 sw11 \ + -- lsp-set-addresses sw11 "f0:00:00:02:02:03 192.168.2.2" + +ADD_NAMESPACES(server) +ADD_VETH(s1, server, br-ext, "2001:db8:3333::2/64", "f0:00:00:01:02:05", \ + "2001:db8:3333::1") + +OVS_WAIT_UNTIL([test "$(ip netns exec server ip a | grep 2001:db8:3333::2 | grep tentative)" = ""]) +OVS_WAIT_UNTIL([test "$(ip netns exec server ip a | grep fe80 | grep tentative)" = ""]) + +AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=phynet:br-ext]) +ovn-nbctl lsp-add public public1 \ + -- lsp-set-addresses public1 unknown \ + -- lsp-set-type public1 localnet \ + -- lsp-set-options public1 network_name=phynet + +ovn-nbctl set logical_router_port rp-public options:prefix_delegation=true +ovn-nbctl set logical_router_port rp-public options:prefix=true +ovn-nbctl set logical_router_port rp-sw0 options:prefix=true +ovn-nbctl set logical_router_port rp-sw1 options:prefix=true + +# reset dibbler state +sed s/eth0/s1/g -i /etc/dibbler/server.conf +cat > /var/lib/dibbler/server-AddrMgr.xml < + 1575481348 + 0 + +EOF +cat > /var/lib/dibbler/server-CfgMgr.xml < + /var/lib/dibbler + Server + 8 + 0 + 0 + +EOF + +NS_CHECK_EXEC([server], [dibbler-server run > dibbler.log &]) +ovn-nbctl --wait=hv sync + +sleep 10 +kill $(pidof dibbler-server) + +OVS_WAIT_UNTIL([ovn-nbctl list logical_router_port rp-public | grep ipv6_prefix]) +OVS_WAIT_UNTIL([ovn-nbctl list logical_router_port rp-sw0 | grep ipv6_prefix]) +OVS_WAIT_UNTIL([ovn-nbctl list logical_router_port rp-sw1 | grep ipv6_prefix]) +AT_CHECK([ovn-nbctl get logical_router_port rp-public ipv6_prefix], [0], [dnl +[["2001:db8:3333::6a2f:0:0/96"]] +]) +AT_CHECK([ovn-nbctl get logical_router_port rp-sw0 ipv6_prefix], [0], [dnl +[["2001:db8:3333::5b81:0:0/96"]] +]) +AT_CHECK([ovn-nbctl get logical_router_port rp-sw1 ipv6_prefix], [0], [dnl +[["2001:db8:3333::42f1:0:0/96"]] +]) + +kill $(pidof ovn-controller) + +as ovn-sb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as ovn-nb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as northd +OVS_APP_EXIT_AND_WAIT([ovn-northd]) + +as +OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d +/.*terminating with signal 15.*/d"]) +AT_CLEANUP