Message ID | 20250102095114.25860-1-shiming.cheng@mediatek.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | ipv6: socket SO_BINDTODEVICE lookup routing fail without IPv6 rule. | expand |
Hi shiming,
kernel test robot noticed the following build warnings:
[auto build test WARNING on net-next/main]
[also build test WARNING on net/main linus/master v6.13-rc5 next-20241220]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/shiming-cheng/ipv6-socket-SO_BINDTODEVICE-lookup-routing-fail-without-IPv6-rule/20250102-174939
base: net-next/main
patch link: https://lore.kernel.org/r/20250102095114.25860-1-shiming.cheng%40mediatek.com
patch subject: [PATCH] ipv6: socket SO_BINDTODEVICE lookup routing fail without IPv6 rule.
config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20250102/202501021940.ecvmrJJb-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250102/202501021940.ecvmrJJb-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501021940.ecvmrJJb-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from include/linux/linkage.h:7,
from include/linux/kernel.h:18,
from net/ipv6/ip6_output.c:26:
net/ipv6/ip6_output.c:1307:19: error: non-static declaration of 'ip6_sk_dst_lookup_flow' follows static declaration
1307 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
| ^~~~~~~~~~~~~~~~~~~~~~
include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL'
56 | extern typeof(sym) sym; \
| ^~~
include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL'
69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL")
| ^~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1307:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
1307 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
| ^~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1291:19: note: previous definition of 'ip6_sk_dst_lookup_flow' with type 'struct dst_entry *(struct sock *, struct flowi6 *, const struct in6_addr *, bool)' {aka 'struct dst_entry *(struct sock *, struct flowi6 *, const struct in6_addr *, _Bool)'}
1291 | struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
| ^~~~~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1309:36: error: invalid storage class for function 'ip6_opt_dup'
1309 | static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
| ^~~~~~~~~~~
net/ipv6/ip6_output.c:1315:35: error: invalid storage class for function 'ip6_rthdr_dup'
1315 | static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
| ^~~~~~~~~~~~~
net/ipv6/ip6_output.c:1321:13: error: invalid storage class for function 'ip6_append_data_mtu'
1321 | static void ip6_append_data_mtu(unsigned int *mtu,
| ^~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1345:12: error: invalid storage class for function 'ip6_setup_cork'
1345 | static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
| ^~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1420:12: error: invalid storage class for function '__ip6_append_data'
1420 | static int __ip6_append_data(struct sock *sk,
| ^~~~~~~~~~~~~~~~~
In file included from include/linux/linkage.h:7,
from include/linux/kernel.h:18,
from net/ipv6/ip6_output.c:26:
net/ipv6/ip6_output.c:1864:19: error: non-static declaration of 'ip6_append_data' follows static declaration
1864 | EXPORT_SYMBOL_GPL(ip6_append_data);
| ^~~~~~~~~~~~~~~
include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL'
56 | extern typeof(sym) sym; \
| ^~~
include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL'
69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL")
| ^~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1864:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
1864 | EXPORT_SYMBOL_GPL(ip6_append_data);
| ^~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1828:5: note: previous definition of 'ip6_append_data' with type 'int(struct sock *, int (*)(void *, char *, int, int, int, struct sk_buff *), void *, size_t, int, struct ipcm6_cookie *, struct flowi6 *, struct rt6_info *, unsigned int)' {aka 'int(struct sock *, int (*)(void *, char *, int, int, int, struct sk_buff *), void *, long unsigned int, int, struct ipcm6_cookie *, struct flowi6 *, struct rt6_info *, unsigned int)'}
1828 | int ip6_append_data(struct sock *sk,
| ^~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1866:13: error: invalid storage class for function 'ip6_cork_steal_dst'
1866 | static void ip6_cork_steal_dst(struct sk_buff *skb, struct inet_cork_full *cork)
| ^~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1874:13: error: invalid storage class for function 'ip6_cork_release'
1874 | static void ip6_cork_release(struct inet_cork_full *cork,
| ^~~~~~~~~~~~~~~~
In file included from include/linux/linkage.h:7,
from include/linux/kernel.h:18,
from net/ipv6/ip6_output.c:26:
net/ipv6/ip6_output.c:2007:19: error: non-static declaration of 'ip6_push_pending_frames' follows static declaration
2007 | EXPORT_SYMBOL_GPL(ip6_push_pending_frames);
| ^~~~~~~~~~~~~~~~~~~~~~~
include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL'
56 | extern typeof(sym) sym; \
| ^~~
include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL'
69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL")
| ^~~~~~~~~~~~~~
net/ipv6/ip6_output.c:2007:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
2007 | EXPORT_SYMBOL_GPL(ip6_push_pending_frames);
| ^~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:1997:5: note: previous definition of 'ip6_push_pending_frames' with type 'int(struct sock *)'
1997 | int ip6_push_pending_frames(struct sock *sk)
| ^~~~~~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:2009:13: error: invalid storage class for function '__ip6_flush_pending_frames'
2009 | static void __ip6_flush_pending_frames(struct sock *sk,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from include/linux/linkage.h:7,
from include/linux/kernel.h:18,
from net/ipv6/ip6_output.c:26:
net/ipv6/ip6_output.c:2031:19: error: non-static declaration of 'ip6_flush_pending_frames' follows static declaration
2031 | EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
| ^~~~~~~~~~~~~~~~~~~~~~~~
include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL'
56 | extern typeof(sym) sym; \
| ^~~
include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL'
69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL")
| ^~~~~~~~~~~~~~
net/ipv6/ip6_output.c:2031:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
2031 | EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
| ^~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:2026:6: note: previous definition of 'ip6_flush_pending_frames' with type 'void(struct sock *)'
2026 | void ip6_flush_pending_frames(struct sock *sk)
| ^~~~~~~~~~~~~~~~~~~~~~~~
net/ipv6/ip6_output.c:2074:1: error: expected declaration or statement at end of input
2074 | }
| ^
At top level:
>> net/ipv6/ip6_output.c:2033:17: warning: 'ip6_make_skb' defined but not used [-Wunused-function]
2033 | struct sk_buff *ip6_make_skb(struct sock *sk,
| ^~~~~~~~~~~~
vim +/ip6_make_skb +2033 net/ipv6/ip6_output.c
0bbe84a67b0b54 Vlad Yasevich 2015-01-31 2025
0bbe84a67b0b54 Vlad Yasevich 2015-01-31 @2026 void ip6_flush_pending_frames(struct sock *sk)
0bbe84a67b0b54 Vlad Yasevich 2015-01-31 2027 {
6422398c2ab092 Vlad Yasevich 2015-01-31 2028 __ip6_flush_pending_frames(sk, &sk->sk_write_queue,
6422398c2ab092 Vlad Yasevich 2015-01-31 2029 &inet_sk(sk)->cork, &inet6_sk(sk)->cork);
0bbe84a67b0b54 Vlad Yasevich 2015-01-31 2030 }
a495f8364efe11 Chris Elston 2012-04-29 2031 EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
6422398c2ab092 Vlad Yasevich 2015-01-31 2032
6422398c2ab092 Vlad Yasevich 2015-01-31 @2033 struct sk_buff *ip6_make_skb(struct sock *sk,
Hi shiming, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] [also build test ERROR on net/main soc/for-next linus/master v6.13-rc5 next-20241220] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/shiming-cheng/ipv6-socket-SO_BINDTODEVICE-lookup-routing-fail-without-IPv6-rule/20250102-174939 base: net-next/main patch link: https://lore.kernel.org/r/20250102095114.25860-1-shiming.cheng%40mediatek.com patch subject: [PATCH] ipv6: socket SO_BINDTODEVICE lookup routing fail without IPv6 rule. config: riscv-randconfig-001-20250102 (https://download.01.org/0day-ci/archive/20250102/202501022057.YOhf05jy-lkp@intel.com/config) compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250102/202501022057.YOhf05jy-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501022057.YOhf05jy-lkp@intel.com/ All errors (new ones prefixed by >>): >> net/ipv6/ip6_output.c:1239:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1259:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1294:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1311:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1317:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1327:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1348:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1429:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1834:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1867:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1876:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1898:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1978:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:1998:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:2013:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:2027:1: error: function definition is not allowed here { ^ net/ipv6/ip6_output.c:2039:1: error: function definition is not allowed here { ^ >> net/ipv6/ip6_output.c:2074:2: error: expected '}' } ^ net/ipv6/ip6_output.c:1107:1: note: to match this '{' { ^ 18 errors generated. vim +1239 net/ipv6/ip6_output.c 34a0b3cdc07874 Adrian Bunk 2005-11-29 1225 497c615abad7ee Herbert Xu 2006-07-30 1226 /** 497c615abad7ee Herbert Xu 2006-07-30 1227 * ip6_dst_lookup - perform route lookup on flow b51cd7c834dba0 Andrew Lunn 2020-07-13 1228 * @net: Network namespace to perform lookup in 497c615abad7ee Herbert Xu 2006-07-30 1229 * @sk: socket which provides route info 497c615abad7ee Herbert Xu 2006-07-30 1230 * @dst: pointer to dst_entry * for result 4c9483b2fb5d25 David S. Miller 2011-03-12 1231 * @fl6: flow to lookup 497c615abad7ee Herbert Xu 2006-07-30 1232 * 497c615abad7ee Herbert Xu 2006-07-30 1233 * This function performs a route lookup on the given flow. 497c615abad7ee Herbert Xu 2006-07-30 1234 * 497c615abad7ee Herbert Xu 2006-07-30 1235 * It returns zero on success, or a standard errno code on error. 497c615abad7ee Herbert Xu 2006-07-30 1236 */ 343d60aada5a35 Roopa Prabhu 2015-07-30 1237 int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, 343d60aada5a35 Roopa Prabhu 2015-07-30 1238 struct flowi6 *fl6) 497c615abad7ee Herbert Xu 2006-07-30 @1239 { 497c615abad7ee Herbert Xu 2006-07-30 1240 *dst = NULL; 343d60aada5a35 Roopa Prabhu 2015-07-30 1241 return ip6_dst_lookup_tail(net, sk, dst, fl6); 497c615abad7ee Herbert Xu 2006-07-30 1242 } 3cf3dc6c2e05e6 Arnaldo Carvalho de Melo 2005-12-13 1243 EXPORT_SYMBOL_GPL(ip6_dst_lookup); 3cf3dc6c2e05e6 Arnaldo Carvalho de Melo 2005-12-13 1244
Hi shiming, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] [also build test ERROR on net/main linus/master v6.13-rc5 next-20241220] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/shiming-cheng/ipv6-socket-SO_BINDTODEVICE-lookup-routing-fail-without-IPv6-rule/20250102-174939 base: net-next/main patch link: https://lore.kernel.org/r/20250102095114.25860-1-shiming.cheng%40mediatek.com patch subject: [PATCH] ipv6: socket SO_BINDTODEVICE lookup routing fail without IPv6 rule. config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20250102/202501022159.X5KKqJoW-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-12) 11.3.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250102/202501022159.X5KKqJoW-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202501022159.X5KKqJoW-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: net/ipv6/ip6_output.c: In function 'ip6_dst_lookup_tail': >> net/ipv6/ip6_output.c:1243:19: error: non-static declaration of 'ip6_dst_lookup' follows static declaration 1243 | EXPORT_SYMBOL_GPL(ip6_dst_lookup); | ^~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1243:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 1243 | EXPORT_SYMBOL_GPL(ip6_dst_lookup); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1237:5: note: previous definition of 'ip6_dst_lookup' with type 'int(struct net *, struct sock *, struct dst_entry **, struct flowi6 *)' 1237 | int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, | ^~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: >> net/ipv6/ip6_output.c:1271:19: error: non-static declaration of 'ip6_dst_lookup_flow' follows static declaration 1271 | EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); | ^~~~~~~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1271:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 1271 | EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1257:19: note: previous definition of 'ip6_dst_lookup_flow' with type 'struct dst_entry *(struct net *, const struct sock *, struct flowi6 *, const struct in6_addr *)' 1257 | struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, | ^~~~~~~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: >> net/ipv6/ip6_output.c:1307:19: error: non-static declaration of 'ip6_sk_dst_lookup_flow' follows static declaration 1307 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); | ^~~~~~~~~~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1307:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 1307 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1291:19: note: previous definition of 'ip6_sk_dst_lookup_flow' with type 'struct dst_entry *(struct sock *, struct flowi6 *, const struct in6_addr *, bool)' {aka 'struct dst_entry *(struct sock *, struct flowi6 *, const struct in6_addr *, _Bool)'} 1291 | struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, | ^~~~~~~~~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1309:36: error: invalid storage class for function 'ip6_opt_dup' 1309 | static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, | ^~~~~~~~~~~ >> net/ipv6/ip6_output.c:1315:35: error: invalid storage class for function 'ip6_rthdr_dup' 1315 | static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, | ^~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1321:13: error: invalid storage class for function 'ip6_append_data_mtu' 1321 | static void ip6_append_data_mtu(unsigned int *mtu, | ^~~~~~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1345:12: error: invalid storage class for function 'ip6_setup_cork' 1345 | static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, | ^~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1420:12: error: invalid storage class for function '__ip6_append_data' 1420 | static int __ip6_append_data(struct sock *sk, | ^~~~~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: >> net/ipv6/ip6_output.c:1864:19: error: non-static declaration of 'ip6_append_data' follows static declaration 1864 | EXPORT_SYMBOL_GPL(ip6_append_data); | ^~~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1864:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 1864 | EXPORT_SYMBOL_GPL(ip6_append_data); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1828:5: note: previous definition of 'ip6_append_data' with type 'int(struct sock *, int (*)(void *, char *, int, int, int, struct sk_buff *), void *, size_t, int, struct ipcm6_cookie *, struct flowi6 *, struct rt6_info *, unsigned int)' {aka 'int(struct sock *, int (*)(void *, char *, int, int, int, struct sk_buff *), void *, long unsigned int, int, struct ipcm6_cookie *, struct flowi6 *, struct rt6_info *, unsigned int)'} 1828 | int ip6_append_data(struct sock *sk, | ^~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1866:13: error: invalid storage class for function 'ip6_cork_steal_dst' 1866 | static void ip6_cork_steal_dst(struct sk_buff *skb, struct inet_cork_full *cork) | ^~~~~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:1874:13: error: invalid storage class for function 'ip6_cork_release' 1874 | static void ip6_cork_release(struct inet_cork_full *cork, | ^~~~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: >> net/ipv6/ip6_output.c:2007:19: error: non-static declaration of 'ip6_push_pending_frames' follows static declaration 2007 | EXPORT_SYMBOL_GPL(ip6_push_pending_frames); | ^~~~~~~~~~~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:2007:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 2007 | EXPORT_SYMBOL_GPL(ip6_push_pending_frames); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:1997:5: note: previous definition of 'ip6_push_pending_frames' with type 'int(struct sock *)' 1997 | int ip6_push_pending_frames(struct sock *sk) | ^~~~~~~~~~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:2009:13: error: invalid storage class for function '__ip6_flush_pending_frames' 2009 | static void __ip6_flush_pending_frames(struct sock *sk, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from include/linux/linkage.h:7, from include/linux/kernel.h:18, from net/ipv6/ip6_output.c:26: >> net/ipv6/ip6_output.c:2031:19: error: non-static declaration of 'ip6_flush_pending_frames' follows static declaration 2031 | EXPORT_SYMBOL_GPL(ip6_flush_pending_frames); | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/export.h:56:28: note: in definition of macro '__EXPORT_SYMBOL' 56 | extern typeof(sym) sym; \ | ^~~ include/linux/export.h:69:41: note: in expansion of macro '_EXPORT_SYMBOL' 69 | #define EXPORT_SYMBOL_GPL(sym) _EXPORT_SYMBOL(sym, "GPL") | ^~~~~~~~~~~~~~ net/ipv6/ip6_output.c:2031:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL' 2031 | EXPORT_SYMBOL_GPL(ip6_flush_pending_frames); | ^~~~~~~~~~~~~~~~~ net/ipv6/ip6_output.c:2026:6: note: previous definition of 'ip6_flush_pending_frames' with type 'void(struct sock *)' 2026 | void ip6_flush_pending_frames(struct sock *sk) | ^~~~~~~~~~~~~~~~~~~~~~~~ >> net/ipv6/ip6_output.c:2074:1: error: expected declaration or statement at end of input 2074 | } | ^ At top level: net/ipv6/ip6_output.c:2033:17: warning: 'ip6_make_skb' defined but not used [-Wunused-function] 2033 | struct sk_buff *ip6_make_skb(struct sock *sk, | ^~~~~~~~~~~~ vim +/ip6_dst_lookup +1243 net/ipv6/ip6_output.c 34a0b3cdc07874 Adrian Bunk 2005-11-29 1225 497c615abad7ee Herbert Xu 2006-07-30 1226 /** 497c615abad7ee Herbert Xu 2006-07-30 1227 * ip6_dst_lookup - perform route lookup on flow b51cd7c834dba0 Andrew Lunn 2020-07-13 1228 * @net: Network namespace to perform lookup in 497c615abad7ee Herbert Xu 2006-07-30 1229 * @sk: socket which provides route info 497c615abad7ee Herbert Xu 2006-07-30 1230 * @dst: pointer to dst_entry * for result 4c9483b2fb5d25 David S. Miller 2011-03-12 1231 * @fl6: flow to lookup 497c615abad7ee Herbert Xu 2006-07-30 1232 * 497c615abad7ee Herbert Xu 2006-07-30 1233 * This function performs a route lookup on the given flow. 497c615abad7ee Herbert Xu 2006-07-30 1234 * 497c615abad7ee Herbert Xu 2006-07-30 1235 * It returns zero on success, or a standard errno code on error. 497c615abad7ee Herbert Xu 2006-07-30 1236 */ 343d60aada5a35 Roopa Prabhu 2015-07-30 1237 int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, 343d60aada5a35 Roopa Prabhu 2015-07-30 1238 struct flowi6 *fl6) 497c615abad7ee Herbert Xu 2006-07-30 1239 { 497c615abad7ee Herbert Xu 2006-07-30 1240 *dst = NULL; 343d60aada5a35 Roopa Prabhu 2015-07-30 1241 return ip6_dst_lookup_tail(net, sk, dst, fl6); 497c615abad7ee Herbert Xu 2006-07-30 1242 } 3cf3dc6c2e05e6 Arnaldo Carvalho de Melo 2005-12-13 @1243 EXPORT_SYMBOL_GPL(ip6_dst_lookup); 3cf3dc6c2e05e6 Arnaldo Carvalho de Melo 2005-12-13 1244 497c615abad7ee Herbert Xu 2006-07-30 1245 /** 68d0c6d34d586a David S. Miller 2011-03-01 1246 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec b51cd7c834dba0 Andrew Lunn 2020-07-13 1247 * @net: Network namespace to perform lookup in 68d0c6d34d586a David S. Miller 2011-03-01 1248 * @sk: socket which provides route info 4c9483b2fb5d25 David S. Miller 2011-03-12 1249 * @fl6: flow to lookup 68d0c6d34d586a David S. Miller 2011-03-01 1250 * @final_dst: final destination address for ipsec lookup 68d0c6d34d586a David S. Miller 2011-03-01 1251 * 68d0c6d34d586a David S. Miller 2011-03-01 1252 * This function performs a route lookup on the given flow. 68d0c6d34d586a David S. Miller 2011-03-01 1253 * 68d0c6d34d586a David S. Miller 2011-03-01 1254 * It returns a valid dst pointer on success, or a pointer encoded 68d0c6d34d586a David S. Miller 2011-03-01 1255 * error code. 68d0c6d34d586a David S. Miller 2011-03-01 1256 */ c4e85f73afb638 Sabrina Dubroca 2019-12-04 1257 struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, 0e0d44ab427554 Steffen Klassert 2013-08-28 1258 const struct in6_addr *final_dst) 68d0c6d34d586a David S. Miller 2011-03-01 1259 { 68d0c6d34d586a David S. Miller 2011-03-01 1260 struct dst_entry *dst = NULL; 68d0c6d34d586a David S. Miller 2011-03-01 1261 int err; 68d0c6d34d586a David S. Miller 2011-03-01 1262 c4e85f73afb638 Sabrina Dubroca 2019-12-04 1263 err = ip6_dst_lookup_tail(net, sk, &dst, fl6); 68d0c6d34d586a David S. Miller 2011-03-01 1264 if (err) 68d0c6d34d586a David S. Miller 2011-03-01 1265 return ERR_PTR(err); 68d0c6d34d586a David S. Miller 2011-03-01 1266 if (final_dst) 4e3fd7a06dc20b Alexey Dobriyan 2011-11-21 1267 fl6->daddr = *final_dst; 2774c131b1d199 David S. Miller 2011-03-01 1268 c4e85f73afb638 Sabrina Dubroca 2019-12-04 1269 return xfrm_lookup_route(net, dst, flowi6_to_flowi(fl6), sk, 0); 68d0c6d34d586a David S. Miller 2011-03-01 1270 } 68d0c6d34d586a David S. Miller 2011-03-01 @1271 EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); 68d0c6d34d586a David S. Miller 2011-03-01 1272 68d0c6d34d586a David S. Miller 2011-03-01 1273 /** 68d0c6d34d586a David S. Miller 2011-03-01 1274 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow 497c615abad7ee Herbert Xu 2006-07-30 1275 * @sk: socket which provides the dst cache and route info 4c9483b2fb5d25 David S. Miller 2011-03-12 1276 * @fl6: flow to lookup 68d0c6d34d586a David S. Miller 2011-03-01 1277 * @final_dst: final destination address for ipsec lookup 96818159c3c089 Alexey Kodanev 2018-04-03 1278 * @connected: whether @sk is connected or not 497c615abad7ee Herbert Xu 2006-07-30 1279 * 497c615abad7ee Herbert Xu 2006-07-30 1280 * This function performs a route lookup on the given flow with the 497c615abad7ee Herbert Xu 2006-07-30 1281 * possibility of using the cached route in the socket if it is valid. 497c615abad7ee Herbert Xu 2006-07-30 1282 * It will take the socket dst lock when operating on the dst cache. 497c615abad7ee Herbert Xu 2006-07-30 1283 * As a result, this function can only be used in process context. 497c615abad7ee Herbert Xu 2006-07-30 1284 * 96818159c3c089 Alexey Kodanev 2018-04-03 1285 * In addition, for a connected socket, cache the dst in the socket 96818159c3c089 Alexey Kodanev 2018-04-03 1286 * if the current cache is not valid. 96818159c3c089 Alexey Kodanev 2018-04-03 1287 * 68d0c6d34d586a David S. Miller 2011-03-01 1288 * It returns a valid dst pointer on success, or a pointer encoded 68d0c6d34d586a David S. Miller 2011-03-01 1289 * error code. 497c615abad7ee Herbert Xu 2006-07-30 1290 */ 4c9483b2fb5d25 David S. Miller 2011-03-12 1291 struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, 96818159c3c089 Alexey Kodanev 2018-04-03 1292 const struct in6_addr *final_dst, 96818159c3c089 Alexey Kodanev 2018-04-03 1293 bool connected) 497c615abad7ee Herbert Xu 2006-07-30 1294 { 68d0c6d34d586a David S. Miller 2011-03-01 1295 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); 497c615abad7ee Herbert Xu 2006-07-30 1296 4c9483b2fb5d25 David S. Miller 2011-03-12 1297 dst = ip6_sk_dst_check(sk, dst, fl6); 96818159c3c089 Alexey Kodanev 2018-04-03 1298 if (dst) 96818159c3c089 Alexey Kodanev 2018-04-03 1299 return dst; 96818159c3c089 Alexey Kodanev 2018-04-03 1300 c4e85f73afb638 Sabrina Dubroca 2019-12-04 1301 dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_dst); 96818159c3c089 Alexey Kodanev 2018-04-03 1302 if (connected && !IS_ERR(dst)) 96818159c3c089 Alexey Kodanev 2018-04-03 1303 ip6_sk_dst_store_flow(sk, dst_clone(dst), fl6); 68d0c6d34d586a David S. Miller 2011-03-01 1304 00bc0ef5880dc7 Jakub Sitnicki 2016-06-08 1305 return dst; 497c615abad7ee Herbert Xu 2006-07-30 1306 } 68d0c6d34d586a David S. Miller 2011-03-01 @1307 EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); 497c615abad7ee Herbert Xu 2006-07-30 1308 0178b695fd6b40 Herbert Xu 2009-02-05 @1309 static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, 0178b695fd6b40 Herbert Xu 2009-02-05 1310 gfp_t gfp) 0178b695fd6b40 Herbert Xu 2009-02-05 1311 { 0178b695fd6b40 Herbert Xu 2009-02-05 1312 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; 0178b695fd6b40 Herbert Xu 2009-02-05 1313 } 0178b695fd6b40 Herbert Xu 2009-02-05 1314 0178b695fd6b40 Herbert Xu 2009-02-05 @1315 static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, 0178b695fd6b40 Herbert Xu 2009-02-05 1316 gfp_t gfp) 0178b695fd6b40 Herbert Xu 2009-02-05 1317 { 0178b695fd6b40 Herbert Xu 2009-02-05 1318 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; 0178b695fd6b40 Herbert Xu 2009-02-05 1319 } 0178b695fd6b40 Herbert Xu 2009-02-05 1320 75a493e60ac4bb Hannes Frederic Sowa 2013-07-02 @1321 static void ip6_append_data_mtu(unsigned int *mtu, 0c1833797a5a6e Gao feng 2012-05-26 1322 int *maxfraglen, 0c1833797a5a6e Gao feng 2012-05-26 1323 unsigned int fragheaderlen, 0c1833797a5a6e Gao feng 2012-05-26 1324 struct sk_buff *skb, 75a493e60ac4bb Hannes Frederic Sowa 2013-07-02 1325 struct rt6_info *rt, e367c2d03dba4c lucien 2014-03-17 1326 unsigned int orig_mtu) 0c1833797a5a6e Gao feng 2012-05-26 1327 { 0c1833797a5a6e Gao feng 2012-05-26 1328 if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { 63159f29be1df7 Ian Morris 2015-03-29 1329 if (!skb) { 0c1833797a5a6e Gao feng 2012-05-26 1330 /* first fragment, reserve header_len */ e367c2d03dba4c lucien 2014-03-17 1331 *mtu = orig_mtu - rt->dst.header_len; 0c1833797a5a6e Gao feng 2012-05-26 1332 0c1833797a5a6e Gao feng 2012-05-26 1333 } else { 0c1833797a5a6e Gao feng 2012-05-26 1334 /* 0c1833797a5a6e Gao feng 2012-05-26 1335 * this fragment is not first, the headers 0c1833797a5a6e Gao feng 2012-05-26 1336 * space is regarded as data space. 0c1833797a5a6e Gao feng 2012-05-26 1337 */ e367c2d03dba4c lucien 2014-03-17 1338 *mtu = orig_mtu; 0c1833797a5a6e Gao feng 2012-05-26 1339 } 0c1833797a5a6e Gao feng 2012-05-26 1340 *maxfraglen = ((*mtu - fragheaderlen) & ~7) 0c1833797a5a6e Gao feng 2012-05-26 1341 + fragheaderlen - sizeof(struct frag_hdr); 0c1833797a5a6e Gao feng 2012-05-26 1342 } 0c1833797a5a6e Gao feng 2012-05-26 1343 } 0c1833797a5a6e Gao feng 2012-05-26 1344 366e41d9774d70 Vlad Yasevich 2015-01-31 @1345 static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, 26879da58711aa Wei Wang 2016-05-02 1346 struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6, f37a4cc6bb0ba0 Pavel Begunkov 2022-01-27 1347 struct rt6_info *rt) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1348 { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1349 struct ipv6_pinfo *np = inet6_sk(sk); 15f926c4457aa6 Eric Dumazet 2023-09-12 1350 unsigned int mtu, frag_size; d656b2ea5fa797 Pavel Begunkov 2022-01-27 1351 struct ipv6_txoptions *nopt, *opt = ipc6->opt; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1352 40ac240c2e06e4 Pavel Begunkov 2022-01-27 1353 /* callers pass dst together with a reference, set it first so 40ac240c2e06e4 Pavel Begunkov 2022-01-27 1354 * ip6_cork_release() can put it down even in case of an error. 40ac240c2e06e4 Pavel Begunkov 2022-01-27 1355 */ 40ac240c2e06e4 Pavel Begunkov 2022-01-27 1356 cork->base.dst = &rt->dst; 40ac240c2e06e4 Pavel Begunkov 2022-01-27 1357 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1358 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1359 * setup for corking ^1da177e4c3f41 Linus Torvalds 2005-04-16 1360 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 1361 if (opt) { 366e41d9774d70 Vlad Yasevich 2015-01-31 1362 if (WARN_ON(v6_cork->opt)) 0178b695fd6b40 Herbert Xu 2009-02-05 1363 return -EINVAL; 0178b695fd6b40 Herbert Xu 2009-02-05 1364 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1365 nopt = v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1366 if (unlikely(!nopt)) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1367 return -ENOBUFS; 0178b695fd6b40 Herbert Xu 2009-02-05 1368 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1369 nopt->tot_len = sizeof(*opt); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1370 nopt->opt_flen = opt->opt_flen; d656b2ea5fa797 Pavel Begunkov 2022-01-27 1371 nopt->opt_nflen = opt->opt_nflen; 0178b695fd6b40 Herbert Xu 2009-02-05 1372 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1373 nopt->dst0opt = ip6_opt_dup(opt->dst0opt, sk->sk_allocation); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1374 if (opt->dst0opt && !nopt->dst0opt) 0178b695fd6b40 Herbert Xu 2009-02-05 1375 return -ENOBUFS; 0178b695fd6b40 Herbert Xu 2009-02-05 1376 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1377 nopt->dst1opt = ip6_opt_dup(opt->dst1opt, sk->sk_allocation); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1378 if (opt->dst1opt && !nopt->dst1opt) 0178b695fd6b40 Herbert Xu 2009-02-05 1379 return -ENOBUFS; 0178b695fd6b40 Herbert Xu 2009-02-05 1380 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1381 nopt->hopopt = ip6_opt_dup(opt->hopopt, sk->sk_allocation); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1382 if (opt->hopopt && !nopt->hopopt) 0178b695fd6b40 Herbert Xu 2009-02-05 1383 return -ENOBUFS; 0178b695fd6b40 Herbert Xu 2009-02-05 1384 d656b2ea5fa797 Pavel Begunkov 2022-01-27 1385 nopt->srcrt = ip6_rthdr_dup(opt->srcrt, sk->sk_allocation); d656b2ea5fa797 Pavel Begunkov 2022-01-27 1386 if (opt->srcrt && !nopt->srcrt) 0178b695fd6b40 Herbert Xu 2009-02-05 1387 return -ENOBUFS; 0178b695fd6b40 Herbert Xu 2009-02-05 1388 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1389 /* need source address above miyazawa*/ ^1da177e4c3f41 Linus Torvalds 2005-04-16 1390 } 26879da58711aa Wei Wang 2016-05-02 1391 v6_cork->hop_limit = ipc6->hlimit; 26879da58711aa Wei Wang 2016-05-02 1392 v6_cork->tclass = ipc6->tclass; 0c1833797a5a6e Gao feng 2012-05-26 1393 if (rt->dst.flags & DST_XFRM_TUNNEL) 6b724bc4300b43 Eric Dumazet 2023-09-12 1394 mtu = READ_ONCE(np->pmtudisc) >= IPV6_PMTUDISC_PROBE ? 749439bfac6e1a Mike Maloney 2018-01-10 1395 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); 0c1833797a5a6e Gao feng 2012-05-26 1396 else 6b724bc4300b43 Eric Dumazet 2023-09-12 1397 mtu = READ_ONCE(np->pmtudisc) >= IPV6_PMTUDISC_PROBE ? c02b3741eb99a1 David S. Miller 2018-01-17 1398 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(xfrm_dst_path(&rt->dst)); 15f926c4457aa6 Eric Dumazet 2023-09-12 1399 15f926c4457aa6 Eric Dumazet 2023-09-12 1400 frag_size = READ_ONCE(np->frag_size); 15f926c4457aa6 Eric Dumazet 2023-09-12 1401 if (frag_size && frag_size < mtu) 15f926c4457aa6 Eric Dumazet 2023-09-12 1402 mtu = frag_size; 15f926c4457aa6 Eric Dumazet 2023-09-12 1403 366e41d9774d70 Vlad Yasevich 2015-01-31 1404 cork->base.fragsize = mtu; fbf47813607ba8 Willem de Bruijn 2018-07-06 1405 cork->base.gso_size = ipc6->gso_size; 678ca42d688534 Willem de Bruijn 2018-07-06 1406 cork->base.tx_flags = 0; c6af0c227a22bb Willem de Bruijn 2019-09-11 1407 cork->base.mark = ipc6->sockc.mark; a32f3e9d1ed146 Anna Emese Nyiri 2024-12-13 1408 cork->base.priority = ipc6->sockc.priority; 822b5bc6db55f1 Vadim Fedorenko 2024-10-01 1409 sock_tx_timestamp(sk, &ipc6->sockc, &cork->base.tx_flags); 4aecca4c76808f Vadim Fedorenko 2024-10-01 1410 if (ipc6->sockc.tsflags & SOCKCM_FLAG_TS_OPT_ID) { 4aecca4c76808f Vadim Fedorenko 2024-10-01 1411 cork->base.flags |= IPCORK_TS_OPT_ID; 4aecca4c76808f Vadim Fedorenko 2024-10-01 1412 cork->base.ts_opt_id = ipc6->sockc.ts_opt_id; 4aecca4c76808f Vadim Fedorenko 2024-10-01 1413 } 366e41d9774d70 Vlad Yasevich 2015-01-31 1414 cork->base.length = 0; 5fdaa88dfefa87 Willem de Bruijn 2018-07-06 1415 cork->base.transmit_time = ipc6->sockc.transmit_time; a818f75e311c23 Jesus Sanchez-Palencia 2018-07-03 1416 366e41d9774d70 Vlad Yasevich 2015-01-31 1417 return 0; 366e41d9774d70 Vlad Yasevich 2015-01-31 1418 } 366e41d9774d70 Vlad Yasevich 2015-01-31 1419 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 @1420 static int __ip6_append_data(struct sock *sk, 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1421 struct sk_buff_head *queue, f3b46a3e8c4030 Pavel Begunkov 2022-01-27 1422 struct inet_cork_full *cork_full, 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1423 struct inet6_cork *v6_cork, 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1424 struct page_frag *pfrag, 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1425 int getfrag(void *from, char *to, int offset, 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1426 int len, int odd, struct sk_buff *skb), f93431c86b631b Wang Yufen 2022-06-07 1427 void *from, size_t length, int transhdrlen, 5fdaa88dfefa87 Willem de Bruijn 2018-07-06 1428 unsigned int flags, struct ipcm6_cookie *ipc6) 366e41d9774d70 Vlad Yasevich 2015-01-31 1429 { 366e41d9774d70 Vlad Yasevich 2015-01-31 1430 struct sk_buff *skb, *skb_prev = NULL; f3b46a3e8c4030 Pavel Begunkov 2022-01-27 1431 struct inet_cork *cork = &cork_full->base; f37a4cc6bb0ba0 Pavel Begunkov 2022-01-27 1432 struct flowi6 *fl6 = &cork_full->fl.u.ip6; 10b8a3de603df7 Paolo Abeni 2018-03-23 1433 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu; b5947e5d1e710c Willem de Bruijn 2018-11-30 1434 struct ubuf_info *uarg = NULL; 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1435 int exthdrlen = 0; 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1436 int dst_exthdrlen = 0; 366e41d9774d70 Vlad Yasevich 2015-01-31 1437 int hh_len; 366e41d9774d70 Vlad Yasevich 2015-01-31 1438 int copy; 366e41d9774d70 Vlad Yasevich 2015-01-31 1439 int err; 366e41d9774d70 Vlad Yasevich 2015-01-31 1440 int offset = 0; 773ba4fe9104a6 Pavel Begunkov 2022-07-12 1441 bool zc = false; 366e41d9774d70 Vlad Yasevich 2015-01-31 1442 u32 tskey = 0; e8dfd42c17faf1 Eric Dumazet 2024-04-26 1443 struct rt6_info *rt = dst_rt6_info(cork->dst); 4aecca4c76808f Vadim Fedorenko 2024-10-01 1444 bool paged, hold_tskey = false, extra_uref = false; 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1445 struct ipv6_txoptions *opt = v6_cork->opt; 32dce968dd987a Vlad Yasevich 2015-01-31 1446 int csummode = CHECKSUM_NONE; 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1447 unsigned int maxnonfragsize, headersize; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1448 unsigned int wmem_alloc_delta = 0; 366e41d9774d70 Vlad Yasevich 2015-01-31 1449 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1450 skb = skb_peek_tail(queue); 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1451 if (!skb) { 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1452 exthdrlen = opt ? opt->opt_flen : 0; 7efdba5bd9a2f3 Romain KUNTZ 2013-01-16 1453 dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1454 } 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1455 15e36f5b8e982d Willem de Bruijn 2018-04-26 1456 paged = !!cork->gso_size; bec1f6f697362c Willem de Bruijn 2018-04-26 1457 mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize; e367c2d03dba4c lucien 2014-03-17 1458 orig_mtu = mtu; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1459 d8d1f30b95a635 Changli Gao 2010-06-10 1460 hh_len = LL_RESERVED_SPACE(rt->dst.dev); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1461 a1b051405bc162 Masahide NAKAMURA 2007-12-20 1462 fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + b4ce92775c2e7f Herbert Xu 2007-11-13 1463 (opt ? opt->opt_nflen : 0); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1464 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1465 headersize = sizeof(struct ipv6hdr) + 3a1cebe7e05027 Hannes Frederic Sowa 2014-05-11 1466 (opt ? opt->opt_flen + opt->opt_nflen : 0) + 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1467 rt->rt6i_nfheader_len; 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1468 5e34af4142ffe6 Tadeusz Struk 2022-03-10 1469 if (mtu <= fragheaderlen || 5e34af4142ffe6 Tadeusz Struk 2022-03-10 1470 ((mtu - fragheaderlen) & ~7) + fragheaderlen <= sizeof(struct frag_hdr)) 6596a022954127 Jiri Bohac 2022-01-19 1471 goto emsgsize; 6596a022954127 Jiri Bohac 2022-01-19 1472 6596a022954127 Jiri Bohac 2022-01-19 1473 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - 6596a022954127 Jiri Bohac 2022-01-19 1474 sizeof(struct frag_hdr); 6596a022954127 Jiri Bohac 2022-01-19 1475 10b8a3de603df7 Paolo Abeni 2018-03-23 1476 /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit 10b8a3de603df7 Paolo Abeni 2018-03-23 1477 * the first fragment 10b8a3de603df7 Paolo Abeni 2018-03-23 1478 */ 10b8a3de603df7 Paolo Abeni 2018-03-23 1479 if (headersize + transhdrlen > mtu) 10b8a3de603df7 Paolo Abeni 2018-03-23 1480 goto emsgsize; 10b8a3de603df7 Paolo Abeni 2018-03-23 1481 26879da58711aa Wei Wang 2016-05-02 1482 if (cork->length + length > mtu - headersize && ipc6->dontfrag && 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1483 (sk->sk_protocol == IPPROTO_UDP || 13651224c00b74 Jakub Kicinski 2022-02-16 1484 sk->sk_protocol == IPPROTO_ICMPV6 || 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1485 sk->sk_protocol == IPPROTO_RAW)) { 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1486 ipv6_local_rxpmtu(sk, fl6, mtu - headersize + 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1487 sizeof(struct ipv6hdr)); 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1488 goto emsgsize; 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1489 } 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1490 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1491 if (ip6_sk_ignore_df(sk)) 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1492 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN; 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1493 else 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1494 maxnonfragsize = mtu; 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1495 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1496 if (cork->length + length > maxnonfragsize - headersize) { 4df98e76cde7c6 Hannes Frederic Sowa 2013-12-16 1497 emsgsize: 10b8a3de603df7 Paolo Abeni 2018-03-23 1498 pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0); 10b8a3de603df7 Paolo Abeni 2018-03-23 1499 ipv6_local_error(sk, EMSGSIZE, fl6, pmtu); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1500 return -EMSGSIZE; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1501 } 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1502 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1503 /* CHECKSUM_PARTIAL only with no extension headers and when 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1504 * we are not going to fragment 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1505 */ 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1506 if (transhdrlen && sk->sk_protocol == IPPROTO_UDP && 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1507 headersize == sizeof(struct ipv6hdr) && 2b89ed65a6f201 Vlad Yasevich 2017-01-29 1508 length <= mtu - headersize && bec1f6f697362c Willem de Bruijn 2018-04-26 1509 (!(flags & MSG_MORE) || cork->gso_size) && c8cd0989bd151f Tom Herbert 2015-12-14 1510 rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) 682b1a9d3f9686 Hannes Frederic Sowa 2015-10-27 1511 csummode = CHECKSUM_PARTIAL; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1512 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1513 if ((flags & MSG_ZEROCOPY) && length) { 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1514 struct msghdr *msg = from; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1515 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1516 if (getfrag == ip_generic_getfrag && msg->msg_ubuf) { 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1517 if (skb_zcopy(skb) && msg->msg_ubuf != skb_zcopy(skb)) 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1518 return -EINVAL; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1519 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1520 /* Leave uarg NULL if can't zerocopy, callers should 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1521 * be able to handle it. 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1522 */ 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1523 if ((rt->dst.dev->features & NETIF_F_SG) && 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1524 csummode == CHECKSUM_PARTIAL) { 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1525 paged = true; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1526 zc = true; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1527 uarg = msg->msg_ubuf; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1528 } 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1529 } else if (sock_flag(sk, SOCK_ZEROCOPY)) { 8c793822c5803e Jonathan Lemon 2021-01-06 1530 uarg = msg_zerocopy_realloc(sk, length, skb_zcopy(skb)); b5947e5d1e710c Willem de Bruijn 2018-11-30 1531 if (!uarg) b5947e5d1e710c Willem de Bruijn 2018-11-30 1532 return -ENOBUFS; 522924b583082f Willem de Bruijn 2019-06-07 1533 extra_uref = !skb_zcopy(skb); /* only ref on new uarg */ b5947e5d1e710c Willem de Bruijn 2018-11-30 1534 if (rt->dst.dev->features & NETIF_F_SG && b5947e5d1e710c Willem de Bruijn 2018-11-30 1535 csummode == CHECKSUM_PARTIAL) { b5947e5d1e710c Willem de Bruijn 2018-11-30 1536 paged = true; 773ba4fe9104a6 Pavel Begunkov 2022-07-12 1537 zc = true; b5947e5d1e710c Willem de Bruijn 2018-11-30 1538 } else { e7d2b510165fff Pavel Begunkov 2022-09-23 1539 uarg_to_msgzc(uarg)->zerocopy = 0; 52900d22288e7d Willem de Bruijn 2018-11-30 1540 skb_zcopy_set(skb, uarg, &extra_uref); b5947e5d1e710c Willem de Bruijn 2018-11-30 1541 } b5947e5d1e710c Willem de Bruijn 2018-11-30 1542 } 6d8192bd69bb43 David Howells 2023-05-22 1543 } else if ((flags & MSG_SPLICE_PAGES) && length) { cafbe182a467bf Eric Dumazet 2023-08-16 1544 if (inet_test_bit(HDRINCL, sk)) 6d8192bd69bb43 David Howells 2023-05-22 1545 return -EPERM; 5a6f6873606e03 David Howells 2023-06-14 1546 if (rt->dst.dev->features & NETIF_F_SG && 5a6f6873606e03 David Howells 2023-06-14 1547 getfrag == ip_generic_getfrag) 6d8192bd69bb43 David Howells 2023-05-22 1548 /* We need an empty buffer to attach stuff to */ 6d8192bd69bb43 David Howells 2023-05-22 1549 paged = true; 6d8192bd69bb43 David Howells 2023-05-22 1550 else 6d8192bd69bb43 David Howells 2023-05-22 1551 flags &= ~MSG_SPLICE_PAGES; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1552 } b5947e5d1e710c Willem de Bruijn 2018-11-30 1553 4aecca4c76808f Vadim Fedorenko 2024-10-01 1554 if (cork->tx_flags & SKBTX_ANY_TSTAMP && 4aecca4c76808f Vadim Fedorenko 2024-10-01 1555 READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) { 4aecca4c76808f Vadim Fedorenko 2024-10-01 1556 if (cork->flags & IPCORK_TS_OPT_ID) { 4aecca4c76808f Vadim Fedorenko 2024-10-01 1557 tskey = cork->ts_opt_id; 4aecca4c76808f Vadim Fedorenko 2024-10-01 1558 } else { 488b6d91b07112 Vadim Fedorenko 2024-02-13 1559 tskey = atomic_inc_return(&sk->sk_tskey) - 1; 4aecca4c76808f Vadim Fedorenko 2024-10-01 1560 hold_tskey = true; 4aecca4c76808f Vadim Fedorenko 2024-10-01 1561 } 4aecca4c76808f Vadim Fedorenko 2024-10-01 1562 } 488b6d91b07112 Vadim Fedorenko 2024-02-13 1563 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1564 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1565 * Let's try using as much space as possible. ^1da177e4c3f41 Linus Torvalds 2005-04-16 1566 * Use MTU if total length of the message fits into the MTU. ^1da177e4c3f41 Linus Torvalds 2005-04-16 1567 * Otherwise, we need to reserve fragment header and ^1da177e4c3f41 Linus Torvalds 2005-04-16 1568 * fragment alignment (= 8-15 octects, in total). ^1da177e4c3f41 Linus Torvalds 2005-04-16 1569 * 634a63e73f0594 Randy Dunlap 2020-09-17 1570 * Note that we may need to "move" the data from the tail ^1da177e4c3f41 Linus Torvalds 2005-04-16 1571 * of the buffer to the new fragment when we split ^1da177e4c3f41 Linus Torvalds 2005-04-16 1572 * the message. ^1da177e4c3f41 Linus Torvalds 2005-04-16 1573 * ^1da177e4c3f41 Linus Torvalds 2005-04-16 1574 * FIXME: It may be fragmented into multiple chunks ^1da177e4c3f41 Linus Torvalds 2005-04-16 1575 * at once if non-fragmentable extension headers ^1da177e4c3f41 Linus Torvalds 2005-04-16 1576 * are too large. ^1da177e4c3f41 Linus Torvalds 2005-04-16 1577 * --yoshfuji ^1da177e4c3f41 Linus Torvalds 2005-04-16 1578 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 1579 2811ebac2521ce Hannes Frederic Sowa 2013-09-21 1580 cork->length += length; 2811ebac2521ce Hannes Frederic Sowa 2013-09-21 1581 if (!skb) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1582 goto alloc_new_skb; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1583 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1584 while (length > 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1585 /* Check if the remaining data fits into current packet. */ e57a34478586fe Yan Zhai 2023-10-24 1586 copy = (cork->length <= mtu ? mtu : maxfraglen) - skb->len; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1587 if (copy < length) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1588 copy = maxfraglen - skb->len; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1589 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1590 if (copy <= 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1591 char *data; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1592 unsigned int datalen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1593 unsigned int fraglen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1594 unsigned int fraggap; 6d123b81ac6150 Jakub Kicinski 2021-06-23 1595 unsigned int alloclen, alloc_extra; aba36930a35e7f Willem de Bruijn 2018-11-24 1596 unsigned int pagedlen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1597 alloc_new_skb: ^1da177e4c3f41 Linus Torvalds 2005-04-16 1598 /* There's no room in the current skb */ 0c1833797a5a6e Gao feng 2012-05-26 1599 if (skb) 0c1833797a5a6e Gao feng 2012-05-26 1600 fraggap = skb->len - maxfraglen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1601 else ^1da177e4c3f41 Linus Torvalds 2005-04-16 1602 fraggap = 0; 0c1833797a5a6e Gao feng 2012-05-26 1603 /* update mtu and maxfraglen if necessary */ 63159f29be1df7 Ian Morris 2015-03-29 1604 if (!skb || !skb_prev) 0c1833797a5a6e Gao feng 2012-05-26 1605 ip6_append_data_mtu(&mtu, &maxfraglen, 75a493e60ac4bb Hannes Frederic Sowa 2013-07-02 1606 fragheaderlen, skb, rt, e367c2d03dba4c lucien 2014-03-17 1607 orig_mtu); 0c1833797a5a6e Gao feng 2012-05-26 1608 0c1833797a5a6e Gao feng 2012-05-26 1609 skb_prev = skb; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1610 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1611 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1612 * If remaining data exceeds the mtu, ^1da177e4c3f41 Linus Torvalds 2005-04-16 1613 * we know we need more fragment(s). ^1da177e4c3f41 Linus Torvalds 2005-04-16 1614 */ ^1da177e4c3f41 Linus Torvalds 2005-04-16 1615 datalen = length + fraggap; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1616 e57a34478586fe Yan Zhai 2023-10-24 1617 if (datalen > (cork->length <= mtu ? mtu : maxfraglen) - fragheaderlen) 0c1833797a5a6e Gao feng 2012-05-26 1618 datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len; 15e36f5b8e982d Willem de Bruijn 2018-04-26 1619 fraglen = datalen + fragheaderlen; aba36930a35e7f Willem de Bruijn 2018-11-24 1620 pagedlen = 0; 15e36f5b8e982d Willem de Bruijn 2018-04-26 1621 6d123b81ac6150 Jakub Kicinski 2021-06-23 1622 alloc_extra = hh_len; 6d123b81ac6150 Jakub Kicinski 2021-06-23 1623 alloc_extra += dst_exthdrlen; 6d123b81ac6150 Jakub Kicinski 2021-06-23 1624 alloc_extra += rt->dst.trailer_len; 6d123b81ac6150 Jakub Kicinski 2021-06-23 1625 6d123b81ac6150 Jakub Kicinski 2021-06-23 1626 /* We just reserve space for fragment header. 6d123b81ac6150 Jakub Kicinski 2021-06-23 1627 * Note: this may be overallocation if the message 6d123b81ac6150 Jakub Kicinski 2021-06-23 1628 * (without MSG_MORE) fits into the MTU. 6d123b81ac6150 Jakub Kicinski 2021-06-23 1629 */ 6d123b81ac6150 Jakub Kicinski 2021-06-23 1630 alloc_extra += sizeof(struct frag_hdr); 6d123b81ac6150 Jakub Kicinski 2021-06-23 1631 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1632 if ((flags & MSG_MORE) && d8d1f30b95a635 Changli Gao 2010-06-10 1633 !(rt->dst.dev->features&NETIF_F_SG)) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1634 alloclen = mtu; 6d123b81ac6150 Jakub Kicinski 2021-06-23 1635 else if (!paged && 6d123b81ac6150 Jakub Kicinski 2021-06-23 1636 (fraglen + alloc_extra < SKB_MAX_ALLOC || 6d123b81ac6150 Jakub Kicinski 2021-06-23 1637 !(rt->dst.dev->features & NETIF_F_SG))) 15e36f5b8e982d Willem de Bruijn 2018-04-26 1638 alloclen = fraglen; 47cf88993c9108 Pavel Begunkov 2022-08-25 1639 else { 773ba4fe9104a6 Pavel Begunkov 2022-07-12 1640 alloclen = fragheaderlen + transhdrlen; 773ba4fe9104a6 Pavel Begunkov 2022-07-12 1641 pagedlen = datalen - transhdrlen; 15e36f5b8e982d Willem de Bruijn 2018-04-26 1642 } 6d123b81ac6150 Jakub Kicinski 2021-06-23 1643 alloclen += alloc_extra; 299b0767642a65 Steffen Klassert 2011-10-11 1644 0c1833797a5a6e Gao feng 2012-05-26 1645 if (datalen != length + fraggap) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1646 /* 0c1833797a5a6e Gao feng 2012-05-26 1647 * this is not the last fragment, the trailer 0c1833797a5a6e Gao feng 2012-05-26 1648 * space is regarded as data space. ^1da177e4c3f41 Linus Torvalds 2005-04-16 1649 */ 0c1833797a5a6e Gao feng 2012-05-26 1650 datalen += rt->dst.trailer_len; 0c1833797a5a6e Gao feng 2012-05-26 1651 } 0c1833797a5a6e Gao feng 2012-05-26 1652 0c1833797a5a6e Gao feng 2012-05-26 1653 fraglen = datalen + fragheaderlen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1654 15e36f5b8e982d Willem de Bruijn 2018-04-26 1655 copy = datalen - transhdrlen - fraggap - pagedlen; ce650a1663354a David Howells 2023-08-02 1656 /* [!] NOTE: copy may be negative if pagedlen>0 ce650a1663354a David Howells 2023-08-02 1657 * because then the equation may reduces to -fraggap. ce650a1663354a David Howells 2023-08-02 1658 */ ce650a1663354a David Howells 2023-08-02 1659 if (copy < 0 && !(flags & MSG_SPLICE_PAGES)) { 232cd35d0804cc Eric Dumazet 2017-05-19 1660 err = -EINVAL; 232cd35d0804cc Eric Dumazet 2017-05-19 1661 goto error; 232cd35d0804cc Eric Dumazet 2017-05-19 1662 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 1663 if (transhdrlen) { 6d123b81ac6150 Jakub Kicinski 2021-06-23 1664 skb = sock_alloc_send_skb(sk, alloclen, ^1da177e4c3f41 Linus Torvalds 2005-04-16 1665 (flags & MSG_DONTWAIT), &err); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1666 } else { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1667 skb = NULL; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1668 if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <= ^1da177e4c3f41 Linus Torvalds 2005-04-16 1669 2 * sk->sk_sndbuf) 6d123b81ac6150 Jakub Kicinski 2021-06-23 1670 skb = alloc_skb(alloclen, ^1da177e4c3f41 Linus Torvalds 2005-04-16 1671 sk->sk_allocation); 63159f29be1df7 Ian Morris 2015-03-29 1672 if (unlikely(!skb)) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1673 err = -ENOBUFS; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1674 } 63159f29be1df7 Ian Morris 2015-03-29 1675 if (!skb) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1676 goto error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1677 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1678 * Fill in the control structures ^1da177e4c3f41 Linus Torvalds 2005-04-16 1679 */ 9c9c9ad5fae7e9 Hannes Frederic Sowa 2013-08-26 1680 skb->protocol = htons(ETH_P_IPV6); 32dce968dd987a Vlad Yasevich 2015-01-31 1681 skb->ip_summed = csummode; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1682 skb->csum = 0; 1f85851e17b64c Gao feng 2012-03-19 1683 /* reserve for fragmentation and ipsec header */ 1f85851e17b64c Gao feng 2012-03-19 1684 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + 1f85851e17b64c Gao feng 2012-03-19 1685 dst_exthdrlen); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1686 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1687 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1688 * Find where to start putting bytes ^1da177e4c3f41 Linus Torvalds 2005-04-16 1689 */ 15e36f5b8e982d Willem de Bruijn 2018-04-26 1690 data = skb_put(skb, fraglen - pagedlen); 1f85851e17b64c Gao feng 2012-03-19 1691 skb_set_network_header(skb, exthdrlen); 1f85851e17b64c Gao feng 2012-03-19 1692 data += fragheaderlen; b0e380b1d8a8e0 Arnaldo Carvalho de Melo 2007-04-10 1693 skb->transport_header = (skb->network_header + b0e380b1d8a8e0 Arnaldo Carvalho de Melo 2007-04-10 1694 fragheaderlen); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1695 if (fraggap) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1696 skb->csum = skb_copy_and_csum_bits( ^1da177e4c3f41 Linus Torvalds 2005-04-16 1697 skb_prev, maxfraglen, 8d5930dfb7edbf Al Viro 2020-07-10 1698 data + transhdrlen, fraggap); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1699 skb_prev->csum = csum_sub(skb_prev->csum, ^1da177e4c3f41 Linus Torvalds 2005-04-16 1700 skb->csum); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1701 data += fraggap; e9fa4f7bd291c2 Herbert Xu 2006-08-13 1702 pskb_trim_unique(skb_prev, maxfraglen); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1703 } 232cd35d0804cc Eric Dumazet 2017-05-19 1704 if (copy > 0 && 5204ccbfa22358 Eric Dumazet 2024-12-03 1705 INDIRECT_CALL_1(getfrag, ip_generic_getfrag, 5204ccbfa22358 Eric Dumazet 2024-12-03 1706 from, data + transhdrlen, offset, 232cd35d0804cc Eric Dumazet 2017-05-19 1707 copy, fraggap, skb) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1708 err = -EFAULT; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1709 kfree_skb(skb); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1710 goto error; ce650a1663354a David Howells 2023-08-02 1711 } else if (flags & MSG_SPLICE_PAGES) { ce650a1663354a David Howells 2023-08-02 1712 copy = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1713 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 1714 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1715 offset += copy; 15e36f5b8e982d Willem de Bruijn 2018-04-26 1716 length -= copy + transhdrlen; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1717 transhdrlen = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1718 exthdrlen = 0; 299b0767642a65 Steffen Klassert 2011-10-11 1719 dst_exthdrlen = 0; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1720 52900d22288e7d Willem de Bruijn 2018-11-30 1721 /* Only the initial fragment is time stamped */ 52900d22288e7d Willem de Bruijn 2018-11-30 1722 skb_shinfo(skb)->tx_flags = cork->tx_flags; 52900d22288e7d Willem de Bruijn 2018-11-30 1723 cork->tx_flags = 0; 52900d22288e7d Willem de Bruijn 2018-11-30 1724 skb_shinfo(skb)->tskey = tskey; 52900d22288e7d Willem de Bruijn 2018-11-30 1725 tskey = 0; 52900d22288e7d Willem de Bruijn 2018-11-30 1726 skb_zcopy_set(skb, uarg, &extra_uref); 52900d22288e7d Willem de Bruijn 2018-11-30 1727 0dec879f636f11 Julian Anastasov 2017-02-06 1728 if ((flags & MSG_CONFIRM) && !skb_prev) 0dec879f636f11 Julian Anastasov 2017-02-06 1729 skb_set_dst_pending_confirm(skb, 1); 0dec879f636f11 Julian Anastasov 2017-02-06 1730 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1731 /* ^1da177e4c3f41 Linus Torvalds 2005-04-16 1732 * Put the packet on the pending queue ^1da177e4c3f41 Linus Torvalds 2005-04-16 1733 */ 1f4c6eb2402968 Eric Dumazet 2018-03-31 1734 if (!skb->destructor) { 1f4c6eb2402968 Eric Dumazet 2018-03-31 1735 skb->destructor = sock_wfree; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1736 skb->sk = sk; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1737 wmem_alloc_delta += skb->truesize; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1738 } 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1739 __skb_queue_tail(queue, skb); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1740 continue; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1741 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 1742 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1743 if (copy > length) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1744 copy = length; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1745 113f99c3358564 Willem de Bruijn 2018-05-17 1746 if (!(rt->dst.dev->features&NETIF_F_SG) && 113f99c3358564 Willem de Bruijn 2018-05-17 1747 skb_tailroom(skb) >= copy) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1748 unsigned int off; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1749 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1750 off = skb->len; 5204ccbfa22358 Eric Dumazet 2024-12-03 1751 if (INDIRECT_CALL_1(getfrag, ip_generic_getfrag, 5204ccbfa22358 Eric Dumazet 2024-12-03 1752 from, skb_put(skb, copy), ^1da177e4c3f41 Linus Torvalds 2005-04-16 1753 offset, copy, off, skb) < 0) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1754 __skb_trim(skb, off); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1755 err = -EFAULT; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1756 goto error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1757 } 6d8192bd69bb43 David Howells 2023-05-22 1758 } else if (flags & MSG_SPLICE_PAGES) { 6d8192bd69bb43 David Howells 2023-05-22 1759 struct msghdr *msg = from; 6d8192bd69bb43 David Howells 2023-05-22 1760 ce650a1663354a David Howells 2023-08-02 1761 err = -EIO; ce650a1663354a David Howells 2023-08-02 1762 if (WARN_ON_ONCE(copy > msg->msg_iter.count)) ce650a1663354a David Howells 2023-08-02 1763 goto error; ce650a1663354a David Howells 2023-08-02 1764 6d8192bd69bb43 David Howells 2023-05-22 1765 err = skb_splice_from_iter(skb, &msg->msg_iter, copy, 6d8192bd69bb43 David Howells 2023-05-22 1766 sk->sk_allocation); 6d8192bd69bb43 David Howells 2023-05-22 1767 if (err < 0) 6d8192bd69bb43 David Howells 2023-05-22 1768 goto error; 6d8192bd69bb43 David Howells 2023-05-22 1769 copy = err; 6d8192bd69bb43 David Howells 2023-05-22 1770 wmem_alloc_delta += copy; 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1771 } else if (!zc) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1772 int i = skb_shinfo(skb)->nr_frags; 5640f7685831e0 Eric Dumazet 2012-09-23 1773 ^1da177e4c3f41 Linus Torvalds 2005-04-16 1774 err = -ENOMEM; 5640f7685831e0 Eric Dumazet 2012-09-23 1775 if (!sk_page_frag_refill(sk, pfrag)) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1776 goto error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1777 1fd3ae8c906c0f Pavel Begunkov 2022-07-12 1778 skb_zcopy_downgrade_managed(skb); 5640f7685831e0 Eric Dumazet 2012-09-23 1779 if (!skb_can_coalesce(skb, i, pfrag->page, 5640f7685831e0 Eric Dumazet 2012-09-23 1780 pfrag->offset)) { ^1da177e4c3f41 Linus Torvalds 2005-04-16 1781 err = -EMSGSIZE; 5640f7685831e0 Eric Dumazet 2012-09-23 1782 if (i == MAX_SKB_FRAGS) ^1da177e4c3f41 Linus Torvalds 2005-04-16 1783 goto error; 5640f7685831e0 Eric Dumazet 2012-09-23 1784 5640f7685831e0 Eric Dumazet 2012-09-23 1785 __skb_fill_page_desc(skb, i, pfrag->page, 5640f7685831e0 Eric Dumazet 2012-09-23 1786 pfrag->offset, 0); 5640f7685831e0 Eric Dumazet 2012-09-23 1787 skb_shinfo(skb)->nr_frags = ++i; 5640f7685831e0 Eric Dumazet 2012-09-23 1788 get_page(pfrag->page); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1789 } 5640f7685831e0 Eric Dumazet 2012-09-23 1790 copy = min_t(int, copy, pfrag->size - pfrag->offset); 5204ccbfa22358 Eric Dumazet 2024-12-03 1791 if (INDIRECT_CALL_1(getfrag, ip_generic_getfrag, 5204ccbfa22358 Eric Dumazet 2024-12-03 1792 from, 5640f7685831e0 Eric Dumazet 2012-09-23 1793 page_address(pfrag->page) + pfrag->offset, 5640f7685831e0 Eric Dumazet 2012-09-23 1794 offset, copy, skb->len, skb) < 0) 5640f7685831e0 Eric Dumazet 2012-09-23 1795 goto error_efault; 5640f7685831e0 Eric Dumazet 2012-09-23 1796 5640f7685831e0 Eric Dumazet 2012-09-23 1797 pfrag->offset += copy; 5640f7685831e0 Eric Dumazet 2012-09-23 1798 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1799 skb->len += copy; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1800 skb->data_len += copy; f945fa7ad9c12a Herbert Xu 2008-01-22 1801 skb->truesize += copy; 1f4c6eb2402968 Eric Dumazet 2018-03-31 1802 wmem_alloc_delta += copy; b5947e5d1e710c Willem de Bruijn 2018-11-30 1803 } else { b5947e5d1e710c Willem de Bruijn 2018-11-30 1804 err = skb_zerocopy_iter_dgram(skb, from, copy); b5947e5d1e710c Willem de Bruijn 2018-11-30 1805 if (err < 0) b5947e5d1e710c Willem de Bruijn 2018-11-30 1806 goto error; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1807 } ^1da177e4c3f41 Linus Torvalds 2005-04-16 1808 offset += copy; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1809 length -= copy; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1810 } 5640f7685831e0 Eric Dumazet 2012-09-23 1811 9e8445a56c253f Paolo Abeni 2018-04-04 1812 if (wmem_alloc_delta) 1f4c6eb2402968 Eric Dumazet 2018-03-31 1813 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1814 return 0; 5640f7685831e0 Eric Dumazet 2012-09-23 1815 5640f7685831e0 Eric Dumazet 2012-09-23 1816 error_efault: 5640f7685831e0 Eric Dumazet 2012-09-23 1817 err = -EFAULT; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1818 error: 8e0449172497a9 Jonathan Lemon 2021-01-06 1819 net_zcopy_put_abort(uarg, extra_uref); bdc712b4c2baf9 David S. Miller 2011-05-06 1820 cork->length -= length; 3bd653c8455bc7 Denis V. Lunev 2008-10-08 1821 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 1f4c6eb2402968 Eric Dumazet 2018-03-31 1822 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); 488b6d91b07112 Vadim Fedorenko 2024-02-13 1823 if (hold_tskey) 488b6d91b07112 Vadim Fedorenko 2024-02-13 1824 atomic_dec(&sk->sk_tskey); ^1da177e4c3f41 Linus Torvalds 2005-04-16 1825 return err; ^1da177e4c3f41 Linus Torvalds 2005-04-16 1826 } 0bbe84a67b0b54 Vlad Yasevich 2015-01-31 1827
On 1/2/25 2:51 AM, shiming cheng wrote: > When using socket IPv6 with SO_BINDTODEVICE, if IPv6 rule is not > matched, it will return ENETUNREACH. In fact, IPv4 does not behave > this way. IPv4 prioritizes looking up IP rules for routing and > forwarding, if not matched it will use socket-bound out interface > to send packets. The modification here is to make IPv6 behave the > same as IPv4. If IP rule is not found, it will also use > socket-bound out interface to send packts. > Please create test cases for IPv4 and IPv6 showing the problem - what you are configuring and the expected result. Also, commit messages should align with first column unless there is a reason for an indentation.
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 6dbdf60b342f..0625597def6f 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -214,6 +214,8 @@ void rt6_multipath_rebalance(struct fib6_info *f6i); void rt6_uncached_list_add(struct rt6_info *rt); void rt6_uncached_list_del(struct rt6_info *rt); +struct rt6_info *ip6_create_rt_oif_rcu(struct net *net, const struct sock *sk, + struct flowi6 *fl6, int flags); static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb) { diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index f7b4608bb316..ed162ac3cb31 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1156,7 +1156,11 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, *dst = ip6_route_output_flags(net, sk, fl6, flags); err = (*dst)->error; - if (err) + if (err && (flags & RT6_LOOKUP_F_IFACE)) { + *dst = (struct dst_entry *)ip6_create_rt_oif_rcu(net, sk, fl6, flags); + if (!*dst) + goto out_err_release; + } else if (err) { goto out_err_release; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 67ff16c04718..7d7450fab44f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1214,6 +1214,40 @@ static struct rt6_info *ip6_create_rt_rcu(const struct fib6_result *res) return nrt; } +struct rt6_info *ip6_create_rt_oif_rcu(struct net *net, const struct sock *sk, + struct flowi6 *fl6, int flags) +{ + struct rt6_info *rt; + unsigned int prefs; + int err; + struct net_device *dev = dev_get_by_index_rcu(net, fl6->flowi6_oif); + + if (!dev) + return NULL; + rt = ip6_dst_alloc(dev_net(dev), dev, flags); + + if (!rt) + return NULL; + rt->dst.error = 0; + rt->dst.output = ip6_output; + rt->dst.lastuse = jiffies; + prefs = sk ? inet6_sk(sk)->srcprefs : 0; + err = ipv6_dev_get_saddr(net, dev, &fl6->daddr, prefs, &fl6->saddr); + + if (err) { + dst_release(&rt->dst); + return NULL; + } + rt->rt6i_dst.addr = fl6->daddr; + rt->rt6i_dst.plen = 128; + rt->rt6i_src.addr = fl6->saddr; + rt->rt6i_dst.plen = 128; + rt->rt6i_idev = in6_dev_get(dev); + rt->rt6i_flags = flags; + return rt; +} +EXPORT_SYMBOL_GPL(ip6_create_rt_oif_rcu); + INDIRECT_CALLABLE_SCOPE struct rt6_info *ip6_pol_route_lookup(struct net *net, struct fib6_table *table, struct flowi6 *fl6,
When using socket IPv6 with SO_BINDTODEVICE, if IPv6 rule is not matched, it will return ENETUNREACH. In fact, IPv4 does not behave this way. IPv4 prioritizes looking up IP rules for routing and forwarding, if not matched it will use socket-bound out interface to send packets. The modification here is to make IPv6 behave the same as IPv4. If IP rule is not found, it will also use socket-bound out interface to send packts. Signed-off-by: shiming cheng <shiming.cheng@mediatek.com> --- include/net/ip6_route.h | 2 ++ net/ipv6/ip6_output.c | 6 +++++- net/ipv6/route.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-)