Eric Woudstra <ericwo...@gmail.com> wrote: > This adds the capability to evaluate 802.1ad, QinQ, PPPoE and PPPoE-in-Q > packets in the bridge filter chain. > > Signed-off-by: Eric Woudstra <ericwo...@gmail.com> > --- > net/netfilter/nft_chain_filter.c | 52 +++++++++++++++++++++++++++++++- > 1 file changed, 51 insertions(+), 1 deletion(-) > > diff --git a/net/netfilter/nft_chain_filter.c > b/net/netfilter/nft_chain_filter.c > index 19a553550c76..8445ddfb9cea 100644 > --- a/net/netfilter/nft_chain_filter.c > +++ b/net/netfilter/nft_chain_filter.c > @@ -232,11 +232,55 @@ nft_do_chain_bridge(void *priv, > struct sk_buff *skb, > const struct nf_hook_state *state) > { > + __be16 outer_proto, proto = 0; > struct nft_pktinfo pkt; > + int ret, offset = 0; > > nft_set_pktinfo(&pkt, skb, state); > > switch (eth_hdr(skb)->h_proto) { > + case htons(ETH_P_PPP_SES): { > + struct ppp_hdr { > + struct pppoe_hdr hdr; > + __be16 proto; > + } *ph; > + > + if (!pskb_may_pull(skb, PPPOE_SES_HLEN)) > + break; > + offset = PPPOE_SES_HLEN; > + outer_proto = skb->protocol; > + ph = (struct ppp_hdr *)(skb->data); > + switch (ph->proto) { > + case htons(PPP_IP): > + proto = htons(ETH_P_IP); > + break; > + case htons(PPP_IPV6): > + proto = htons(ETH_P_IPV6); > + break; > + }
What if ph->proto is neither ipv4 nor ipv6? I don't think we should clobber skb->protocol or set a new network header in that case. > + ret = nft_do_chain(&pkt, priv); > + > + if (offset) { > + skb_reset_network_header(skb); if ret == NF_STOLEN, skb has already been free'd or is queued elsewhere and must not be modified anymore. I would restrict this to ret == NF_ACCEPT.