Clang 4.0 complains:

../lib/odp-execute.c:61:37: error: taking address of packed member 'eth_dst' of
class or structure 'eth_header' may result in an unaligned pointer value
      [-Werror,-Waddress-of-packed-member]
            ether_addr_copy_masked(&eh->eth_src, key->eth_src, mask->eth_src);
                                    ^~~~~~~~~~~
../lib/odp-execute.c:62:37: error: taking address of packed member 'eth_dst' of
class or structure 'eth_header' may result in an unaligned pointer value
      [-Werror,-Waddress-of-packed-member]
            ether_addr_copy_masked(&eh->eth_dst, key->eth_dst, mask->eth_dst);

Ethernet source addresses are 48 bits offset into the Ethernet header,
so taking a pointer for this is not guaranteed to be valid on all
architectures. Fix this by referencing the memory direct from the
Ethernet header pointer.

Signed-off-by: Joe Stringer <[email protected]>
---
 lib/odp-execute.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 08bc50a46a2e..f0dadf56c422 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -48,6 +48,21 @@ ether_addr_copy_masked(struct eth_addr *dst, const struct 
eth_addr src,
 }
 
 static void
+ether_addrs_copy_masked(struct eth_header *hdr,
+                        const struct eth_addr src, const struct eth_addr smask,
+                        const struct eth_addr dst, const struct eth_addr dmask)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(src.be16); i++) {
+        hdr->eth_src.be16[i] = src.be16[i]
+                             | (hdr->eth_src.be16[i] & ~smask.be16[i]);
+        hdr->eth_dst.be16[i] = dst.be16[i]
+                             | (hdr->eth_dst.be16[i] & ~dmask.be16[i]);
+    }
+}
+
+static void
 odp_eth_set_addrs(struct dp_packet *packet, const struct ovs_key_ethernet *key,
                   const struct ovs_key_ethernet *mask)
 {
@@ -58,8 +73,8 @@ odp_eth_set_addrs(struct dp_packet *packet, const struct 
ovs_key_ethernet *key,
             eh->eth_src = key->eth_src;
             eh->eth_dst = key->eth_dst;
         } else {
-            ether_addr_copy_masked(&eh->eth_src, key->eth_src, mask->eth_src);
-            ether_addr_copy_masked(&eh->eth_dst, key->eth_dst, mask->eth_dst);
+            ether_addrs_copy_masked(eh, key->eth_src, mask->eth_src,
+                                    key->eth_dst, mask->eth_dst);
         }
     }
 }
-- 
2.12.2

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to