[NETFILTER]: nf_{conntrack,nat}_proto_udp{,lite}: annotate with const
[safe/jmp/linux-2.6] / net / ipv4 / ipip.c
index b7f6ff4..da28158 100644 (file)
@@ -157,10 +157,10 @@ static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local)
        return NULL;
 }
 
-static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
+static struct ip_tunnel **__ipip_bucket(struct ip_tunnel_parm *parms)
 {
-       __be32 remote = t->parms.iph.daddr;
-       __be32 local = t->parms.iph.saddr;
+       __be32 remote = parms->iph.daddr;
+       __be32 local = parms->iph.saddr;
        unsigned h = 0;
        int prio = 0;
 
@@ -175,6 +175,10 @@ static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
        return &tunnels[prio][h];
 }
 
+static inline struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
+{
+       return __ipip_bucket(&t->parms);
+}
 
 static void ipip_tunnel_unlink(struct ip_tunnel *t)
 {
@@ -206,19 +210,9 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
        __be32 local = parms->iph.saddr;
        struct ip_tunnel *t, **tp, *nt;
        struct net_device *dev;
-       unsigned h = 0;
-       int prio = 0;
        char name[IFNAMSIZ];
 
-       if (remote) {
-               prio |= 2;
-               h ^= HASH(remote);
-       }
-       if (local) {
-               prio |= 1;
-               h ^= HASH(local);
-       }
-       for (tp = &tunnels[prio][h]; (t = *tp) != NULL; tp = &t->next) {
+       for (tp = __ipip_bucket(parms); (t = *tp) != NULL; tp = &t->next) {
                if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
                        return t;
        }
@@ -231,7 +225,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
                int i;
                for (i=1; i<100; i++) {
                        sprintf(name, "tunl%d", i);
-                       if (__dev_get_by_name(name) == NULL)
+                       if (__dev_get_by_name(&init_net, name) == NULL)
                                break;
                }
                if (i==100)
@@ -243,7 +237,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
                return NULL;
 
        nt = netdev_priv(dev);
-       SET_MODULE_OWNER(dev);
        dev->init = ipip_tunnel_init;
        nt->parms = *parms;
 
@@ -280,8 +273,8 @@ static int ipip_err(struct sk_buff *skb, u32 info)
    ICMP in the real Internet is absolutely infeasible.
  */
        struct iphdr *iph = (struct iphdr*)skb->data;
-       int type = skb->h.icmph->type;
-       int code = skb->h.icmph->code;
+       const int type = icmp_hdr(skb)->type;
+       const int code = icmp_hdr(skb)->code;
        struct ip_tunnel *t;
        int err;
 
@@ -336,8 +329,8 @@ out:
        struct iphdr *iph = (struct iphdr*)dp;
        int hlen = iph->ihl<<2;
        struct iphdr *eiph;
-       int type = skb->h.icmph->type;
-       int code = skb->h.icmph->code;
+       const int type = icmp_hdr(skb)->type;
+       const int code = icmp_hdr(skb)->code;
        int rel_type = 0;
        int rel_code = 0;
        __be32 rel_info = 0;
@@ -354,7 +347,7 @@ out:
        default:
                return 0;
        case ICMP_PARAMETERPROB:
-               n = ntohl(skb->h.icmph->un.gateway) >> 24;
+               n = ntohl(icmp_hdr(skb)->un.gateway) >> 24;
                if (n < hlen)
                        return 0;
 
@@ -373,7 +366,7 @@ out:
                        return 0;
                case ICMP_FRAG_NEEDED:
                        /* And it is the only really necessary thing :-) */
-                       n = ntohs(skb->h.icmph->un.frag.mtu);
+                       n = ntohs(icmp_hdr(skb)->un.frag.mtu);
                        if (n < hlen+68)
                                return 0;
                        n -= hlen;
@@ -412,7 +405,7 @@ out:
        fl.fl4_daddr = eiph->saddr;
        fl.fl4_tos = RT_TOS(eiph->tos);
        fl.proto = IPPROTO_IPIP;
-       if (ip_route_output_key(&rt, &key)) {
+       if (ip_route_output_key(&init_net, &rt, &key)) {
                kfree_skb(skb2);
                return 0;
        }
@@ -425,7 +418,7 @@ out:
                fl.fl4_daddr = eiph->daddr;
                fl.fl4_src = eiph->saddr;
                fl.fl4_tos = eiph->tos;
-               if (ip_route_output_key(&rt, &fl) ||
+               if (ip_route_output_key(&init_net, &rt, &fl) ||
                    rt->u.dst.dev->type != ARPHRD_TUNNEL) {
                        ip_rt_put(rt);
                        kfree_skb(skb2);
@@ -485,7 +478,7 @@ static int ipip_rcv(struct sk_buff *skb)
 
                secpath_reset(skb);
 
-               skb->mac.raw = skb->nh.raw;
+               skb->mac_header = skb->network_header;
                skb_reset_network_header(skb);
                skb->protocol = htons(ETH_P_IP);
                skb->pkt_type = PACKET_HOST;
@@ -522,7 +515,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_device *tdev;                        /* Device to other host */
        struct iphdr  *old_iph = ip_hdr(skb);
        struct iphdr  *iph;                     /* Our new IP header */
-       int    max_headroom;                    /* The extra header space needed */
+       unsigned int max_headroom;              /* The extra header space needed */
        __be32 dst = tiph->daddr;
        int    mtu;
 
@@ -554,7 +547,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                                                .saddr = tiph->saddr,
                                                .tos = RT_TOS(tos) } },
                                    .proto = IPPROTO_IPIP };
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        tunnel->stat.tx_carrier_errors++;
                        goto tx_error_icmp;
                }
@@ -601,7 +594,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        max_headroom = (LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr));
 
