aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pppol2tp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r--drivers/net/pppol2tp.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index e0b072d9fdb7..3d10ca050b79 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
302 struct pppol2tp_session *session; 302 struct pppol2tp_session *session;
303 struct hlist_node *walk; 303 struct hlist_node *walk;
304 304
305 read_lock(&tunnel->hlist_lock); 305 read_lock_bh(&tunnel->hlist_lock);
306 hlist_for_each_entry(session, walk, session_list, hlist) { 306 hlist_for_each_entry(session, walk, session_list, hlist) {
307 if (session->tunnel_addr.s_session == session_id) { 307 if (session->tunnel_addr.s_session == session_id) {
308 read_unlock(&tunnel->hlist_lock); 308 read_unlock_bh(&tunnel->hlist_lock);
309 return session; 309 return session;
310 } 310 }
311 } 311 }
312 read_unlock(&tunnel->hlist_lock); 312 read_unlock_bh(&tunnel->hlist_lock);
313 313
314 return NULL; 314 return NULL;
315} 315}
@@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
320{ 320{
321 struct pppol2tp_tunnel *tunnel = NULL; 321 struct pppol2tp_tunnel *tunnel = NULL;
322 322
323 read_lock(&pppol2tp_tunnel_list_lock); 323 read_lock_bh(&pppol2tp_tunnel_list_lock);
324 list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { 324 list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
325 if (tunnel->stats.tunnel_id == tunnel_id) { 325 if (tunnel->stats.tunnel_id == tunnel_id) {
326 read_unlock(&pppol2tp_tunnel_list_lock); 326 read_unlock_bh(&pppol2tp_tunnel_list_lock);
327 return tunnel; 327 return tunnel;
328 } 328 }
329 } 329 }
330 read_unlock(&pppol2tp_tunnel_list_lock); 330 read_unlock_bh(&pppol2tp_tunnel_list_lock);
331 331
332 return NULL; 332 return NULL;
333} 333}
@@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
342static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb) 342static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
343{ 343{
344 struct sk_buff *skbp; 344 struct sk_buff *skbp;
345 struct sk_buff *tmp;
345 u16 ns = PPPOL2TP_SKB_CB(skb)->ns; 346 u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
346 347
347 spin_lock(&session->reorder_q.lock); 348 spin_lock_bh(&session->reorder_q.lock);
348 skb_queue_walk(&session->reorder_q, skbp) { 349 skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
349 if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { 350 if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
350 __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); 351 __skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
351 PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, 352 PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
@@ -360,7 +361,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_
360 __skb_queue_tail(&session->reorder_q, skb); 361 __skb_queue_tail(&session->reorder_q, skb);
361 362
362out: 363out:
363 spin_unlock(&session->reorder_q.lock); 364 spin_unlock_bh(&session->reorder_q.lock);
364} 365}
365 366
366/* Dequeue a single skb. 367/* Dequeue a single skb.
@@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s
371 int length = PPPOL2TP_SKB_CB(skb)->length; 372 int length = PPPOL2TP_SKB_CB(skb)->length;
372 struct sock *session_sock = NULL; 373 struct sock *session_sock = NULL;
373 374
374 /* We're about to requeue the skb, so unlink it and return resources 375 /* We're about to requeue the skb, so return resources
375 * to its current owner (a socket receive buffer). 376 * to its current owner (a socket receive buffer).
376 */ 377 */
377 skb_unlink(skb, &session->reorder_q);
378 skb_orphan(skb); 378 skb_orphan(skb);
379 379
380 tunnel->stats.rx_packets++; 380 tunnel->stats.rx_packets++;
@@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
442 * expect to send up next, dequeue it and any other 442 * expect to send up next, dequeue it and any other
443 * in-sequence packets behind it. 443 * in-sequence packets behind it.
444 */ 444 */
445 spin_lock(&session->reorder_q.lock); 445 spin_lock_bh(&session->reorder_q.lock);
446 skb_queue_walk_safe(&session->reorder_q, skb, tmp) { 446 skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
447 if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) { 447 if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) {
448 session->stats.rx_seq_discards++; 448 session->stats.rx_seq_discards++;
@@ -455,6 +455,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
455 skb_queue_len(&session->reorder_q)); 455 skb_queue_len(&session->reorder_q));
456 __skb_unlink(skb, &session->reorder_q); 456 __skb_unlink(skb, &session->reorder_q);
457 kfree_skb(skb); 457 kfree_skb(skb);
458 sock_put(session->sock);
458 continue; 459 continue;
459 } 460 }
460 461
@@ -469,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
469 goto out; 470 goto out;
470 } 471 }
471 } 472 }
472 spin_unlock(&session->reorder_q.lock); 473 __skb_unlink(skb, &session->reorder_q);
474
475 /* Process the skb. We release the queue lock while we
476 * do so to let other contexts process the queue.
477 */
478 spin_unlock_bh(&session->reorder_q.lock);
473 pppol2tp_recv_dequeue_skb(session, skb); 479 pppol2tp_recv_dequeue_skb(session, skb);
474 spin_lock(&session->reorder_q.lock); 480 spin_lock_bh(&session->reorder_q.lock);
475 } 481 }
476 482
477out: 483out:
478 spin_unlock(&session->reorder_q.lock); 484 spin_unlock_bh(&session->reorder_q.lock);
479} 485}
480 486
481/* Internal receive frame. Do the real work of receiving an L2TP data frame 487/* Internal receive frame. Do the real work of receiving an L2TP data frame
@@ -1058,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1058 1064
1059 /* Get routing info from the tunnel socket */ 1065 /* Get routing info from the tunnel socket */
1060 dst_release(skb->dst); 1066 dst_release(skb->dst);
1061 skb->dst = sk_dst_get(sk_tun); 1067 skb->dst = dst_clone(__sk_dst_get(sk_tun));
1062 skb_orphan(skb); 1068 skb_orphan(skb);
1063 skb->sk = sk_tun; 1069 skb->sk = sk_tun;
1064 1070
@@ -1106,10 +1112,12 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
1106 PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, 1112 PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
1107 "%s: closing all sessions...\n", tunnel->name); 1113 "%s: closing all sessions...\n", tunnel->name);
1108 1114
1109 write_lock(&tunnel->hlist_lock); 1115 write_lock_bh(&tunnel->hlist_lock);
1110 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { 1116 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
1111again: 1117again:
1112 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { 1118 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
1119 struct sk_buff *skb;
1120
1113 session = hlist_entry(walk, struct pppol2tp_session, hlist); 1121 session = hlist_entry(walk, struct pppol2tp_session, hlist);
1114 1122
1115 sk = session->sock; 1123 sk = session->sock;
@@ -1126,7 +1134,7 @@ again:
1126 * disappear as we're jumping between locks. 1134 * disappear as we're jumping between locks.
1127 */ 1135 */
1128 sock_hold(sk); 1136 sock_hold(sk);
1129 write_unlock(&tunnel->hlist_lock); 1137 write_unlock_bh(&tunnel->hlist_lock);
1130 lock_sock(sk); 1138 lock_sock(sk);
1131 1139
1132 if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { 1140 if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -1138,7 +1146,10 @@ again:
1138 /* Purge any queued data */ 1146 /* Purge any queued data */
1139 skb_queue_purge(&sk->sk_receive_queue); 1147 skb_queue_purge(&sk->sk_receive_queue);
1140 skb_queue_purge(&sk->sk_write_queue); 1148 skb_queue_purge(&sk->sk_write_queue);
1141 skb_queue_purge(&session->reorder_q); 1149 while ((skb = skb_dequeue(&session->reorder_q))) {
1150 kfree_skb(skb);
1151 sock_put(sk);
1152 }
1142 1153
1143 release_sock(sk); 1154 release_sock(sk);
1144 sock_put(sk); 1155 sock_put(sk);
@@ -1148,11 +1159,11 @@ again:
1148 * list so we are guaranteed to make forward 1159 * list so we are guaranteed to make forward
1149 * progress. 1160 * progress.
1150 */ 1161 */
1151 write_lock(&tunnel->hlist_lock); 1162 write_lock_bh(&tunnel->hlist_lock);
1152 goto again; 1163 goto again;
1153 } 1164 }
1154 } 1165 }
1155 write_unlock(&tunnel->hlist_lock); 1166 write_unlock_bh(&tunnel->hlist_lock);
1156} 1167}
1157 1168
1158/* Really kill the tunnel. 1169/* Really kill the tunnel.
@@ -1161,9 +1172,9 @@ again:
1161static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) 1172static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
1162{ 1173{
1163 /* Remove from socket list */ 1174 /* Remove from socket list */
1164 write_lock(&pppol2tp_tunnel_list_lock); 1175 write_lock_bh(&pppol2tp_tunnel_list_lock);
1165 list_del_init(&tunnel->list); 1176 list_del_init(&tunnel->list);
1166 write_unlock(&pppol2tp_tunnel_list_lock); 1177 write_unlock_bh(&pppol2tp_tunnel_list_lock);
1167 1178
1168 atomic_dec(&pppol2tp_tunnel_count); 1179 atomic_dec(&pppol2tp_tunnel_count);
1169 kfree(tunnel); 1180 kfree(tunnel);
@@ -1239,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk)
1239 /* Delete the session socket from the 1250 /* Delete the session socket from the
1240 * hash 1251 * hash
1241 */ 1252 */
1242 write_lock(&tunnel->hlist_lock); 1253 write_lock_bh(&tunnel->hlist_lock);
1243 hlist_del_init(&session->hlist); 1254 hlist_del_init(&session->hlist);
1244 write_unlock(&tunnel->hlist_lock); 1255 write_unlock_bh(&tunnel->hlist_lock);
1245 1256
1246 atomic_dec(&pppol2tp_session_count); 1257 atomic_dec(&pppol2tp_session_count);
1247 } 1258 }
@@ -1386,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
1386 1397
1387 /* Add tunnel to our list */ 1398 /* Add tunnel to our list */
1388 INIT_LIST_HEAD(&tunnel->list); 1399 INIT_LIST_HEAD(&tunnel->list);
1389 write_lock(&pppol2tp_tunnel_list_lock); 1400 write_lock_bh(&pppol2tp_tunnel_list_lock);
1390 list_add(&tunnel->list, &pppol2tp_tunnel_list); 1401 list_add(&tunnel->list, &pppol2tp_tunnel_list);
1391 write_unlock(&pppol2tp_tunnel_list_lock); 1402 write_unlock_bh(&pppol2tp_tunnel_list_lock);
1392 atomic_inc(&pppol2tp_tunnel_count); 1403 atomic_inc(&pppol2tp_tunnel_count);
1393 1404
1394 /* Bump the reference count. The tunnel context is deleted 1405 /* Bump the reference count. The tunnel context is deleted
@@ -1593,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1593 sk->sk_user_data = session; 1604 sk->sk_user_data = session;
1594 1605
1595 /* Add session to the tunnel's hash list */ 1606 /* Add session to the tunnel's hash list */
1596 write_lock(&tunnel->hlist_lock); 1607 write_lock_bh(&tunnel->hlist_lock);
1597 hlist_add_head(&session->hlist, 1608 hlist_add_head(&session->hlist,
1598 pppol2tp_session_id_hash(tunnel, 1609 pppol2tp_session_id_hash(tunnel,
1599 session->tunnel_addr.s_session)); 1610 session->tunnel_addr.s_session));
1600 write_unlock(&tunnel->hlist_lock); 1611 write_unlock_bh(&tunnel->hlist_lock);
1601 1612
1602 atomic_inc(&pppol2tp_session_count); 1613 atomic_inc(&pppol2tp_session_count);
1603 1614
@@ -2199,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
2199 int next = 0; 2210 int next = 0;
2200 int i; 2211 int i;
2201 2212
2202 read_lock(&tunnel->hlist_lock); 2213 read_lock_bh(&tunnel->hlist_lock);
2203 for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { 2214 for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
2204 hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { 2215 hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
2205 if (curr == NULL) { 2216 if (curr == NULL) {
@@ -2217,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
2217 } 2228 }
2218 } 2229 }
2219out: 2230out:
2220 read_unlock(&tunnel->hlist_lock); 2231 read_unlock_bh(&tunnel->hlist_lock);
2221 if (!found) 2232 if (!found)
2222 session = NULL; 2233 session = NULL;
2223 2234
@@ -2228,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
2228{ 2239{
2229 struct pppol2tp_tunnel *tunnel = NULL; 2240 struct pppol2tp_tunnel *tunnel = NULL;
2230 2241
2231 read_lock(&pppol2tp_tunnel_list_lock); 2242 read_lock_bh(&pppol2tp_tunnel_list_lock);
2232 if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { 2243 if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
2233 goto out; 2244 goto out;
2234 } 2245 }
2235 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); 2246 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
2236out: 2247out:
2237 read_unlock(&pppol2tp_tunnel_list_lock); 2248 read_unlock_bh(&pppol2tp_tunnel_list_lock);
2238 2249
2239 return tunnel; 2250 return tunnel;
2240} 2251}