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);