On Tue, Jan 17, 2023 at 11:09:17PM +0100, Jan Klemkow wrote:
> Hi,
> 
> we have several drivers which have to parse the content of mbufs.  This
> diff suggest a central parsing function for this.  Thus, we can reduce
> redundant code.
> 
> I just start with ix(4) and ixl(4) because it was easy to test for me.
> But, this could also improve em(4), igc(4), ale(4) and oce(4).
> 
> I'm not sure about the name, the api nor the place of this code.  So, if
> someone has a better idea: i'm open to anything.
> 
> bye,
> Jan
> 

Hi,

I like code this deduplication.

This newly introduced function doesn't touch ifnet but only extracts
protocol headers from mbuf(9). I guess mbuf_extract_headers() or
something like is much better for name with the ern/uipc_mbuf2.c as
place.

> Index: dev/pci/if_ix.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
> retrieving revision 1.189
> diff -u -p -r1.189 if_ix.c
> --- dev/pci/if_ix.c   2 Sep 2022 14:08:09 -0000       1.189
> +++ dev/pci/if_ix.c   17 Jan 2023 16:31:19 -0000
> @@ -2477,23 +2477,18 @@ static inline int
>  ixgbe_csum_offload(struct mbuf *mp, uint32_t *vlan_macip_lens,
>      uint32_t *type_tucmd_mlhl, uint32_t *olinfo_status)
>  {
> -     struct ether_header *eh = mtod(mp, struct ether_header *);
> -     struct mbuf *m;
> -     int hoff;
> +     struct ether_header *eh = NULL;
> +     struct ip *ip = NULL;
> +     struct ip6_hdr *ip6 = NULL;
>       int offload = 0;
>       uint32_t iphlen;
>       uint8_t ipproto;
>  
> -     *vlan_macip_lens |= (sizeof(*eh) << IXGBE_ADVTXD_MACLEN_SHIFT);
> +     if_parse(mp, &eh, &ip, &ip6, NULL, NULL);
>  
> -     switch (ntohs(eh->ether_type)) {
> -     case ETHERTYPE_IP: {
> -             struct ip *ip;
> -
> -             m = m_getptr(mp, sizeof(*eh), &hoff);
> -             KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip));
> -             ip = (struct ip *)(mtod(m, caddr_t) + hoff);
> +     *vlan_macip_lens |= (sizeof(*eh) << IXGBE_ADVTXD_MACLEN_SHIFT);
>  
> +     if (ip) {
>               iphlen = ip->ip_hl << 2;
>               ipproto = ip->ip_p;
>  
> @@ -2503,26 +2498,14 @@ ixgbe_csum_offload(struct mbuf *mp, uint
>               }
>  
>               *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
> -             break;
> -     }
> -
>  #ifdef INET6
> -     case ETHERTYPE_IPV6: {
> -             struct ip6_hdr *ip6;
> -
> -             m = m_getptr(mp, sizeof(*eh), &hoff);
> -             KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip6));
> -             ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
> -
> +     } else if (ip6) {
>               iphlen = sizeof(*ip6);
>               ipproto = ip6->ip6_nxt;
>  
>               *type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
> -             break;
> -     }
>  #endif
> -
> -     default:
> +     } else {
>               return offload;
>       }
>  
> Index: dev/pci/if_ixl.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_ixl.c,v
> retrieving revision 1.84
> diff -u -p -r1.84 if_ixl.c
> --- dev/pci/if_ixl.c  5 Aug 2022 13:57:16 -0000       1.84
> +++ dev/pci/if_ixl.c  16 Jan 2023 23:58:05 -0000
> @@ -2784,12 +2784,15 @@ ixl_load_mbuf(bus_dma_tag_t dmat, bus_dm
>  static uint64_t
>  ixl_tx_setup_offload(struct mbuf *m0)
>  {
> -     struct mbuf *m;
> -     int hoff;
> +     struct ether_header *eh = NULL;
> +     struct ip *ip = NULL;
> +     struct ip6_hdr *ip6 = NULL;
> +     struct tcphdr *th = NULL;
>       uint64_t hlen;
>       uint8_t ipproto;
>       uint64_t offload = 0;
>  
> +
>       if (ISSET(m0->m_flags, M_VLANTAG)) {
>               uint64_t vtag = m0->m_pkthdr.ether_vtag;
>               offload |= IXL_TX_DESC_CMD_IL2TAG1;
> @@ -2800,39 +2803,23 @@ ixl_tx_setup_offload(struct mbuf *m0)
>           M_IPV4_CSUM_OUT|M_TCP_CSUM_OUT|M_UDP_CSUM_OUT))
>               return (offload);
>  
> -     switch (ntohs(mtod(m0, struct ether_header *)->ether_type)) {
> -     case ETHERTYPE_IP: {
> -             struct ip *ip;
> -
> -             m = m_getptr(m0, ETHER_HDR_LEN, &hoff);
> -             KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip));
> -             ip = (struct ip *)(mtod(m, caddr_t) + hoff);
> +     if_parse(m0, &eh, &ip, &ip6, &th, NULL);
>  
> +     if (ip) {
>               offload |= ISSET(m0->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT) ?
>                   IXL_TX_DESC_CMD_IIPT_IPV4_CSUM :
>                   IXL_TX_DESC_CMD_IIPT_IPV4;
>   
>               hlen = ip->ip_hl << 2;
>               ipproto = ip->ip_p;
> -             break;
> -     }
> -
>  #ifdef INET6
> -     case ETHERTYPE_IPV6: {
> -             struct ip6_hdr *ip6;
> -
> -             m = m_getptr(m0, ETHER_HDR_LEN, &hoff);
> -             KASSERT(m != NULL && m->m_len - hoff >= sizeof(*ip6));
> -             ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
> - 
> +     } else if (ip6) {
>               offload |= IXL_TX_DESC_CMD_IIPT_IPV6;
>  
>               hlen = sizeof(*ip6);
>               ipproto = ip6->ip6_nxt;
> -             break;
> -     }
>  #endif
> -     default:
> +     } else {
>               panic("CSUM_OUT set for non-IP packet");
>               /* NOTREACHED */
>       }
> @@ -2842,15 +2829,12 @@ ixl_tx_setup_offload(struct mbuf *m0)
>  
>       switch (ipproto) {
>       case IPPROTO_TCP: {
> -             struct tcphdr *th;
> -
>               if (!ISSET(m0->m_pkthdr.csum_flags, M_TCP_CSUM_OUT))
>                       break;
>  
> -             m = m_getptr(m, hoff + hlen, &hoff);
> -             KASSERT(m != NULL && m->m_len - hoff >= sizeof(*th));
> -             th = (struct tcphdr *)(mtod(m, caddr_t) + hoff);
> - 
> +             if (th == NULL)
> +                     break;
> +
>               offload |= IXL_TX_DESC_CMD_L4T_EOFT_TCP;
>               offload |= (uint64_t)th->th_off << IXL_TX_DESC_L4LEN_SHIFT;
>               break;
> Index: net/if.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if.c,v
> retrieving revision 1.683
> diff -u -p -r1.683 if.c
> --- net/if.c  23 Nov 2022 16:57:37 -0000      1.683
> +++ net/if.c  16 Jan 2023 23:20:21 -0000
> @@ -96,6 +96,10 @@
>  #include <net/netisr.h>
>  
>  #include <netinet/in.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip6.h>
> +#include <netinet/tcp.h>
> +#include <netinet/udp.h>
>  #include <netinet/if_ether.h>
>  #include <netinet/igmp.h>
>  #ifdef MROUTING
> @@ -3352,6 +3356,75 @@ if_rxr_ioctl(struct if_rxrinfo *ifri, co
>       ifr.ifr_info = *rxr;
>  
>       return (if_rxr_info_ioctl(ifri, 1, &ifr));
> +}
> +
> +void
> +if_parse(struct mbuf *mp, struct ether_header **eh, struct ip **ip4,
> +    struct ip6_hdr **ip6, struct tcphdr **tcp, struct udphdr **udp)
> +{
> +     struct mbuf             *m;
> +     int                      hoff;
> +     uint8_t                  ipproto;
> +     uint64_t                 hlen;
> +
> +     if (eh == NULL)
> +             return;
> +
> +     *eh = mtod(mp, struct ether_header *);
> +     switch (ntohs((*eh)->ether_type)) {
> +     case ETHERTYPE_IP:
> +             if (ip4 == NULL)
> +                     return;
> +
> +             m = m_getptr(mp, sizeof(**eh), &hoff);
> +             KASSERT(m != NULL && m->m_len - hoff >= sizeof(**ip4));
> +             *ip4 = (struct ip *)(mtod(m, caddr_t) + hoff);
> +
> +             hlen = (*ip4)->ip_hl << 2;
> +             ipproto = (*ip4)->ip_p;
> +
> +             break;
> +
> +#ifdef INET6
> +     case ETHERTYPE_IPV6:
> +             if (ip6 == NULL)
> +                     return;
> +
> +             m = m_getptr(mp, sizeof(**eh), &hoff);
> +             KASSERT(m != NULL && m->m_len - hoff >= sizeof(**ip6));
> +             *ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
> +
> +             hlen = sizeof(**ip6);
> +             ipproto = (*ip6)->ip6_nxt;
> +
> +             break;
> +#endif
> +
> +     default:
> +             return;
> +     }
> +
> +     switch (ipproto) {
> +     case IPPROTO_TCP:
> +             if (tcp == NULL)
> +                     return;
> +
> +             m = m_getptr(m, hoff + hlen, &hoff);
> +             KASSERT(m != NULL && m->m_len - hoff >= sizeof(**tcp));
> +             *tcp = (struct tcphdr *)(mtod(m, caddr_t) + hoff);
> +             break;
> +
> +     case IPPROTO_UDP:
> +             if (udp == NULL)
> +                     return;
> +
> +             m = m_getptr(m, hoff + hlen, &hoff);
> +             KASSERT(m != NULL && m->m_len - hoff >= sizeof(**udp));
> +             *udp = (struct udphdr *)(mtod(m, caddr_t) + hoff);
> +             break;
> +     }
> +
> +     return;
>  }
>  
>  /*
> Index: net/if_var.h
> ===================================================================
> RCS file: /cvs/src/sys/net/if_var.h,v
> retrieving revision 1.122
> diff -u -p -r1.122 if_var.h
> --- net/if_var.h      23 Nov 2022 14:50:59 -0000      1.122
> +++ net/if_var.h      16 Jan 2023 21:50:06 -0000
> @@ -317,6 +317,13 @@ int              niq_enlist(struct niqueue *, struct
>  
>  extern struct ifnet_head ifnetlist;
>  
> +#include <netinet/in.h>
> +#include <netinet/ip.h>
> +#include <netinet/ip6.h>
> +#include <netinet/tcp.h>
> +#include <netinet/udp.h>
> +#include <netinet/if_ether.h>
> +
>  void if_start(struct ifnet *);
>  int  if_enqueue(struct ifnet *, struct mbuf *);
>  int  if_enqueue_ifq(struct ifnet *, struct mbuf *);
> @@ -371,6 +378,8 @@ u_int     if_rxr_get(struct if_rxring *, u_i
>  int  if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *);
>  int  if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int,
>           struct if_rxring *);
> +void if_parse(struct mbuf *, struct ether_header **, struct ip **,
> +    struct ip6_hdr **, struct tcphdr **, struct udphdr **);
>  
>  void if_counters_alloc(struct ifnet *);
>  void if_counters_free(struct ifnet *);
> 

Reply via email to