]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/bridge/br_netfilter.c
[SK_BUFF]: unions of just one member don't get anything done, kill them
[net-next-2.6.git] / net / bridge / br_netfilter.c
index ea3337ad0edcf3b7b19132fc5770ce5e4c90eeb4..8cee7fdc16c31b3d3becfc507f8627c64489cf7c 100644 (file)
@@ -48,8 +48,8 @@
 
 #define skb_origaddr(skb)       (((struct bridge_skb_cb *) \
                                 (skb->nf_bridge->data))->daddr.ipv4)
-#define store_orig_dstaddr(skb)         (skb_origaddr(skb) = (skb)->nh.iph->daddr)
-#define dnat_took_place(skb)    (skb_origaddr(skb) != (skb)->nh.iph->daddr)
+#define store_orig_dstaddr(skb)         (skb_origaddr(skb) = ip_hdr(skb)->daddr)
+#define dnat_took_place(skb)    (skb_origaddr(skb) != ip_hdr(skb)->daddr)
 
 #ifdef CONFIG_SYSCTL
 static struct ctl_table_header *brnf_sysctl_header;
@@ -61,14 +61,14 @@ static int brnf_filter_vlan_tagged __read_mostly = 1;
 #define brnf_filter_vlan_tagged 1
 #endif
 
-static __be16 inline vlan_proto(const struct sk_buff *skb)
+static inline __be16 vlan_proto(const struct sk_buff *skb)
 {
        return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
 }
 
 #define IS_VLAN_IP(skb) \
        (skb->protocol == htons(ETH_P_8021Q) && \
-        vlan_proto(skb) == htons(ETH_P_IP) &&  \
+        vlan_proto(skb) == htons(ETH_P_IP) &&  \
         brnf_filter_vlan_tagged)
 
 #define IS_VLAN_IPV6(skb) \
@@ -124,7 +124,7 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
 
 static inline void nf_bridge_save_header(struct sk_buff *skb)
 {
-        int header_size = ETH_HLEN;
+       int header_size = ETH_HLEN;
 
        if (skb->protocol == htons(ETH_P_8021Q))
                header_size += VLAN_HLEN;
@@ -139,7 +139,7 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
 int nf_bridge_copy_header(struct sk_buff *skb)
 {
        int err;
-        int header_size = ETH_HLEN;
+       int header_size = ETH_HLEN;
 
        if (skb->protocol == htons(ETH_P_8021Q))
                header_size += VLAN_HLEN;
@@ -174,7 +174,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
        skb->dev = nf_bridge->physindev;
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_push(skb, VLAN_HLEN);
-               skb->nh.raw -= VLAN_HLEN;
+               skb->network_header -= VLAN_HLEN;
        }
        NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
                       br_handle_frame_finish, 1);
@@ -255,7 +255,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
        else {
                if (skb->protocol == htons(ETH_P_8021Q)) {
                        skb_pull(skb, VLAN_HLEN);
-                       skb->nh.raw += VLAN_HLEN;
+                       skb->network_header += VLAN_HLEN;
                }
                skb->dst->output(skb);
        }
@@ -265,7 +265,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 static int br_nf_pre_routing_finish(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
-       struct iphdr *iph = skb->nh.iph;
+       struct iphdr *iph = ip_hdr(skb);
        struct nf_bridge_info *nf_bridge = skb->nf_bridge;
        int err;
 
@@ -325,7 +325,7 @@ bridged_dnat:
                                if (skb->protocol ==
                                    htons(ETH_P_8021Q)) {
                                        skb_push(skb, VLAN_HLEN);
-                                       skb->nh.raw -= VLAN_HLEN;
+                                       skb->network_header -= VLAN_HLEN;
                                }
                                NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
                                               skb, skb->dev, NULL,
@@ -344,7 +344,7 @@ bridged_dnat:
        skb->dev = nf_bridge->physindev;
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_push(skb, VLAN_HLEN);
-               skb->nh.raw -= VLAN_HLEN;
+               skb->network_header -= VLAN_HLEN;
        }
        NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
                       br_handle_frame_finish, 1);
