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