From cfda4537ec769d79066ad3a0f68352afd3ca648a Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Wed, 2 Dec 2015 23:53:43 -0800 Subject: [PATCH] compat: Backport ip_skb_dst_mtu(). >From upstream f87c10a8aa1e ("ipv4: introduce ip_dst_mtu_maybe_forward and protect forwarding path against pmtu spoofing") Signed-off-by: Joe Stringer Acked-by: Pravin B Shelar --- acinclude.m4 | 1 + datapath/linux/compat/include/net/ip.h | 39 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 5aaaa1081..78da9402b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -348,6 +348,7 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [inet_get_local_port_range.*net], [OVS_DEFINE([HAVE_INET_GET_LOCAL_PORT_RANGE_USING_NET])]) OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [ip_is_fragment]) + OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [ip_skb_dst_mtu]) OVS_GREP_IFELSE([$KSRC/include/net/dst_metadata.h], [metadata_dst]) OVS_GREP_IFELSE([$KSRC/include/linux/net.h], [sock_create_kern.*net], diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h index a9401a7f0..ead6e2904 100644 --- a/datapath/linux/compat/include/net/ip.h +++ b/datapath/linux/compat/include/net/ip.h @@ -22,4 +22,43 @@ static inline void rpl_inet_get_local_port_range(struct net *net, int *low, #endif +/* IPv4 datagram length is stored into 16bit field (tot_len) */ +#ifndef IP_MAX_MTU +#define IP_MAX_MTU 0xFFFFU +#endif + +#ifndef HAVE_IP_SKB_DST_MTU +static inline bool rpl_ip_sk_use_pmtu(const struct sock *sk) +{ + return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; +} +#define ip_sk_use_pmtu rpl_ip_sk_use_pmtu + +static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, + bool forwarding) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) + struct net *net = dev_net(dst->dev); + + if (net->ipv4.sysctl_ip_fwd_use_pmtu || + dst_metric_locked(dst, RTAX_MTU) || + !forwarding) + return dst_mtu(dst); +#endif + + return min(dst->dev->mtu, IP_MAX_MTU); +} + +static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb) +{ + if (!skb->sk || ip_sk_use_pmtu(skb->sk)) { + bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; + return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); + } else { + return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU); + } +} +#define ip_skb_dst_mtu rpl_ip_skb_dst_mtu +#endif /* HAVE_IP_SKB_DST_MTU */ + #endif -- 2.20.1