On Tue, Jul 2, 2024 at 10:56 PM Jun Wang <junwan...@cestc.cn> wrote:
>
> We encountered a scenario where, if the received packet contains
> padding bytes, and we then add Geneve tunnel encapsulation without
> carrying the padding bytes, it results in checksum errors when sending
> out. Therefore, adding an inner_l2_pad is necessary.
>
> For example, this type of packet format:
> 0000   06 6c 6a 71 e1 d3 6c e2 d3 8b ea 24 81 00 03 e9
> 0010   08 00 45 00 00 28 9d e5 40 00 3b 06 6e 64 0a 6f
> 0020   05 14 0a fe 19 06 01 bb 22 ae 59 c0 8c 61 8e 26
> 0030   14 e3 50 10 00 7f ce 3a 00 00 00 00 9e 38 cf 64

Hello Jun,

Thank you for this submission. This is an interesting case and I don't
know that we have an appropriate test case for micrograms like this.
Was this the

One question I have is shouldn't we remove the padding while we
encapsulate, not keep it? The encapsulation should always push the
frame size past 64 bytes.


Thanks,
M

>
> Fixes: 084c8087292c ("userspace: Support VXLAN and GENEVE TSO.")
>
> Signed-off-by: Jun Wang <junwan...@cestc.cn>
> ---
>  lib/dp-packet.h         | 21 ++++++++++++++++++++-
>  lib/netdev-native-tnl.c |  3 +++
>  2 files changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index a75b1c5..d583b28 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];
> @@ -209,7 +211,10 @@ 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 *);
> @@ -435,6 +440,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;
> @@ -448,6 +454,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)
>  {
> @@ -455,6 +467,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)
>  {
> @@ -543,7 +562,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 0f9f07f..96ffdc1 100644
> --- a/lib/netdev-native-tnl.c
> +++ b/lib/netdev-native-tnl.c
> @@ -156,6 +156,7 @@ netdev_tnl_push_ip_header(struct dp_packet *packet, const 
> void *header,
>      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);
> @@ -163,7 +164,9 @@ netdev_tnl_push_ip_header(struct dp_packet *packet, const 
> void *header,
>      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)) {
> --
> 1.8.3.1
>
>
>
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to