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.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 86e5dba079fe..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++;
@@ -470,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
470 goto out; 470 goto out;
471 } 471 }
472 } 472 }
473 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);
474 pppol2tp_recv_dequeue_skb(session, skb); 479 pppol2tp_recv_dequeue_skb(session, skb);
475 spin_lock(&session->reorder_q.lock); 480 spin_lock_bh(&session->reorder_q.lock);
476 } 481 }
477 482
478out: 483out:
479 spin_unlock(&session->reorder_q.lock); 484 spin_unlock_bh(&session->reorder_q.lock);
480} 485}
481 486
482/* 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
@@ -1059,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1059 1064
1060 /* Get routing info from the tunnel socket */ 1065 /* Get routing info from the tunnel socket */
1061 dst_release(skb->dst); 1066 dst_release(skb->dst);
1062 skb->dst = sk_dst_get(sk_tun); 1067 skb->dst = dst_clone(__sk_dst_get(sk_tun));
1063 skb_orphan(skb); 1068 skb_orphan(skb);
1064 skb->sk = sk_tun; 1069 skb->sk = sk_tun;
1065 1070
@@ -1107,7 +1112,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
1107 PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, 1112 PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
1108 "%s: closing all sessions...\n", tunnel->name); 1113 "%s: closing all sessions...\n", tunnel->name);
1109 1114
1110 write_lock(&tunnel->hlist_lock); 1115 write_lock_bh(&tunnel->hlist_lock);
1111 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { 1116 for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
1112again: 1117again:
1113 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { 1118 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
@@ -1129,7 +1134,7 @@ again:
1129 * disappear as we're jumping between locks. 1134 * disappear as we're jumping between locks.
1130 */ 1135 */
1131 sock_hold(sk); 1136 sock_hold(sk);
1132 write_unlock(&tunnel->hlist_lock); 1137 write_unlock_bh(&tunnel->hlist_lock);
1133 lock_sock(sk); 1138 lock_sock(sk);
1134 1139
1135 if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { 1140 if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -1154,11 +1159,11 @@ again:
1154 * list so we are guaranteed to make forward 1159 * list so we are guaranteed to make forward
1155 * progress. 1160 * progress.
1156 */ 1161 */
1157 write_lock(&tunnel->hlist_lock); 1162 write_lock_bh(&tunnel->hlist_lock);
1158 goto again; 1163 goto again;
1159 } 1164 }
1160 } 1165 }
1161 write_unlock(&tunnel->hlist_lock); 1166 write_unlock_bh(&tunnel->hlist_lock);
1162} 1167}
1163 1168
1164/* Really kill the tunnel. 1169/* Really kill the tunnel.
@@ -1167,9 +1172,9 @@ again:
1167static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) 1172static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
1168{ 1173{
1169 /* Remove from socket list */ 1174 /* Remove from socket list */
1170 write_lock(&pppol2tp_tunnel_list_lock); 1175 write_lock_bh(&pppol2tp_tunnel_list_lock);
1171 list_del_init(&tunnel->list); 1176 list_del_init(&tunnel->list);
1172 write_unlock(&pppol2tp_tunnel_list_lock); 1177 write_unlock_bh(&pppol2tp_tunnel_list_lock);
1173 1178
1174 atomic_dec(&pppol2tp_tunnel_count); 1179 atomic_dec(&pppol2tp_tunnel_count);
1175 kfree(tunnel); 1180 kfree(tunnel);
@@ -1245,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk)
1245 /* Delete the session socket from the 1250 /* Delete the session socket from the
1246 * hash 1251 * hash
1247 */ 1252 */
1248 write_lock(&tunnel->hlist_lock); 1253 write_lock_bh(&tunnel->hlist_lock);
1249 hlist_del_init(&session->hlist); 1254 hlist_del_init(&session->hlist);
1250 write_unlock(&tunnel->hlist_lock); 1255 write_unlock_bh(&tunnel->hlist_lock);
1251 1256
1252 atomic_dec(&pppol2tp_session_count); 1257 atomic_dec(&pppol2tp_session_count);
1253 } 1258 }
@@ -1392,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
1392 1397
1393 /* Add tunnel to our list */ 1398 /* Add tunnel to our list */
1394 INIT_LIST_HEAD(&tunnel->list); 1399 INIT_LIST_HEAD(&tunnel->list);
1395 write_lock(&pppol2tp_tunnel_list_lock); 1400 write_lock_bh(&pppol2tp_tunnel_list_lock);
1396 list_add(&tunnel->list, &pppol2tp_tunnel_list); 1401 list_add(&tunnel->list, &pppol2tp_tunnel_list);
1397 write_unlock(&pppol2tp_tunnel_list_lock); 1402 write_unlock_bh(&pppol2tp_tunnel_list_lock);
1398 atomic_inc(&pppol2tp_tunnel_count); 1403 atomic_inc(&pppol2tp_tunnel_count);
1399 1404
1400 /* Bump the reference count. The tunnel context is deleted 1405 /* Bump the reference count. The tunnel context is deleted
@@ -1599,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1599 sk->sk_user_data = session; 1604 sk->sk_user_data = session;
1600 1605
1601 /* Add session to the tunnel's hash list */ 1606 /* Add session to the tunnel's hash list */
1602 write_lock(&tunnel->hlist_lock); 1607 write_lock_bh(&tunnel->hlist_lock);
1603 hlist_add_head(&session->hlist, 1608 hlist_add_head(&session->hlist,
1604 pppol2tp_session_id_hash(tunnel, 1609 pppol2tp_session_id_hash(tunnel,
1605 session->tunnel_addr.s_session)); 1610 session->tunnel_addr.s_session));
1606 write_unlock(&tunnel->hlist_lock); 1611 write_unlock_bh(&tunnel->hlist_lock);
1607 1612
1608 atomic_inc(&pppol2tp_session_count); 1613 atomic_inc(&pppol2tp_session_count);
1609 1614
@@ -2205,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
2205 int next = 0; 2210 int next = 0;
2206 int i; 2211 int i;
2207 2212
2208 read_lock(&tunnel->hlist_lock); 2213 read_lock_bh(&tunnel->hlist_lock);
2209 for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { 2214 for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
2210 hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { 2215 hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
2211 if (curr == NULL) { 2216 if (curr == NULL) {
@@ -2223,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
2223 } 2228 }
2224 } 2229 }
2225out: 2230out:
2226 read_unlock(&tunnel->hlist_lock); 2231 read_unlock_bh(&tunnel->hlist_lock);
2227 if (!found) 2232 if (!found)
2228 session = NULL; 2233 session = NULL;
2229 2234
@@ -2234,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
2234{ 2239{
2235 struct pppol2tp_tunnel *tunnel = NULL; 2240 struct pppol2tp_tunnel *tunnel = NULL;
2236 2241
2237 read_lock(&pppol2tp_tunnel_list_lock); 2242 read_lock_bh(&pppol2tp_tunnel_list_lock);
2238 if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { 2243 if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
2239 goto out; 2244 goto out;
2240 } 2245 }
2241 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); 2246 tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
2242out: 2247out:
2243 read_unlock(&pppol2tp_tunnel_list_lock); 2248 read_unlock_bh(&pppol2tp_tunnel_list_lock);
2244 2249
2245 return tunnel; 2250 return tunnel;
2246} 2251}