X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=net%2Fipv6%2Fip6_tunnel.c;h=25bc5ed4910456f9dace494e8a55b19bec837e2b;hb=ff1dcadb1b55dbf471c5ed109dbbdf06bd19ef3b;hp=84d7ebdb9d211103c678579009d6c24dc905379f;hpb=d11ea48aab3b57cc931cc7120603e1c2ffb04302;p=mv-sheeva.git diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 84d7ebdb9d2..25bc5ed4910 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -66,7 +66,7 @@ MODULE_LICENSE("GPL"); #define HASH_SIZE 32 -#define HASH(addr) (((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \ +#define HASH(addr) ((__force u32)((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \ (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ (HASH_SIZE - 1)) @@ -391,7 +391,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw) static int ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, - int type, int code, int offset, __u32 info) + int type, int code, int offset, __be32 info) { struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data; struct ip6_tnl *t; @@ -542,6 +542,7 @@ ip6ip6_rcv(struct sk_buff *skb) skb->dev = t->dev; dst_release(skb->dst); skb->dst = NULL; + nf_reset(skb); if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY) ipv6_copy_dscp(ipv6h, skb->nh.ipv6h); ip6ip6_ecn_decapsulate(ipv6h, skb); @@ -664,9 +665,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) dsfield = ipv6_get_dsfield(ipv6h); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) - fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_TCLASS_MASK); + fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK); if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) - fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_FLOWLABEL_MASK); + fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK); if (encap_limit >= 0 && (opt = create_tel(encap_limit)) == NULL) goto tx_err; @@ -734,7 +735,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr)); ipv6h = skb->nh.ipv6h; - *(u32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000); + *(__be32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000); dsfield = INET_ECN_encapsulate(0, dsfield); ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); @@ -747,7 +748,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); - if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { + if (net_xmit_eval(err) == 0) { stats->tx_bytes += pkt_len; stats->tx_packets++; } else { @@ -1149,6 +1150,20 @@ fail: return err; } +static void __exit ip6ip6_destroy_tunnels(void) +{ + int h; + struct ip6_tnl *t; + + for (h = 0; h < HASH_SIZE; h++) { + while ((t = tnls_r_l[h]) != NULL) + unregister_netdevice(t->dev); + } + + t = tnls_wc[0]; + unregister_netdevice(t->dev); +} + /** * ip6_tunnel_cleanup - free resources and unregister protocol **/ @@ -1158,7 +1173,9 @@ static void __exit ip6_tunnel_cleanup(void) if (xfrm6_tunnel_deregister(&ip6ip6_handler)) printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); - unregister_netdev(ip6ip6_fb_tnl_dev); + rtnl_lock(); + ip6ip6_destroy_tunnels(); + rtnl_unlock(); } module_init(ip6_tunnel_init);