From: stephane <stephane.ml.bryant@xxxxxxxxx> This pulls back the mac header into the skb when queuing packets to userspace in the bridge, and conversely when processing the verdict. Signed-off-by: Stephane Bryant <stephane.ml.bryant@xxxxxxxxx> --- net/netfilter/nfnetlink_queue.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 1d39365..b299236 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -317,6 +317,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, bool csum_verify; char *secdata = NULL; u32 seclen = 0; + int mac_header_len = 0; size = nlmsg_total_size(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) @@ -353,6 +354,18 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, skb_checksum_help(entskb)) return NULL; +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) + if ((entry->state.pf == PF_BRIDGE) && + (entskb->dev && (entskb->data > skb_mac_header(entskb)))) { + /* push back the mac header into the data so that + * it gets copied in + */ + mac_header_len = + (int)(entskb->data - skb_mac_header(entskb)); + skb_push(entskb, mac_header_len); + } +#endif + data_len = ACCESS_ONCE(queue->copy_range); if (data_len > entskb->len) data_len = entskb->len; @@ -542,6 +555,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } nlh->nlmsg_len = skb->len; + + if (mac_header_len > 0) + skb_pull(entskb, mac_header_len); + return skb; nla_put_failure: @@ -1070,12 +1087,29 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl, if (nfqa[NFQA_PAYLOAD]) { u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]); - int diff = payload_len - entry->skb->len; + int diff = 0; + int mac_header_len = 0; +#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) + if ((entry->state.pf == PF_BRIDGE) && + (entry->skb->dev && + (entry->skb->data > skb_mac_header(entry->skb)))) { + /* push back the mac header into the data so that + * it gets copied in before mangling + */ + mac_header_len = (int)(entry->skb->data - + skb_mac_header(entry->skb)); + skb_push(entry->skb, mac_header_len); + } +#endif + diff = payload_len - entry->skb->len; if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]), payload_len, entry, diff) < 0) verdict = NF_DROP; + if (mac_header_len > 0) /* pull mac header again */ + skb_pull(entry->skb, mac_header_len); + if (ct && diff) nfnl_ct->seq_adjust(entry->skb, ct, ctinfo, diff); } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html