]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/netfilter/nfnetlink_log.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux.git] / net / netfilter / nfnetlink_log.c
index d69e1863e5369ce9e2ca73be6aa9f2e6037dab3e..0ba020ca38e68cde127fca47439d5bb2a5a456d6 100644 (file)
@@ -385,6 +385,57 @@ nfulnl_timer(struct timer_list *t)
        instance_put(inst);
 }
 
+static u32 nfulnl_get_bridge_size(const struct sk_buff *skb)
+{
+       u32 size = 0;
+
+       if (!skb_mac_header_was_set(skb))
+               return 0;
+
+       if (skb_vlan_tag_present(skb)) {
+               size += nla_total_size(0); /* nested */
+               size += nla_total_size(sizeof(u16)); /* id */
+               size += nla_total_size(sizeof(u16)); /* tag */
+       }
+
+       if (skb->network_header > skb->mac_header)
+               size += nla_total_size(skb->network_header - skb->mac_header);
+
+       return size;
+}
+
+static int nfulnl_put_bridge(struct nfulnl_instance *inst, const struct sk_buff *skb)
+{
+       if (!skb_mac_header_was_set(skb))
+               return 0;
+
+       if (skb_vlan_tag_present(skb)) {
+               struct nlattr *nest;
+
+               nest = nla_nest_start(inst->skb, NFULA_VLAN);
+               if (!nest)
+                       goto nla_put_failure;
+
+               if (nla_put_be16(inst->skb, NFULA_VLAN_TCI, htons(skb->vlan_tci)) ||
+                   nla_put_be16(inst->skb, NFULA_VLAN_PROTO, skb->vlan_proto))
+                       goto nla_put_failure;
+
+               nla_nest_end(inst->skb, nest);
+       }
+
+       if (skb->mac_header < skb->network_header) {
+               int len = (int)(skb->network_header - skb->mac_header);
+
+               if (nla_put(inst->skb, NFULA_L2HDR, len, skb_mac_header(skb)))
+                       goto nla_put_failure;
+       }
+
+       return 0;
+
+nla_put_failure:
+       return -1;
+}
+
 /* This is an inline function, we don't really care about a long
  * list of arguments */
 static inline int
@@ -580,6 +631,10 @@ __build_packet_message(struct nfnl_log_net *log,
                                 NFULA_CT, NFULA_CT_INFO) < 0)
                goto nla_put_failure;
 
+       if ((pf == NFPROTO_NETDEV || pf == NFPROTO_BRIDGE) &&
+           nfulnl_put_bridge(inst, skb) < 0)
+               goto nla_put_failure;
+
        if (data_len) {
                struct nlattr *nla;
                int size = nla_attr_size(data_len);
@@ -687,6 +742,8 @@ nfulnl_log_packet(struct net *net,
                                size += nfnl_ct->build_size(ct);
                }
        }
+       if (pf == NFPROTO_NETDEV || pf == NFPROTO_BRIDGE)
+               size += nfulnl_get_bridge_size(skb);
 
        qthreshold = inst->qthreshold;
        /* per-rule qthreshold overrides per-instance */