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.c94
1 files changed, 82 insertions, 12 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index e98d9773158d..f1a946785c6a 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -489,6 +489,30 @@ out:
489 spin_unlock_bh(&session->reorder_q.lock); 489 spin_unlock_bh(&session->reorder_q.lock);
490} 490}
491 491
492static inline int pppol2tp_verify_udp_checksum(struct sock *sk,
493 struct sk_buff *skb)
494{
495 struct udphdr *uh = udp_hdr(skb);
496 u16 ulen = ntohs(uh->len);
497 struct inet_sock *inet;
498 __wsum psum;
499
500 if (sk->sk_no_check || skb_csum_unnecessary(skb) || !uh->check)
501 return 0;
502
503 inet = inet_sk(sk);
504 psum = csum_tcpudp_nofold(inet->saddr, inet->daddr, ulen,
505 IPPROTO_UDP, 0);
506
507 if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
508 !csum_fold(csum_add(psum, skb->csum)))
509 return 0;
510
511 skb->csum = psum;
512
513 return __skb_checksum_complete(skb);
514}
515
492/* Internal receive frame. Do the real work of receiving an L2TP data frame 516/* Internal receive frame. Do the real work of receiving an L2TP data frame
493 * here. The skb is not on a list when we get here. 517 * here. The skb is not on a list when we get here.
494 * Returns 0 if the packet was a data packet and was successfully passed on. 518 * Returns 0 if the packet was a data packet and was successfully passed on.
@@ -509,6 +533,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
509 if (tunnel == NULL) 533 if (tunnel == NULL)
510 goto no_tunnel; 534 goto no_tunnel;
511 535
536 if (tunnel->sock && pppol2tp_verify_udp_checksum(tunnel->sock, skb))
537 goto discard_bad_csum;
538
512 /* UDP always verifies the packet length. */ 539 /* UDP always verifies the packet length. */
513 __skb_pull(skb, sizeof(struct udphdr)); 540 __skb_pull(skb, sizeof(struct udphdr));
514 541
@@ -725,6 +752,14 @@ discard:
725 752
726 return 0; 753 return 0;
727 754
755discard_bad_csum:
756 LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
757 UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
758 tunnel->stats.rx_errors++;
759 kfree_skb(skb);
760
761 return 0;
762
728error: 763error:
729 /* Put UDP header back */ 764 /* Put UDP header back */
730 __skb_push(skb, sizeof(struct udphdr)); 765 __skb_push(skb, sizeof(struct udphdr));
@@ -851,7 +886,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
851 static const unsigned char ppph[2] = { 0xff, 0x03 }; 886 static const unsigned char ppph[2] = { 0xff, 0x03 };
852 struct sock *sk = sock->sk; 887 struct sock *sk = sock->sk;
853 struct inet_sock *inet; 888 struct inet_sock *inet;
854 __wsum csum = 0; 889 __wsum csum;
855 struct sk_buff *skb; 890 struct sk_buff *skb;
856 int error; 891 int error;
857 int hdr_len; 892 int hdr_len;
@@ -859,6 +894,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
859 struct pppol2tp_tunnel *tunnel; 894 struct pppol2tp_tunnel *tunnel;
860 struct udphdr *uh; 895 struct udphdr *uh;
861 unsigned int len; 896 unsigned int len;
897 struct sock *sk_tun;
898 u16 udp_len;
862 899
863 error = -ENOTCONN; 900 error = -ENOTCONN;
864 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) 901 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
@@ -870,7 +907,8 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
870 if (session == NULL) 907 if (session == NULL)
871 goto error; 908 goto error;
872 909
873 tunnel = pppol2tp_sock_to_tunnel(session->tunnel_sock); 910 sk_tun = session->tunnel_sock;
911 tunnel = pppol2tp_sock_to_tunnel(sk_tun);
874 if (tunnel == NULL) 912 if (tunnel == NULL)
875 goto error_put_sess; 913 goto error_put_sess;
876 914
@@ -893,11 +931,12 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
893 skb_reset_transport_header(skb); 931 skb_reset_transport_header(skb);
894 932
895 /* Build UDP header */ 933 /* Build UDP header */
896 inet = inet_sk(session->tunnel_sock); 934 inet = inet_sk(sk_tun);
935 udp_len = hdr_len + sizeof(ppph) + total_len;
897 uh = (struct udphdr *) skb->data; 936 uh = (struct udphdr *) skb->data;
898 uh->source = inet->sport; 937 uh->source = inet->sport;
899 uh->dest = inet->dport; 938 uh->dest = inet->dport;
900 uh->len = htons(hdr_len + sizeof(ppph) + total_len); 939 uh->len = htons(udp_len);
901 uh->check = 0; 940 uh->check = 0;
902 skb_put(skb, sizeof(struct udphdr)); 941 skb_put(skb, sizeof(struct udphdr));
903 942
@@ -919,8 +958,22 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
919 skb_put(skb, total_len); 958 skb_put(skb, total_len);
920 959
921 /* Calculate UDP checksum if configured to do so */ 960 /* Calculate UDP checksum if configured to do so */
922 if (session->tunnel_sock->sk_no_check != UDP_CSUM_NOXMIT) 961 if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
923 csum = udp_csum_outgoing(sk, skb); 962 skb->ip_summed = CHECKSUM_NONE;
963 else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
964 skb->ip_summed = CHECKSUM_COMPLETE;
965 csum = skb_checksum(skb, 0, udp_len, 0);
966 uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
967 udp_len, IPPROTO_UDP, csum);
968 if (uh->check == 0)
969 uh->check = CSUM_MANGLED_0;
970 } else {
971 skb->ip_summed = CHECKSUM_PARTIAL;
972 skb->csum_start = skb_transport_header(skb) - skb->head;
973 skb->csum_offset = offsetof(struct udphdr, check);
974 uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr,
975 udp_len, IPPROTO_UDP, 0);
976 }
924 977
925 /* Debug */ 978 /* Debug */
926 if (session->send_seq) 979 if (session->send_seq)
@@ -1008,13 +1061,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1008 struct sock *sk = (struct sock *) chan->private; 1061 struct sock *sk = (struct sock *) chan->private;
1009 struct sock *sk_tun; 1062 struct sock *sk_tun;
1010 int hdr_len; 1063 int hdr_len;
1064 u16 udp_len;
1011 struct pppol2tp_session *session; 1065 struct pppol2tp_session *session;
1012 struct pppol2tp_tunnel *tunnel; 1066 struct pppol2tp_tunnel *tunnel;
1013 int rc; 1067 int rc;
1014 int headroom; 1068 int headroom;
1015 int data_len = skb->len; 1069 int data_len = skb->len;
1016 struct inet_sock *inet; 1070 struct inet_sock *inet;
1017 __wsum csum = 0; 1071 __wsum csum;
1018 struct udphdr *uh; 1072 struct udphdr *uh;
1019 unsigned int len; 1073 unsigned int len;
1020 int old_headroom; 1074 int old_headroom;
@@ -1060,6 +1114,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1060 /* Setup L2TP header */ 1114 /* Setup L2TP header */
1061 pppol2tp_build_l2tp_header(session, __skb_push(skb, hdr_len)); 1115 pppol2tp_build_l2tp_header(session, __skb_push(skb, hdr_len));
1062 1116
1117 udp_len = sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len;
1118
1063 /* Setup UDP header */ 1119 /* Setup UDP header */
1064 inet = inet_sk(sk_tun); 1120 inet = inet_sk(sk_tun);
1065 __skb_push(skb, sizeof(*uh)); 1121 __skb_push(skb, sizeof(*uh));
@@ -1067,13 +1123,9 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1067 uh = udp_hdr(skb); 1123 uh = udp_hdr(skb);
1068 uh->source = inet->sport; 1124 uh->source = inet->sport;
1069 uh->dest = inet->dport; 1125 uh->dest = inet->dport;
1070 uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len); 1126 uh->len = htons(udp_len);
1071 uh->check = 0; 1127 uh->check = 0;
1072 1128
1073 /* *BROKEN* Calculate UDP checksum if configured to do so */
1074 if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT)
1075 csum = udp_csum_outgoing(sk_tun, skb);
1076
1077 /* Debug */ 1129 /* Debug */
1078 if (session->send_seq) 1130 if (session->send_seq)
1079 PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG, 1131 PRINTK(session->debug, PPPOL2TP_MSG_DATA, KERN_DEBUG,
@@ -1108,6 +1160,24 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1108 skb->dst = dst_clone(__sk_dst_get(sk_tun)); 1160 skb->dst = dst_clone(__sk_dst_get(sk_tun));
1109 pppol2tp_skb_set_owner_w(skb, sk_tun); 1161 pppol2tp_skb_set_owner_w(skb, sk_tun);
1110 1162
1163 /* Calculate UDP checksum if configured to do so */
1164 if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
1165 skb->ip_summed = CHECKSUM_NONE;
1166 else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
1167 skb->ip_summed = CHECKSUM_COMPLETE;
1168 csum = skb_checksum(skb, 0, udp_len, 0);
1169 uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
1170 udp_len, IPPROTO_UDP, csum);
1171 if (uh->check == 0)
1172 uh->check = CSUM_MANGLED_0;
1173 } else {
1174 skb->ip_summed = CHECKSUM_PARTIAL;
1175 skb->csum_start = skb_transport_header(skb) - skb->head;
1176 skb->csum_offset = offsetof(struct udphdr, check);
1177 uh->check = ~csum_tcpudp_magic(inet->saddr, inet->daddr,
1178 udp_len, IPPROTO_UDP, 0);
1179 }
1180
1111 /* Queue the packet to IP for output */ 1181 /* Queue the packet to IP for output */
1112 len = skb->len; 1182 len = skb->len;
1113 rc = ip_queue_xmit(skb, 1); 1183 rc = ip_queue_xmit(skb, 1);