@@ -372,9 +372,10 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
 /* We only check the length. A bridge shouldn't do any hop-by-hop stuff anyway */
 static int check_hbh_len(struct sk_buff *skb)
 {
-       unsigned char *raw = (u8 *) (skb->nh.ipv6h + 1);
+       unsigned char *raw = (u8 *)(ipv6_hdr(skb) + 1);
        u32 pkt_len;
-       int off = raw - skb->nh.raw;
+       const unsigned char *nh = skb_network_header(skb);
+       int off = raw - nh;
        int len = (raw[1] + 1) << 3;
 
        if ((raw + len) - skb->data > skb_headlen(skb))
@@ -384,9 +385,9 @@ static int check_hbh_len(struct sk_buff *skb)
        len -= 2;
 
        while (len > 0) {
-               int optlen = skb->nh.raw[off + 1] + 2;
+               int optlen = nh[off + 1] + 2;
 
-               switch (skb->nh.raw[off]) {
+               switch (nh[off]) {
                case IPV6_TLV_PAD0:
                        optlen = 1;
                        break;
@@ -395,17 +396,18 @@ static int check_hbh_len(struct sk_buff *skb)
                        break;
 
                case IPV6_TLV_JUMBO:
-                       if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2)
+                       if (nh[off + 1] != 4 || (off & 3) != 2)
                                goto bad;
-                       pkt_len = ntohl(*(__be32 *) (skb->nh.raw + off + 2));
+                       pkt_len = ntohl(*(__be32 *) (nh + off + 2));
                        if (pkt_len <= IPV6_MAXPLEN ||
-                           skb->nh.ipv6h->payload_len)
+                           ipv6_hdr(skb)->payload_len)
                                goto bad;
                        if (pkt_len > skb->len - sizeof(struct ipv6hdr))
                                goto bad;
                        if (pskb_trim_rcsum(skb,
                                            pkt_len + sizeof(struct ipv6hdr)))
                                goto bad;
+                       nh = skb_network_header(skb);
                        break;
                default:
                        if (optlen > len)
@@ -439,7 +441,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto inhdr_error;
 
-       hdr = skb->nh.ipv6h;
+       hdr = ipv6_hdr(skb);
 
        if (hdr->version != 6)
                goto inhdr_error;
@@ -495,7 +497,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 
                if (skb->protocol == htons(ETH_P_8021Q)) {
                        skb_pull_rcsum(skb, VLAN_HLEN);
-                       skb->nh.raw += VLAN_HLEN;
+                       skb->network_header += VLAN_HLEN;
                }
                return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
        }
@@ -512,20 +514,20 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_pull_rcsum(skb, VLAN_HLEN);
-               skb->nh.raw += VLAN_HLEN;
+               skb->network_header += VLAN_HLEN;
        }
 
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
                goto inhdr_error;
 
-       iph = skb->nh.iph;
+       iph = ip_hdr(skb);
        if (iph->ihl < 5 || iph->version != 4)
                goto inhdr_error;
 
        if (!pskb_may_pull(skb, 4 * iph->ihl))
                goto inhdr_error;
 
-       iph = skb->nh.iph;
+       iph = ip_hdr(skb);
        if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0)
                goto inhdr_error;
 
@@ -593,7 +595,7 @@ static int br_nf_forward_finish(struct sk_buff *skb)
        }
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_push(skb, VLAN_HLEN);
-               skb->nh.raw -= VLAN_HLEN;
+               skb->network_header -= VLAN_HLEN;
        }
        NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
                       skb->dev, br_forward_finish, 1);
@@ -629,7 +631,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
 
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_pull(*pskb, VLAN_HLEN);
-               (*pskb)->nh.raw += VLAN_HLEN;
+               (*pskb)->network_header += VLAN_HLEN;
        }
 
        nf_bridge = skb->nf_bridge;
