From: stephane <stephane.ml.bryant@xxxxxxxxx> -this creates 2 netlink attribute NLQA_VLAN and NLQA_L2HDR -these are filled up for the PF_BRIDGE family on the way to userspace Signed-off-by: Stephane Bryant <stephane.ml.bryant@xxxxxxxxx> --- include/uapi/linux/netfilter/nfnetlink_queue.h | 7 ++++ net/netfilter/nfnetlink_queue.c | 53 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h index b67a853..211fcdc 100644 --- a/include/uapi/linux/netfilter/nfnetlink_queue.h +++ b/include/uapi/linux/netfilter/nfnetlink_queue.h @@ -30,6 +30,11 @@ struct nfqnl_msg_packet_timestamp { __aligned_be64 usec; }; +struct nfqnl_msg_vlan { + __be16 proto; + __u16 tci; +} __attribute__ ((packed)); + enum nfqnl_attr_type { NFQA_UNSPEC, NFQA_PACKET_HDR, @@ -50,6 +55,8 @@ enum nfqnl_attr_type { NFQA_UID, /* __u32 sk uid */ NFQA_GID, /* __u32 sk gid */ NFQA_SECCTX, /* security context string */ + NFQA_VLAN, /* packet vlan info */ + NFQA_L2HDR, /* full L2 header */ __NFQA_MAX }; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 1d39365..b40cdb4 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -295,6 +295,54 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata) return seclen; } +static u32 nfqnl_get_bridge_nla_len(struct nf_queue_entry *entry) +{ + u32 nlalen = 0; + struct sk_buff *entskb = entry->skb; + + if ((entry->state.pf != PF_BRIDGE) || (!skb_mac_header_was_set(entskb))) + return 0; + + if (skb_vlan_tag_present(entskb)) + nlalen += nla_total_size(sizeof(struct nfqnl_msg_vlan)); + + if (entskb->network_header > entskb->mac_header) + nlalen += nla_total_size((entskb->network_header - + entskb->mac_header)); + + return nlalen; +} + +static int nfqnl_put_bridge_nla(struct nf_queue_entry *entry, + struct sk_buff *skb) +{ + struct sk_buff *entskb = entry->skb; + + if ((entry->state.pf != PF_BRIDGE) || (!skb_mac_header_was_set(entskb))) + return 0; + + if (skb_vlan_tag_present(entskb)) { + struct nfqnl_msg_vlan pvlan; + + pvlan.tci = entskb->vlan_tci; + pvlan.proto = entskb->vlan_proto; + if (nla_put(skb, NFQA_VLAN, sizeof(pvlan), &pvlan)) + goto nla_put_failure; + } + + if (entskb->mac_header < entskb->network_header) { + int len = (int)(entskb->network_header - entskb->mac_header); + + if (nla_put(skb, NFQA_L2HDR, len, skb_mac_header(entskb))) + goto nla_put_failure; + } + + return 0; + +nla_put_failure: + return -1; +} + static struct sk_buff * nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, struct nf_queue_entry *entry, @@ -334,6 +382,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, if (entskb->tstamp.tv64) size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); + size += nfqnl_get_bridge_nla_len(entry); + if (entry->state.hook <= NF_INET_FORWARD || (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL)) csum_verify = !skb_csum_unnecessary(entskb); @@ -499,6 +549,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, } } + if (nfqnl_put_bridge_nla(entry, skb)) + goto nla_put_failure; + if (entskb->tstamp.tv64) { struct nfqnl_msg_packet_timestamp ts; struct timespec64 kts = ktime_to_timespec64(skb->tstamp); -- 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