From 0f09d6e30dc59fdb5f05530a160f42b3487481d6 Mon Sep 17 00:00:00 2001 From: Joe Stringer Date: Tue, 2 Feb 2016 15:19:02 -0800 Subject: [PATCH] compat: Detect and use upstream ip_fragment(). Previously a version check was used to determine whether the upstream ip_fragment() should be used or the backported version. The actual test is for whether upstream commit d6b915e29f4a ("ip_fragment: don't forward defragmented DF packet") is present, so test for that instead. Signed-off-by: Joe Stringer Acked-by: Pravin B Shelar --- acinclude.m4 | 3 +++ datapath/linux/compat/include/net/inet_frag.h | 2 ++ datapath/linux/compat/include/net/ip.h | 18 +++++++++--------- datapath/linux/compat/inet_fragment.c | 4 ++-- datapath/linux/compat/ip_fragment.c | 4 ++-- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index e99420e5f..93fab5d1f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -351,6 +351,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ OVS_GREP_IFELSE([$KSRC/include/net/ip.h], [ip_do_fragment]) 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/ip.h], [IPSKB_FRAG_PMTU], + [OVS_DEFINE([HAVE_CORRECT_MRU_HANDLING])]) OVS_GREP_IFELSE([$KSRC/include/net/inet_frag.h], [hashfn.*const], [OVS_DEFINE([HAVE_INET_FRAGS_CONST])]) OVS_GREP_IFELSE([$KSRC/include/net/inet_frag.h], [last_in], diff --git a/datapath/linux/compat/include/net/inet_frag.h b/datapath/linux/compat/include/net/inet_frag.h index 64edffa2b..606e95243 100644 --- a/datapath/linux/compat/include/net/inet_frag.h +++ b/datapath/linux/compat/include/net/inet_frag.h @@ -55,6 +55,7 @@ static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q) #endif #endif +#ifndef HAVE_CORRECT_MRU_HANDLING static unsigned int rpl_frag_percpu_counter_batch = 130000; #define frag_percpu_counter_batch rpl_frag_percpu_counter_batch @@ -78,6 +79,7 @@ void rpl_inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); void rpl_inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f); #define inet_frag_destroy(q, f, work) rpl_inet_frag_destroy(q, f) +#endif /* !HAVE_CORRECT_MRU_HANDLING */ #endif /* OVS_FRAGMENT_BACKPORT */ #endif /* inet_frag.h */ diff --git a/datapath/linux/compat/include/net/ip.h b/datapath/linux/compat/include/net/ip.h index 29ec5145f..cd87bcc09 100644 --- a/datapath/linux/compat/include/net/ip.h +++ b/datapath/linux/compat/include/net/ip.h @@ -72,7 +72,12 @@ static inline unsigned int rpl_ip_skb_dst_mtu(const struct sk_buff *skb) #define OVS_VPORT_OUTPUT_PARAMS struct sk_buff *skb #endif -#ifdef OVS_FRAGMENT_BACKPORT +/* Prior to upstream commit d6b915e29f4a ("ip_fragment: don't forward + * defragmented DF packet"), IPCB(skb)->frag_max_size was not always populated + * correctly, which would lead to reassembled packets not being refragmented. + * So, we backport all of ip_defrag() in these cases. + */ +#if !defined(HAVE_CORRECT_MRU_HANDLING) && defined(OVS_FRAGMENT_BACKPORT) #if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) static inline bool ip_defrag_user_in_between(u32 user, @@ -81,7 +86,7 @@ static inline bool ip_defrag_user_in_between(u32 user, { return user >= lower_bond && user <= upper_bond; } -#endif +#endif /* < v4.2 */ #ifndef HAVE_IP_DO_FRAGMENT static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, @@ -111,17 +116,12 @@ static inline int rpl_ip_do_fragment(struct sock *sk, struct sk_buff *skb, #define ip_do_fragment rpl_ip_do_fragment #endif /* IP_DO_FRAGMENT */ -/* Prior to upstream commit d6b915e29f4a ("ip_fragment: don't forward - * defragmented DF packet"), IPCB(skb)->frag_max_size was not always populated - * correctly, which would lead to reassembled packets not being refragmented. - * So, we backport all of ip_defrag() in these cases. - */ int rpl_ip_defrag(struct sk_buff *skb, u32 user); #define ip_defrag rpl_ip_defrag int __init rpl_ipfrag_init(void); void rpl_ipfrag_fini(void); -#else /* OVS_FRAGMENT_BACKPORT */ +#else /* HAVE_CORRECT_MRU_HANDLING || !OVS_FRAGMENT_BACKPORT */ /* We have no good way to detect the presence of upstream commit 8282f27449bf * ("inet: frag: Always orphan skbs inside ip_defrag()"), but it should be @@ -137,7 +137,7 @@ static inline int rpl_ip_defrag(struct sk_buff *skb, u32 user) static inline int rpl_ipfrag_init(void) { return 0; } static inline void rpl_ipfrag_fini(void) { } -#endif /* OVS_FRAGMENT_BACKPORT */ +#endif /* HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ #define ipfrag_init rpl_ipfrag_init #define ipfrag_fini rpl_ipfrag_fini diff --git a/datapath/linux/compat/inet_fragment.c b/datapath/linux/compat/inet_fragment.c index 0b9b9515e..10db99fd0 100644 --- a/datapath/linux/compat/inet_fragment.c +++ b/datapath/linux/compat/inet_fragment.c @@ -13,7 +13,7 @@ #include -#ifdef OVS_FRAGMENT_BACKPORT +#if !defined(HAVE_CORRECT_MRU_HANDLING) && defined(OVS_FRAGMENT_BACKPORT) #include #include @@ -557,4 +557,4 @@ void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q, net_dbg_ratelimited("%s%s", prefix, msg); } -#endif /* OVS_FRAGMENT_BACKPORT */ +#endif /* !HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ diff --git a/datapath/linux/compat/ip_fragment.c b/datapath/linux/compat/ip_fragment.c index 4fa50193b..cf2daaa5a 100644 --- a/datapath/linux/compat/ip_fragment.c +++ b/datapath/linux/compat/ip_fragment.c @@ -25,7 +25,7 @@ #include -#ifdef OVS_FRAGMENT_BACKPORT +#if !defined(HAVE_CORRECT_MRU_HANDLING) && defined(OVS_FRAGMENT_BACKPORT) #define pr_fmt(fmt) "IPv4: " fmt @@ -747,4 +747,4 @@ void rpl_ipfrag_fini(void) unregister_pernet_subsys(&ip4_frags_ops); } -#endif /* OVS_FRAGMENT_BACKPORT */ +#endif /* !HAVE_CORRECT_MRU_HANDLING && OVS_FRAGMENT_BACKPORT */ -- 2.20.1