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.c68
1 files changed, 27 insertions, 41 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 5910df60c93e..449a9825200d 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -232,7 +232,7 @@ static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
232static const struct proto_ops pppol2tp_ops; 232static const struct proto_ops pppol2tp_ops;
233 233
234/* per-net private data for this module */ 234/* per-net private data for this module */
235static int pppol2tp_net_id; 235static int pppol2tp_net_id __read_mostly;
236struct pppol2tp_net { 236struct pppol2tp_net {
237 struct list_head pppol2tp_tunnel_list; 237 struct list_head pppol2tp_tunnel_list;
238 rwlock_t pppol2tp_tunnel_list_lock; 238 rwlock_t pppol2tp_tunnel_list_lock;
@@ -516,7 +516,7 @@ static inline int pppol2tp_verify_udp_checksum(struct sock *sk,
516 return 0; 516 return 0;
517 517
518 inet = inet_sk(sk); 518 inet = inet_sk(sk);
519 psum = csum_tcpudp_nofold(inet->saddr, inet->daddr, ulen, 519 psum = csum_tcpudp_nofold(inet->inet_saddr, inet->inet_daddr, ulen,
520 IPPROTO_UDP, 0); 520 IPPROTO_UDP, 0);
521 521
522 if ((skb->ip_summed == CHECKSUM_COMPLETE) && 522 if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
756 756
757 /* Try to dequeue as many skbs from reorder_q as we can. */ 757 /* Try to dequeue as many skbs from reorder_q as we can. */
758 pppol2tp_recv_dequeue(session); 758 pppol2tp_recv_dequeue(session);
759 sock_put(sock);
759 760
760 return 0; 761 return 0;
761 762
@@ -772,6 +773,7 @@ discard_bad_csum:
772 UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0); 773 UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
773 tunnel->stats.rx_errors++; 774 tunnel->stats.rx_errors++;
774 kfree_skb(skb); 775 kfree_skb(skb);
776 sock_put(sock);
775 777
776 return 0; 778 return 0;
777 779
@@ -949,8 +951,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
949 inet = inet_sk(sk_tun); 951 inet = inet_sk(sk_tun);
950 udp_len = hdr_len + sizeof(ppph) + total_len; 952 udp_len = hdr_len + sizeof(ppph) + total_len;
951 uh = (struct udphdr *) skb->data; 953 uh = (struct udphdr *) skb->data;
952 uh->source = inet->sport; 954 uh->source = inet->inet_sport;
953 uh->dest = inet->dport; 955 uh->dest = inet->inet_dport;
954 uh->len = htons(udp_len); 956 uh->len = htons(udp_len);
955 uh->check = 0; 957 uh->check = 0;
956 skb_put(skb, sizeof(struct udphdr)); 958 skb_put(skb, sizeof(struct udphdr));
@@ -978,7 +980,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
978 else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { 980 else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
979 skb->ip_summed = CHECKSUM_COMPLETE; 981 skb->ip_summed = CHECKSUM_COMPLETE;
980 csum = skb_checksum(skb, 0, udp_len, 0); 982 csum = skb_checksum(skb, 0, udp_len, 0);
981 uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, 983 uh->check = csum_tcpudp_magic(inet->inet_saddr,
984 inet->inet_daddr,
982 udp_len, IPPROTO_UDP, csum); 985 udp_len, IPPROTO_UDP, csum);
983 if (uh->check == 0) 986 if (uh->check == 0)
984 uh->check = CSUM_MANGLED_0; 987 uh->check = CSUM_MANGLED_0;
@@ -986,7 +989,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
986 skb->ip_summed = CHECKSUM_PARTIAL; 989 skb->ip_summed = CHECKSUM_PARTIAL;
987 skb->csum_start = skb_transport_header(skb) - skb->head; 990 skb->csum_start = skb_transport_header(skb) - skb->head;
988 skb->csum_offset = offsetof(struct udphdr, check); 991 skb->csum_offset = offsetof(struct udphdr, check);
989 uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr, 992 uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
993 inet->inet_daddr,
990 udp_len, IPPROTO_UDP, 0); 994 udp_len, IPPROTO_UDP, 0);
991 } 995 }
992 996
@@ -1136,8 +1140,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1136 __skb_push(skb, sizeof(*uh)); 1140 __skb_push(skb, sizeof(*uh));
1137 skb_reset_transport_header(skb); 1141 skb_reset_transport_header(skb);
1138 uh = udp_hdr(skb); 1142 uh = udp_hdr(skb);
1139 uh->source = inet->sport; 1143 uh->source = inet->inet_sport;
1140 uh->dest = inet->dport; 1144 uh->dest = inet->inet_dport;
1141 uh->len = htons(udp_len); 1145 uh->len = htons(udp_len);
1142 uh->check = 0; 1146 uh->check = 0;
1143 1147
@@ -1178,10 +1182,12 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1178 /* Calculate UDP checksum if configured to do so */ 1182 /* Calculate UDP checksum if configured to do so */
1179 if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT) 1183 if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
1180 skb->ip_summed = CHECKSUM_NONE; 1184 skb->ip_summed = CHECKSUM_NONE;
1181 else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { 1185 else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1186 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
1182 skb->ip_summed = CHECKSUM_COMPLETE; 1187 skb->ip_summed = CHECKSUM_COMPLETE;
1183 csum = skb_checksum(skb, 0, udp_len, 0); 1188 csum = skb_checksum(skb, 0, udp_len, 0);
1184 uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, 1189 uh->check = csum_tcpudp_magic(inet->inet_saddr,
1190 inet->inet_daddr,
1185 udp_len, IPPROTO_UDP, csum); 1191 udp_len, IPPROTO_UDP, csum);
1186 if (uh->check == 0) 1192 if (uh->check == 0)
1187 uh->check = CSUM_MANGLED_0; 1193 uh->check = CSUM_MANGLED_0;
@@ -1189,7 +1195,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1189 skb->ip_summed = CHECKSUM_PARTIAL; 1195 skb->ip_summed = CHECKSUM_PARTIAL;
1190 skb->csum_start = skb_transport_header(skb) - skb->head; 1196 skb->csum_start = skb_transport_header(skb) - skb->head;
1191 skb->csum_offset = offsetof(struct udphdr, check); 1197 skb->csum_offset = offsetof(struct udphdr, check);
1192 uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr, 1198 uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
1199 inet->inet_daddr,
1193 udp_len, IPPROTO_UDP, 0); 1200 udp_len, IPPROTO_UDP, 0);
1194 } 1201 }
1195 1202
@@ -1533,7 +1540,7 @@ static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
1533 * if the tunnel socket goes away. 1540 * if the tunnel socket goes away.
1534 */ 1541 */
1535 tunnel->old_sk_destruct = sk->sk_destruct; 1542 tunnel->old_sk_destruct = sk->sk_destruct;
1536 sk->sk_destruct = &pppol2tp_tunnel_destruct; 1543 sk->sk_destruct = pppol2tp_tunnel_destruct;
1537 1544
1538 tunnel->sock = sk; 1545 tunnel->sock = sk;
1539 sk->sk_allocation = GFP_ATOMIC; 1546 sk->sk_allocation = GFP_ATOMIC;
@@ -1657,6 +1664,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
1657 if (tunnel_sock == NULL) 1664 if (tunnel_sock == NULL)
1658 goto end; 1665 goto end;
1659 1666
1667 sock_hold(tunnel_sock);
1660 tunnel = tunnel_sock->sk_user_data; 1668 tunnel = tunnel_sock->sk_user_data;
1661 } else { 1669 } else {
1662 tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel); 1670 tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
@@ -2601,53 +2609,31 @@ static struct pppox_proto pppol2tp_proto = {
2601 2609
2602static __net_init int pppol2tp_init_net(struct net *net) 2610static __net_init int pppol2tp_init_net(struct net *net)
2603{ 2611{
2604 struct pppol2tp_net *pn; 2612 struct pppol2tp_net *pn = pppol2tp_pernet(net);
2605 struct proc_dir_entry *pde; 2613 struct proc_dir_entry *pde;
2606 int err;
2607
2608 pn = kzalloc(sizeof(*pn), GFP_KERNEL);
2609 if (!pn)
2610 return -ENOMEM;
2611 2614
2612 INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list); 2615 INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
2613 rwlock_init(&pn->pppol2tp_tunnel_list_lock); 2616 rwlock_init(&pn->pppol2tp_tunnel_list_lock);
2614 2617
2615 err = net_assign_generic(net, pppol2tp_net_id, pn);
2616 if (err)
2617 goto out;
2618
2619 pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops); 2618 pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
2620#ifdef CONFIG_PROC_FS 2619#ifdef CONFIG_PROC_FS
2621 if (!pde) { 2620 if (!pde)
2622 err = -ENOMEM; 2621 return -ENOMEM;
2623 goto out;
2624 }
2625#endif 2622#endif
2626 2623
2627 return 0; 2624 return 0;
2628
2629out:
2630 kfree(pn);
2631 return err;
2632} 2625}
2633 2626
2634static __net_exit void pppol2tp_exit_net(struct net *net) 2627static __net_exit void pppol2tp_exit_net(struct net *net)
2635{ 2628{
2636 struct pppoe_net *pn;
2637
2638 proc_net_remove(net, "pppol2tp"); 2629 proc_net_remove(net, "pppol2tp");
2639 pn = net_generic(net, pppol2tp_net_id);
2640 /*
2641 * if someone has cached our net then
2642 * further net_generic call will return NULL
2643 */
2644 net_assign_generic(net, pppol2tp_net_id, NULL);
2645 kfree(pn);
2646} 2630}
2647 2631
2648static struct pernet_operations pppol2tp_net_ops = { 2632static struct pernet_operations pppol2tp_net_ops = {
2649 .init = pppol2tp_init_net, 2633 .init = pppol2tp_init_net,
2650 .exit = pppol2tp_exit_net, 2634 .exit = pppol2tp_exit_net,
2635 .id = &pppol2tp_net_id,
2636 .size = sizeof(struct pppol2tp_net),
2651}; 2637};
2652 2638
2653static int __init pppol2tp_init(void) 2639static int __init pppol2tp_init(void)
@@ -2661,7 +2647,7 @@ static int __init pppol2tp_init(void)
2661 if (err) 2647 if (err)
2662 goto out_unregister_pppol2tp_proto; 2648 goto out_unregister_pppol2tp_proto;
2663 2649
2664 err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops); 2650 err = register_pernet_device(&pppol2tp_net_ops);
2665 if (err) 2651 if (err)
2666 goto out_unregister_pppox_proto; 2652 goto out_unregister_pppox_proto;
2667 2653
@@ -2680,7 +2666,7 @@ out_unregister_pppol2tp_proto:
2680static void __exit pppol2tp_exit(void) 2666static void __exit pppol2tp_exit(void)
2681{ 2667{
2682 unregister_pppox_proto(PX_PROTO_OL2TP); 2668 unregister_pppox_proto(PX_PROTO_OL2TP);
2683 unregister_pernet_gen_device(pppol2tp_net_id, &pppol2tp_net_ops); 2669 unregister_pernet_device(&pppol2tp_net_ops);
2684 proto_unregister(&pppol2tp_sk_proto); 2670 proto_unregister(&pppol2tp_sk_proto);
2685} 2671}
2686 2672