Re: fix vlan handling with tcplro on ix(4)

2023-07-27 Thread Alexander Bluhm
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)

2023-07-27 Thread Chris Cappuccio
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)

2023-07-26 Thread Alexander Bluhm
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)

2023-07-26 Thread Jan Klemkow
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 *);