aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp
diff options
context:
space:
mode:
Diffstat (limited to 'net/l2tp')
-rw-r--r--net/l2tp/l2tp_core.c28
-rw-r--r--net/l2tp/l2tp_ip.c52
-rw-r--r--net/l2tp/l2tp_netlink.c3
3 files changed, 56 insertions, 27 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index c64ce0a0bb03..ed8a2335442f 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -954,7 +954,7 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
954} 954}
955 955
956static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, 956static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
957 size_t data_len) 957 struct flowi *fl, size_t data_len)
958{ 958{
959 struct l2tp_tunnel *tunnel = session->tunnel; 959 struct l2tp_tunnel *tunnel = session->tunnel;
960 unsigned int len = skb->len; 960 unsigned int len = skb->len;
@@ -987,7 +987,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
987 987
988 /* Queue the packet to IP for output */ 988 /* Queue the packet to IP for output */
989 skb->local_df = 1; 989 skb->local_df = 1;
990 error = ip_queue_xmit(skb); 990 error = ip_queue_xmit(skb, fl);
991 991
992 /* Update stats */ 992 /* Update stats */
993 if (error >= 0) { 993 if (error >= 0) {
@@ -1028,6 +1028,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1028 int data_len = skb->len; 1028 int data_len = skb->len;
1029 struct l2tp_tunnel *tunnel = session->tunnel; 1029 struct l2tp_tunnel *tunnel = session->tunnel;
1030 struct sock *sk = tunnel->sock; 1030 struct sock *sk = tunnel->sock;
1031 struct flowi *fl;
1031 struct udphdr *uh; 1032 struct udphdr *uh;
1032 struct inet_sock *inet; 1033 struct inet_sock *inet;
1033 __wsum csum; 1034 __wsum csum;
@@ -1060,14 +1061,21 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1060 IPSKB_REROUTED); 1061 IPSKB_REROUTED);
1061 nf_reset(skb); 1062 nf_reset(skb);
1062 1063
1064 bh_lock_sock(sk);
1065 if (sock_owned_by_user(sk)) {
1066 dev_kfree_skb(skb);
1067 goto out_unlock;
1068 }
1069
1063 /* Get routing info from the tunnel socket */ 1070 /* Get routing info from the tunnel socket */
1064 skb_dst_drop(skb); 1071 skb_dst_drop(skb);
1065 skb_dst_set(skb, dst_clone(__sk_dst_get(sk))); 1072 skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
1066 1073
1074 inet = inet_sk(sk);
1075 fl = &inet->cork.fl;
1067 switch (tunnel->encap) { 1076 switch (tunnel->encap) {
1068 case L2TP_ENCAPTYPE_UDP: 1077 case L2TP_ENCAPTYPE_UDP:
1069 /* Setup UDP header */ 1078 /* Setup UDP header */
1070 inet = inet_sk(sk);
1071 __skb_push(skb, sizeof(*uh)); 1079 __skb_push(skb, sizeof(*uh));
1072 skb_reset_transport_header(skb); 1080 skb_reset_transport_header(skb);
1073 uh = udp_hdr(skb); 1081 uh = udp_hdr(skb);
@@ -1105,7 +1113,9 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1105 1113
1106 l2tp_skb_set_owner_w(skb, sk); 1114 l2tp_skb_set_owner_w(skb, sk);
1107 1115
1108 l2tp_xmit_core(session, skb, data_len); 1116 l2tp_xmit_core(session, skb, fl, data_len);
1117out_unlock:
1118 bh_unlock_sock(sk);
1109 1119
1110abort: 1120abort:
1111 return 0; 1121 return 0;
@@ -1425,16 +1435,15 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
1425 1435
1426 /* Add tunnel to our list */ 1436 /* Add tunnel to our list */
1427 INIT_LIST_HEAD(&tunnel->list); 1437 INIT_LIST_HEAD(&tunnel->list);
1428 spin_lock_bh(&pn->l2tp_tunnel_list_lock);
1429 list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
1430 spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
1431 synchronize_rcu();
1432 atomic_inc(&l2tp_tunnel_count); 1438 atomic_inc(&l2tp_tunnel_count);
1433 1439
1434 /* Bump the reference count. The tunnel context is deleted 1440 /* Bump the reference count. The tunnel context is deleted
1435 * only when this drops to zero. 1441 * only when this drops to zero. Must be done before list insertion
1436 */ 1442 */
1437 l2tp_tunnel_inc_refcount(tunnel); 1443 l2tp_tunnel_inc_refcount(tunnel);
1444 spin_lock_bh(&pn->l2tp_tunnel_list_lock);
1445 list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
1446 spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
1438 1447
1439 err = 0; 1448 err = 0;
1440err: 1449err:
@@ -1626,7 +1635,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
1626 hlist_add_head_rcu(&session->global_hlist, 1635 hlist_add_head_rcu(&session->global_hlist,
1627 l2tp_session_id_hash_2(pn, session_id)); 1636 l2tp_session_id_hash_2(pn, session_id));
1628 spin_unlock_bh(&pn->l2tp_session_hlist_lock); 1637 spin_unlock_bh(&pn->l2tp_session_hlist_lock);
1629 synchronize_rcu();
1630 } 1638 }
1631 1639
1632 /* Ignore management session in session count value */ 1640 /* Ignore management session in session count value */
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 5c04f3e42704..b6466e71f5e1 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -296,12 +296,12 @@ out_in_use:
296 296
297static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 297static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
298{ 298{
299 int rc;
300 struct inet_sock *inet = inet_sk(sk);
301 struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr; 299 struct sockaddr_l2tpip *lsa = (struct sockaddr_l2tpip *) uaddr;
300 struct inet_sock *inet = inet_sk(sk);
301 struct flowi4 *fl4;
302 struct rtable *rt; 302 struct rtable *rt;
303 __be32 saddr; 303 __be32 saddr;
304 int oif; 304 int oif, rc;
305 305
306 rc = -EINVAL; 306 rc = -EINVAL;
307 if (addr_len < sizeof(*lsa)) 307 if (addr_len < sizeof(*lsa))
@@ -311,6 +311,8 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
311 if (lsa->l2tp_family != AF_INET) 311 if (lsa->l2tp_family != AF_INET)
312 goto out; 312 goto out;
313 313
314 lock_sock(sk);
315
314 sk_dst_reset(sk); 316 sk_dst_reset(sk);
315 317
316 oif = sk->sk_bound_dev_if; 318 oif = sk->sk_bound_dev_if;
@@ -320,7 +322,8 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
320 if (ipv4_is_multicast(lsa->l2tp_addr.s_addr)) 322 if (ipv4_is_multicast(lsa->l2tp_addr.s_addr))
321 goto out; 323 goto out;
322 324
323 rt = ip_route_connect(lsa->l2tp_addr.s_addr, saddr, 325 fl4 = &inet->cork.fl.u.ip4;
326 rt = ip_route_connect(fl4, lsa->l2tp_addr.s_addr, saddr,
324 RT_CONN_FLAGS(sk), oif, 327 RT_CONN_FLAGS(sk), oif,
325 IPPROTO_L2TP, 328 IPPROTO_L2TP,
326 0, 0, sk, true); 329 0, 0, sk, true);
@@ -340,10 +343,10 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
340 l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id; 343 l2tp_ip_sk(sk)->peer_conn_id = lsa->l2tp_conn_id;
341 344
342 if (!inet->inet_saddr) 345 if (!inet->inet_saddr)
343 inet->inet_saddr = rt->rt_src; 346 inet->inet_saddr = fl4->saddr;
344 if (!inet->inet_rcv_saddr) 347 if (!inet->inet_rcv_saddr)
345 inet->inet_rcv_saddr = rt->rt_src; 348 inet->inet_rcv_saddr = fl4->saddr;
346 inet->inet_daddr = rt->rt_dst; 349 inet->inet_daddr = fl4->daddr;
347 sk->sk_state = TCP_ESTABLISHED; 350 sk->sk_state = TCP_ESTABLISHED;
348 inet->inet_id = jiffies; 351 inet->inet_id = jiffies;
349 352
@@ -356,6 +359,7 @@ static int l2tp_ip_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
356 359
357 rc = 0; 360 rc = 0;
358out: 361out:
362 release_sock(sk);
359 return rc; 363 return rc;
360} 364}
361 365
@@ -416,23 +420,28 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
416 int rc; 420 int rc;
417 struct l2tp_ip_sock *lsa = l2tp_ip_sk(sk); 421 struct l2tp_ip_sock *lsa = l2tp_ip_sk(sk);
418 struct inet_sock *inet = inet_sk(sk); 422 struct inet_sock *inet = inet_sk(sk);
419 struct ip_options *opt = inet->opt;
420 struct rtable *rt = NULL; 423 struct rtable *rt = NULL;
424 struct flowi4 *fl4;
421 int connected = 0; 425 int connected = 0;
422 __be32 daddr; 426 __be32 daddr;
423 427
428 lock_sock(sk);
429
430 rc = -ENOTCONN;
424 if (sock_flag(sk, SOCK_DEAD)) 431 if (sock_flag(sk, SOCK_DEAD))
425 return -ENOTCONN; 432 goto out;
426 433
427 /* Get and verify the address. */ 434 /* Get and verify the address. */
428 if (msg->msg_name) { 435 if (msg->msg_name) {
429 struct sockaddr_l2tpip *lip = (struct sockaddr_l2tpip *) msg->msg_name; 436 struct sockaddr_l2tpip *lip = (struct sockaddr_l2tpip *) msg->msg_name;
437 rc = -EINVAL;
430 if (msg->msg_namelen < sizeof(*lip)) 438 if (msg->msg_namelen < sizeof(*lip))
431 return -EINVAL; 439 goto out;
432 440
433 if (lip->l2tp_family != AF_INET) { 441 if (lip->l2tp_family != AF_INET) {
442 rc = -EAFNOSUPPORT;
434 if (lip->l2tp_family != AF_UNSPEC) 443 if (lip->l2tp_family != AF_UNSPEC)
435 return -EAFNOSUPPORT; 444 goto out;
436 } 445 }
437 446
438 daddr = lip->l2tp_addr.s_addr; 447 daddr = lip->l2tp_addr.s_addr;
@@ -467,19 +476,27 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
467 goto error; 476 goto error;
468 } 477 }
469 478
479 fl4 = &inet->cork.fl.u.ip4;
470 if (connected) 480 if (connected)
471 rt = (struct rtable *) __sk_dst_check(sk, 0); 481 rt = (struct rtable *) __sk_dst_check(sk, 0);
472 482
473 if (rt == NULL) { 483 if (rt == NULL) {
484 struct ip_options_rcu *inet_opt;
485
486 rcu_read_lock();
487 inet_opt = rcu_dereference(inet->inet_opt);
488
474 /* Use correct destination address if we have options. */ 489 /* Use correct destination address if we have options. */
475 if (opt && opt->srr) 490 if (inet_opt && inet_opt->opt.srr)
476 daddr = opt->faddr; 491 daddr = inet_opt->opt.faddr;
492
493 rcu_read_unlock();
477 494
478 /* If this fails, retransmit mechanism of transport layer will 495 /* If this fails, retransmit mechanism of transport layer will
479 * keep trying until route appears or the connection times 496 * keep trying until route appears or the connection times
480 * itself out. 497 * itself out.
481 */ 498 */
482 rt = ip_route_output_ports(sock_net(sk), sk, 499 rt = ip_route_output_ports(sock_net(sk), fl4, sk,
483 daddr, inet->inet_saddr, 500 daddr, inet->inet_saddr,
484 inet->inet_dport, inet->inet_sport, 501 inet->inet_dport, inet->inet_sport,
485 sk->sk_protocol, RT_CONN_FLAGS(sk), 502 sk->sk_protocol, RT_CONN_FLAGS(sk),
@@ -491,7 +508,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
491 skb_dst_set(skb, dst_clone(&rt->dst)); 508 skb_dst_set(skb, dst_clone(&rt->dst));
492 509
493 /* Queue the packet to IP for output */ 510 /* Queue the packet to IP for output */
494 rc = ip_queue_xmit(skb); 511 rc = ip_queue_xmit(skb, &inet->cork.fl);
495 512
496error: 513error:
497 /* Update stats */ 514 /* Update stats */
@@ -503,12 +520,15 @@ error:
503 lsa->tx_errors++; 520 lsa->tx_errors++;
504 } 521 }
505 522
523out:
524 release_sock(sk);
506 return rc; 525 return rc;
507 526
508no_route: 527no_route:
509 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 528 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
510 kfree_skb(skb); 529 kfree_skb(skb);
511 return -EHOSTUNREACH; 530 rc = -EHOSTUNREACH;
531 goto out;
512} 532}
513 533
514static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 534static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 4c1e540732d7..93a41a09458b 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -795,11 +795,12 @@ int l2tp_nl_register_ops(enum l2tp_pwtype pw_type, const struct l2tp_nl_cmd_ops
795 goto out; 795 goto out;
796 796
797 l2tp_nl_cmd_ops[pw_type] = ops; 797 l2tp_nl_cmd_ops[pw_type] = ops;
798 ret = 0;
798 799
799out: 800out:
800 genl_unlock(); 801 genl_unlock();
801err: 802err:
802 return 0; 803 return ret;
803} 804}
804EXPORT_SYMBOL_GPL(l2tp_nl_register_ops); 805EXPORT_SYMBOL_GPL(l2tp_nl_register_ops);
805 806