diff mbox series

[ovs-dev] ovn: Calculate UDP checksum for DNS over IPv6

Message ID 20180307153100.23342-1-mmichels@redhat.com
State Accepted
Headers show
Series [ovs-dev] ovn: Calculate UDP checksum for DNS over IPv6 | expand

Commit Message

Mark Michelson March 7, 2018, 3:31 p.m. UTC
Unlike IPv4, IPv6 mandates the calculation of the UDP checksum. For DNS
resolution in OVN, we were setting the checksum to 0, which results in
errors.

This patch fixes the problem by calculating the checksum for DNS over
IPv6. It also alters the applicable test by skipping the checksum when
comparing the expected and actual packets.

Signed-off-by: Mark Michelson <mmichels@redhat.com>
---
 ovn/controller/pinctrl.c | 11 +++++++++++
 tests/ovn.at             |  5 +++--
 2 files changed, 14 insertions(+), 2 deletions(-)

Comments

Ben Pfaff March 7, 2018, 8:37 p.m. UTC | #1
On Wed, Mar 07, 2018 at 09:31:00AM -0600, Mark Michelson wrote:
> Unlike IPv4, IPv6 mandates the calculation of the UDP checksum. For DNS
> resolution in OVN, we were setting the checksum to 0, which results in
> errors.
> 
> This patch fixes the problem by calculating the checksum for DNS over
> IPv6. It also alters the applicable test by skipping the checksum when
> comparing the expected and actual packets.
> 
> Signed-off-by: Mark Michelson <mmichels@redhat.com>

Thanks for the fix!  I applied this to master and branch-2.9.
diff mbox series

Patch

diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index 2a3f7d3f3..75516bf4e 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -929,6 +929,17 @@  pinctrl_handle_dns_lookup(
     } else {
         struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(&pkt_out);
         nh->ip6_plen = htons(new_l4_size);
+
+        /* IPv6 needs UDP checksum calculated */
+        uint32_t csum;
+        csum = packet_csum_pseudoheader6(nh);
+        csum = csum_continue(csum, out_udp, dp_packet_size(&pkt_out) -
+                             ((const unsigned char *)out_udp -
+                             (const unsigned char *)eth));
+        out_udp->udp_csum = csum_finish(csum);
+        if (!out_udp->udp_csum) {
+            out_udp->udp_csum = htons(0xffff);
+        }
     }
 
     pin->packet = dp_packet_data(&pkt_out);
diff --git a/tests/ovn.at b/tests/ovn.at
index 8ee3bf0b5..df8c538fd 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -7116,8 +7116,9 @@  test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $
 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
 
 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
-cat 1.expected > expout
-AT_CHECK([cat 1.packets], [0], [expout])
+# Skipping the UDP checksum.
+cat 1.expected | cut -c 1-120,125- > expout
+AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
 
 reset_pcap_file hv1-vif1 hv1/vif1
 reset_pcap_file hv1-vif2 hv1/vif2