aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c45
-rw-r--r--net/ipv6/af_inet6.c32
-rw-r--r--net/ipv6/ndisc.c16
-rw-r--r--net/ipv6/route.c4
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/ipv6/xfrm6_policy.c2
6 files changed, 51 insertions, 50 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f9afb452249c..03e2a1ad71e9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2224,10 +2224,24 @@ int addrconf_del_ifaddr(struct net *net, void __user *arg)
2224 return err; 2224 return err;
2225} 2225}
2226 2226
2227static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
2228 int plen, int scope)
2229{
2230 struct inet6_ifaddr *ifp;
2231
2232 ifp = ipv6_add_addr(idev, addr, plen, scope, IFA_F_PERMANENT);
2233 if (!IS_ERR(ifp)) {
2234 spin_lock_bh(&ifp->lock);
2235 ifp->flags &= ~IFA_F_TENTATIVE;
2236 spin_unlock_bh(&ifp->lock);
2237 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2238 in6_ifa_put(ifp);
2239 }
2240}
2241
2227#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) 2242#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2228static void sit_add_v4_addrs(struct inet6_dev *idev) 2243static void sit_add_v4_addrs(struct inet6_dev *idev)
2229{ 2244{
2230 struct inet6_ifaddr * ifp;
2231 struct in6_addr addr; 2245 struct in6_addr addr;
2232 struct net_device *dev; 2246 struct net_device *dev;
2233 struct net *net = dev_net(idev->dev); 2247 struct net *net = dev_net(idev->dev);
@@ -2246,14 +2260,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
2246 } 2260 }
2247 2261
2248 if (addr.s6_addr32[3]) { 2262 if (addr.s6_addr32[3]) {
2249 ifp = ipv6_add_addr(idev, &addr, 128, scope, IFA_F_PERMANENT); 2263 add_addr(idev, &addr, 128, scope);
2250 if (!IS_ERR(ifp)) {
2251 spin_lock_bh(&ifp->lock);
2252 ifp->flags &= ~IFA_F_TENTATIVE;
2253 spin_unlock_bh(&ifp->lock);
2254 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2255 in6_ifa_put(ifp);
2256 }
2257 return; 2264 return;
2258 } 2265 }
2259 2266
@@ -2281,15 +2288,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
2281 else 2288 else
2282 plen = 96; 2289 plen = 96;
2283 2290
2284 ifp = ipv6_add_addr(idev, &addr, plen, flag, 2291 add_addr(idev, &addr, plen, flag);
2285 IFA_F_PERMANENT);
2286 if (!IS_ERR(ifp)) {
2287 spin_lock_bh(&ifp->lock);
2288 ifp->flags &= ~IFA_F_TENTATIVE;
2289 spin_unlock_bh(&ifp->lock);
2290 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2291 in6_ifa_put(ifp);
2292 }
2293 } 2292 }
2294 } 2293 }
2295 } 2294 }
@@ -2299,7 +2298,6 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
2299static void init_loopback(struct net_device *dev) 2298static void init_loopback(struct net_device *dev)
2300{ 2299{
2301 struct inet6_dev *idev; 2300 struct inet6_dev *idev;
2302 struct inet6_ifaddr * ifp;
2303 2301
2304 /* ::1 */ 2302 /* ::1 */
2305 2303
@@ -2310,14 +2308,7 @@ static void init_loopback(struct net_device *dev)
2310 return; 2308 return;
2311 } 2309 }
2312 2310
2313 ifp = ipv6_add_addr(idev, &in6addr_loopback, 128, IFA_HOST, IFA_F_PERMANENT); 2311 add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
2314 if (!IS_ERR(ifp)) {
2315 spin_lock_bh(&ifp->lock);
2316 ifp->flags &= ~IFA_F_TENTATIVE;
2317 spin_unlock_bh(&ifp->lock);
2318 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2319 in6_ifa_put(ifp);
2320 }
2321} 2312}
2322 2313
2323static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) 2314static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c802bc1658a8..fa2ac7ee662f 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -799,24 +799,34 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
799 int proto; 799 int proto;
800 __wsum csum; 800 __wsum csum;
801 801
802 if (unlikely(!pskb_may_pull(skb, sizeof(*iph)))) 802 iph = skb_gro_header(skb, sizeof(*iph));
803 if (unlikely(!iph))
803 goto out; 804 goto out;
804 805
805 iph = ipv6_hdr(skb); 806 skb_gro_pull(skb, sizeof(*iph));
806 __skb_pull(skb, sizeof(*iph)); 807 skb_set_transport_header(skb, skb_gro_offset(skb));
807 808
808 flush += ntohs(iph->payload_len) != skb->len; 809 flush += ntohs(iph->payload_len) != skb_gro_len(skb);
809 810
810 rcu_read_lock(); 811 rcu_read_lock();
811 proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr); 812 proto = iph->nexthdr;
812 iph = ipv6_hdr(skb);
813 IPV6_GRO_CB(skb)->proto = proto;
814 ops = rcu_dereference(inet6_protos[proto]); 813 ops = rcu_dereference(inet6_protos[proto]);
815 if (!ops || !ops->gro_receive) 814 if (!ops || !ops->gro_receive) {
816 goto out_unlock; 815 __pskb_pull(skb, skb_gro_offset(skb));
816 proto = ipv6_gso_pull_exthdrs(skb, proto);
817 skb_gro_pull(skb, -skb_transport_offset(skb));
818 skb_reset_transport_header(skb);
819 __skb_push(skb, skb_gro_offset(skb));
820
821 if (!ops || !ops->gro_receive)
822 goto out_unlock;
823
824 iph = ipv6_hdr(skb);
825 }
826
827 IPV6_GRO_CB(skb)->proto = proto;
817 828
818 flush--; 829 flush--;
819 skb_reset_transport_header(skb);
820 nlen = skb_network_header_len(skb); 830 nlen = skb_network_header_len(skb);
821 831
822 for (p = *head; p; p = p->next) { 832 for (p = *head; p; p = p->next) {
@@ -880,7 +890,7 @@ out_unlock:
880} 890}
881 891
882static struct packet_type ipv6_packet_type = { 892static struct packet_type ipv6_packet_type = {
883 .type = __constant_htons(ETH_P_IPV6), 893 .type = cpu_to_be16(ETH_P_IPV6),
884 .func = ipv6_rcv, 894 .func = ipv6_rcv,
885 .gso_send_check = ipv6_gso_send_check, 895 .gso_send_check = ipv6_gso_send_check,
886 .gso_segment = ipv6_gso_segment, 896 .gso_segment = ipv6_gso_segment,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 3e2970841bd8..3cd83b85e9ef 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1538,13 +1538,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1538 if (rt->rt6i_flags & RTF_GATEWAY) { 1538 if (rt->rt6i_flags & RTF_GATEWAY) {
1539 ND_PRINTK2(KERN_WARNING 1539 ND_PRINTK2(KERN_WARNING
1540 "ICMPv6 Redirect: destination is not a neighbour.\n"); 1540 "ICMPv6 Redirect: destination is not a neighbour.\n");
1541 dst_release(dst); 1541 goto release;
1542 return;
1543 }
1544 if (!xrlim_allow(dst, 1*HZ)) {
1545 dst_release(dst);
1546 return;
1547 } 1542 }
1543 if (!xrlim_allow(dst, 1*HZ))
1544 goto release;
1548 1545
1549 if (dev->addr_len) { 1546 if (dev->addr_len) {
1550 read_lock_bh(&neigh->lock); 1547 read_lock_bh(&neigh->lock);
@@ -1570,8 +1567,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1570 ND_PRINTK0(KERN_ERR 1567 ND_PRINTK0(KERN_ERR
1571 "ICMPv6 Redirect: %s() failed to allocate an skb.\n", 1568 "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
1572 __func__); 1569 __func__);
1573 dst_release(dst); 1570 goto release;
1574 return;
1575 } 1571 }
1576 1572
1577 skb_reserve(buff, LL_RESERVED_SPACE(dev)); 1573 skb_reserve(buff, LL_RESERVED_SPACE(dev));
@@ -1631,6 +1627,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1631 1627
1632 if (likely(idev != NULL)) 1628 if (likely(idev != NULL))
1633 in6_dev_put(idev); 1629 in6_dev_put(idev);
1630 return;
1631
1632release:
1633 dst_release(dst);
1634} 1634}
1635 1635
1636static void pndisc_redo(struct sk_buff *skb) 1636static void pndisc_redo(struct sk_buff *skb)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9c574235c905..c3d486a3edad 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -98,7 +98,7 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
98 98
99static struct dst_ops ip6_dst_ops_template = { 99static struct dst_ops ip6_dst_ops_template = {
100 .family = AF_INET6, 100 .family = AF_INET6,
101 .protocol = __constant_htons(ETH_P_IPV6), 101 .protocol = cpu_to_be16(ETH_P_IPV6),
102 .gc = ip6_dst_gc, 102 .gc = ip6_dst_gc,
103 .gc_thresh = 1024, 103 .gc_thresh = 1024,
104 .check = ip6_dst_check, 104 .check = ip6_dst_check,
@@ -117,7 +117,7 @@ static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
117 117
118static struct dst_ops ip6_dst_blackhole_ops = { 118static struct dst_ops ip6_dst_blackhole_ops = {
119 .family = AF_INET6, 119 .family = AF_INET6,
120 .protocol = __constant_htons(ETH_P_IPV6), 120 .protocol = cpu_to_be16(ETH_P_IPV6),
121 .destroy = ip6_dst_destroy, 121 .destroy = ip6_dst_destroy,
122 .check = ip6_dst_check, 122 .check = ip6_dst_check,
123 .update_pmtu = ip6_rt_blackhole_update_pmtu, 123 .update_pmtu = ip6_rt_blackhole_update_pmtu,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e5b85d45bee8..00f1269e11e9 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -948,7 +948,7 @@ struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
948 948
949 switch (skb->ip_summed) { 949 switch (skb->ip_summed) {
950 case CHECKSUM_COMPLETE: 950 case CHECKSUM_COMPLETE:
951 if (!tcp_v6_check(skb->len, &iph->saddr, &iph->daddr, 951 if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
952 skb->csum)) { 952 skb->csum)) {
953 skb->ip_summed = CHECKSUM_UNNECESSARY; 953 skb->ip_summed = CHECKSUM_UNNECESSARY;
954 break; 954 break;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 97ab068e8ccc..b4b16a43f277 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -272,7 +272,7 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
272 272
273static struct dst_ops xfrm6_dst_ops = { 273static struct dst_ops xfrm6_dst_ops = {
274 .family = AF_INET6, 274 .family = AF_INET6,
275 .protocol = __constant_htons(ETH_P_IPV6), 275 .protocol = cpu_to_be16(ETH_P_IPV6),
276 .gc = xfrm6_garbage_collect, 276 .gc = xfrm6_garbage_collect,
277 .update_pmtu = xfrm6_update_pmtu, 277 .update_pmtu = xfrm6_update_pmtu,
278 .destroy = xfrm6_dst_destroy, 278 .destroy = xfrm6_dst_destroy,