Message ID | 20180528071533.6846-2-ecklm94@gmail.com |
---|---|
State | Changes Requested |
Delegated to: | Pablo Neira |
Headers | show |
Series | [nf-next] netfilter: nft: add support for native socket matching | expand |
Hi Máté, Thank you for the patch! Yet something to improve: [auto build test ERROR on nf-next/master] url: https://github.com/0day-ci/linux/commits/M-t-Eckl/netfilter-nft-add-support-for-native-socket-matching/20180529-064304 base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master config: i386-allmodconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': >> include/net/netfilter/nf_socket.h:12:12: error: dereferencing pointer to incomplete type 'struct sock' switch (sk->sk_state) { ^~ >> include/net/netfilter/nf_socket.h:13:7: error: 'TCP_TIME_WAIT' undeclared (first use in this function); did you mean 'BPF_TCP_TIME_WAIT'? case TCP_TIME_WAIT: ^~~~~~~~~~~~~ BPF_TCP_TIME_WAIT include/net/netfilter/nf_socket.h:13:7: note: each undeclared identifier is reported only once for each function it appears in >> include/net/netfilter/nf_socket.h:14:10: error: implicit declaration of function 'inet_twsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_twsk(sk)->tw_transparent; ^~~~~~~~~ in_task >> include/net/netfilter/nf_socket.h:14:23: error: invalid type argument of '->' (have 'int') return inet_twsk(sk)->tw_transparent; ^~ >> include/net/netfilter/nf_socket.h:15:7: error: 'TCP_NEW_SYN_RECV' undeclared (first use in this function); did you mean 'BPF_TCP_NEW_SYN_RECV'? case TCP_NEW_SYN_RECV: ^~~~~~~~~~~~~~~~ BPF_TCP_NEW_SYN_RECV >> include/net/netfilter/nf_socket.h:16:10: error: implicit declaration of function 'inet_rsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~ in_task >> include/net/netfilter/nf_socket.h:16:19: error: implicit declaration of function 'inet_reqsk'; did you mean 'net_eq'? [-Werror=implicit-function-declaration] return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~~~ net_eq include/net/netfilter/nf_socket.h:16:34: error: invalid type argument of '->' (have 'int') return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~ >> include/net/netfilter/nf_socket.h:18:10: error: implicit declaration of function 'inet_sk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_sk(sk)->transparent; ^~~~~~~ in_task include/net/netfilter/nf_socket.h:18:21: error: invalid type argument of '->' (have 'int') return inet_sk(sk)->transparent; ^~ In file included from include/net/inet_sock.h:27:0, from net/netfilter/nft_socket.c:8: include/net/request_sock.h: At top level: >> include/net/request_sock.h:72:36: error: conflicting types for 'inet_reqsk' static inline struct request_sock *inet_reqsk(const struct sock *sk) ^~~~~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:16:19: note: previous implicit declaration of 'inet_reqsk' was here return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~~~ In file included from net/netfilter/nft_socket.c:8:0: >> include/net/inet_sock.h:107:41: error: conflicting types for 'inet_rsk' static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) ^~~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:16:10: note: previous implicit declaration of 'inet_rsk' was here return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~ In file included from net/netfilter/nft_socket.c:8:0: >> include/net/inet_sock.h:273:33: error: conflicting types for 'inet_sk' static inline struct inet_sock *inet_sk(const struct sock *sk) ^~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:18:10: note: previous implicit declaration of 'inet_sk' was here return inet_sk(sk)->transparent; ^~~~~~~ include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': >> include/net/netfilter/nf_socket.h:20:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ cc1: some warnings being treated as errors vim +12 include/net/netfilter/nf_socket.h 8db4c5be Pablo Neira Ayuso 2016-10-27 9 8db4c5be Pablo Neira Ayuso 2016-10-27 10 static inline bool nf_sk_is_transparent(struct sock *sk) 8db4c5be Pablo Neira Ayuso 2016-10-27 11 { 8db4c5be Pablo Neira Ayuso 2016-10-27 @12 switch (sk->sk_state) { 8db4c5be Pablo Neira Ayuso 2016-10-27 @13 case TCP_TIME_WAIT: 8db4c5be Pablo Neira Ayuso 2016-10-27 @14 return inet_twsk(sk)->tw_transparent; 8db4c5be Pablo Neira Ayuso 2016-10-27 @15 case TCP_NEW_SYN_RECV: 8db4c5be Pablo Neira Ayuso 2016-10-27 @16 return inet_rsk(inet_reqsk(sk))->no_srccheck; 8db4c5be Pablo Neira Ayuso 2016-10-27 17 default: 8db4c5be Pablo Neira Ayuso 2016-10-27 @18 return inet_sk(sk)->transparent; 8db4c5be Pablo Neira Ayuso 2016-10-27 19 } 8db4c5be Pablo Neira Ayuso 2016-10-27 @20 } 8db4c5be Pablo Neira Ayuso 2016-10-27 21 :::::: The code at line 12 was first introduced by commit :::::: 8db4c5be88f62ffd7a552f70687a10c614dc697b netfilter: move socket lookup infrastructure to nf_socket_ipv{4,6}.c :::::: TO: Pablo Neira Ayuso <pablo@netfilter.org> :::::: CC: Pablo Neira Ayuso <pablo@netfilter.org> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Máté, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on nf-next/master] url: https://github.com/0day-ci/linux/commits/M-t-Eckl/netfilter-nft-add-support-for-native-socket-matching/20180529-064304 base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) include/net/netfilter/nf_socket.h:12:19: sparse: no member 'sk_state' in struct sock include/net/netfilter/nf_socket.h:13:14: sparse: undefined identifier 'TCP_TIME_WAIT' include/net/netfilter/nf_socket.h:14:24: sparse: undefined identifier 'inet_twsk' include/net/netfilter/nf_socket.h:15:14: sparse: undefined identifier 'TCP_NEW_SYN_RECV' include/net/netfilter/nf_socket.h:16:24: sparse: undefined identifier 'inet_rsk' include/net/netfilter/nf_socket.h:18:24: sparse: undefined identifier 'inet_sk' >> include/net/netfilter/nf_socket.h:13:14: sparse: incompatible types for 'case' statement include/net/netfilter/nf_socket.h:15:14: sparse: incompatible types for 'case' statement >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:85:21: sparse: cast to restricted __be32 >> net/netfilter/nft_socket.c:104:47: sparse: incorrect type in argument 3 (different base types) @@ expected unsigned int [unsigned] [usertype] value @@ got ed int [unsigned] [usertype] value @@ net/netfilter/nft_socket.c:104:47: expected unsigned int [unsigned] [usertype] value net/netfilter/nft_socket.c:104:47: got restricted __be32 [usertype] <noident> >> net/netfilter/nft_socket.c:111:22: sparse: symbol 'nft_socket_type' was not declared. Should it be static? include/net/netfilter/nf_socket.h:13:14: sparse: Expected constant expression in case statement include/net/netfilter/nf_socket.h:15:14: sparse: Expected constant expression in case statement In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': include/net/netfilter/nf_socket.h:12:12: error: dereferencing pointer to incomplete type 'struct sock' switch (sk->sk_state) { ^~ include/net/netfilter/nf_socket.h:13:7: error: 'TCP_TIME_WAIT' undeclared (first use in this function); did you mean 'BPF_TCP_TIME_WAIT'? case TCP_TIME_WAIT: ^~~~~~~~~~~~~ BPF_TCP_TIME_WAIT include/net/netfilter/nf_socket.h:13:7: note: each undeclared identifier is reported only once for each function it appears in include/net/netfilter/nf_socket.h:14:10: error: implicit declaration of function 'inet_twsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_twsk(sk)->tw_transparent; ^~~~~~~~~ in_task include/net/netfilter/nf_socket.h:14:23: error: invalid type argument of '->' (have 'int') return inet_twsk(sk)->tw_transparent; ^~ include/net/netfilter/nf_socket.h:15:7: error: 'TCP_NEW_SYN_RECV' undeclared (first use in this function); did you mean 'BPF_TCP_NEW_SYN_RECV'? case TCP_NEW_SYN_RECV: ^~~~~~~~~~~~~~~~ BPF_TCP_NEW_SYN_RECV include/net/netfilter/nf_socket.h:16:10: error: implicit declaration of function 'inet_rsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~ in_task include/net/netfilter/nf_socket.h:16:19: error: implicit declaration of function 'inet_reqsk'; did you mean 'net_eq'? [-Werror=implicit-function-declaration] return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~~~ net_eq include/net/netfilter/nf_socket.h:16:34: error: invalid type argument of '->' (have 'int') return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~ include/net/netfilter/nf_socket.h:18:10: error: implicit declaration of function 'inet_sk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] return inet_sk(sk)->transparent; ^~~~~~~ in_task include/net/netfilter/nf_socket.h:18:21: error: invalid type argument of '->' (have 'int') return inet_sk(sk)->transparent; ^~ In file included from include/net/inet_sock.h:27:0, from net/netfilter/nft_socket.c:8: include/net/request_sock.h: At top level: include/net/request_sock.h:72:36: error: conflicting types for 'inet_reqsk' static inline struct request_sock *inet_reqsk(const struct sock *sk) ^~~~~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:16:19: note: previous implicit declaration of 'inet_reqsk' was here return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~~~ In file included from net/netfilter/nft_socket.c:8:0: include/net/inet_sock.h:107:41: error: conflicting types for 'inet_rsk' static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) ^~~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:16:10: note: previous implicit declaration of 'inet_rsk' was here return inet_rsk(inet_reqsk(sk))->no_srccheck; ^~~~~~~~ In file included from net/netfilter/nft_socket.c:8:0: include/net/inet_sock.h:273:33: error: conflicting types for 'inet_sk' static inline struct inet_sock *inet_sk(const struct sock *sk) ^~~~~~~ In file included from net/netfilter/nft_socket.c:7:0: include/net/netfilter/nf_socket.h:18:10: note: previous implicit declaration of 'inet_sk' was here return inet_sk(sk)->transparent; ^~~~~~~ include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': include/net/netfilter/nf_socket.h:20:1: warning: control reaches end of non-void function [-Wreturn-type] } ^ cc1: some warnings being treated as errors Please review and possibly fold the followup patch. vim +85 net/netfilter/nft_socket.c 63 64 static int nft_socket_init(const struct nft_ctx *ctx, 65 const struct nft_expr *expr, 66 const struct nlattr * const tb[]) 67 { 68 struct nft_socket *priv = nft_expr_priv(expr); 69 unsigned int len; 70 71 if (!tb[NFTA_SOCKET_DREG] || !tb[NFTA_SOCKET_KEY]) 72 return -EINVAL; 73 74 switch(ctx->family) { 75 case NFPROTO_IPV4: 76 #ifdef CONFIG_NF_SOCKET_IPV6 77 case NFPROTO_IPV6: 78 #endif 79 case NFPROTO_INET: 80 break; 81 default: 82 return -EOPNOTSUPP; 83 } 84 > 85 priv->key = ntohl(nla_get_u32(tb[NFTA_SOCKET_KEY])); 86 switch(priv->key) { 87 case NFT_SOCKET_TRANSPARENT: 88 len = sizeof(u8); 89 break; 90 default: 91 return -EOPNOTSUPP; 92 } 93 94 priv->dreg = nft_parse_register(tb[NFTA_SOCKET_DREG]); 95 return nft_validate_register_store(ctx, priv->dreg, NULL, 96 NFT_DATA_VALUE, len); 97 } 98 99 static int nft_socket_dump(struct sk_buff *skb, 100 const struct nft_expr *expr) 101 { 102 const struct nft_socket *priv = nft_expr_priv(expr); 103 > 104 if (nla_put_u32(skb, NFTA_SOCKET_KEY, htonl(priv->key))) 105 return -1; 106 if (nft_dump_register(skb, NFTA_SOCKET_DREG, priv->dreg)) 107 return -1; 108 return 0; 109 } 110 > 111 struct nft_expr_type nft_socket_type; 112 static const struct nft_expr_ops nft_socket_ops = { 113 .type = &nft_socket_type, 114 .size = NFT_EXPR_SIZE(sizeof(struct nft_socket)), 115 .eval = nft_socket_eval, 116 .init = nft_socket_init, 117 .dump = nft_socket_dump, 118 }; 119 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, May 29, 2018 at 08:10:53AM +0800, kbuild test robot wrote: q > Hi Máté, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on nf-next/master] > > url: https://github.com/0day-ci/linux/commits/M-t-Eckl/netfilter-nft-add-support-for-native-socket-matching/20180529-064304 > base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master > config: i386-allmodconfig (attached as .config) > compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 > reproduce: > # save the attached .config to linux build tree > make ARCH=i386 > > All error/warnings (new ones prefixed by >>): > > In file included from net/netfilter/nft_socket.c:7:0: > include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': > >> include/net/netfilter/nf_socket.h:12:12: error: dereferencing pointer to incomplete type 'struct sock' > switch (sk->sk_state) { > ^~ > >> include/net/netfilter/nf_socket.h:13:7: error: 'TCP_TIME_WAIT' undeclared (first use in this function); did you mean 'BPF_TCP_TIME_WAIT'? > case TCP_TIME_WAIT: > ^~~~~~~~~~~~~ > BPF_TCP_TIME_WAIT > include/net/netfilter/nf_socket.h:13:7: note: each undeclared identifier is reported only once for each function it appears in > >> include/net/netfilter/nf_socket.h:14:10: error: implicit declaration of function 'inet_twsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] > return inet_twsk(sk)->tw_transparent; > ^~~~~~~~~ > in_task > >> include/net/netfilter/nf_socket.h:14:23: error: invalid type argument of '->' (have 'int') > return inet_twsk(sk)->tw_transparent; > ^~ > >> include/net/netfilter/nf_socket.h:15:7: error: 'TCP_NEW_SYN_RECV' undeclared (first use in this function); did you mean 'BPF_TCP_NEW_SYN_RECV'? > case TCP_NEW_SYN_RECV: > ^~~~~~~~~~~~~~~~ > BPF_TCP_NEW_SYN_RECV > >> include/net/netfilter/nf_socket.h:16:10: error: implicit declaration of function 'inet_rsk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] > return inet_rsk(inet_reqsk(sk))->no_srccheck; > ^~~~~~~~ > in_task > >> include/net/netfilter/nf_socket.h:16:19: error: implicit declaration of function 'inet_reqsk'; did you mean 'net_eq'? [-Werror=implicit-function-declaration] > return inet_rsk(inet_reqsk(sk))->no_srccheck; > ^~~~~~~~~~ > net_eq > include/net/netfilter/nf_socket.h:16:34: error: invalid type argument of '->' (have 'int') > return inet_rsk(inet_reqsk(sk))->no_srccheck; > ^~ > >> include/net/netfilter/nf_socket.h:18:10: error: implicit declaration of function 'inet_sk'; did you mean 'in_task'? [-Werror=implicit-function-declaration] > return inet_sk(sk)->transparent; > ^~~~~~~ > in_task > include/net/netfilter/nf_socket.h:18:21: error: invalid type argument of '->' (have 'int') > return inet_sk(sk)->transparent; > ^~ > In file included from include/net/inet_sock.h:27:0, > from net/netfilter/nft_socket.c:8: > include/net/request_sock.h: At top level: > >> include/net/request_sock.h:72:36: error: conflicting types for 'inet_reqsk' > static inline struct request_sock *inet_reqsk(const struct sock *sk) > ^~~~~~~~~~ > In file included from net/netfilter/nft_socket.c:7:0: > include/net/netfilter/nf_socket.h:16:19: note: previous implicit declaration of 'inet_reqsk' was here > return inet_rsk(inet_reqsk(sk))->no_srccheck; > ^~~~~~~~~~ > In file included from net/netfilter/nft_socket.c:8:0: > >> include/net/inet_sock.h:107:41: error: conflicting types for 'inet_rsk' > static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) > ^~~~~~~~ > In file included from net/netfilter/nft_socket.c:7:0: > include/net/netfilter/nf_socket.h:16:10: note: previous implicit declaration of 'inet_rsk' was here > return inet_rsk(inet_reqsk(sk))->no_srccheck; > ^~~~~~~~ > In file included from net/netfilter/nft_socket.c:8:0: > >> include/net/inet_sock.h:273:33: error: conflicting types for 'inet_sk' > static inline struct inet_sock *inet_sk(const struct sock *sk) > ^~~~~~~ > In file included from net/netfilter/nft_socket.c:7:0: > include/net/netfilter/nf_socket.h:18:10: note: previous implicit declaration of 'inet_sk' was here > return inet_sk(sk)->transparent; > ^~~~~~~ > include/net/netfilter/nf_socket.h: In function 'nf_sk_is_transparent': > >> include/net/netfilter/nf_socket.h:20:1: warning: control reaches end of non-void function [-Wreturn-type] > } > ^ > cc1: some warnings being treated as errors > > vim +12 include/net/netfilter/nf_socket.h > > 8db4c5be Pablo Neira Ayuso 2016-10-27 9 > 8db4c5be Pablo Neira Ayuso 2016-10-27 10 static inline bool nf_sk_is_transparent(struct sock *sk) > 8db4c5be Pablo Neira Ayuso 2016-10-27 11 { > 8db4c5be Pablo Neira Ayuso 2016-10-27 @12 switch (sk->sk_state) { > 8db4c5be Pablo Neira Ayuso 2016-10-27 @13 case TCP_TIME_WAIT: > 8db4c5be Pablo Neira Ayuso 2016-10-27 @14 return inet_twsk(sk)->tw_transparent; > 8db4c5be Pablo Neira Ayuso 2016-10-27 @15 case TCP_NEW_SYN_RECV: > 8db4c5be Pablo Neira Ayuso 2016-10-27 @16 return inet_rsk(inet_reqsk(sk))->no_srccheck; > 8db4c5be Pablo Neira Ayuso 2016-10-27 17 default: > 8db4c5be Pablo Neira Ayuso 2016-10-27 @18 return inet_sk(sk)->transparent; > 8db4c5be Pablo Neira Ayuso 2016-10-27 19 } > 8db4c5be Pablo Neira Ayuso 2016-10-27 @20 } > 8db4c5be Pablo Neira Ayuso 2016-10-27 21 > > :::::: The code at line 12 was first introduced by commit > :::::: 8db4c5be88f62ffd7a552f70687a10c614dc697b netfilter: move socket lookup infrastructure to nf_socket_ipv{4,6}.c > > :::::: TO: Pablo Neira Ayuso <pablo@netfilter.org> > :::::: CC: Pablo Neira Ayuso <pablo@netfilter.org> > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation This patch is based on [1], which has been applied after this patch was submitted. These errors should not be present in a new build. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git/commit/?id=e5a10bb2acf246c13dc164fd37d4c77d9acaf88f -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 9c71f024f9cc..96ab31539bf6 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -904,6 +904,34 @@ enum nft_rt_attributes { }; #define NFTA_RT_MAX (__NFTA_RT_MAX - 1) +/** + * enum nft_socket_attributes - nf_tables socket expression netlink attributes + * + * @NFTA_SOCKET_KEY: socket key to match + * @NFTA_SOCKET_DREG: destination register + */ +enum nft_socket_attributes { + NFTA_SOCKET_UNSPEC, + + NFTA_SOCKET_KEY, + NFTA_SOCKET_DREG, + + __NFTA_SOCKET_MAX +}; +#define NFTA_SOCKET_MAX (__NFTA_SOCKET_MAX - 1) + +/* + * enum nft_socket_keys - nf_tables socket expression keys + * + * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option_ + */ +enum nft_socket_keys { + NFT_SOCKET_TRANSPARENT, + + __NFT_SOCKET_MAX +}; +#define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1) + /** * enum nft_ct_keys - nf_tables ct expression keys * diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index a5b60e6a983e..cbc2d030affc 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -617,6 +617,15 @@ config NFT_FIB_INET The lookup will be delegated to the IPv4 or IPv6 FIB depending on the protocol of the packet. +config NFT_SOCKET + tristate "Netfilter nf_tables socket match support" + depends on IPV6 || IPV6=n + select NF_SOCKET_IPV4 + select NF_SOCKET_IPV6 if IPV6 + help + This option allows matching for the presence or absence of a + corresponding socket and its attributes. + if NF_TABLES_NETDEV config NF_DUP_NETDEV diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 1aa710b5d384..05a01ff4d25a 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -102,6 +102,7 @@ obj-$(CONFIG_NFT_FIB) += nft_fib.o obj-$(CONFIG_NFT_FIB_INET) += nft_fib_inet.o obj-$(CONFIG_NFT_FIB_NETDEV) += nft_fib_netdev.o obj-$(CONFIG_NF_OSF) += nf_osf.o +obj-$(CONFIG_NFT_SOCKET) += nft_socket.o # nf_tables netdev obj-$(CONFIG_NFT_DUP_NETDEV) += nft_dup_netdev.o diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c new file mode 100644 index 000000000000..5eb1069ac338 --- /dev/null +++ b/net/netfilter/nft_socket.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/module.h> +#include <linux/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables_core.h> +#include <net/netfilter/nf_socket.h> +#include <net/inet_sock.h> + +struct nft_socket { + enum nft_socket_keys key:8; + union { + enum nft_registers dreg:8; + }; +}; + +static void nft_socket_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + const struct nft_socket *priv = nft_expr_priv(expr); + struct sk_buff *skb = pkt->skb; + struct sock *sk = skb->sk; + u32 *dest = ®s->data[priv->dreg]; + + if (!sk) + switch(nft_pf(pkt)) { + case NFPROTO_IPV4: + sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, nft_in(pkt)); + break; +#ifdef CONFIG_NF_SOCKET_IPV6 + case NFPROTO_IPV6: + sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, nft_in(pkt)); + break; +#endif + default: + WARN_ON_ONCE(1); + regs->verdict.code = NFT_BREAK; + return; + } + + if(!sk) { + nft_reg_store8(dest, 0); + return; + } + + skb->sk = sk; // So that subsequent socket matching not to require other lookups + + switch(priv->key) { + case NFT_SOCKET_TRANSPARENT: + nft_reg_store8(dest, nf_sk_is_transparent(sk)); + break; + default: + WARN_ON(1); + regs->verdict.code = NFT_BREAK; + } +} + +static const struct nla_policy nft_socket_policy[NFTA_SOCKET_MAX + 1] = { + [NFTA_SOCKET_KEY] = { .type = NLA_U32 }, + [NFTA_SOCKET_DREG] = { .type = NLA_U32 }, +}; + +static int nft_socket_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) +{ + struct nft_socket *priv = nft_expr_priv(expr); + unsigned int len; + + if (!tb[NFTA_SOCKET_DREG] || !tb[NFTA_SOCKET_KEY]) + return -EINVAL; + + switch(ctx->family) { + case NFPROTO_IPV4: +#ifdef CONFIG_NF_SOCKET_IPV6 + case NFPROTO_IPV6: +#endif + case NFPROTO_INET: + break; + default: + return -EOPNOTSUPP; + } + + priv->key = ntohl(nla_get_u32(tb[NFTA_SOCKET_KEY])); + switch(priv->key) { + case NFT_SOCKET_TRANSPARENT: + len = sizeof(u8); + break; + default: + return -EOPNOTSUPP; + } + + priv->dreg = nft_parse_register(tb[NFTA_SOCKET_DREG]); + return nft_validate_register_store(ctx, priv->dreg, NULL, + NFT_DATA_VALUE, len); +} + +static int nft_socket_dump(struct sk_buff *skb, + const struct nft_expr *expr) +{ + const struct nft_socket *priv = nft_expr_priv(expr); + + if (nla_put_u32(skb, NFTA_SOCKET_KEY, htonl(priv->key))) + return -1; + if (nft_dump_register(skb, NFTA_SOCKET_DREG, priv->dreg)) + return -1; + return 0; +} + +struct nft_expr_type nft_socket_type; +static const struct nft_expr_ops nft_socket_ops = { + .type = &nft_socket_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_socket)), + .eval = nft_socket_eval, + .init = nft_socket_init, + .dump = nft_socket_dump, +}; + +struct nft_expr_type nft_socket_type __read_mostly = { + .name = "socket", + .ops = &nft_socket_ops, + .policy = nft_socket_policy, + .maxattr = NFTA_SOCKET_MAX, + .owner = THIS_MODULE, +}; + +static int __init nft_socket_module_init(void) +{ + return nft_register_expr(&nft_socket_type); +} + +static void __exit nft_socket_module_exit(void) +{ + nft_unregister_expr(&nft_socket_type); +} + +module_init(nft_socket_module_init); +module_exit(nft_socket_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Máté Eckl"); +MODULE_DESCRIPTION("nf_tables socket match module");
Now it can only match the transparent flag of an ip/ipv6 socket. Signed-off-by: Máté Eckl <ecklm94@gmail.com> --- include/uapi/linux/netfilter/nf_tables.h | 28 +++++ net/netfilter/Kconfig | 9 ++ net/netfilter/Makefile | 1 + net/netfilter/nft_socket.c | 143 +++++++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 net/netfilter/nft_socket.c