aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/l2tp/l2tp_core.c')
-rw-r--r--net/l2tp/l2tp_core.c118
1 files changed, 13 insertions, 105 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index a4e37d7158dc..bea259043205 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -495,52 +495,6 @@ out:
495 spin_unlock_bh(&session->reorder_q.lock); 495 spin_unlock_bh(&session->reorder_q.lock);
496} 496}
497 497
498static inline int l2tp_verify_udp_checksum(struct sock *sk,
499 struct sk_buff *skb)
500{
501 struct udphdr *uh = udp_hdr(skb);
502 u16 ulen = ntohs(uh->len);
503 __wsum psum;
504
505 if (sk->sk_no_check || skb_csum_unnecessary(skb))
506 return 0;
507
508#if IS_ENABLED(CONFIG_IPV6)
509 if (sk->sk_family == PF_INET6 && !l2tp_tunnel(sk)->v4mapped) {
510 if (!uh->check) {
511 LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n");
512 return 1;
513 }
514 if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
515 !csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
516 &ipv6_hdr(skb)->daddr, ulen,
517 IPPROTO_UDP, skb->csum)) {
518 skb->ip_summed = CHECKSUM_UNNECESSARY;
519 return 0;
520 }
521 skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
522 &ipv6_hdr(skb)->daddr,
523 skb->len, IPPROTO_UDP,
524 0));
525 } else
526#endif
527 {
528 struct inet_sock *inet;
529 if (!uh->check)
530 return 0;
531 inet = inet_sk(sk);
532 psum = csum_tcpudp_nofold(inet->inet_saddr, inet->inet_daddr,
533 ulen, IPPROTO_UDP, 0);
534
535 if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
536 !csum_fold(csum_add(psum, skb->csum)))
537 return 0;
538 skb->csum = psum;
539 }
540
541 return __skb_checksum_complete(skb);
542}
543
544static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr) 498static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr)
545{ 499{
546 u32 nws; 500 u32 nws;
@@ -895,8 +849,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
895 u16 version; 849 u16 version;
896 int length; 850 int length;
897 851
898 if (tunnel->sock && l2tp_verify_udp_checksum(tunnel->sock, skb)) 852 /* UDP has verifed checksum */
899 goto discard_bad_csum;
900 853
901 /* UDP always verifies the packet length. */ 854 /* UDP always verifies the packet length. */
902 __skb_pull(skb, sizeof(struct udphdr)); 855 __skb_pull(skb, sizeof(struct udphdr));
@@ -979,14 +932,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
979 932
980 return 0; 933 return 0;
981 934
982discard_bad_csum:
983 LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
984 UDP_INC_STATS_USER(tunnel->l2tp_net, UDP_MIB_INERRORS, 0);
985 atomic_long_inc(&tunnel->stats.rx_errors);
986 kfree_skb(skb);
987
988 return 0;
989
990error: 935error:
991 /* Put UDP header back */ 936 /* Put UDP header back */
992 __skb_push(skb, sizeof(struct udphdr)); 937 __skb_push(skb, sizeof(struct udphdr));
@@ -1128,7 +1073,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
1128 } 1073 }
1129 1074
1130 /* Queue the packet to IP for output */ 1075 /* Queue the packet to IP for output */
1131 skb->local_df = 1; 1076 skb->ignore_df = 1;
1132#if IS_ENABLED(CONFIG_IPV6) 1077#if IS_ENABLED(CONFIG_IPV6)
1133 if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) 1078 if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
1134 error = inet6_csk_xmit(tunnel->sock, skb, NULL); 1079 error = inet6_csk_xmit(tunnel->sock, skb, NULL);
@@ -1150,31 +1095,6 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
1150 return 0; 1095 return 0;
1151} 1096}
1152 1097
1153#if IS_ENABLED(CONFIG_IPV6)
1154static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb,
1155 int udp_len)
1156{
1157 struct ipv6_pinfo *np = inet6_sk(sk);
1158 struct udphdr *uh = udp_hdr(skb);
1159
1160 if (!skb_dst(skb) || !skb_dst(skb)->dev ||
1161 !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {
1162 __wsum csum = skb_checksum(skb, 0, udp_len, 0);
1163 skb->ip_summed = CHECKSUM_UNNECESSARY;
1164 uh->check = csum_ipv6_magic(&np->saddr, &sk->sk_v6_daddr, udp_len,
1165 IPPROTO_UDP, csum);
1166 if (uh->check == 0)
1167 uh->check = CSUM_MANGLED_0;
1168 } else {
1169 skb->ip_summed = CHECKSUM_PARTIAL;
1170 skb->csum_start = skb_transport_header(skb) - skb->head;
1171 skb->csum_offset = offsetof(struct udphdr, check);
1172 uh->check = ~csum_ipv6_magic(&np->saddr, &sk->sk_v6_daddr,
1173 udp_len, IPPROTO_UDP, 0);
1174 }
1175}
1176#endif
1177
1178/* If caller requires the skb to have a ppp header, the header must be 1098/* If caller requires the skb to have a ppp header, the header must be
1179 * inserted in the skb data before calling this function. 1099 * inserted in the skb data before calling this function.
1180 */ 1100 */
@@ -1186,7 +1106,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1186 struct flowi *fl; 1106 struct flowi *fl;
1187 struct udphdr *uh; 1107 struct udphdr *uh;
1188 struct inet_sock *inet; 1108 struct inet_sock *inet;
1189 __wsum csum;
1190 int headroom; 1109 int headroom;
1191 int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; 1110 int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
1192 int udp_len; 1111 int udp_len;
@@ -1235,33 +1154,17 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1235 uh->dest = inet->inet_dport; 1154 uh->dest = inet->inet_dport;
1236 udp_len = uhlen + hdr_len + data_len; 1155 udp_len = uhlen + hdr_len + data_len;
1237 uh->len = htons(udp_len); 1156 uh->len = htons(udp_len);
1238 uh->check = 0;
1239 1157
1240 /* Calculate UDP checksum if configured to do so */ 1158 /* Calculate UDP checksum if configured to do so */
1241#if IS_ENABLED(CONFIG_IPV6) 1159#if IS_ENABLED(CONFIG_IPV6)
1242 if (sk->sk_family == PF_INET6 && !tunnel->v4mapped) 1160 if (sk->sk_family == PF_INET6 && !tunnel->v4mapped)
1243 l2tp_xmit_ipv6_csum(sk, skb, udp_len); 1161 udp6_set_csum(udp_get_no_check6_tx(sk),
1162 skb, &inet6_sk(sk)->saddr,
1163 &sk->sk_v6_daddr, udp_len);
1244 else 1164 else
1245#endif 1165#endif
1246 if (sk->sk_no_check == UDP_CSUM_NOXMIT) 1166 udp_set_csum(sk->sk_no_check_tx, skb, inet->inet_saddr,
1247 skb->ip_summed = CHECKSUM_NONE; 1167 inet->inet_daddr, udp_len);
1248 else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1249 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
1250 skb->ip_summed = CHECKSUM_COMPLETE;
1251 csum = skb_checksum(skb, 0, udp_len, 0);
1252 uh->check = csum_tcpudp_magic(inet->inet_saddr,
1253 inet->inet_daddr,
1254 udp_len, IPPROTO_UDP, csum);
1255 if (uh->check == 0)
1256 uh->check = CSUM_MANGLED_0;
1257 } else {
1258 skb->ip_summed = CHECKSUM_PARTIAL;
1259 skb->csum_start = skb_transport_header(skb) - skb->head;
1260 skb->csum_offset = offsetof(struct udphdr, check);
1261 uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
1262 inet->inet_daddr,
1263 udp_len, IPPROTO_UDP, 0);
1264 }
1265 break; 1168 break;
1266 1169
1267 case L2TP_ENCAPTYPE_IP: 1170 case L2TP_ENCAPTYPE_IP:
@@ -1490,6 +1393,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
1490 sizeof(udp6_addr), 0); 1393 sizeof(udp6_addr), 0);
1491 if (err < 0) 1394 if (err < 0)
1492 goto out; 1395 goto out;
1396
1397 if (cfg->udp6_zero_tx_checksums)
1398 udp_set_no_check6_tx(sock->sk, true);
1399 if (cfg->udp6_zero_rx_checksums)
1400 udp_set_no_check6_rx(sock->sk, true);
1493 } else 1401 } else
1494#endif 1402#endif
1495 { 1403 {
@@ -1518,7 +1426,7 @@ static int l2tp_tunnel_sock_create(struct net *net,
1518 } 1426 }
1519 1427
1520 if (!cfg->use_udp_checksums) 1428 if (!cfg->use_udp_checksums)
1521 sock->sk->sk_no_check = UDP_CSUM_NOXMIT; 1429 sock->sk->sk_no_check_tx = 1;
1522 1430
1523 break; 1431 break;
1524 1432