diff options
author | Tom Herbert <therbert@google.com> | 2014-05-23 11:47:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-23 16:28:53 -0400 |
commit | 6b649feafe10b293f4bd5a74aca95faf625ae525 (patch) | |
tree | 842991b315c84e51fa4c2ececfba60e2992944b9 /net/l2tp | |
parent | 1c19448c9ba6545b80ded18488a64a7f3d8e6998 (diff) |
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: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp')
-rw-r--r-- | net/l2tp/l2tp_core.c | 9 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.h | 4 | ||||
-rw-r--r-- | net/l2tp/l2tp_netlink.c | 7 |
3 files changed, 18 insertions, 2 deletions
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 | ||
168 | struct l2tp_tunnel { | 170 | struct 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]) |