From: Stephane Bryant <stephane.ml.bryant@gmail.com>
To: pablo@netfilter.org
Cc: netfilter-devel@vger.kernel.org, stephane <stephane.ml.bryant@gmail.com>
Subject: [PATCH nf-next 3/3] netfilter: bridge: copy back VLAN header for bridge packet queued to userspace
Date: Fri, 15 Jan 2016 09:48:54 +0100 [thread overview]
Message-ID: <1452847734-3766-4-git-send-email-stephane.ml.bryant@gmail.com> (raw)
In-Reply-To: <1452847734-3766-1-git-send-email-stephane.ml.bryant@gmail.com>
From: stephane <stephane.ml.bryant@gmail.com>
For bridge packets queued to userspace, this uses the skb tci info
to reinstate the VLAN header, and conversely parses and removes it
to fill the tci info on the way back.
Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com>
---
net/netfilter/nfnetlink_queue.c | 72 ++++++++++++++++++++++++++++++-----------
1 file changed, 54 insertions(+), 18 deletions(-)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b299236..07723f9 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -317,7 +317,8 @@ 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_t mac_header_len = 0;
+ size_t vlan_len = 0;
size = nlmsg_total_size(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -357,12 +358,10 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
#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);
+ if (skb_vlan_tag_present(entskb))
+ vlan_len = VLAN_HLEN;
}
#endif
@@ -372,7 +371,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
hlen = skb_zerocopy_headlen(entskb);
hlen = min_t(unsigned int, hlen, data_len);
- size += sizeof(struct nlattr) + hlen;
+ size += sizeof(struct nlattr) + hlen + mac_header_len +
+ vlan_len;
cap_len = entskb->len;
rem_len = data_len - hlen;
break;
@@ -548,7 +548,26 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
nla = (struct nlattr *)skb_put(skb, sizeof(*nla));
nla->nla_type = NFQA_PAYLOAD;
- nla->nla_len = nla_attr_size(data_len);
+ nla->nla_len =
+ nla_attr_size(data_len + mac_header_len + vlan_len);
+ if (mac_header_len > 0) {
+ unsigned char *mac_header;
+
+ mac_header = skb_put(skb, mac_header_len + vlan_len);
+ memcpy(mac_header, skb_mac_header(entskb),
+ mac_header_len);
+ if (vlan_len > 0) {
+ struct vlan_ethhdr *veth =
+ (struct vlan_ethhdr *)mac_header;
+
+ u16 proto = veth->h_vlan_proto;
+
+ veth->h_vlan_proto = entskb->vlan_proto;
+ veth->h_vlan_TCI =
+ htons(skb_vlan_tag_get(entskb));
+ veth->h_vlan_encapsulated_proto = proto;
+ }
+ }
if (skb_zerocopy(skb, entskb, data_len, hlen))
goto nla_put_failure;
@@ -556,9 +575,6 @@ 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:
@@ -1087,24 +1103,44 @@ static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
if (nfqa[NFQA_PAYLOAD]) {
u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]);
+ unsigned char *payload = nla_data(nfqa[NFQA_PAYLOAD]);
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));
+ struct vlan_ethhdr *veth =
+ (struct vlan_ethhdr *)payload;
+
+ mac_header_len = (int)
+ (entry->skb->data - skb_mac_header(entry->skb));
+ /* push back mac header before mangling */
skb_push(entry->skb, mac_header_len);
- }
+ /* check for VLAN in NFQA_PAYLOAD */
+ if ((payload_len >= VLAN_ETH_HLEN) &&
+ ((veth->h_vlan_proto == htons(ETH_P_8021Q)) ||
+ (veth->h_vlan_proto == htons(ETH_P_8021AD)))) {
+ entry->skb->vlan_proto = veth->h_vlan_proto;
+ entry->skb->vlan_tci =
+ ntohs(veth->h_vlan_TCI) |
+ VLAN_TAG_PRESENT;
+ memmove(payload + VLAN_HLEN, payload,
+ 2 * ETH_ALEN);
+ entry->skb->protocol =
+ veth->h_vlan_encapsulated_proto;
+ payload += VLAN_HLEN;
+ payload_len -= VLAN_HLEN;
+ } else {
+ entry->skb->vlan_tci &= ~VLAN_TAG_PRESENT;
+ entry->skb->protocol = veth->h_vlan_proto;
+ }
+ }
#endif
diff = payload_len - entry->skb->len;
- if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]),
- payload_len, entry, diff) < 0)
+ if (nfqnl_mangle(payload, payload_len, entry, diff) < 0)
verdict = NF_DROP;
if (mac_header_len > 0) /* pull mac header again */
--
2.1.4
next prev parent reply other threads:[~2016-01-15 8:49 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-15 8:48 [PATCH nf-next 0/3] netfilter: bridge: add queuing to userspace for AF_BRIDGE family Stephane Bryant
2016-01-15 8:48 ` [PATCH nf-next 1/3] netfilter: bridge: add nf_afinfo to enable queuing to userspace Stephane Bryant
2016-01-15 9:06 ` kbuild test robot
2016-01-15 9:49 ` Florian Westphal
2016-01-20 14:34 ` stéphane bryant
2016-01-20 15:52 ` Florian Westphal
2016-01-15 8:48 ` [PATCH nf-next 2/3] netfilter: bridge: pull back mac header into skb queued " Stephane Bryant
2016-01-15 8:48 ` Stephane Bryant [this message]
2016-01-15 10:06 ` [PATCH nf-next 3/3] netfilter: bridge: copy back VLAN header for bridge packet " Florian Westphal
2016-01-15 10:49 ` Florian Westphal
2016-01-15 11:02 ` Pablo Neira Ayuso
2016-01-15 14:04 ` Florian Westphal
2016-01-15 16:33 ` Pablo Neira Ayuso
2016-01-16 11:00 ` stéphane bryant
2016-01-16 11:06 ` Florian Westphal
2016-01-23 9:30 ` stéphane bryant
2016-01-23 20:39 ` Florian Westphal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1452847734-3766-4-git-send-email-stephane.ml.bryant@gmail.com \
--to=stephane.ml.bryant@gmail.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).