aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorStephane Bryant <stephane.ml.bryant@gmail.com>2016-03-26 03:42:11 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2016-03-29 07:26:38 -0400
commit15824ab29f364abd3299ecd17ea48473d971aa79 (patch)
tree09b403b832f68bdfbb3e65a016d0a692f0d2578e /net/netfilter
parentac28634456867b23b95faccba7997a62ec430603 (diff)
netfilter: bridge: pass L2 header and VLAN as netlink attributes in queues to userspace
- This creates 2 netlink attribute NFQA_VLAN and NFQA_L2HDR. - These are filled up for the PF_BRIDGE family on the way to userspace. - NFQA_VLAN is a nested attribute, with the NFQA_VLAN_PROTO and the NFQA_VLAN_TCI carrying the corresponding vlan_proto and vlan_tci fields from the skb using big endian ordering (and using the CFI bit as the VLAN_TAG_PRESENT flag in vlan_tci as in the skb) Signed-off-by: Stephane Bryant <stephane.ml.bryant@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nfnetlink_queue.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 75429997ed41..6889c7c855d1 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -295,6 +295,59 @@ static u32 nfqnl_get_sk_secctx(struct sk_buff *skb, char **secdata)
295 return seclen; 295 return seclen;
296} 296}
297 297
298static u32 nfqnl_get_bridge_size(struct nf_queue_entry *entry)
299{
300 struct sk_buff *entskb = entry->skb;
301 u32 nlalen = 0;
302
303 if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
304 return 0;
305
306 if (skb_vlan_tag_present(entskb))
307 nlalen += nla_total_size(nla_total_size(sizeof(__be16)) +
308 nla_total_size(sizeof(__be16)));
309
310 if (entskb->network_header > entskb->mac_header)
311 nlalen += nla_total_size((entskb->network_header -
312 entskb->mac_header));
313
314 return nlalen;
315}
316
317static int nfqnl_put_bridge(struct nf_queue_entry *entry, struct sk_buff *skb)
318{
319 struct sk_buff *entskb = entry->skb;
320
321 if (entry->state.pf != PF_BRIDGE || !skb_mac_header_was_set(entskb))
322 return 0;
323
324 if (skb_vlan_tag_present(entskb)) {
325 struct nlattr *nest;
326
327 nest = nla_nest_start(skb, NFQA_VLAN | NLA_F_NESTED);
328 if (!nest)
329 goto nla_put_failure;
330
331 if (nla_put_be16(skb, NFQA_VLAN_TCI, htons(entskb->vlan_tci)) ||
332 nla_put_be16(skb, NFQA_VLAN_PROTO, entskb->vlan_proto))
333 goto nla_put_failure;
334
335 nla_nest_end(skb, nest);
336 }
337
338 if (entskb->mac_header < entskb->network_header) {
339 int len = (int)(entskb->network_header - entskb->mac_header);
340
341 if (nla_put(skb, NFQA_L2HDR, len, skb_mac_header(entskb)))
342 goto nla_put_failure;
343 }
344
345 return 0;
346
347nla_put_failure:
348 return -1;
349}
350
298static struct sk_buff * 351static struct sk_buff *
299nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, 352nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
300 struct nf_queue_entry *entry, 353 struct nf_queue_entry *entry,
@@ -334,6 +387,8 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
334 if (entskb->tstamp.tv64) 387 if (entskb->tstamp.tv64)
335 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp)); 388 size += nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
336 389
390 size += nfqnl_get_bridge_size(entry);
391
337 if (entry->state.hook <= NF_INET_FORWARD || 392 if (entry->state.hook <= NF_INET_FORWARD ||
338 (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL)) 393 (entry->state.hook == NF_INET_POST_ROUTING && entskb->sk == NULL))
339 csum_verify = !skb_csum_unnecessary(entskb); 394 csum_verify = !skb_csum_unnecessary(entskb);
@@ -497,6 +552,9 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
497 } 552 }
498 } 553 }
499 554
555 if (nfqnl_put_bridge(entry, skb) < 0)
556 goto nla_put_failure;
557
500 if (entskb->tstamp.tv64) { 558 if (entskb->tstamp.tv64) {
501 struct nfqnl_msg_packet_timestamp ts; 559 struct nfqnl_msg_packet_timestamp ts;
502 struct timespec64 kts = ktime_to_timespec64(skb->tstamp); 560 struct timespec64 kts = ktime_to_timespec64(skb->tstamp);