diff options
Diffstat (limited to 'net/l2tp')
-rw-r--r-- | net/l2tp/l2tp_core.c | 6 | ||||
-rw-r--r-- | net/l2tp/l2tp_eth.c | 2 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip.c | 24 | ||||
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 2 |
4 files changed, 19 insertions, 15 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ed8a2335442..34b2ddeacb6 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <net/protocol.h> | 55 | #include <net/protocol.h> |
56 | 56 | ||
57 | #include <asm/byteorder.h> | 57 | #include <asm/byteorder.h> |
58 | #include <asm/atomic.h> | 58 | #include <linux/atomic.h> |
59 | 59 | ||
60 | #include "l2tp_core.h" | 60 | #include "l2tp_core.h" |
61 | 61 | ||
@@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len | |||
1045 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + | 1045 | headroom = NET_SKB_PAD + sizeof(struct iphdr) + |
1046 | uhlen + hdr_len; | 1046 | uhlen + hdr_len; |
1047 | old_headroom = skb_headroom(skb); | 1047 | old_headroom = skb_headroom(skb); |
1048 | if (skb_cow_head(skb, headroom)) | 1048 | if (skb_cow_head(skb, headroom)) { |
1049 | dev_kfree_skb(skb); | ||
1049 | goto abort; | 1050 | goto abort; |
1051 | } | ||
1050 | 1052 | ||
1051 | new_headroom = skb_headroom(skb); | 1053 | new_headroom = skb_headroom(skb); |
1052 | skb_orphan(skb); | 1054 | skb_orphan(skb); |
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index a8193f52c13..d2726a74597 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { | |||
103 | static void l2tp_eth_dev_setup(struct net_device *dev) | 103 | static void l2tp_eth_dev_setup(struct net_device *dev) |
104 | { | 104 | { |
105 | ether_setup(dev); | 105 | ether_setup(dev); |
106 | 106 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | |
107 | dev->netdev_ops = &l2tp_eth_netdev_ops; | 107 | dev->netdev_ops = &l2tp_eth_netdev_ops; |
108 | dev->destructor = free_netdev; | 108 | dev->destructor = free_netdev; |
109 | } | 109 | } |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index b6466e71f5e..55670ec3cd0 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -393,11 +393,6 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) | |||
393 | { | 393 | { |
394 | int rc; | 394 | int rc; |
395 | 395 | ||
396 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) | ||
397 | goto drop; | ||
398 | |||
399 | nf_reset(skb); | ||
400 | |||
401 | /* Charge it to the socket, dropping if the queue is full. */ | 396 | /* Charge it to the socket, dropping if the queue is full. */ |
402 | rc = sock_queue_rcv_skb(sk, skb); | 397 | rc = sock_queue_rcv_skb(sk, skb); |
403 | if (rc < 0) | 398 | if (rc < 0) |
@@ -480,18 +475,16 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
480 | if (connected) | 475 | if (connected) |
481 | rt = (struct rtable *) __sk_dst_check(sk, 0); | 476 | rt = (struct rtable *) __sk_dst_check(sk, 0); |
482 | 477 | ||
478 | rcu_read_lock(); | ||
483 | if (rt == NULL) { | 479 | if (rt == NULL) { |
484 | struct ip_options_rcu *inet_opt; | 480 | const struct ip_options_rcu *inet_opt; |
485 | 481 | ||
486 | rcu_read_lock(); | ||
487 | inet_opt = rcu_dereference(inet->inet_opt); | 482 | inet_opt = rcu_dereference(inet->inet_opt); |
488 | 483 | ||
489 | /* Use correct destination address if we have options. */ | 484 | /* Use correct destination address if we have options. */ |
490 | if (inet_opt && inet_opt->opt.srr) | 485 | if (inet_opt && inet_opt->opt.srr) |
491 | daddr = inet_opt->opt.faddr; | 486 | daddr = inet_opt->opt.faddr; |
492 | 487 | ||
493 | rcu_read_unlock(); | ||
494 | |||
495 | /* If this fails, retransmit mechanism of transport layer will | 488 | /* If this fails, retransmit mechanism of transport layer will |
496 | * keep trying until route appears or the connection times | 489 | * keep trying until route appears or the connection times |
497 | * itself out. | 490 | * itself out. |
@@ -503,12 +496,20 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
503 | sk->sk_bound_dev_if); | 496 | sk->sk_bound_dev_if); |
504 | if (IS_ERR(rt)) | 497 | if (IS_ERR(rt)) |
505 | goto no_route; | 498 | goto no_route; |
506 | sk_setup_caps(sk, &rt->dst); | 499 | if (connected) |
500 | sk_setup_caps(sk, &rt->dst); | ||
501 | else | ||
502 | dst_release(&rt->dst); /* safe since we hold rcu_read_lock */ | ||
507 | } | 503 | } |
508 | skb_dst_set(skb, dst_clone(&rt->dst)); | 504 | |
505 | /* We dont need to clone dst here, it is guaranteed to not disappear. | ||
506 | * __dev_xmit_skb() might force a refcount if needed. | ||
507 | */ | ||
508 | skb_dst_set_noref(skb, &rt->dst); | ||
509 | 509 | ||
510 | /* Queue the packet to IP for output */ | 510 | /* Queue the packet to IP for output */ |
511 | rc = ip_queue_xmit(skb, &inet->cork.fl); | 511 | rc = ip_queue_xmit(skb, &inet->cork.fl); |
512 | rcu_read_unlock(); | ||
512 | 513 | ||
513 | error: | 514 | error: |
514 | /* Update stats */ | 515 | /* Update stats */ |
@@ -525,6 +526,7 @@ out: | |||
525 | return rc; | 526 | return rc; |
526 | 527 | ||
527 | no_route: | 528 | no_route: |
529 | rcu_read_unlock(); | ||
528 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); | 530 | IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); |
529 | kfree_skb(skb); | 531 | kfree_skb(skb); |
530 | rc = -EHOSTUNREACH; | 532 | rc = -EHOSTUNREACH; |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 39a21d0c61c..f42cd091596 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -97,7 +97,7 @@ | |||
97 | #include <net/xfrm.h> | 97 | #include <net/xfrm.h> |
98 | 98 | ||
99 | #include <asm/byteorder.h> | 99 | #include <asm/byteorder.h> |
100 | #include <asm/atomic.h> | 100 | #include <linux/atomic.h> |
101 | 101 | ||
102 | #include "l2tp_core.h" | 102 | #include "l2tp_core.h" |
103 | 103 | ||