diff options
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r-- | drivers/net/pppol2tp.c | 68 |
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 }; | |||
232 | static const struct proto_ops pppol2tp_ops; | 232 | static const struct proto_ops pppol2tp_ops; |
233 | 233 | ||
234 | /* per-net private data for this module */ | 234 | /* per-net private data for this module */ |
235 | static int pppol2tp_net_id; | 235 | static int pppol2tp_net_id __read_mostly; |
236 | struct pppol2tp_net { | 236 | struct 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 | ||
2602 | static __net_init int pppol2tp_init_net(struct net *net) | 2610 | static __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 | |||
2629 | out: | ||
2630 | kfree(pn); | ||
2631 | return err; | ||
2632 | } | 2625 | } |
2633 | 2626 | ||
2634 | static __net_exit void pppol2tp_exit_net(struct net *net) | 2627 | static __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 | ||
2648 | static struct pernet_operations pppol2tp_net_ops = { | 2632 | static 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 | ||
2653 | static int __init pppol2tp_init(void) | 2639 | static 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: | |||
2680 | static void __exit pppol2tp_exit(void) | 2666 | static 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 | ||