On Wed, Jul 26, 2023 at 11:30:45AM +0200, Jan Klemkow wrote:
> Hi,
>
> I missed the vlan-tag size in the mss calculation of lro packets in
> ix(4). This diff add vlan-header detection in ether_extract_headers()
> and uses this information to calculate the right mss.
>
> This fixes forwarding of vlan tagged lro packets.
>
> ok?
OK bluhm@
I will test later. My machines are currently down.
> Index: dev/pci/if_ix.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
> retrieving revision 1.200
> diff -u -p -r1.200 if_ix.c
> --- dev/pci/if_ix.c 18 Jul 2023 16:01:20 -0000 1.200
> +++ dev/pci/if_ix.c 26 Jul 2023 09:21:15 -0000
> @@ -3275,6 +3275,10 @@ ixgbe_rxeof(struct rx_ring *rxr)
> /* Calculate header size. */
> ether_extract_headers(sendmp, &ext);
> hdrlen = sizeof(*ext.eh);
> +#if NVLAN > 0
> + if (ext.evh)
> + hdrlen += ETHER_VLAN_ENCAP_LEN;
> +#endif
> if (ext.ip4)
> hdrlen += ext.ip4->ip_hl << 2;
> if (ext.ip6)
> Index: net/if_ethersubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.290
> diff -u -p -r1.290 if_ethersubr.c
> --- net/if_ethersubr.c 6 Jul 2023 19:46:53 -0000 1.290
> +++ net/if_ethersubr.c 26 Jul 2023 09:20:57 -0000
> @@ -1040,6 +1040,7 @@ ether_extract_headers(struct mbuf *mp, s
> uint64_t hlen;
> int hoff;
> uint8_t ipproto;
> + uint16_t ether_type;
>
> /* Return NULL if header was not recognized. */
> memset(ext, 0, sizeof(*ext));
> @@ -1048,9 +1049,20 @@ ether_extract_headers(struct mbuf *mp, s
> return;
>
> ext->eh = mtod(mp, struct ether_header *);
> - switch (ntohs(ext->eh->ether_type)) {
> + ether_type = ntohs(ext->eh->ether_type);
> + hlen = sizeof(*ext->eh);
> +
> +#if NVLAN > 0
> + if (ether_type == ETHERTYPE_VLAN) {
> + ext->evh = mtod(mp, struct ether_vlan_header *);
> + ether_type = ntohs(ext->evh->evl_proto);
> + hlen = sizeof(*ext->evh);
> + }
> +#endif
> +
> + switch (ether_type) {
> case ETHERTYPE_IP:
> - m = m_getptr(mp, sizeof(*ext->eh), &hoff);
> + m = m_getptr(mp, hlen, &hoff);
> if (m == NULL || m->m_len - hoff < sizeof(*ext->ip4))
> return;
> ext->ip4 = (struct ip *)(mtod(m, caddr_t) + hoff);
> @@ -1064,7 +1076,7 @@ ether_extract_headers(struct mbuf *mp, s
> break;
> #ifdef INET6
> case ETHERTYPE_IPV6:
> - m = m_getptr(mp, sizeof(*ext->eh), &hoff);
> + m = m_getptr(mp, hlen, &hoff);
> if (m == NULL || m->m_len - hoff < sizeof(*ext->ip6))
> return;
> ext->ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
> Index: netinet/if_ether.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/if_ether.h,v
> retrieving revision 1.89
> diff -u -p -r1.89 if_ether.h
> --- netinet/if_ether.h 6 Jul 2023 19:46:53 -0000 1.89
> +++ netinet/if_ether.h 26 Jul 2023 09:20:22 -0000
> @@ -301,11 +301,12 @@ uint64_t ether_addr_to_e64(const struct
> void ether_e64_to_addr(struct ether_addr *, uint64_t);
>
> struct ether_extracted {
> - struct ether_header *eh;
> - struct ip *ip4;
> - struct ip6_hdr *ip6;
> - struct tcphdr *tcp;
> - struct udphdr *udp;
> + struct ether_header *eh;
> + struct ether_vlan_header *evh;
> + struct ip *ip4;
> + struct ip6_hdr *ip6;
> + struct tcphdr *tcp;
> + struct udphdr *udp;
> };
>
> void ether_extract_headers(struct mbuf *, struct ether_extracted *);