-       if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
+       if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
+           (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
                struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
                if (!new_skb) {
                        ip_rt_put(rt);
@@ -617,7 +611,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                old_iph = ip_hdr(skb);
        }
 
-       skb->h.raw = skb->nh.raw;
+       skb->transport_header = skb->network_header;
        skb_push(skb, sizeof(struct iphdr));
        skb_reset_network_header(skb);
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -657,6 +651,40 @@ tx_error:
        return 0;
 }
 
+static void ipip_tunnel_bind_dev(struct net_device *dev)
+{
+       struct net_device *tdev = NULL;
+       struct ip_tunnel *tunnel;
+       struct iphdr *iph;
+
+       tunnel = netdev_priv(dev);
+       iph = &tunnel->parms.iph;
+
+       if (iph->daddr) {
+               struct flowi fl = { .oif = tunnel->parms.link,
+                                   .nl_u = { .ip4_u =
+                                             { .daddr = iph->daddr,
+                                               .saddr = iph->saddr,
+                                               .tos = RT_TOS(iph->tos) } },
+                                   .proto = IPPROTO_IPIP };
+               struct rtable *rt;
+               if (!ip_route_output_key(&init_net, &rt, &fl)) {
+                       tdev = rt->u.dst.dev;
+                       ip_rt_put(rt);
+               }
+               dev->flags |= IFF_POINTOPOINT;
+       }
+
+       if (!tdev && tunnel->parms.link)
+               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+       if (tdev) {
+               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
+               dev->mtu = tdev->mtu - sizeof(struct iphdr);
+       }
+       dev->iflink = tunnel->parms.link;
+}
+
 static int
 ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -729,6 +757,11 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
                                t->parms.iph.frag_off = p.iph.frag_off;
+                               if (t->parms.link != p.link) {
+                                       t->parms.link = p.link;
+                                       ipip_tunnel_bind_dev(dev);
+                                       netdev_state_change(dev);
+                               }
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
@@ -780,7 +813,6 @@ static int ipip_tunnel_change_mtu(struct net_device *dev, int new_mtu)
 
 static void ipip_tunnel_setup(struct net_device *dev)
 {
-       SET_MODULE_OWNER(dev);
        dev->uninit             = ipip_tunnel_uninit;
        dev->hard_start_xmit    = ipip_tunnel_xmit;
        dev->get_stats          = ipip_tunnel_get_stats;
@@ -798,12 +830,9 @@ static void ipip_tunnel_setup(struct net_device *dev)
 
 static int ipip_tunnel_init(struct net_device *dev)
 {
-       struct net_device *tdev = NULL;
        struct ip_tunnel *tunnel;
-       struct iphdr *iph;
 
        tunnel = netdev_priv(dev);
-       iph = &tunnel->parms.iph;
 
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
@@ -811,29 +840,7 @@ static int ipip_tunnel_init(struct net_device *dev)
        memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
        memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-       if (iph->daddr) {
-               struct flowi fl = { .oif = tunnel->parms.link,
-                                   .nl_u = { .ip4_u =
-                                             { .daddr = iph->daddr,
-                                               .saddr = iph->saddr,
-                                               .tos = RT_TOS(iph->tos) } },
-                                   .proto = IPPROTO_IPIP };
-               struct rtable *rt;
-               if (!ip_route_output_key(&rt, &fl)) {
-                       tdev = rt->u.dst.dev;
-                       ip_rt_put(rt);
-               }
-               dev->flags |= IFF_POINTOPOINT;
-       }
-
-       if (!tdev && tunnel->parms.link)
-               tdev = __dev_get_by_index(tunnel->parms.link);
-
-       if (tdev) {
-               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
-               dev->mtu = tdev->mtu - sizeof(struct iphdr);
-       }
-       dev->iflink = tunnel->parms.link;
+       ipip_tunnel_bind_dev(dev);
 
        return 0;
 }