@@ -665,13 +667,13 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
                if (!IS_VLAN_ARP(skb))
                        return NF_ACCEPT;
                skb_pull(*pskb, VLAN_HLEN);
-               (*pskb)->nh.raw += VLAN_HLEN;
+               (*pskb)->network_header += VLAN_HLEN;
        }
 
-       if (skb->nh.arph->ar_pln != 4) {
+       if (arp_hdr(skb)->ar_pln != 4) {
                if (IS_VLAN_ARP(skb)) {
                        skb_push(*pskb, VLAN_HLEN);
-                       (*pskb)->nh.raw -= VLAN_HLEN;
+                       (*pskb)->network_header -= VLAN_HLEN;
                }
                return NF_ACCEPT;
        }
@@ -721,7 +723,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
        }
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_push(skb, VLAN_HLEN);
-               skb->nh.raw -= VLAN_HLEN;
+               skb->network_header -= VLAN_HLEN;
        }
 
        NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
@@ -753,7 +755,8 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 #ifdef CONFIG_NETFILTER_DEBUG
        /* Be very paranoid. This probably won't happen anymore, but let's
         * keep the check just to be sure... */
-       if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) {
+       if (skb_mac_header(skb) < skb->head ||
+           skb_mac_header(skb) + ETH_HLEN > skb->data) {
                printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
                       "bad mac.raw pointer.\n");
                goto print_error;
@@ -787,7 +790,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 
        if (skb->protocol == htons(ETH_P_8021Q)) {
                skb_pull(skb, VLAN_HLEN);
-               skb->nh.raw += VLAN_HLEN;
+               skb->network_header += VLAN_HLEN;
        }
 
        nf_bridge_save_header(skb);
@@ -808,7 +811,7 @@ print_error:
                if (realoutdev)
                        printk("[%s]", realoutdev->name);
        }
-       printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw,
+       printk(" head:%p, raw:%p, data:%p\n", skb->head, skb_mac_header(skb),
               skb->data);
        dump_stack();
        return NF_ACCEPT;
@@ -836,10 +839,10 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
  * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
  * ip_refrag() can return NF_STOLEN. */
 static struct nf_hook_ops br_nf_ops[] = {
-       { .hook = br_nf_pre_routing, 
-         .owner = THIS_MODULE, 
-         .pf = PF_BRIDGE, 
-         .hooknum = NF_BR_PRE_ROUTING, 
+       { .hook = br_nf_pre_routing,
+         .owner = THIS_MODULE,
+         .pf = PF_BRIDGE,
+         .hooknum = NF_BR_PRE_ROUTING,
          .priority = NF_BR_PRI_BRNF, },
        { .hook = br_nf_local_in,
          .owner = THIS_MODULE,
@@ -949,44 +952,29 @@ static ctl_table brnf_net_table[] = {
 };
 #endif
 
-int br_netfilter_init(void)
+int __init br_netfilter_init(void)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) {
-               int ret;
-
-               if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0)
-                       continue;
-
-               while (i--)
-                       nf_unregister_hook(&br_nf_ops[i]);
+       int ret;
 
+       ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+       if (ret < 0)
                return ret;
-       }
-
 #ifdef CONFIG_SYSCTL
-       brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0);
+       brnf_sysctl_header = register_sysctl_table(brnf_net_table);
        if (brnf_sysctl_header == NULL) {
                printk(KERN_WARNING
                       "br_netfilter: can't register to sysctl.\n");
-               for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++)
-                       nf_unregister_hook(&br_nf_ops[i]);
-               return -EFAULT;
+               nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
+               return -ENOMEM;
        }
 #endif
-
        printk(KERN_NOTICE "Bridge firewalling registered\n");
-
        return 0;
 }
 
 void br_netfilter_fini(void)
 {
-       int i;
-
-       for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--)
-               nf_unregister_hook(&br_nf_ops[i]);
+       nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops));
 #ifdef CONFIG_SYSCTL
        unregister_sysctl_table(brnf_sysctl_header);
 #endif