Re: fix vlan handling with tcplro on ix(4)
On Thu, Jul 27, 2023 at 09:15:48AM -0700, Chris Cappuccio wrote: > Jan Klemkow [j.klem...@wemelug.de] wrote: > > +#if NVLAN > 0 > > + if (ext.evh) > > + hdrlen += ETHER_VLAN_ENCAP_LEN; > > +#endif > > if (ext.ip4) > > hdrlen += ext.ip4->ip_hl << 2; > > if (ext.ip6) > > I'm not sure this should be tied to the compilation of the vlan > driver in the kernel. Since the length is larger in either case, > the ix driver should behave the same in either case. If NVLAN is not compiled in, vlan should be ignored here. That works as ether_extract_headers() also has #if NVLAN > 0. Then ext.ip4 and ext.ip6 is NULL. This is correct in this place. More important question is what happens when ether_extract_headers() is called during transmit in em(4), igc(4), ixl(4) and ix(4). Without NVLAN in kernel everything is fine as ether_extract_headers() ignores IP in packets with vlan tag. With vlan it looks like checksum offloading is broken if M_VLANTAG is not set. But with vlan hardware offloading everything should work. That is the case for em(4), ixl(4) and ix(4). igc(4) has #ifdef notyet #if NVLAN > 0, so I guess transmit checksum offload does not work for vlan packets. Jan's diff improves it a little bit, but does not fix it completely. I will test and see what works. But this is unrelated to Jan's fix. I think it should be commited, as I see better test results with ix(4) and it should fix sthen's setup. bluhm
Re: fix vlan handling with tcplro on ix(4)
Jan Klemkow [j.klem...@wemelug.de] wrote: > +#if NVLAN > 0 > + if (ext.evh) > + hdrlen += ETHER_VLAN_ENCAP_LEN; > +#endif > if (ext.ip4) > hdrlen += ext.ip4->ip_hl << 2; > if (ext.ip6) I'm not sure this should be tied to the compilation of the vlan driver in the kernel. Since the length is larger in either case, the ix driver should behave the same in either case. Chris
Re: fix vlan handling with tcplro on ix(4)
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 - 1.200 > +++ dev/pci/if_ix.c 26 Jul 2023 09:21:15 - > @@ -3275,6 +3275,10 @@ ixgbe_rxeof(struct rx_ring *rxr) > /* Calculate header size. */ > ether_extract_headers(sendmp, ); > 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.c6 Jul 2023 19:46:53 - 1.290 > +++ net/if_ethersubr.c26 Jul 2023 09:20:57 - > @@ -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), ); > + m = m_getptr(mp, hlen, ); > 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), ); > + m = m_getptr(mp, hlen, ); > 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.h6 Jul 2023 19:46:53 - 1.89 > +++ netinet/if_ether.h26 Jul 2023 09:20:22 - > @@ -301,11 +301,12 @@ uint64_tether_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 *);
fix vlan handling with tcplro on ix(4)
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? bye, Jan 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 - 1.200 +++ dev/pci/if_ix.c 26 Jul 2023 09:21:15 - @@ -3275,6 +3275,10 @@ ixgbe_rxeof(struct rx_ring *rxr) /* Calculate header size. */ ether_extract_headers(sendmp, ); 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 - 1.290 +++ net/if_ethersubr.c 26 Jul 2023 09:20:57 - @@ -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), ); + m = m_getptr(mp, hlen, ); 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), ); + m = m_getptr(mp, hlen, ); 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 - 1.89 +++ netinet/if_ether.h 26 Jul 2023 09:20:22 - @@ -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 *);