Skip to content

Commit 40df456

Browse files
Zongkai LIblp
authored andcommitted
ovn-northd: add dhcpv6 stateless option support
This patch adds DHCPv6 stateless option support, to allow ovn native dhcpv6 work in stateless mode. User can add new option dhcpv6_stateless with string value true in DHCP_Options.options column, to let ovn dhcpv6 only reply other configurations for DHCPv6 request messages come from VM/VIF ports, and let VM/VIF ports get their IPv6 addresses configured via stateless way. Signed-off-by: Zongkai LI <zealokii@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
1 parent 9240e9a commit 40df456

3 files changed

Lines changed: 72 additions & 9 deletions

File tree

ovn/northd/ovn-northd.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,11 +2007,23 @@ build_dhcpv6_action(struct ovn_port *op, struct in6_addr *offer_ip,
20072007
ipv6_string_mapped(ia_addr, offer_ip);
20082008

20092009
ds_put_format(options_action,
2010-
REGBIT_DHCP_OPTS_RESULT" = put_dhcpv6_opts(ia_addr = %s, ",
2011-
ia_addr);
2010+
REGBIT_DHCP_OPTS_RESULT" = put_dhcpv6_opts(");
2011+
2012+
/* Check whether the dhcpv6 options should be configured as stateful.
2013+
* Only reply with ia_addr option for dhcpv6 stateful address mode. */
2014+
if (!smap_get_bool(&op->nbsp->dhcpv6_options->options,
2015+
"dhcpv6_stateless", false)) {
2016+
char ia_addr[INET6_ADDRSTRLEN + 1];
2017+
ipv6_string_mapped(ia_addr, offer_ip);
2018+
2019+
ds_put_format(options_action, "ia_addr = %s, ", ia_addr);
2020+
}
2021+
20122022
struct smap_node *node;
20132023
SMAP_FOR_EACH (node, &op->nbsp->dhcpv6_options->options) {
2014-
ds_put_format(options_action, "%s = %s, ", node->key, node->value);
2024+
if (strcmp(node->key, "dhcpv6_stateless")) {
2025+
ds_put_format(options_action, "%s = %s, ", node->key, node->value);
2026+
}
20152027
}
20162028
ds_chomp(options_action, ' ');
20172029
ds_chomp(options_action, ',');
@@ -2022,6 +2034,7 @@ build_dhcpv6_action(struct ovn_port *op, struct in6_addr *offer_ip,
20222034
"udp.dst = 546; outport = inport; flags.loopback = 1; "
20232035
"output;",
20242036
server_mac, server_ip);
2037+
20252038
return true;
20262039
}
20272040

ovn/ovn-nb.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,17 @@
13361336
Example: <code>"ovn.org"</code>.
13371337
</p>
13381338
</column>
1339+
1340+
<column name="options" key="dhcpv6_stateless">
1341+
<p>
1342+
This option specifies the OVN native DHCPv6 will work in stateless
1343+
mode, which means OVN native DHCPv6 will not offer IPv6 addresses
1344+
for VM/VIF ports, but only reply other configurations, such as
1345+
DNS and domain search list. When setting this option with string
1346+
value "true", VM/VIF will configure IPv6 addresses by stateless
1347+
way. Default value for this option is false.
1348+
</p>
1349+
</column>
13391350
</group>
13401351
</group>
13411352

tests/ovn.at

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ reg1[0] = put_dhcpv6_opts();
921921
reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
922922
formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
923923
encodes as 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)
924+
reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
925+
formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
926+
encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.02.00.06.00.12.34.56.78.9a.bc.17.00.20.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
924927
reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
925928
encodes as 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)
926929
reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
@@ -3744,7 +3747,7 @@ OVS_APP_EXIT_AND_WAIT([ovsdb-server])
37443747

37453748
AT_CLEANUP
37463749

3747-
AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 2 LSPs/LS])
3750+
AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
37483751
AT_KEYWORDS([dhcpv6])
37493752
AT_SKIP_IF([test $HAVE_PYTHON = no])
37503753
ovn_start
@@ -3760,11 +3763,20 @@ ovn-nbctl lsp-add ls1 ls1-lp2 \
37603763

37613764
ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
37623765

3766+
ovn-nbctl lsp-add ls1 ls1-lp3 \
3767+
-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3768+
3769+
ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3770+
37633771
ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
37643772
options="\"server_id\"=\"00:00:00:10:00:01\"" \
37653773
-- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
37663774
-- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
37673775

3776+
ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3777+
options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3778+
-- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3779+
37683780
ovn-nbctl ls-add ls2
37693781
ovn-nbctl lsp-add ls2 ls2-lp1 \
37703782
-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
@@ -3803,6 +3815,12 @@ ovs-vsctl -- add-port br-int hv1-vif4 -- \
38033815
options:rxq_pcap=hv1/vif4-rx.pcap \
38043816
ofport-request=4
38053817

3818+
ovs-vsctl -- add-port br-int hv1-vif5 -- \
3819+
set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
3820+
options:tx_pcap=hv1/vif5-tx.pcap \
3821+
options:rxq_pcap=hv1/vif5-rx.pcap \
3822+
ofport-request=5
3823+
38063824
ovn_populate_arp
38073825

38083826
sleep 2
@@ -3812,8 +3830,8 @@ trim_zeros() {
38123830
}
38133831

38143832
# This shell function sends a DHCPv6 request packet
3815-
# test_dhcp INPORT SRC_MAC DHCPv6_MSG_TYPE OUTPORT...
3816-
# The OUTPORTs (zero or more) list the VIFs on which the original DHCP
3833+
# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
3834+
# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
38173835
# packet should be received twice (one from ovn-controller and the other
38183836
# from the "ovs-ofctl monitor br-int resume"
38193837
test_dhcpv6() {
@@ -3835,13 +3853,19 @@ test_dhcpv6() {
38353853
if test $msg_code = 01; then
38363854
reply_code=02
38373855
fi
3838-
local reply=${src_mac}${server_mac}86dd0000000000541101${server_lla}${src_lla}
3856+
local msg_len=54
3857+
if test $offer_ip = 1; then
3858+
msg_len=28
3859+
fi
3860+
local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
38393861
# udp header and dhcpv6 header
3840-
reply+=022302220054ffff${reply_code}010203
3862+
reply+=0223022200${msg_len}ffff${reply_code}010203
38413863
# Client identifier
38423864
reply+=0001000a00030001${src_mac}
38433865
# IA-NA
3844-
reply+=0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
3866+
if test $offer_ip != 1; then
3867+
reply+=0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
3868+
fi
38453869
# Server identifier
38463870
reply+=0002000a00030001${server_mac}
38473871
echo $reply | trim_zeros >> $inport.expected
@@ -3950,6 +3974,21 @@ $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.pa
39503974
cat 4.expected > expout
39513975
AT_CHECK([cat 4.packets], [0], [expout])
39523976

3977+
# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
3978+
# The DHCPv6 reply should doesn't contian offer_ip.
3979+
src_mac=f00000000022
3980+
src_lla=fe80000000000000f20000fffe000022
3981+
reset_pcap_file hv1-vif5 hv1/vif5
3982+
test_dhcpv6 5 $src_mac $src_lla 01 1 5
3983+
3984+
# NXT_RESUMEs should be 3.
3985+
OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3986+
3987+
$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
3988+
# Skipping the UDP checksum
3989+
cat 5.expected | cut -c 1-120,125- > expout
3990+
AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
3991+
39533992
as hv1
39543993
OVS_APP_EXIT_AND_WAIT([ovn-controller])
39553994
OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])

0 commit comments

Comments
 (0)