diff options
Diffstat (limited to 'drivers/net/pppol2tp.c')
-rw-r--r-- | drivers/net/pppol2tp.c | 62 |
1 files changed, 22 insertions, 40 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5910df60c93e..9fbb2eba9a06 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) && |
@@ -949,8 +949,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
949 | inet = inet_sk(sk_tun); | 949 | inet = inet_sk(sk_tun); |
950 | udp_len = hdr_len + sizeof(ppph) + total_len; | 950 | udp_len = hdr_len + sizeof(ppph) + total_len; |
951 | uh = (struct udphdr *) skb->data; | 951 | uh = (struct udphdr *) skb->data; |
952 | uh->source = inet->sport; | 952 | uh->source = inet->inet_sport; |
953 | uh->dest = inet->dport; | 953 | uh->dest = inet->inet_dport; |
954 | uh->len = htons(udp_len); | 954 | uh->len = htons(udp_len); |
955 | uh->check = 0; | 955 | uh->check = 0; |
956 | skb_put(skb, sizeof(struct udphdr)); | 956 | skb_put(skb, sizeof(struct udphdr)); |
@@ -978,7 +978,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)) { | 978 | else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { |
979 | skb->ip_summed = CHECKSUM_COMPLETE; | 979 | skb->ip_summed = CHECKSUM_COMPLETE; |
980 | csum = skb_checksum(skb, 0, udp_len, 0); | 980 | csum = skb_checksum(skb, 0, udp_len, 0); |
981 | uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, | 981 | uh->check = csum_tcpudp_magic(inet->inet_saddr, |
982 | inet->inet_daddr, | ||
982 | udp_len, IPPROTO_UDP, csum); | 983 | udp_len, IPPROTO_UDP, csum); |
983 | if (uh->check == 0) | 984 | if (uh->check == 0) |
984 | uh->check = CSUM_MANGLED_0; | 985 | uh->check = CSUM_MANGLED_0; |
@@ -986,7 +987,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
986 | skb->ip_summed = CHECKSUM_PARTIAL; | 987 | skb->ip_summed = CHECKSUM_PARTIAL; |
987 | skb->csum_start = skb_transport_header(skb) - skb->head; | 988 | skb->csum_start = skb_transport_header(skb) - skb->head; |
988 | skb->csum_offset = offsetof(struct udphdr, check); | 989 | skb->csum_offset = offsetof(struct udphdr, check); |
989 | uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr, | 990 | uh->check = ~csum_tcpudp_magic(inet->inet_saddr, |
991 | inet->inet_daddr, | ||
990 | udp_len, IPPROTO_UDP, 0); | 992 | udp_len, IPPROTO_UDP, 0); |
991 | } | 993 | } |
992 | 994 | ||
@@ -1136,8 +1138,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1136 | __skb_push(skb, sizeof(*uh)); | 1138 | __skb_push(skb, sizeof(*uh)); |
1137 | skb_reset_transport_header(skb); | 1139 | skb_reset_transport_header(skb); |
1138 | uh = udp_hdr(skb); | 1140 | uh = udp_hdr(skb); |
1139 | uh->source = inet->sport; | 1141 | uh->source = inet->inet_sport; |
1140 | uh->dest = inet->dport; | 1142 | uh->dest = inet->inet_dport; |
1141 | uh->len = htons(udp_len); | 1143 | uh->len = htons(udp_len); |
1142 | uh->check = 0; | 1144 | uh->check = 0; |
1143 | 1145 | ||
@@ -1181,7 +1183,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1181 | else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { | 1183 | else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) { |
1182 | skb->ip_summed = CHECKSUM_COMPLETE; | 1184 | skb->ip_summed = CHECKSUM_COMPLETE; |
1183 | csum = skb_checksum(skb, 0, udp_len, 0); | 1185 | csum = skb_checksum(skb, 0, udp_len, 0); |
1184 | uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr, | 1186 | uh->check = csum_tcpudp_magic(inet->inet_saddr, |
1187 | inet->inet_daddr, | ||
1185 | udp_len, IPPROTO_UDP, csum); | 1188 | udp_len, IPPROTO_UDP, csum); |
1186 | if (uh->check == 0) | 1189 | if (uh->check == 0) |
1187 | uh->check = CSUM_MANGLED_0; | 1190 | uh->check = CSUM_MANGLED_0; |
@@ -1189,7 +1192,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1189 | skb->ip_summed = CHECKSUM_PARTIAL; | 1192 | skb->ip_summed = CHECKSUM_PARTIAL; |
1190 | skb->csum_start = skb_transport_header(skb) - skb->head; | 1193 | skb->csum_start = skb_transport_header(skb) - skb->head; |
1191 | skb->csum_offset = offsetof(struct udphdr, check); | 1194 | skb->csum_offset = offsetof(struct udphdr, check); |
1192 | uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr, | 1195 | uh->check = ~csum_tcpudp_magic(inet->inet_saddr, |
1196 | inet->inet_daddr, | ||
1193 | udp_len, IPPROTO_UDP, 0); | 1197 | udp_len, IPPROTO_UDP, 0); |
1194 | } | 1198 | } |
1195 | 1199 | ||
@@ -1533,7 +1537,7 @@ static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net, | |||
1533 | * if the tunnel socket goes away. | 1537 | * if the tunnel socket goes away. |
1534 | */ | 1538 | */ |
1535 | tunnel->old_sk_destruct = sk->sk_destruct; | 1539 | tunnel->old_sk_destruct = sk->sk_destruct; |
1536 | sk->sk_destruct = &pppol2tp_tunnel_destruct; | 1540 | sk->sk_destruct = pppol2tp_tunnel_destruct; |
1537 | 1541 | ||
1538 | tunnel->sock = sk; | 1542 | tunnel->sock = sk; |
1539 | sk->sk_allocation = GFP_ATOMIC; | 1543 | sk->sk_allocation = GFP_ATOMIC; |
@@ -2601,53 +2605,31 @@ static struct pppox_proto pppol2tp_proto = { | |||
2601 | 2605 | ||
2602 | static __net_init int pppol2tp_init_net(struct net *net) | 2606 | static __net_init int pppol2tp_init_net(struct net *net) |
2603 | { | 2607 | { |
2604 | struct pppol2tp_net *pn; | 2608 | struct pppol2tp_net *pn = pppol2tp_pernet(net); |
2605 | struct proc_dir_entry *pde; | 2609 | struct proc_dir_entry *pde; |
2606 | int err; | ||
2607 | |||
2608 | pn = kzalloc(sizeof(*pn), GFP_KERNEL); | ||
2609 | if (!pn) | ||
2610 | return -ENOMEM; | ||
2611 | 2610 | ||
2612 | INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list); | 2611 | INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list); |
2613 | rwlock_init(&pn->pppol2tp_tunnel_list_lock); | 2612 | rwlock_init(&pn->pppol2tp_tunnel_list_lock); |
2614 | 2613 | ||
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); | 2614 | pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops); |
2620 | #ifdef CONFIG_PROC_FS | 2615 | #ifdef CONFIG_PROC_FS |
2621 | if (!pde) { | 2616 | if (!pde) |
2622 | err = -ENOMEM; | 2617 | return -ENOMEM; |
2623 | goto out; | ||
2624 | } | ||
2625 | #endif | 2618 | #endif |
2626 | 2619 | ||
2627 | return 0; | 2620 | return 0; |
2628 | |||
2629 | out: | ||
2630 | kfree(pn); | ||
2631 | return err; | ||
2632 | } | 2621 | } |
2633 | 2622 | ||
2634 | static __net_exit void pppol2tp_exit_net(struct net *net) | 2623 | static __net_exit void pppol2tp_exit_net(struct net *net) |
2635 | { | 2624 | { |
2636 | struct pppoe_net *pn; | ||
2637 | |||
2638 | proc_net_remove(net, "pppol2tp"); | 2625 | 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 | } | 2626 | } |
2647 | 2627 | ||
2648 | static struct pernet_operations pppol2tp_net_ops = { | 2628 | static struct pernet_operations pppol2tp_net_ops = { |
2649 | .init = pppol2tp_init_net, | 2629 | .init = pppol2tp_init_net, |
2650 | .exit = pppol2tp_exit_net, | 2630 | .exit = pppol2tp_exit_net, |
2631 | .id = &pppol2tp_net_id, | ||
2632 | .size = sizeof(struct pppol2tp_net), | ||
2651 | }; | 2633 | }; |
2652 | 2634 | ||
2653 | static int __init pppol2tp_init(void) | 2635 | static int __init pppol2tp_init(void) |
@@ -2661,7 +2643,7 @@ static int __init pppol2tp_init(void) | |||
2661 | if (err) | 2643 | if (err) |
2662 | goto out_unregister_pppol2tp_proto; | 2644 | goto out_unregister_pppol2tp_proto; |
2663 | 2645 | ||
2664 | err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops); | 2646 | err = register_pernet_device(&pppol2tp_net_ops); |
2665 | if (err) | 2647 | if (err) |
2666 | goto out_unregister_pppox_proto; | 2648 | goto out_unregister_pppox_proto; |
2667 | 2649 | ||
@@ -2680,7 +2662,7 @@ out_unregister_pppol2tp_proto: | |||
2680 | static void __exit pppol2tp_exit(void) | 2662 | static void __exit pppol2tp_exit(void) |
2681 | { | 2663 | { |
2682 | unregister_pppox_proto(PX_PROTO_OL2TP); | 2664 | unregister_pppox_proto(PX_PROTO_OL2TP); |
2683 | unregister_pernet_gen_device(pppol2tp_net_id, &pppol2tp_net_ops); | 2665 | unregister_pernet_device(&pppol2tp_net_ops); |
2684 | proto_unregister(&pppol2tp_sk_proto); | 2666 | proto_unregister(&pppol2tp_sk_proto); |
2685 | } | 2667 | } |
2686 | 2668 | ||