aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pppol2tp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-06-04 20:39:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-06-04 20:39:33 -0400
commit3e387fcdc485d94fe2c4b52e7c30c0c4cd1fe364 (patch)
tree577de7b1aed18106b30e3e1d517b165f137e52ac /drivers/net/pppol2tp.c
parent9489a0625854cd7482bb0e8b37de4406cdcd49e0 (diff)
parent24b95685ffcdb3dc28f64b9e8af6ea3e8360fbc5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (56 commits) l2tp: Fix possible oops if transmitting or receiving when tunnel goes down tcp: Fix for race due to temporary drop of the socket lock in skb_splice_bits. tcp: Increment OUTRSTS in tcp_send_active_reset() raw: Raw socket leak. lt2p: Fix possible WARN_ON from socket code when UDP socket is closed USB ID for Philips CPWUA054/00 Wireless USB Adapter 11g ssb: Fix context assertion in ssb_pcicore_dev_irqvecs_enable libertas: fix command size for CMD_802_11_SUBSCRIBE_EVENT ipw2200: expire and use oldest BSS on adhoc create airo warning fix b43legacy: Fix controller restart crash sctp: Fix ECN markings for IPv6 sctp: Flush the queue only once during fast retransmit. sctp: Start T3-RTX timer when fast retransmitting lowest TSN sctp: Correctly implement Fast Recovery cwnd manipulations. sctp: Move sctp_v4_dst_saddr out of loop sctp: retran_path update bug fix tcp: fix skb vs fack_count out-of-sync condition sunhme: Cleanup use of deprecated calls to save_and_cli and restore_flags. xfrm: xfrm_algo: correct usage of RIPEMD-160 ...
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r--drivers/net/pppol2tp.c111
1 files changed, 88 insertions, 23 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 8db342f2fdc9..70cfdb46aa27 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -240,12 +240,15 @@ static inline struct pppol2tp_session *pppol2tp_sock_to_session(struct sock *sk)
240 if (sk == NULL) 240 if (sk == NULL)
241 return NULL; 241 return NULL;
242 242
243 sock_hold(sk);
243 session = (struct pppol2tp_session *)(sk->sk_user_data); 244 session = (struct pppol2tp_session *)(sk->sk_user_data);
244 if (session == NULL) 245 if (session == NULL) {
245 return NULL; 246 sock_put(sk);
247 goto out;
248 }
246 249
247 BUG_ON(session->magic != L2TP_SESSION_MAGIC); 250 BUG_ON(session->magic != L2TP_SESSION_MAGIC);
248 251out:
249 return session; 252 return session;
250} 253}
251 254
@@ -256,12 +259,15 @@ static inline struct pppol2tp_tunnel *pppol2tp_sock_to_tunnel(struct sock *sk)
256 if (sk == NULL) 259 if (sk == NULL)
257 return NULL; 260 return NULL;
258 261
262 sock_hold(sk);
259 tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data); 263 tunnel = (struct pppol2tp_tunnel *)(sk->sk_user_data);
260 if (tunnel == NULL) 264 if (tunnel == NULL) {
261 return NULL; 265 sock_put(sk);
266 goto out;
267 }
262 268
263 BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC); 269 BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
264 270out:
265 return tunnel; 271 return tunnel;
266} 272}
267 273
@@ -716,12 +722,14 @@ discard:
716 session->stats.rx_errors++; 722 session->stats.rx_errors++;
717 kfree_skb(skb); 723 kfree_skb(skb);
718 sock_put(session->sock); 724 sock_put(session->sock);
725 sock_put(sock);
719 726
720 return 0; 727 return 0;
721 728
722error: 729error:
723 /* Put UDP header back */ 730 /* Put UDP header back */
724 __skb_push(skb, sizeof(struct udphdr)); 731 __skb_push(skb, sizeof(struct udphdr));
732 sock_put(sock);
725 733
726no_tunnel: 734no_tunnel:
727 return 1; 735 return 1;
@@ -745,10 +753,13 @@ static int pppol2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
745 "%s: received %d bytes\n", tunnel->name, skb->len); 753 "%s: received %d bytes\n", tunnel->name, skb->len);
746 754
747 if (pppol2tp_recv_core(sk, skb)) 755 if (pppol2tp_recv_core(sk, skb))
748 goto pass_up; 756 goto pass_up_put;
749 757
758 sock_put(sk);
750 return 0; 759 return 0;
751 760
761pass_up_put:
762 sock_put(sk);
752pass_up: 763pass_up:
753 return 1; 764 return 1;
754} 765}
@@ -858,7 +869,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
858 869
859 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); 870 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
860 if (tunnel == NULL) 871 if (tunnel == NULL)
861 goto error; 872 goto error_put_sess;
862 873
863 /* What header length is configured for this session? */ 874 /* What header length is configured for this session? */
864 hdr_len = pppol2tp_l2tp_header_len(session); 875 hdr_len = pppol2tp_l2tp_header_len(session);
@@ -870,7 +881,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
870 sizeof(ppph) + total_len, 881 sizeof(ppph) + total_len,
871 0, GFP_KERNEL); 882 0, GFP_KERNEL);
872 if (!skb) 883 if (!skb)
873 goto error; 884 goto error_put_sess_tun;
874 885
875 /* Reserve space for headers. */ 886 /* Reserve space for headers. */
876 skb_reserve(skb, NET_SKB_PAD); 887 skb_reserve(skb, NET_SKB_PAD);
@@ -900,7 +911,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
900 error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); 911 error = memcpy_fromiovec(skb->data, m->msg_iov, total_len);
901 if (error < 0) { 912 if (error < 0) {
902 kfree_skb(skb); 913 kfree_skb(skb);
903 goto error; 914 goto error_put_sess_tun;
904 } 915 }
905 skb_put(skb, total_len); 916 skb_put(skb, total_len);
906 917
@@ -947,10 +958,33 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
947 session->stats.tx_errors++; 958 session->stats.tx_errors++;
948 } 959 }
949 960
961 return error;
962
963error_put_sess_tun:
964 sock_put(session->tunnel_sock);
965error_put_sess:
966 sock_put(sk);
950error: 967error:
951 return error; 968 return error;
952} 969}
953 970
971/* Automatically called when the skb is freed.
972 */
973static void pppol2tp_sock_wfree(struct sk_buff *skb)
974{
975 sock_put(skb->sk);
976}
977
978/* For data skbs that we transmit, we associate with the tunnel socket
979 * but don't do accounting.
980 */
981static inline void pppol2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
982{
983 sock_hold(sk);
984 skb->sk = sk;
985 skb->destructor = pppol2tp_sock_wfree;
986}
987
954/* Transmit function called by generic PPP driver. Sends PPP frame 988/* Transmit function called by generic PPP driver. Sends PPP frame
955 * over PPPoL2TP socket. 989 * over PPPoL2TP socket.
956 * 990 *
@@ -993,10 +1027,10 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
993 1027
994 sk_tun = session->tunnel_sock; 1028 sk_tun = session->tunnel_sock;
995 if (sk_tun == NULL) 1029 if (sk_tun == NULL)
996 goto abort; 1030 goto abort_put_sess;
997 tunnel = pppol2tp_sock_to_tunnel(sk_tun); 1031 tunnel = pppol2tp_sock_to_tunnel(sk_tun);
998 if (tunnel == NULL) 1032 if (tunnel == NULL)
999 goto abort; 1033 goto abort_put_sess;
1000 1034
1001 /* What header length is configured for this session? */ 1035 /* What header length is configured for this session? */
1002 hdr_len = pppol2tp_l2tp_header_len(session); 1036 hdr_len = pppol2tp_l2tp_header_len(session);
@@ -1009,7 +1043,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1009 sizeof(struct udphdr) + hdr_len + sizeof(ppph); 1043 sizeof(struct udphdr) + hdr_len + sizeof(ppph);
1010 old_headroom = skb_headroom(skb); 1044 old_headroom = skb_headroom(skb);
1011 if (skb_cow_head(skb, headroom)) 1045 if (skb_cow_head(skb, headroom))
1012 goto abort; 1046 goto abort_put_sess_tun;
1013 1047
1014 new_headroom = skb_headroom(skb); 1048 new_headroom = skb_headroom(skb);
1015 skb_orphan(skb); 1049 skb_orphan(skb);
@@ -1069,7 +1103,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1069 /* Get routing info from the tunnel socket */ 1103 /* Get routing info from the tunnel socket */
1070 dst_release(skb->dst); 1104 dst_release(skb->dst);
1071 skb->dst = dst_clone(__sk_dst_get(sk_tun)); 1105 skb->dst = dst_clone(__sk_dst_get(sk_tun));
1072 skb->sk = sk_tun; 1106 pppol2tp_skb_set_owner_w(skb, sk_tun);
1073 1107
1074 /* Queue the packet to IP for output */ 1108 /* Queue the packet to IP for output */
1075 len = skb->len; 1109 len = skb->len;
@@ -1086,8 +1120,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1086 session->stats.tx_errors++; 1120 session->stats.tx_errors++;
1087 } 1121 }
1088 1122
1123 sock_put(sk_tun);
1124 sock_put(sk);
1089 return 1; 1125 return 1;
1090 1126
1127abort_put_sess_tun:
1128 sock_put(sk_tun);
1129abort_put_sess:
1130 sock_put(sk);
1091abort: 1131abort:
1092 /* Free the original skb */ 1132 /* Free the original skb */
1093 kfree_skb(skb); 1133 kfree_skb(skb);
@@ -1191,7 +1231,7 @@ static void pppol2tp_tunnel_destruct(struct sock *sk)
1191{ 1231{
1192 struct pppol2tp_tunnel *tunnel; 1232 struct pppol2tp_tunnel *tunnel;
1193 1233
1194 tunnel = pppol2tp_sock_to_tunnel(sk); 1234 tunnel = sk->sk_user_data;
1195 if (tunnel == NULL) 1235 if (tunnel == NULL)
1196 goto end; 1236 goto end;
1197 1237
@@ -1230,10 +1270,12 @@ static void pppol2tp_session_destruct(struct sock *sk)
1230 if (sk->sk_user_data != NULL) { 1270 if (sk->sk_user_data != NULL) {
1231 struct pppol2tp_tunnel *tunnel; 1271 struct pppol2tp_tunnel *tunnel;
1232 1272
1233 session = pppol2tp_sock_to_session(sk); 1273 session = sk->sk_user_data;
1234 if (session == NULL) 1274 if (session == NULL)
1235 goto out; 1275 goto out;
1236 1276
1277 BUG_ON(session->magic != L2TP_SESSION_MAGIC);
1278
1237 /* Don't use pppol2tp_sock_to_tunnel() here to 1279 /* Don't use pppol2tp_sock_to_tunnel() here to
1238 * get the tunnel context because the tunnel 1280 * get the tunnel context because the tunnel
1239 * socket might have already been closed (its 1281 * socket might have already been closed (its
@@ -1279,6 +1321,7 @@ out:
1279static int pppol2tp_release(struct socket *sock) 1321static int pppol2tp_release(struct socket *sock)
1280{ 1322{
1281 struct sock *sk = sock->sk; 1323 struct sock *sk = sock->sk;
1324 struct pppol2tp_session *session;
1282 int error; 1325 int error;
1283 1326
1284 if (!sk) 1327 if (!sk)
@@ -1296,9 +1339,18 @@ static int pppol2tp_release(struct socket *sock)
1296 sock_orphan(sk); 1339 sock_orphan(sk);
1297 sock->sk = NULL; 1340 sock->sk = NULL;
1298 1341
1342 session = pppol2tp_sock_to_session(sk);
1343
1299 /* Purge any queued data */ 1344 /* Purge any queued data */
1300 skb_queue_purge(&sk->sk_receive_queue); 1345 skb_queue_purge(&sk->sk_receive_queue);
1301 skb_queue_purge(&sk->sk_write_queue); 1346 skb_queue_purge(&sk->sk_write_queue);
1347 if (session != NULL) {
1348 struct sk_buff *skb;
1349 while ((skb = skb_dequeue(&session->reorder_q))) {
1350 kfree_skb(skb);
1351 sock_put(sk);
1352 }
1353 }
1302 1354
1303 release_sock(sk); 1355 release_sock(sk);
1304 1356
@@ -1601,7 +1653,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1601 1653
1602 error = ppp_register_channel(&po->chan); 1654 error = ppp_register_channel(&po->chan);
1603 if (error) 1655 if (error)
1604 goto end; 1656 goto end_put_tun;
1605 1657
1606 /* This is how we get the session context from the socket. */ 1658 /* This is how we get the session context from the socket. */
1607 sk->sk_user_data = session; 1659 sk->sk_user_data = session;
@@ -1621,6 +1673,8 @@ out_no_ppp:
1621 PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, 1673 PRINTK(session->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
1622 "%s: created\n", session->name); 1674 "%s: created\n", session->name);
1623 1675
1676end_put_tun:
1677 sock_put(tunnel_sock);
1624end: 1678end:
1625 release_sock(sk); 1679 release_sock(sk);
1626 1680
@@ -1668,6 +1722,7 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
1668 *usockaddr_len = len; 1722 *usockaddr_len = len;
1669 1723
1670 error = 0; 1724 error = 0;
1725 sock_put(sock->sk);
1671 1726
1672end: 1727end:
1673 return error; 1728 return error;
@@ -1906,14 +1961,17 @@ static int pppol2tp_ioctl(struct socket *sock, unsigned int cmd,
1906 err = -EBADF; 1961 err = -EBADF;
1907 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); 1962 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
1908 if (tunnel == NULL) 1963 if (tunnel == NULL)
1909 goto end; 1964 goto end_put_sess;
1910 1965
1911 err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg); 1966 err = pppol2tp_tunnel_ioctl(tunnel, cmd, arg);
1912 goto end; 1967 sock_put(session->tunnel_sock);
1968 goto end_put_sess;
1913 } 1969 }
1914 1970
1915 err = pppol2tp_session_ioctl(session, cmd, arg); 1971 err = pppol2tp_session_ioctl(session, cmd, arg);
1916 1972
1973end_put_sess:
1974 sock_put(sk);
1917end: 1975end:
1918 return err; 1976 return err;
1919} 1977}
@@ -2059,14 +2117,17 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
2059 err = -EBADF; 2117 err = -EBADF;
2060 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); 2118 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
2061 if (tunnel == NULL) 2119 if (tunnel == NULL)
2062 goto end; 2120 goto end_put_sess;
2063 2121
2064 err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val); 2122 err = pppol2tp_tunnel_setsockopt(sk, tunnel, optname, val);
2123 sock_put(session->tunnel_sock);
2065 } else 2124 } else
2066 err = pppol2tp_session_setsockopt(sk, session, optname, val); 2125 err = pppol2tp_session_setsockopt(sk, session, optname, val);
2067 2126
2068 err = 0; 2127 err = 0;
2069 2128
2129end_put_sess:
2130 sock_put(sk);
2070end: 2131end:
2071 return err; 2132 return err;
2072} 2133}
@@ -2181,20 +2242,24 @@ static int pppol2tp_getsockopt(struct socket *sock, int level,
2181 err = -EBADF; 2242 err = -EBADF;
2182 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); 2243 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock);
2183 if (tunnel == NULL) 2244 if (tunnel == NULL)
2184 goto end; 2245 goto end_put_sess;
2185 2246
2186 err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val); 2247 err = pppol2tp_tunnel_getsockopt(sk, tunnel, optname, &val);
2248 sock_put(session->tunnel_sock);
2187 } else 2249 } else
2188 err = pppol2tp_session_getsockopt(sk, session, optname, &val); 2250 err = pppol2tp_session_getsockopt(sk, session, optname, &val);
2189 2251
2190 err = -EFAULT; 2252 err = -EFAULT;
2191 if (put_user(len, (int __user *) optlen)) 2253 if (put_user(len, (int __user *) optlen))
2192 goto end; 2254 goto end_put_sess;
2193 2255
2194 if (copy_to_user((void __user *) optval, &val, len)) 2256 if (copy_to_user((void __user *) optval, &val, len))
2195 goto end; 2257 goto end_put_sess;
2196 2258
2197 err = 0; 2259 err = 0;
2260
2261end_put_sess:
2262 sock_put(sk);
2198end: 2263end:
2199 return err; 2264 return err;
2200} 2265}