[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