After detailed verification, I found that my previous modification had issues. 
Directly modifying l2_pad_size causes the calculation of the outer UDP 
checksum to be incorrect. Therefore, I made another revision, adding a new
inner_l2_pad_size, which seems more reasonable. With this change, 
if packets with padding smaller than 64 bytes are present, both the inner 
and outer checksums validate correctly after adding tunnel encapsulation.

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index 
584e1eb44f9c999fd368b7f84d05abc3c02c242b..fd64d371c23e0f08f1cc0c032f4bb69c1bd8f9a0
 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -176,6 +176,8 @@ struct dp_packet {
     ovs_be32 packet_type;          /* Packet type as defined in OpenFlow */
     uint16_t csum_start;           /* Position to start checksumming from. */
     uint16_t csum_offset;          /* Offset to place checksum. */
+    uint16_t inner_l2_pad_size;    /* Detected inner l2 padding size.
+                                    * Padding is non-pullable. */
     union {
         struct pkt_metadata md;
         uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
@@ -208,7 +210,9 @@ static inline void *dp_packet_eth(const struct dp_packet *);
 static inline void dp_packet_reset_offsets(struct dp_packet *);
 static inline void dp_packet_reset_offload(struct dp_packet *);
 static inline uint16_t dp_packet_l2_pad_size(const struct dp_packet *);
+static inline uint16_t dp_packet_inner_l2_pad_size(const struct dp_packet *);
 static inline void dp_packet_set_l2_pad_size(struct dp_packet *, uint16_t);
+static inline void dp_packet_set_inner_l2_pad_size(struct dp_packet *, 
uint16_t);
 static inline void *dp_packet_l2_5(const struct dp_packet *);
 static inline void dp_packet_set_l2_5(struct dp_packet *, void *);
 static inline void *dp_packet_l3(const struct dp_packet *);
@@ -431,6 +435,7 @@ static inline void
 dp_packet_reset_offsets(struct dp_packet *b)
 {
     b->l2_pad_size = 0;
+    b->inner_l2_pad_size = 0;
     b->l2_5_ofs = UINT16_MAX;
     b->l3_ofs = UINT16_MAX;
     b->l4_ofs = UINT16_MAX;
@@ -444,6 +449,12 @@ dp_packet_l2_pad_size(const struct dp_packet *b)
     return b->l2_pad_size;
 }
 
+static inline uint16_t
+dp_packet_inner_l2_pad_size(const struct dp_packet *b)
+{
+    return b->inner_l2_pad_size;
+}
+
 static inline void
 dp_packet_set_l2_pad_size(struct dp_packet *b, uint16_t pad_size)
 {
@@ -451,6 +462,13 @@ dp_packet_set_l2_pad_size(struct dp_packet *b, uint16_t 
pad_size)
     b->l2_pad_size = pad_size;
 }
 
+static inline void
+dp_packet_set_inner_l2_pad_size(struct dp_packet *b, uint16_t pad_size)
+{
+    ovs_assert(pad_size <= dp_packet_size(b));
+    b->inner_l2_pad_size = pad_size;
+}
+
 static inline void *
 dp_packet_l2_5(const struct dp_packet *b)
 {
@@ -539,7 +557,7 @@ dp_packet_inner_l4_size(const struct dp_packet *b)
     return OVS_LIKELY(b->inner_l4_ofs != UINT16_MAX)
            ? (const char *) dp_packet_tail(b)
            - (const char *) dp_packet_inner_l4(b)
-           - dp_packet_l2_pad_size(b)
+           - dp_packet_inner_l2_pad_size(b)
            : 0;
 }
 
diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
index 
b3f6a11afc6bfa0dc2bf08fce48196ef7a7b6368..395bdd433d268a8de482ed36ed4fab0c757e888c
 100644
--- a/lib/netdev-native-tnl.c
+++ b/lib/netdev-native-tnl.c
@@ -157,6 +157,7 @@ netdev_tnl_push_ip_header(struct dp_packet *packet,
     struct eth_header *eth;
     struct ip_header *ip;
     struct ovs_16aligned_ip6_hdr *ip6;
+    uint16_t l2_pad_size;
 
     eth = dp_packet_push_uninit(packet, size);
     *ip_tot_size = dp_packet_size(packet) - sizeof (struct eth_header);
@@ -164,7 +165,9 @@ netdev_tnl_push_ip_header(struct dp_packet *packet,
     memcpy(eth, header, size);
     /* The encapsulated packet has type Ethernet. Adjust dp_packet. */
     packet->packet_type = htonl(PT_ETH);
+    l2_pad_size = dp_packet_l2_pad_size(packet);
     dp_packet_reset_offsets(packet);
+    dp_packet_set_inner_l2_pad_size(packet, l2_pad_size);
     packet->l3_ofs = sizeof (struct eth_header);
 
     if (netdev_tnl_is_header_ipv6(header)) {




Jun Wang
_______________________________________________
discuss mailing list
disc...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-discuss

Reply via email to