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>
This commit is contained in:
committed by
David S. Miller
parent
1c19448c9b
commit
6b649feafe
@@ -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,
|
|||||||
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,
|
|||||||
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 {
|
|||||||
#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
|
|||||||
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])
|
||||||
|
Reference in New Issue
Block a user