shuffle protocol family input in ether_input()

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

shuffle protocol family input in ether_input()

David Gwynne-5
the main change here is to defer chopping the ethernet header off
the frame until just before the protocol input function is called.
this means we don't have to reattach it for pppoe.

ok?

Index: if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.249
diff -u -p -r1.249 if_ethersubr.c
--- if_ethersubr.c 9 Jan 2018 06:24:15 -0000 1.249
+++ if_ethersubr.c 9 Jan 2018 06:32:39 -0000
@@ -315,12 +315,9 @@ int
 ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
 {
  struct ether_header *eh;
- struct niqueue *inq;
+ void (*input)(struct ifnet *, struct mbuf *);
  u_int16_t etype;
  struct arpcom *ac;
-#if NPPPOE > 0
- struct ether_header *eh_tmp;
-#endif
 
  /* Drop short frames */
  if (m->m_len < ETHER_HDR_LEN)
@@ -328,7 +325,6 @@ ether_input(struct ifnet *ifp, struct mb
 
  ac = (struct arpcom *)ifp;
  eh = mtod(m, struct ether_header *);
- m_adj(m, ETHER_HDR_LEN);
 
  if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
  /*
@@ -376,45 +372,34 @@ ether_input(struct ifnet *ifp, struct mb
 
  switch (etype) {
  case ETHERTYPE_IP:
- ipv4_input(ifp, m);
- return (1);
+ input = ipv4_input;
+ break;
 
  case ETHERTYPE_ARP:
  if (ifp->if_flags & IFF_NOARP)
  goto dropanyway;
- arpinput(ifp, m);
- return (1);
+ input = arpinput;
+ break;
 
  case ETHERTYPE_REVARP:
  if (ifp->if_flags & IFF_NOARP)
  goto dropanyway;
- revarpinput(ifp, m);
- return (1);
+ input = revarpinput;
+ break;
 
 #ifdef INET6
  /*
  * Schedule IPv6 software interrupt for incoming IPv6 packet.
  */
  case ETHERTYPE_IPV6:
- ipv6_input(ifp, m);
- return (1);
+ input = ipv6_input;
+ break;
 #endif /* INET6 */
 #if NPPPOE > 0 || defined(PIPEX)
  case ETHERTYPE_PPPOEDISC:
  case ETHERTYPE_PPPOE:
  if (m->m_flags & (M_MCAST | M_BCAST))
  goto dropanyway;
- M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
- if (m == NULL)
- return (1);
-
- eh_tmp = mtod(m, struct ether_header *);
- /*
- * danger!
- * eh_tmp and eh may overlap because eh
- * is stolen from the mbuf above.
- */
- memmove(eh_tmp, eh, sizeof(struct ether_header));
 #ifdef PIPEX
  if (pipex_enable) {
  struct pipex_session *session;
@@ -426,22 +411,23 @@ ether_input(struct ifnet *ifp, struct mb
  }
 #endif
  if (etype == ETHERTYPE_PPPOEDISC)
- inq = &pppoediscinq;
+ niq_enqueue(&pppoediscinq, m);
  else
- inq = &pppoeinq;
- break;
+ niq_enqueue(&pppoeinq, m);
+ return (1);
 #endif
 #ifdef MPLS
  case ETHERTYPE_MPLS:
  case ETHERTYPE_MPLS_MCAST:
- mpls_input(ifp, m);
- return (1);
+ input = mpls_input;
+ break;
 #endif
  default:
  goto dropanyway;
  }
 
- niq_enqueue(inq, m);
+ m_adj(m, sizeof(*eh));
+ (*input)(ifp, m);
  return (1);
 dropanyway:
  m_freem(m);

Reply | Threaded
Open this post in threaded view
|

Re: shuffle protocol family input in ether_input()

Alexander Bluhm
On Tue, Jan 09, 2018 at 06:40:49PM +1000, David Gwynne wrote:
> the main change here is to defer chopping the ethernet header off
> the frame until just before the protocol input function is called.
> this means we don't have to reattach it for pppoe.
>
> ok?

OK bluhm@

> Index: if_ethersubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.249
> diff -u -p -r1.249 if_ethersubr.c
> --- if_ethersubr.c 9 Jan 2018 06:24:15 -0000 1.249
> +++ if_ethersubr.c 9 Jan 2018 06:32:39 -0000
> @@ -315,12 +315,9 @@ int
>  ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie)
>  {
>   struct ether_header *eh;
> - struct niqueue *inq;
> + void (*input)(struct ifnet *, struct mbuf *);
>   u_int16_t etype;
>   struct arpcom *ac;
> -#if NPPPOE > 0
> - struct ether_header *eh_tmp;
> -#endif
>  
>   /* Drop short frames */
>   if (m->m_len < ETHER_HDR_LEN)
> @@ -328,7 +325,6 @@ ether_input(struct ifnet *ifp, struct mb
>  
>   ac = (struct arpcom *)ifp;
>   eh = mtod(m, struct ether_header *);
> - m_adj(m, ETHER_HDR_LEN);
>  
>   if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
>   /*
> @@ -376,45 +372,34 @@ ether_input(struct ifnet *ifp, struct mb
>  
>   switch (etype) {
>   case ETHERTYPE_IP:
> - ipv4_input(ifp, m);
> - return (1);
> + input = ipv4_input;
> + break;
>  
>   case ETHERTYPE_ARP:
>   if (ifp->if_flags & IFF_NOARP)
>   goto dropanyway;
> - arpinput(ifp, m);
> - return (1);
> + input = arpinput;
> + break;
>  
>   case ETHERTYPE_REVARP:
>   if (ifp->if_flags & IFF_NOARP)
>   goto dropanyway;
> - revarpinput(ifp, m);
> - return (1);
> + input = revarpinput;
> + break;
>  
>  #ifdef INET6
>   /*
>   * Schedule IPv6 software interrupt for incoming IPv6 packet.
>   */
>   case ETHERTYPE_IPV6:
> - ipv6_input(ifp, m);
> - return (1);
> + input = ipv6_input;
> + break;
>  #endif /* INET6 */
>  #if NPPPOE > 0 || defined(PIPEX)
>   case ETHERTYPE_PPPOEDISC:
>   case ETHERTYPE_PPPOE:
>   if (m->m_flags & (M_MCAST | M_BCAST))
>   goto dropanyway;
> - M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
> - if (m == NULL)
> - return (1);
> -
> - eh_tmp = mtod(m, struct ether_header *);
> - /*
> - * danger!
> - * eh_tmp and eh may overlap because eh
> - * is stolen from the mbuf above.
> - */
> - memmove(eh_tmp, eh, sizeof(struct ether_header));
>  #ifdef PIPEX
>   if (pipex_enable) {
>   struct pipex_session *session;
> @@ -426,22 +411,23 @@ ether_input(struct ifnet *ifp, struct mb
>   }
>  #endif
>   if (etype == ETHERTYPE_PPPOEDISC)
> - inq = &pppoediscinq;
> + niq_enqueue(&pppoediscinq, m);
>   else
> - inq = &pppoeinq;
> - break;
> + niq_enqueue(&pppoeinq, m);
> + return (1);
>  #endif
>  #ifdef MPLS
>   case ETHERTYPE_MPLS:
>   case ETHERTYPE_MPLS_MCAST:
> - mpls_input(ifp, m);
> - return (1);
> + input = mpls_input;
> + break;
>  #endif
>   default:
>   goto dropanyway;
>   }
>  
> - niq_enqueue(inq, m);
> + m_adj(m, sizeof(*eh));
> + (*input)(ifp, m);
>   return (1);
>  dropanyway:
>   m_freem(m);