On Mon, May 23, 2016 at 03:23:52PM +0200, Martin Pieuchot wrote:
> HW-vlan breaks our if_input() design because vlan packets are
> decapsulated before calling if_input().
> 
> So it doesn't matter in which order you configured your pseudo-driver,
> they all have to deal with this layer violation.
> 
> Here's a jumbo diff for carp(4) and bridge(4).

This is for sure not nice. It would be nicer to do this filtering not on
the pseudo-interface level since that means we need to add it in anything
that plugs into the chain. Wondering if this can be abstracted somehow.

Since this is currently a big bug, OK claudio@
 
> Index: net/if_bridge.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_bridge.c,v
> retrieving revision 1.278
> diff -u -p -r1.278 if_bridge.c
> --- net/if_bridge.c   12 Apr 2016 06:20:30 -0000      1.278
> +++ net/if_bridge.c   23 May 2016 13:17:08 -0000
> @@ -1063,6 +1063,18 @@ bridge_process(struct ifnet *ifp, struct
>       if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
>               goto reenqueue;
>  
> +#if NVLAN > 0
> +     /*
> +      * If the underlying interface removed the VLAN header itself,
> +      * add it back.
> +      */
> +     if (ISSET(m->m_flags, M_VLANTAG)) {
> +             m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
> +             if (m == NULL)
> +                     return;
> +     }
> +#endif
> +
>  #if NBPFILTER > 0
>       if (sc->sc_if.if_bpf)
>               bpf_mtap_ether(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN);
> Index: netinet/ip_carp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_carp.c,v
> retrieving revision 1.289
> diff -u -p -r1.289 ip_carp.c
> --- netinet/ip_carp.c 18 May 2016 03:46:03 -0000      1.289
> +++ netinet/ip_carp.c 23 May 2016 13:14:48 -0000
> @@ -80,6 +80,10 @@
>  #include <net/bpf.h>
>  #endif
>  
> +#if NVLAN > 0
> +#include <net/if_vlan_var.h>
> +#endif
> +
>  #include <netinet/ip_carp.h>
>  
>  struct carp_mc_entry {
> @@ -1398,6 +1402,15 @@ carp_input(struct ifnet *ifp0, struct mb
>       struct carp_if *cif;
>       struct carp_softc *sc;
>       struct srp_ref sr;
> +
> +#if NVLAN > 0
> +     /*
> +      * If the underlying interface removed the VLAN header itself,
> +      * it's not for us.
> +      */
> +     if (ISSET(m->m_flags, M_VLANTAG))
> +             return (0);
> +#endif
>  
>       eh = mtod(m, struct ether_header *);
>       cif = (struct carp_if *)cookie;
> 

-- 
:wq Claudio

Reply via email to