diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 20 | ||||
-rw-r--r-- | net/ipv6/raw.c | 7 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 7 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 43 |
5 files changed, 62 insertions, 17 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7196ac2f2d16..7744a2592693 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3076,7 +3076,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); | 3076 | netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); |
3077 | } | 3077 | } |
3078 | 3078 | ||
3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { | 3079 | static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { |
3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, | 3080 | [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, |
3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, | 3081 | [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, |
3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, | 3082 | [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index c54830b89593..750943e2d34e 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -549,20 +549,18 @@ ipq_rcv_skb(struct sk_buff *skb) | |||
549 | static void | 549 | static void |
550 | ipq_rcv_sk(struct sock *sk, int len) | 550 | ipq_rcv_sk(struct sock *sk, int len) |
551 | { | 551 | { |
552 | do { | 552 | struct sk_buff *skb; |
553 | struct sk_buff *skb; | 553 | unsigned int qlen; |
554 | 554 | ||
555 | if (down_trylock(&ipqnl_sem)) | 555 | down(&ipqnl_sem); |
556 | return; | ||
557 | 556 | ||
558 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { | 557 | for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { |
559 | ipq_rcv_skb(skb); | 558 | skb = skb_dequeue(&sk->sk_receive_queue); |
560 | kfree_skb(skb); | 559 | ipq_rcv_skb(skb); |
561 | } | 560 | kfree_skb(skb); |
561 | } | ||
562 | 562 | ||
563 | up(&ipqnl_sem); | 563 | up(&ipqnl_sem); |
564 | |||
565 | } while (ipqnl && ipqnl->sk_receive_queue.qlen); | ||
566 | } | 564 | } |
567 | 565 | ||
568 | static int | 566 | static int |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 1352c1d9bf4d..617645bc5ed6 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -455,11 +455,11 @@ csum_copy_err: | |||
455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | 455 | static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, |
456 | struct raw6_sock *rp) | 456 | struct raw6_sock *rp) |
457 | { | 457 | { |
458 | struct inet_sock *inet = inet_sk(sk); | ||
459 | struct sk_buff *skb; | 458 | struct sk_buff *skb; |
460 | int err = 0; | 459 | int err = 0; |
461 | int offset; | 460 | int offset; |
462 | int len; | 461 | int len; |
462 | int total_len; | ||
463 | u32 tmp_csum; | 463 | u32 tmp_csum; |
464 | u16 csum; | 464 | u16 csum; |
465 | 465 | ||
@@ -470,7 +470,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
470 | goto out; | 470 | goto out; |
471 | 471 | ||
472 | offset = rp->offset; | 472 | offset = rp->offset; |
473 | if (offset >= inet->cork.length - 1) { | 473 | total_len = inet_sk(sk)->cork.length - (skb->nh.raw - skb->data); |
474 | if (offset >= total_len - 1) { | ||
474 | err = -EINVAL; | 475 | err = -EINVAL; |
475 | ip6_flush_pending_frames(sk); | 476 | ip6_flush_pending_frames(sk); |
476 | goto out; | 477 | goto out; |
@@ -514,7 +515,7 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl, | |||
514 | 515 | ||
515 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, | 516 | tmp_csum = csum_ipv6_magic(&fl->fl6_src, |
516 | &fl->fl6_dst, | 517 | &fl->fl6_dst, |
517 | inet->cork.length, fl->proto, tmp_csum); | 518 | total_len, fl->proto, tmp_csum); |
518 | 519 | ||
519 | if (tmp_csum == 0) | 520 | if (tmp_csum == 0) |
520 | tmp_csum = -1; | 521 | tmp_csum = -1; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4760c85e19db..0f69e800a0ad 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -139,9 +139,12 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
139 | int rover; | 139 | int rover; |
140 | 140 | ||
141 | spin_lock(&tcp_portalloc_lock); | 141 | spin_lock(&tcp_portalloc_lock); |
142 | rover = tcp_port_rover; | 142 | if (tcp_port_rover < low) |
143 | rover = low; | ||
144 | else | ||
145 | rover = tcp_port_rover; | ||
143 | do { rover++; | 146 | do { rover++; |
144 | if ((rover < low) || (rover > high)) | 147 | if (rover > high) |
145 | rover = low; | 148 | rover = low; |
146 | head = &tcp_bhash[tcp_bhashfn(rover)]; | 149 | head = &tcp_bhash[tcp_bhashfn(rover)]; |
147 | spin_lock(&head->lock); | 150 | spin_lock(&head->lock); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8a4f37de4d2d..4429b1a1fe5f 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -11,7 +11,11 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <asm/bug.h> | ||
15 | #include <linux/compiler.h> | ||
14 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <linux/netdevice.h> | ||
18 | #include <net/addrconf.h> | ||
15 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
16 | #include <net/ip.h> | 20 | #include <net/ip.h> |
17 | #include <net/ipv6.h> | 21 | #include <net/ipv6.h> |
@@ -166,6 +170,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int | |||
166 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); | 170 | memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); |
167 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; | 171 | x->u.rt6.rt6i_dst = rt0->rt6i_dst; |
168 | x->u.rt6.rt6i_src = rt0->rt6i_src; | 172 | x->u.rt6.rt6i_src = rt0->rt6i_src; |
173 | x->u.rt6.rt6i_idev = rt0->rt6i_idev; | ||
174 | in6_dev_hold(rt0->rt6i_idev); | ||
169 | header_len -= x->u.dst.xfrm->props.header_len; | 175 | header_len -= x->u.dst.xfrm->props.header_len; |
170 | trailer_len -= x->u.dst.xfrm->props.trailer_len; | 176 | trailer_len -= x->u.dst.xfrm->props.trailer_len; |
171 | } | 177 | } |
@@ -251,11 +257,48 @@ static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
251 | path->ops->update_pmtu(path, mtu); | 257 | path->ops->update_pmtu(path, mtu); |
252 | } | 258 | } |
253 | 259 | ||
260 | static void xfrm6_dst_destroy(struct dst_entry *dst) | ||
261 | { | ||
262 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
263 | |||
264 | if (likely(xdst->u.rt6.rt6i_idev)) | ||
265 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
266 | xfrm_dst_destroy(xdst); | ||
267 | } | ||
268 | |||
269 | static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | ||
270 | int unregister) | ||
271 | { | ||
272 | struct xfrm_dst *xdst; | ||
273 | |||
274 | if (!unregister) | ||
275 | return; | ||
276 | |||
277 | xdst = (struct xfrm_dst *)dst; | ||
278 | if (xdst->u.rt6.rt6i_idev->dev == dev) { | ||
279 | struct inet6_dev *loopback_idev = in6_dev_get(&loopback_dev); | ||
280 | BUG_ON(!loopback_idev); | ||
281 | |||
282 | do { | ||
283 | in6_dev_put(xdst->u.rt6.rt6i_idev); | ||
284 | xdst->u.rt6.rt6i_idev = loopback_idev; | ||
285 | in6_dev_hold(loopback_idev); | ||
286 | xdst = (struct xfrm_dst *)xdst->u.dst.child; | ||
287 | } while (xdst->u.dst.xfrm); | ||
288 | |||
289 | __in6_dev_put(loopback_idev); | ||
290 | } | ||
291 | |||
292 | xfrm_dst_ifdown(dst, dev); | ||
293 | } | ||
294 | |||
254 | static struct dst_ops xfrm6_dst_ops = { | 295 | static struct dst_ops xfrm6_dst_ops = { |
255 | .family = AF_INET6, | 296 | .family = AF_INET6, |
256 | .protocol = __constant_htons(ETH_P_IPV6), | 297 | .protocol = __constant_htons(ETH_P_IPV6), |
257 | .gc = xfrm6_garbage_collect, | 298 | .gc = xfrm6_garbage_collect, |
258 | .update_pmtu = xfrm6_update_pmtu, | 299 | .update_pmtu = xfrm6_update_pmtu, |
300 | .destroy = xfrm6_dst_destroy, | ||
301 | .ifdown = xfrm6_dst_ifdown, | ||
259 | .gc_thresh = 1024, | 302 | .gc_thresh = 1024, |
260 | .entry_size = sizeof(struct xfrm_dst), | 303 | .entry_size = sizeof(struct xfrm_dst), |
261 | }; | 304 | }; |