aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/l2tp.h2
-rw-r--r--net/l2tp/l2tp_core.c9
-rw-r--r--net/l2tp/l2tp_core.h4
-rw-r--r--net/l2tp/l2tp_netlink.c7
4 files changed, 20 insertions, 2 deletions
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index 8adb68160327..21caa2631c20 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -124,6 +124,8 @@ enum {
124 L2TP_ATTR_STATS, /* nested */ 124 L2TP_ATTR_STATS, /* nested */
125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */ 125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
126 L2TP_ATTR_IP6_DADDR, /* struct in6_addr */ 126 L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
127 L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* u8 */
128 L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* u8 */
127 __L2TP_ATTR_MAX, 129 __L2TP_ATTR_MAX,
128}; 130};
129 131
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index a1186105f537..379558014b60 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1102,7 +1102,9 @@ static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb,
1102 struct ipv6_pinfo *np = inet6_sk(sk); 1102 struct ipv6_pinfo *np = inet6_sk(sk);
1103 struct udphdr *uh = udp_hdr(skb); 1103 struct udphdr *uh = udp_hdr(skb);
1104 1104
1105 if (!skb_dst(skb) || !skb_dst(skb)->dev || 1105 if (udp_get_no_check6_tx(sk))
1106 skb->ip_summed = CHECKSUM_NONE;
1107 else if (!skb_dst(skb) || !skb_dst(skb)->dev ||
1106 !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) { 1108 !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {
1107 __wsum csum = skb_checksum(skb, 0, udp_len, 0); 1109 __wsum csum = skb_checksum(skb, 0, udp_len, 0);
1108 skb->ip_summed = CHECKSUM_UNNECESSARY; 1110 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1435,6 +1437,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
1435 sizeof(udp6_addr), 0); 1437 sizeof(udp6_addr), 0);
1436 if (err < 0) 1438 if (err < 0)
1437 goto out; 1439 goto out;
1440
1441 if (cfg->udp6_zero_tx_checksums)
1442 udp_set_no_check6_tx(sock->sk, true);
1443 if (cfg->udp6_zero_rx_checksums)
1444 udp_set_no_check6_rx(sock->sk, true);
1438 } else 1445 } else
1439#endif 1446#endif
1440 { 1447 {
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 3f93ccd6ba97..68aa9ffd4ae4 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -162,7 +162,9 @@ struct l2tp_tunnel_cfg {
162#endif 162#endif
163 u16 local_udp_port; 163 u16 local_udp_port;
164 u16 peer_udp_port; 164 u16 peer_udp_port;
165 unsigned int use_udp_checksums:1; 165 unsigned int use_udp_checksums:1,
166 udp6_zero_tx_checksums:1,
167 udp6_zero_rx_checksums:1;
166}; 168};
167 169
168struct l2tp_tunnel { 170struct l2tp_tunnel {
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index f3d331bdd706..0ac907adb2f4 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -161,6 +161,13 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
161 cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]); 161 cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
162 if (info->attrs[L2TP_ATTR_UDP_CSUM]) 162 if (info->attrs[L2TP_ATTR_UDP_CSUM])
163 cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]); 163 cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
164
165#if IS_ENABLED(CONFIG_IPV6)
166 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX])
167 cfg.udp6_zero_tx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]);
168 if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX])
169 cfg.udp6_zero_rx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]);
170#endif
164 } 171 }
165 172
166 if (info->attrs[L2TP_ATTR_DEBUG]) 173 if (info->attrs[L2TP_ATTR_DEBUG])