Commit 6b649fea authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

l2tp: Add support for zero IPv6 checksums

Added new L2TP configuration options to allow TX and RX of
zero checksums in IPv6. Default is not to use them.
Signed-off-by: default avatarTom Herbert <therbert@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1c19448c
...@@ -124,6 +124,8 @@ enum { ...@@ -124,6 +124,8 @@ enum {
L2TP_ATTR_STATS, /* nested */ L2TP_ATTR_STATS, /* nested */
L2TP_ATTR_IP6_SADDR, /* struct in6_addr */ L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
L2TP_ATTR_IP6_DADDR, /* struct in6_addr */ L2TP_ATTR_IP6_DADDR, /* struct in6_addr */
L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* u8 */
L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* u8 */
__L2TP_ATTR_MAX, __L2TP_ATTR_MAX,
}; };
......
...@@ -1102,7 +1102,9 @@ static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb, ...@@ -1102,7 +1102,9 @@ static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb,
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct udphdr *uh = udp_hdr(skb); struct udphdr *uh = udp_hdr(skb);
if (!skb_dst(skb) || !skb_dst(skb)->dev || if (udp_get_no_check6_tx(sk))
skb->ip_summed = CHECKSUM_NONE;
else if (!skb_dst(skb) || !skb_dst(skb)->dev ||
!(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) { !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {
__wsum csum = skb_checksum(skb, 0, udp_len, 0); __wsum csum = skb_checksum(skb, 0, udp_len, 0);
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
...@@ -1435,6 +1437,11 @@ static int l2tp_tunnel_sock_create(struct net *net, ...@@ -1435,6 +1437,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
sizeof(udp6_addr), 0); sizeof(udp6_addr), 0);
if (err < 0) if (err < 0)
goto out; goto out;
if (cfg->udp6_zero_tx_checksums)
udp_set_no_check6_tx(sock->sk, true);
if (cfg->udp6_zero_rx_checksums)
udp_set_no_check6_rx(sock->sk, true);
} else } else
#endif #endif
{ {
......
...@@ -162,7 +162,9 @@ struct l2tp_tunnel_cfg { ...@@ -162,7 +162,9 @@ struct l2tp_tunnel_cfg {
#endif #endif
u16 local_udp_port; u16 local_udp_port;
u16 peer_udp_port; u16 peer_udp_port;
unsigned int use_udp_checksums:1; unsigned int use_udp_checksums:1,
udp6_zero_tx_checksums:1,
udp6_zero_rx_checksums:1;
}; };
struct l2tp_tunnel { struct l2tp_tunnel {
......
...@@ -161,6 +161,13 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info ...@@ -161,6 +161,13 @@ static int l2tp_nl_cmd_tunnel_create(struct sk_buff *skb, struct genl_info *info
cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]); cfg.peer_udp_port = nla_get_u16(info->attrs[L2TP_ATTR_UDP_DPORT]);
if (info->attrs[L2TP_ATTR_UDP_CSUM]) if (info->attrs[L2TP_ATTR_UDP_CSUM])
cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]); cfg.use_udp_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_CSUM]);
#if IS_ENABLED(CONFIG_IPV6)
if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX])
cfg.udp6_zero_tx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]);
if (info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX])
cfg.udp6_zero_rx_checksums = nla_get_flag(info->attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]);
#endif
} }
if (info->attrs[L2TP_ATTR_DEBUG]) if (info->attrs[L2TP_ATTR_DEBUG])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment