[ovs-dev] [PATCH v5 2/2] ovn-northd: Add logical flows to support DHCPv6

Ben Pfaff blp at ovn.org
Sun Aug 14 20:47:43 UTC 2016


On Fri, Aug 05, 2016 at 09:36:39AM +0530, Numan Siddique wrote:
> OVN implements native DHCPv6. DHCPv6 options are stored
> in the 'DHCP_Options' NB table and logical ports refer to this
> table to configure the DHCPv6 options.
> 
> For each logical port configured with DHCPv6 Options following flows
> are added
>  - A logical flow which copies the DHCPv6 options to the DHCPv6
>    request packets using the 'put_dhcpv6_opts' action and advances the
>    packet to the next stage.
> 
>  - A logical flow which implements the DHCPv6 reponder by sending
>    the DHCPv6 reply back to the inport once the 'put_dhcpv6_opts' action
>    is applied.
> 
> Signed-off-by: Numan Siddique <nusiddiq at redhat.com>

Thanks for the patch!  I folded in the following incremental, which is
mostly minor stylistic and documentation changes.

I applied both patches to master.  Thanks again!

(Now I get to go rebase my own patch series that rewrites action
parsing...)

--8<--------------------------cut here-------------------------->8--

diff --git a/ovn/northd/ovn-northd.8.xml b/ovn/northd/ovn-northd.8.xml
index a26c4aa..1cf6b6e 100644
--- a/ovn/northd/ovn-northd.8.xml
+++ b/ovn/northd/ovn-northd.8.xml
@@ -487,9 +487,9 @@ nd_na {
     <h3>Ingress Table 10: DHCP option processing</h3>
 
     <p>
-      This table adds the DHCPv4 options to a DHCPv4 packet and DHCPv6 options
-      to a DHCPv6 packet from the logical ports configured with IPv4 address(es)
-      and DHCPv4 options and IPv6 address(es) and DHCPv6 options.
+      This table adds the DHCPv4 options to a DHCPv4 packet from the
+      logical ports configured with IPv4 address(es) and DHCPv4 options,
+      and similarly for DHCPv6 options.
     </p>
 
     <ul>
@@ -502,13 +502,13 @@ nd_na {
         </p>
 
         <pre>
-reg0[3] = put_dhcp_opts(offer_ip = <var>O</var>, <i>options</i>...);
+reg0[3] = put_dhcp_opts(offer_ip = <var>ip</var>, <var>options</var>...);
 next;
         </pre>
 
         <p>
           For DHCPDISCOVER and DHCPREQUEST, this transforms the packet into a
-          DHCP reply, adds the DHCP offer IP <var>O</var> and options to the
+          DHCP reply, adds the DHCP offer IP <var>ip</var> and options to the
           packet, and stores 1 into reg0[3].  For other kinds of packets, it
           just stores 0 into reg0[3].  Either way, it continues to the next
           table.
@@ -526,14 +526,14 @@ next;
         </p>
 
         <pre>
-reg0[3] = put_dhcpv6_opts(ia_addr = <var>0</var>, <i>options</i>...);
+reg0[3] = put_dhcpv6_opts(ia_addr = <var>ip</var>, <var>options</var>...);
 next;
         </pre>
 
         <p>
           For DHCPv6 Solicit/Request/Confirm packets, this transforms the
           packet into a DHCPv6 Advertise/Reply, adds the DHCPv6 offer IP
-          <var>O</var> and options to the packet, and stores 1 into reg0[3].
+          <var>ip</var> and options to the packet, and stores 1 into reg0[3].
           For other kinds of packets, it just stores 0 into reg0[3]. Either
           way, it continues to the next table.
         </p>
@@ -565,7 +565,7 @@ next;
         <pre>
 eth.dst = eth.src;
 eth.src = <var>E</var>;
-ip4.dst = <var>O</var>;
+ip4.dst = <var>A</var>;
 ip4.src = <var>S</var>;
 udp.src = 67;
 udp.dst = 68;
@@ -576,7 +576,7 @@ output;
 
         <p>
           where <var>E</var> is the server MAC address and <var>S</var> is the
-          server IPv4 address defined in the DHCPv4 options and <var>O</var> is
+          server IPv4 address defined in the DHCPv4 options and <var>A</var> is
           the IPv4 address defined in the logical port's addresses column.
         </p>
 
@@ -599,19 +599,19 @@ output;
         <pre>
 eth.dst = eth.src;
 eth.src = <var>E</var>;
-ip6.dst = <var>O</var>;
+ip6.dst = <var>A</var>;
 ip6.src = <var>S</var>;
 udp.src = 547;
 udp.dst = 546;
 outport = <var>P</var>;
-inport = ""; /* Allow sending out inport. */
+flags.loopback = 1;
 output;
         </pre>
 
         <p>
           where <var>E</var> is the server MAC address and <var>S</var> is the
           server IPv6 LLA address  generated from the <code>server_id</code>
-          defined in the DHCPv6 options and <var>O</var> is
+          defined in the DHCPv6 options and <var>A</var> is
           the IPv6 address defined in the logical port's addresses column.
         </p>
 
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 9f5f3ab..8f99533 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -1844,7 +1844,7 @@ build_dhcpv6_action(struct ovn_port *op, struct in6_addr *offer_ip,
         return false;
     }
 
-    /* Get the link local ip of the DHCPv6 server from the server mac. */
+    /* Get the link local IP of the DHCPv6 server from the server MAC. */
     struct in6_addr lla;
     in6_generate_lla(ea, &lla);
 
@@ -1858,7 +1858,7 @@ build_dhcpv6_action(struct ovn_port *op, struct in6_addr *offer_ip,
                   REGBIT_DHCP_OPTS_RESULT" = put_dhcpv6_opts(ia_addr = %s, ",
                   ia_addr);
     struct smap_node *node;
-    SMAP_FOR_EACH(node, &op->nbsp->dhcpv6_options->options) {
+    SMAP_FOR_EACH (node, &op->nbsp->dhcpv6_options->options) {
         ds_put_format(options_action, "%s = %s, ", node->key, node->value);
     }
     ds_chomp(options_action, ' ');
@@ -2310,12 +2310,12 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows)
                     &od->nbs->ports[i]->dhcpv6_options->options, "server_id");
                 struct eth_addr ea;
                 if (server_mac && eth_addr_from_string(server_mac, &ea)) {
-                    /* Get the link local ip of the DHCPv6 server from the
-                     * server mac. */
+                    /* Get the link local IP of the DHCPv6 server from the
+                     * server MAC. */
                     struct in6_addr lla;
                     in6_generate_lla(ea, &lla);
 
-                    char server_ip[IPV6_SCAN_LEN + 1];
+                    char server_ip[INET6_ADDRSTRLEN + 1];
                     ipv6_string_mapped(server_ip, &lla);
 
                     struct ds match = DS_EMPTY_INITIALIZER;
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index e5f06fb..8fb5244 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -1024,29 +1024,30 @@
 
   <table name="DHCP_Options" title="DHCP options">
     <p>
-      OVN implements a native DHCPv4 support which caters to the common
+      OVN implements native DHCPv4 support which caters to the common
       use case of providing an IPv4 address to a booting instance by
       providing stateless replies to DHCPv4 requests based on statically
       configured address mappings. To do this it allows a short list of
       DHCPv4 options to be configured and applied at each compute host
-      running ovn-controller.
+      running <code>ovn-controller</code>.
     </p>
+
     <p>
-      OVN also implements a native DHCPv6 support which provides stateless
+      OVN also implements native DHCPv6 support which provides stateless
       replies to DHCPv6 requests.
     </p>
 
     <column name="cidr">
       <p>
-        The DHCPv4/DHCPv6 options will be included if the logical port has the
+        The DHCPv4/DHCPv6 options will be included if the logical port has its
         IP address in this <ref column="cidr"/>.
       </p>
     </column>
 
     <group title="DHCPv4 options">
       <p>
-        CMS should define the set of DHCPv4 options as key/value pairs in the
-        <ref column="options"/> column of this table. For
+        The CMS should define the set of DHCPv4 options as key/value pairs
+        in the <ref column="options"/> column of this table. For
         <code>ovn-controller</code> to include these DHCPv4 options, the
         <ref column="dhcpv4_options"/> of <ref table="Logical_Switch_Port"/>
         should refer to an entry in this table.
@@ -1248,14 +1249,14 @@
 
     <group title="DHCPv6 options">
       <p>
-        OVN also implements native DHCPv6 support. CMS should define
+        OVN also implements native DHCPv6 support. The CMS should define
         the set of DHCPv6 options as key/value pairs. The define DHCPv6
         options will be included in the DHCPv6 response to the DHCPv6
         Solicit/Request/Confirm packet from the logical ports having the
         IPv6 addresses in the <ref column="cidr"/>.
       </p>
 
-      <group title="Mandatory DHCPv4 options">
+      <group title="Mandatory DHCPv6 options">
         <p>
           The following options must be defined.
         </p>
@@ -1265,8 +1266,8 @@
             The Ethernet address for the DHCP server to use. This is also
             included in the DHCPv6 reply as option 2, ``Server Identifier''
             to carry a DUID identifying a server between a client and a server.
-            <code>ovn-controller</code> defines DUID Based on
-            Link-layer Address [DUID-LL]
+            <code>ovn-controller</code> defines DUID based on
+            Link-layer Address [DUID-LL].
           </p>
         </column>
       </group>
@@ -1276,14 +1277,14 @@
           Below are the supported DHCPv6 options whose values are an IPv6
           address, e.g. <code>aef0::4</code>.  Some options accept multiple
           IPv6 addresses enclosed within curly braces, e.g. <code>{aef0::4,
-          aef0::5}</code>. Please refer the RFC 3315 for more details on
+          aef0::5}</code>. Please refer to RFC 3315 for more details on
           DHCPv6 options and their codes.
         </p>
 
         <column name="options" key="dns_server">
           <p>
-            The DHCPv6 option code for this option is 23. This option is used
-            to specify the DNS servers.
+            The DHCPv6 option code for this option is 23. This option specifies
+            the DNS servers that the VM should use.
           </p>
         </column>
       </group>
@@ -1295,9 +1296,9 @@
 
         <column name="options" key="domain_search">
           <p>
-            The DHCPv6 option code for this option is 24. This option is used
-            to specify the domain search list the client can use when resolving
-            hostnames with DNS.
+            The DHCPv6 option code for this option is 24. This option specifies
+            the domain search list the client should use to resolve hostnames
+            with DNS.
           </p>
 
           <p>
diff --git a/tests/ovn.at b/tests/ovn.at
index d015a13..cf198e3 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -748,10 +748,10 @@ get_nd(xxreg0, ip6.dst); => Cannot use numeric field xxreg0 where string field i
 put_nd(inport, nd.target, nd.sll); => actions=push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[], prereqs=((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (icmp6.type == 0x88 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd))) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
 
 # put_dhcpv6_opts
-reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02); => actions=controller(userdata=00.00.00.05.00.00.00.00.80.01.00.08.00.00.00.00.05.00.10.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.02.00.06.00.00.00.00.00.10.02,pause), prereqs=1
-reg1[0] = put_dhcpv6_opts(); => actions=controller(userdata=00.00.00.05.00.00.00.00.80.01.00.08.00.00.00.00,pause), prereqs=1
-reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2}); => actions=controller(userdata=00.00.00.05.00.00.00.00.80.01.00.08.00.00.00.00.17.00.20.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause), prereqs=1
-reg1[0] = put_dhcpv6_opts(domain_search="ovn.org"); => actions=controller(userdata=00.00.00.05.00.00.00.00.80.01.00.08.00.00.00.00.18.00.07.00.6f.76.6e.2e.6f.72.67,pause), prereqs=1
+reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02); => actions=controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.05.00.10.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.02.00.06.00.00.00.00.00.10.02,pause), prereqs=1
+reg1[0] = put_dhcpv6_opts(); => actions=controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause), prereqs=1
+reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2}); => actions=controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.17.00.20.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause), prereqs=1
+reg1[0] = put_dhcpv6_opts(domain_search="ovn.org"); => actions=controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.18.00.07.00.6f.76.6e.2e.6f.72.67,pause), prereqs=1
 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4); => Syntax error at `x' expecting DHCPv6 option name.
 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi"); => Syntax error at `"hi"'.
 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy); => Syntax error at `xyzzy' expecting DHCPv6 option name.



More information about the dev mailing list