> Hi Lorenzo,
Hi Mark,
thx for the review.
>
> I think this can be done more simply. In northd, the logical flow we create
> for the put_dhcp_opts() action has the following match conditions:
>
> ip4.src == {OFFER_IP, 0.0.0.0} && ip4.dst == {SERVER_IP, 255.255.255.255}
>
> Since the flow already filters based on destination IP address, it should
> mean that pinctrl_handle_put_dhcp_opts() will only be called if the
> destination IP address is the configured OVN server IP, or if it is
> broadcast.
>
> Therefore, checking for an IP match in pinctrl_handle_put_dhcp_opts() is
> unnecessary. The "case DHCP_MSG_DISCOVER:" section simply doesn't need to
> check in_flow->nw_dst at all. We can just set the msg_type to DHCP_MSG_OFFER
> and break.
>
> What do you think?
I think you are right, we already filter based on ip.dst == server_ip in the
logical flow match, so we can just get rid of the check in
pinctrl_handle_put_dhcp_opts(). I will fix it in v2.
>
> Thanks,
> Mark Michelson
>
> PS One final item: Why is the test altered so that the new test case is at
> the beginning? This causes the sequence numbers of all subsequent test_dhcp
> calls to get bumped by one. Would it be easier to add the new test case to
> the end, and therefore not have to update so much of the test?
it is to keep the DHCP_DISCOVER tests together, but I can put it at the end.
Regards,
Lorenzo
>
> On 9/5/24 05:43, Lorenzo Bianconi wrote:
> > According to RFC 2131 section 4.4.4, when the DHCP client knows the
> > address of a DHCP server, in either INIT or REBOOTING state, the client
> > may use that address in the DHCPDISCOVER or DHCPREQUEST rather than the
> > IP broadcast address. Fix pinctrl_handle_put_dhcp_opts implementation
> > according to the RFC 2131.
> >
> > Reported-at: https://issues.redhat.com/browse/FDP-765
> > Signed-off-by: Lorenzo Bianconi <[email protected]>
> > ---
> > controller/pinctrl.c | 48 ++++++++++++++++++++++++++++++++++-----
> > tests/ovn.at | 53 ++++++++++++++++++++++++++++----------------
> > 2 files changed, 76 insertions(+), 25 deletions(-)
> >
> > diff --git a/controller/pinctrl.c b/controller/pinctrl.c
> > index c86b4f940..d3096c2d3 100644
> > --- a/controller/pinctrl.c
> > +++ b/controller/pinctrl.c
> > @@ -2596,14 +2596,50 @@ pinctrl_handle_put_dhcp_opts(
> > uint8_t msg_type = 0;
> > switch (dhcp_opts.dhcp_msg_type) {
> > - case DHCP_MSG_DISCOVER:
> > + case DHCP_MSG_DISCOVER: {
> > msg_type = DHCP_MSG_OFFER;
> > - if (in_flow->nw_dst != htonl(INADDR_BROADCAST)) {
> > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> > - VLOG_WARN_RL(&rl, "DHCP DISCOVER must be Broadcast");
> > - goto exit;
> > + if (in_flow->nw_dst == htonl(INADDR_BROADCAST)) {
> > + break;
> > }
> > - break;
> > +
> > + const char *ptr = reply_dhcp_opts_ptr->data;
> > + const char *ptr_end = ptr + reply_dhcp_opts_ptr->size;
> > + ovs_be32 server_id = htonl(INADDR_BROADCAST);
> > +
> > + while (ptr < ptr_end) {
> > + struct dhcp_opt_header *in_dhcp_opt =
> > + (struct dhcp_opt_header *) ptr;
> > +
> > + /* RFC 2131 section 4.4.4.
> > + * When the DHCP client knows the address of a DHCP server, in
> > + * either INIT or REBOOTING state, the client may use that
> > address
> > + * in the DHCPDISCOVER or DHCPREQUEST rather than the IP
> > broadcast
> > + * address.
> > + */
> > + if (in_dhcp_opt->code == OVN_DHCP_OPT_CODE_SERVER_ID) {
> > + server_id =
> > get_unaligned_be32(DHCP_OPT_PAYLOAD(in_dhcp_opt));
> > + break;
> > + }
> > +
> > + ptr += sizeof *in_dhcp_opt;
> > + if (ptr > ptr_end) {
> > + break;
> > + }
> > + ptr += in_dhcp_opt->len;
> > + if (ptr > ptr_end) {
> > + break;
> > + }
> > + }
> > +
> > + if (in_flow->nw_dst == server_id) {
> > + break;
> > + }
> > +
> > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> > + VLOG_WARN_RL(&rl, "DHCP DISCOVER invalid address: "IP_FMT,
> > + IP_ARGS(in_flow->nw_dst));
> > + goto exit;
> > + }
> > case DHCP_MSG_REQUEST: {
> > msg_type = DHCP_MSG_ACK;
> > if (dhcp_opts.request_ip != *offer_ip) {
> > diff --git a/tests/ovn.at b/tests/ovn.at
> > index acf18c4e0..f21249b3e 100644
> > --- a/tests/ovn.at
> > +++ b/tests/ovn.at
> > @@ -7047,6 +7047,21 @@ compare_dhcp_packets 1
> > # ----------------------------------------------------------------------
> > +# Send unicast DHCPDISCOVER.
> > +reset_pcap_file hv1-vif1 hv1/vif1
> > +reset_pcap_file hv1-vif2 hv1/vif2
> > +rm -f 1.expected
> > +rm -f 2.expected
> > +offer_ip=`ip_to_hex 10 0 0 4`
> > +server_ip=`ip_to_hex 10 0 0 1`
> > +ciaddr=`ip_to_hex 0 0 0 0`
> > +request_ip=0
> > +expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> > +test_dhcp 2 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 0 1
> > $offer_ip $server_ip ff1000000001 $server_ip 02 $expected_dhcp_opts
> > +compare_dhcp_packets 1
> > +
> > +# ----------------------------------------------------------------------
> > +
> > # ovs-ofctl also resumes the packets and this causes other ports to
> > receive
> > # the DHCP request packet. So reset the pcap files so that its easier to
> > test.
> > reset_pcap_file hv1-vif1 hv1/vif1
> > @@ -7061,7 +7076,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=$offer_ip
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 2 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 3 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7078,7 +7093,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=`ip_to_hex 10 0 0 7`
> > expected_dhcp_opts=""
> > -test_dhcp 3 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 06 $expected_dhcp_opts
> > +test_dhcp 4 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 06 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7094,7 +7109,7 @@ rm -f 2.expected
> > ciaddr=`ip_to_hex 0 0 0 0`
> > offer_ip=0
> > request_ip=0
> > -test_dhcp 4 2 f00000000002 09 0 $ciaddr $offer_ip $request_ip 0 0 1 1
> > +test_dhcp 5 2 f00000000002 09 0 $ciaddr $offer_ip $request_ip 0 0 1 1
> > # NXT_RESUMEs should be 4.
> > # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
> > @@ -7117,7 +7132,7 @@ request_ip=0
> > src_ip=$offer_ip
> > dst_ip=$server_ip
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 5 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 6 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7136,7 +7151,7 @@ request_ip=0
> > src_ip=$offer_ip
> > dst_ip=`ip_to_hex 255 255 255 255`
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 6 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 7 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7155,7 +7170,7 @@ request_ip=0
> > src_ip=$offer_ip
> > dst_ip=`ip_to_hex 255 255 255 255`
> > expected_dhcp_opts=""
> > -test_dhcp 7 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> > +test_dhcp 8 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7174,7 +7189,7 @@ request_ip=0
> > src_ip=$offer_ip
> > dst_ip=`ip_to_hex 255 255 255 255`
> > expected_dhcp_opts=""
> > -test_dhcp 8 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> > +test_dhcp 9 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7189,7 +7204,7 @@ rm -f 2.expected
> > ciaddr=`ip_to_hex 0 0 0 0`
> > src_ip=`ip_to_hex 10 0 0 6`
> > dst_ip=`ip_to_hex 10 0 0 4`
> > -test_dhcp --no-resume 9 2 f00000000002 03 0 $ciaddr 0 0 0 1 $src_ip
> > $dst_ip 1
> > +test_dhcp --no-resume 10 2 f00000000002 03 0 $ciaddr 0 0 0 1 $src_ip
> > $dst_ip 1
> > # vif1-tx.pcap should have received the DHCPv4 request packet
> > OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
> > @@ -7207,7 +7222,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=0
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 10 1 f00000000001 01 1 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > +test_dhcp 11 1 f00000000001 01 1 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > compare_dhcp_packets 1
> > # ----------------------------------------------------------------------
> > @@ -7223,7 +7238,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 10 0 0 6`
> > request_ip=0
> > expected_dhcp_opts=0
> > -test_dhcp 11 2 f00000000002 07 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001
> > +test_dhcp 12 2 f00000000002 07 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001
> > # There is no reply for this. Check for the INFO log in ovn-controller.log
> > OVS_WAIT_UNTIL(
> > @@ -7250,7 +7265,7 @@ dst_ip=$server_ip
> > # In the expected_dhcp_opts we should not see 330400000e10 which is
> > # dhcp lease time option and 0104ffffff00 which is subnet mask option.
> > expected_dhcp_opts=03040a00000136040a000001
> > -test_dhcp 12 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 13 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # Now add the dhcp option T1 to the dhcp options.
> > @@ -7275,7 +7290,7 @@ dst_ip=$server_ip
> > # In the expected_dhcp_opts we should not see 330400000e10 which is
> > # dhcp lease time option.
> >
> > expected_dhcp_opts=3a0400000fa0330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 13 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 14 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7295,7 +7310,7 @@ dst_ip=$server_ip
> > # In the expected_dhcp_opts we should not see 330400000e10 which is
> > # dhcp lease time option and 0104ffffff00 which is subnet mask option.
> > expected_dhcp_opts=03040a00000136040a000001
> > -test_dhcp 14 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 15 2 f00000000002 08 0 $ciaddr $offer_ip $request_ip 0 1 $src_ip
> > $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7321,7 +7336,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=$offer_ip
> >
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a00000142040a0a0a0a
> > -test_dhcp 15 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 16 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7347,7 +7362,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=$offer_ip
> >
> > expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a0000014210746573745f746674705f736572766572
> > -test_dhcp 16 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 17 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7373,7 +7388,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=$offer_ip
> >
> > expected_dhcp_opts=771305746573743103636f6d00057465737432c006330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 17 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > +test_dhcp 18 2 f00000000002 03 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 05 $expected_dhcp_opts
> > compare_dhcp_packets 2
> > # ----------------------------------------------------------------------
> > @@ -7384,7 +7399,7 @@ server_ip=`ip_to_hex 10 0 0 1`
> > ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=0
> > expected_dhcp_opts=""
> > -test_dhcp 18 1 f00000000001 04 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > +test_dhcp 19 1 f00000000001 04 0 $ciaddr $offer_ip $request_ip 0 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > OVS_WAIT_UNTIL(
> > [test 1 -le $(grep -F -i -c 'DHCPDECLINE from f0:00:00:00:00:01,
> > 10.0.0.4 duplicated' hv1/ovn-controller.log)
> > ])
> > @@ -7413,7 +7428,7 @@ ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=0
> > boofile=4308626f6f7466696c65
> >
> > expected_dhcp_opts=${boofile}330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 19 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 1 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > +test_dhcp 20 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 1 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > compare_dhcp_packets 1
> > # Test that ovn-controller pinctrl thread handles dhcp requests when it
> > @@ -7460,7 +7475,7 @@ ciaddr=`ip_to_hex 0 0 0 0`
> > request_ip=0
> > boofile=4308626f6f7466696c65
> >
> > expected_dhcp_opts=${boofile}330400000e100104ffffff0003040a00000136040a000001
> > -test_dhcp 20 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 1 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > +test_dhcp 21 1 f00000000001 01 0 $ciaddr $offer_ip $request_ip 1 0
> > ff1000000001 $server_ip 02 $expected_dhcp_opts
> > compare_dhcp_packets 1
> > as hv1
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev