1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 296518518SPatrick McHardy #ifndef _NET_NF_TABLES_H 396518518SPatrick McHardy #define _NET_NF_TABLES_H 496518518SPatrick McHardy 5a1b840adSAnder Juaristi #include <asm/unaligned.h> 696518518SPatrick McHardy #include <linux/list.h> 796518518SPatrick McHardy #include <linux/netfilter.h> 867a8fc27SPatrick McHardy #include <linux/netfilter/nfnetlink.h> 90ca743a5SPablo Neira Ayuso #include <linux/netfilter/x_tables.h> 1096518518SPatrick McHardy #include <linux/netfilter/nf_tables.h> 11ce355e20SEric Dumazet #include <linux/u64_stats_sync.h> 121b2470e5SFlorian Westphal #include <linux/rhashtable.h> 133b49e2e9SPablo Neira Ayuso #include <net/netfilter/nf_flow_table.h> 1496518518SPatrick McHardy #include <net/netlink.h> 1514bfb13fSPablo Neira Ayuso #include <net/flow_offload.h> 16d59d2f82SPablo Neira Ayuso #include <net/netns/generic.h> 1796518518SPatrick McHardy 18d25e2e93SPablo Neira Ayuso #define NFT_MAX_HOOKS (NF_INET_INGRESS + 1) 19d25e2e93SPablo Neira Ayuso 20a4cb98f3SPaul Gortmaker struct module; 21a4cb98f3SPaul Gortmaker 2220a69341SPatrick McHardy #define NFT_JUMP_STACK_SIZE 16 2320a69341SPatrick McHardy 24b5bdc6f9SPablo Neira Ayuso enum { 25b5bdc6f9SPablo Neira Ayuso NFT_PKTINFO_L4PROTO = (1 << 0), 26c46b38dcSPablo Neira Ayuso NFT_PKTINFO_INNER = (1 << 1), 27b5bdc6f9SPablo Neira Ayuso }; 28b5bdc6f9SPablo Neira Ayuso 2996518518SPatrick McHardy struct nft_pktinfo { 3096518518SPatrick McHardy struct sk_buff *skb; 31897389deSFlorian Westphal const struct nf_hook_state *state; 32b5bdc6f9SPablo Neira Ayuso u8 flags; 334566bf27SPatrick McHardy u8 tprot; 34897389deSFlorian Westphal u16 fragoff; 35897389deSFlorian Westphal unsigned int thoff; 36c46b38dcSPablo Neira Ayuso unsigned int inneroff; 3796518518SPatrick McHardy }; 3896518518SPatrick McHardy 3985554eb9SFlorian Westphal static inline struct sock *nft_sk(const struct nft_pktinfo *pkt) 4085554eb9SFlorian Westphal { 41897389deSFlorian Westphal return pkt->state->sk; 4285554eb9SFlorian Westphal } 4385554eb9SFlorian Westphal 442d7b4aceSFlorian Westphal static inline unsigned int nft_thoff(const struct nft_pktinfo *pkt) 452d7b4aceSFlorian Westphal { 46897389deSFlorian Westphal return pkt->thoff; 472d7b4aceSFlorian Westphal } 482d7b4aceSFlorian Westphal 490e5a1c7eSPablo Neira Ayuso static inline struct net *nft_net(const struct nft_pktinfo *pkt) 500e5a1c7eSPablo Neira Ayuso { 51897389deSFlorian Westphal return pkt->state->net; 520e5a1c7eSPablo Neira Ayuso } 530e5a1c7eSPablo Neira Ayuso 540e5a1c7eSPablo Neira Ayuso static inline unsigned int nft_hook(const struct nft_pktinfo *pkt) 550e5a1c7eSPablo Neira Ayuso { 56897389deSFlorian Westphal return pkt->state->hook; 570e5a1c7eSPablo Neira Ayuso } 580e5a1c7eSPablo Neira Ayuso 590e5a1c7eSPablo Neira Ayuso static inline u8 nft_pf(const struct nft_pktinfo *pkt) 600e5a1c7eSPablo Neira Ayuso { 61897389deSFlorian Westphal return pkt->state->pf; 620e5a1c7eSPablo Neira Ayuso } 630e5a1c7eSPablo Neira Ayuso 640e5a1c7eSPablo Neira Ayuso static inline const struct net_device *nft_in(const struct nft_pktinfo *pkt) 650e5a1c7eSPablo Neira Ayuso { 66897389deSFlorian Westphal return pkt->state->in; 670e5a1c7eSPablo Neira Ayuso } 680e5a1c7eSPablo Neira Ayuso 690e5a1c7eSPablo Neira Ayuso static inline const struct net_device *nft_out(const struct nft_pktinfo *pkt) 700e5a1c7eSPablo Neira Ayuso { 71897389deSFlorian Westphal return pkt->state->out; 720e5a1c7eSPablo Neira Ayuso } 730e5a1c7eSPablo Neira Ayuso 740ca743a5SPablo Neira Ayuso static inline void nft_set_pktinfo(struct nft_pktinfo *pkt, 750ca743a5SPablo Neira Ayuso struct sk_buff *skb, 76073bfd56SDavid S. Miller const struct nf_hook_state *state) 770ca743a5SPablo Neira Ayuso { 780ca743a5SPablo Neira Ayuso pkt->skb = skb; 79897389deSFlorian Westphal pkt->state = state; 800ca743a5SPablo Neira Ayuso } 810ca743a5SPablo Neira Ayuso 82f06ad944SFlorian Westphal static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt) 83beac5afaSPablo Neira Ayuso { 84b5bdc6f9SPablo Neira Ayuso pkt->flags = 0; 85beac5afaSPablo Neira Ayuso pkt->tprot = 0; 86897389deSFlorian Westphal pkt->thoff = 0; 87897389deSFlorian Westphal pkt->fragoff = 0; 88beac5afaSPablo Neira Ayuso } 89beac5afaSPablo Neira Ayuso 90a55e22e9SPatrick McHardy /** 91a55e22e9SPatrick McHardy * struct nft_verdict - nf_tables verdict 92a55e22e9SPatrick McHardy * 93a55e22e9SPatrick McHardy * @code: nf_tables/netfilter verdict code 94a55e22e9SPatrick McHardy * @chain: destination chain for NFT_JUMP/NFT_GOTO 95a55e22e9SPatrick McHardy */ 96a55e22e9SPatrick McHardy struct nft_verdict { 97a55e22e9SPatrick McHardy u32 code; 98a55e22e9SPatrick McHardy struct nft_chain *chain; 99a55e22e9SPatrick McHardy }; 100a55e22e9SPatrick McHardy 10196518518SPatrick McHardy struct nft_data { 10296518518SPatrick McHardy union { 10396518518SPatrick McHardy u32 data[4]; 1041ca2e170SPatrick McHardy struct nft_verdict verdict; 10596518518SPatrick McHardy }; 10696518518SPatrick McHardy } __attribute__((aligned(__alignof__(u64)))); 10796518518SPatrick McHardy 108642c8effSPablo Neira Ayuso #define NFT_REG32_NUM 20 109642c8effSPablo Neira Ayuso 110a55e22e9SPatrick McHardy /** 111a55e22e9SPatrick McHardy * struct nft_regs - nf_tables register set 112a55e22e9SPatrick McHardy * 113a55e22e9SPatrick McHardy * @data: data registers 114a55e22e9SPatrick McHardy * @verdict: verdict register 115a55e22e9SPatrick McHardy * 116a55e22e9SPatrick McHardy * The first four data registers alias to the verdict register. 117a55e22e9SPatrick McHardy */ 118a55e22e9SPatrick McHardy struct nft_regs { 119a55e22e9SPatrick McHardy union { 120642c8effSPablo Neira Ayuso u32 data[NFT_REG32_NUM]; 121a55e22e9SPatrick McHardy struct nft_verdict verdict; 122a55e22e9SPatrick McHardy }; 123a55e22e9SPatrick McHardy }; 124a55e22e9SPatrick McHardy 12512e4ecfaSPablo Neira Ayuso struct nft_regs_track { 12612e4ecfaSPablo Neira Ayuso struct { 12712e4ecfaSPablo Neira Ayuso const struct nft_expr *selector; 12812e4ecfaSPablo Neira Ayuso const struct nft_expr *bitwise; 12934cc9e52SPablo Neira Ayuso u8 num_reg; 13012e4ecfaSPablo Neira Ayuso } regs[NFT_REG32_NUM]; 13112e4ecfaSPablo Neira Ayuso 13212e4ecfaSPablo Neira Ayuso const struct nft_expr *cur; 13312e4ecfaSPablo Neira Ayuso const struct nft_expr *last; 13412e4ecfaSPablo Neira Ayuso }; 13512e4ecfaSPablo Neira Ayuso 136a1b840adSAnder Juaristi /* Store/load an u8, u16 or u64 integer to/from the u32 data register. 13710596608SLiping Zhang * 13810596608SLiping Zhang * Note, when using concatenations, register allocation happens at 32-bit 13910596608SLiping Zhang * level. So for store instruction, pad the rest part with zero to avoid 14010596608SLiping Zhang * garbage values. 14110596608SLiping Zhang */ 14210596608SLiping Zhang 14310596608SLiping Zhang static inline void nft_reg_store8(u32 *dreg, u8 val) 14410596608SLiping Zhang { 14510596608SLiping Zhang *dreg = 0; 14610596608SLiping Zhang *(u8 *)dreg = val; 14710596608SLiping Zhang } 14810596608SLiping Zhang 1497cd9a58dSPablo Neira Ayuso static inline u8 nft_reg_load8(const u32 *sreg) 150a1b840adSAnder Juaristi { 151a1b840adSAnder Juaristi return *(u8 *)sreg; 152a1b840adSAnder Juaristi } 153a1b840adSAnder Juaristi 154a1b840adSAnder Juaristi static inline void nft_reg_store16(u32 *dreg, u16 val) 155a1b840adSAnder Juaristi { 156a1b840adSAnder Juaristi *dreg = 0; 157a1b840adSAnder Juaristi *(u16 *)dreg = val; 158a1b840adSAnder Juaristi } 159a1b840adSAnder Juaristi 1607278b3c1SFlorian Westphal static inline void nft_reg_store_be16(u32 *dreg, __be16 val) 1617278b3c1SFlorian Westphal { 1627278b3c1SFlorian Westphal nft_reg_store16(dreg, (__force __u16)val); 1637278b3c1SFlorian Westphal } 1647278b3c1SFlorian Westphal 1657cd9a58dSPablo Neira Ayuso static inline u16 nft_reg_load16(const u32 *sreg) 16610596608SLiping Zhang { 16710596608SLiping Zhang return *(u16 *)sreg; 16810596608SLiping Zhang } 16910596608SLiping Zhang 1707278b3c1SFlorian Westphal static inline __be16 nft_reg_load_be16(const u32 *sreg) 1717278b3c1SFlorian Westphal { 1727278b3c1SFlorian Westphal return (__force __be16)nft_reg_load16(sreg); 1737278b3c1SFlorian Westphal } 1747278b3c1SFlorian Westphal 1757278b3c1SFlorian Westphal static inline __be32 nft_reg_load_be32(const u32 *sreg) 1767278b3c1SFlorian Westphal { 1777278b3c1SFlorian Westphal return *(__force __be32 *)sreg; 1787278b3c1SFlorian Westphal } 1797278b3c1SFlorian Westphal 180a1b840adSAnder Juaristi static inline void nft_reg_store64(u32 *dreg, u64 val) 18110596608SLiping Zhang { 182a1b840adSAnder Juaristi put_unaligned(val, (u64 *)dreg); 183a1b840adSAnder Juaristi } 184a1b840adSAnder Juaristi 1857cd9a58dSPablo Neira Ayuso static inline u64 nft_reg_load64(const u32 *sreg) 186a1b840adSAnder Juaristi { 187a1b840adSAnder Juaristi return get_unaligned((u64 *)sreg); 18810596608SLiping Zhang } 18910596608SLiping Zhang 19049499c3eSPatrick McHardy static inline void nft_data_copy(u32 *dst, const struct nft_data *src, 19149499c3eSPatrick McHardy unsigned int len) 19296518518SPatrick McHardy { 1931e105e6aSFlorian Westphal if (len % NFT_REG32_SIZE) 1941e105e6aSFlorian Westphal dst[len / NFT_REG32_SIZE] = 0; 19549499c3eSPatrick McHardy memcpy(dst, src, len); 19696518518SPatrick McHardy } 19796518518SPatrick McHardy 19896518518SPatrick McHardy /** 19920a69341SPatrick McHardy * struct nft_ctx - nf_tables rule/set context 20096518518SPatrick McHardy * 20199633ab2SPablo Neira Ayuso * @net: net namespace 20296518518SPatrick McHardy * @table: the table the chain is contained in 20396518518SPatrick McHardy * @chain: the chain the rule is contained in 2040ca743a5SPablo Neira Ayuso * @nla: netlink attributes 205128ad332SPablo Neira Ayuso * @portid: netlink portID of the original message 206128ad332SPablo Neira Ayuso * @seq: netlink sequence number 20736596dadSPablo Neira Ayuso * @family: protocol family 20826b2f552STaehee Yoo * @level: depth of the chains 209128ad332SPablo Neira Ayuso * @report: notify via unicast netlink message 21096518518SPatrick McHardy */ 21196518518SPatrick McHardy struct nft_ctx { 21299633ab2SPablo Neira Ayuso struct net *net; 2137c95f6d8SPablo Neira Ayuso struct nft_table *table; 2147c95f6d8SPablo Neira Ayuso struct nft_chain *chain; 2150ca743a5SPablo Neira Ayuso const struct nlattr * const *nla; 216128ad332SPablo Neira Ayuso u32 portid; 217128ad332SPablo Neira Ayuso u32 seq; 218c9626a2cSPablo Neira Ayuso u16 flags; 21936596dadSPablo Neira Ayuso u8 family; 22026b2f552STaehee Yoo u8 level; 221128ad332SPablo Neira Ayuso bool report; 22296518518SPatrick McHardy }; 22396518518SPatrick McHardy 224f323ef3aSPablo Neira Ayuso enum nft_data_desc_flags { 225f323ef3aSPablo Neira Ayuso NFT_DATA_DESC_SETELEM = (1 << 0), 226f323ef3aSPablo Neira Ayuso }; 227f323ef3aSPablo Neira Ayuso 22896518518SPatrick McHardy struct nft_data_desc { 22996518518SPatrick McHardy enum nft_data_types type; 230341b6941SPablo Neira Ayuso unsigned int size; 23196518518SPatrick McHardy unsigned int len; 232f323ef3aSPablo Neira Ayuso unsigned int flags; 23396518518SPatrick McHardy }; 23496518518SPatrick McHardy 235341b6941SPablo Neira Ayuso int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 23696518518SPatrick McHardy struct nft_data_desc *desc, const struct nlattr *nla); 237bb7b40aeSPablo Neira Ayuso void nft_data_hold(const struct nft_data *data, enum nft_data_types type); 23859105446SPablo Neira Ayuso void nft_data_release(const struct nft_data *data, enum nft_data_types type); 2395eccdfaaSJoe Perches int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data, 24096518518SPatrick McHardy enum nft_data_types type, unsigned int len); 24196518518SPatrick McHardy 24296518518SPatrick McHardy static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg) 24396518518SPatrick McHardy { 24496518518SPatrick McHardy return reg == NFT_REG_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; 24596518518SPatrick McHardy } 24696518518SPatrick McHardy 24720a69341SPatrick McHardy static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) 24820a69341SPatrick McHardy { 249bf798657SPablo Neira Ayuso return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE; 25020a69341SPatrick McHardy } 25120a69341SPatrick McHardy 252f1d505bbSJohn W. Linville int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest); 253b1c96ed3SPatrick McHardy int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); 254b1c96ed3SPatrick McHardy 2554f16d25cSPablo Neira Ayuso int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len); 256345023b0SPablo Neira Ayuso int nft_parse_register_store(const struct nft_ctx *ctx, 257345023b0SPablo Neira Ayuso const struct nlattr *attr, u8 *dreg, 25896518518SPatrick McHardy const struct nft_data *data, 25945d9bcdaSPatrick McHardy enum nft_data_types type, unsigned int len); 26096518518SPatrick McHardy 26186f1ec32SPatrick McHardy /** 26286f1ec32SPatrick McHardy * struct nft_userdata - user defined data associated with an object 26386f1ec32SPatrick McHardy * 26486f1ec32SPatrick McHardy * @len: length of the data 26586f1ec32SPatrick McHardy * @data: content 26686f1ec32SPatrick McHardy * 26786f1ec32SPatrick McHardy * The presence of user data is indicated in an object specific fashion, 26886f1ec32SPatrick McHardy * so a length of zero can't occur and the value "len" indicates data 26986f1ec32SPatrick McHardy * of length len + 1. 27086f1ec32SPatrick McHardy */ 27186f1ec32SPatrick McHardy struct nft_userdata { 27286f1ec32SPatrick McHardy u8 len; 2736daf1414SGustavo A. R. Silva unsigned char data[]; 27486f1ec32SPatrick McHardy }; 27586f1ec32SPatrick McHardy 27696518518SPatrick McHardy /** 27720a69341SPatrick McHardy * struct nft_set_elem - generic representation of set elements 27820a69341SPatrick McHardy * 27920a69341SPatrick McHardy * @key: element key 2807b225d0bSPablo Neira Ayuso * @key_end: closing element key 281fe2811ebSPatrick McHardy * @priv: element private data and extensions 28220a69341SPatrick McHardy */ 28320a69341SPatrick McHardy struct nft_set_elem { 2847d740264SPatrick McHardy union { 2857d740264SPatrick McHardy u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; 2867d740264SPatrick McHardy struct nft_data val; 2877d740264SPatrick McHardy } key; 2887b225d0bSPablo Neira Ayuso union { 2897b225d0bSPablo Neira Ayuso u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; 2907b225d0bSPablo Neira Ayuso struct nft_data val; 2917b225d0bSPablo Neira Ayuso } key_end; 292fdb9c405SPablo Neira Ayuso union { 293fdb9c405SPablo Neira Ayuso u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; 294fdb9c405SPablo Neira Ayuso struct nft_data val; 295fdb9c405SPablo Neira Ayuso } data; 296fe2811ebSPatrick McHardy void *priv; 29720a69341SPatrick McHardy }; 29820a69341SPatrick McHardy 29920a69341SPatrick McHardy struct nft_set; 30020a69341SPatrick McHardy struct nft_set_iter { 3018588ac09SPablo Neira Ayuso u8 genmask; 30220a69341SPatrick McHardy unsigned int count; 30320a69341SPatrick McHardy unsigned int skip; 30420a69341SPatrick McHardy int err; 30520a69341SPatrick McHardy int (*fn)(const struct nft_ctx *ctx, 306de70185dSPablo Neira Ayuso struct nft_set *set, 30720a69341SPatrick McHardy const struct nft_set_iter *iter, 308de70185dSPablo Neira Ayuso struct nft_set_elem *elem); 30920a69341SPatrick McHardy }; 31020a69341SPatrick McHardy 31120a69341SPatrick McHardy /** 312c50b960cSPatrick McHardy * struct nft_set_desc - description of set elements 313c50b960cSPatrick McHardy * 314c50b960cSPatrick McHardy * @klen: key length 315c50b960cSPatrick McHardy * @dlen: data length 316c50b960cSPatrick McHardy * @size: number of set elements 317f3a2181eSStefano Brivio * @field_len: length of each field in concatenation, bytes 318f3a2181eSStefano Brivio * @field_count: number of concatenated fields in element 319d56aab26SPablo Neira Ayuso * @expr: set must support for expressions 320c50b960cSPatrick McHardy */ 321c50b960cSPatrick McHardy struct nft_set_desc { 322c50b960cSPatrick McHardy unsigned int klen; 323c50b960cSPatrick McHardy unsigned int dlen; 324c50b960cSPatrick McHardy unsigned int size; 325f3a2181eSStefano Brivio u8 field_len[NFT_REG32_COUNT]; 326f3a2181eSStefano Brivio u8 field_count; 327d56aab26SPablo Neira Ayuso bool expr; 328c50b960cSPatrick McHardy }; 329c50b960cSPatrick McHardy 330c50b960cSPatrick McHardy /** 331c50b960cSPatrick McHardy * enum nft_set_class - performance class 332c50b960cSPatrick McHardy * 333c50b960cSPatrick McHardy * @NFT_LOOKUP_O_1: constant, O(1) 334c50b960cSPatrick McHardy * @NFT_LOOKUP_O_LOG_N: logarithmic, O(log N) 335c50b960cSPatrick McHardy * @NFT_LOOKUP_O_N: linear, O(N) 336c50b960cSPatrick McHardy */ 337c50b960cSPatrick McHardy enum nft_set_class { 338c50b960cSPatrick McHardy NFT_SET_CLASS_O_1, 339c50b960cSPatrick McHardy NFT_SET_CLASS_O_LOG_N, 340c50b960cSPatrick McHardy NFT_SET_CLASS_O_N, 341c50b960cSPatrick McHardy }; 342c50b960cSPatrick McHardy 343c50b960cSPatrick McHardy /** 344c50b960cSPatrick McHardy * struct nft_set_estimate - estimation of memory and performance 345c50b960cSPatrick McHardy * characteristics 346c50b960cSPatrick McHardy * 347c50b960cSPatrick McHardy * @size: required memory 34855af753cSPablo Neira Ayuso * @lookup: lookup performance class 3490b5a7874SPablo Neira Ayuso * @space: memory class 350c50b960cSPatrick McHardy */ 351c50b960cSPatrick McHardy struct nft_set_estimate { 3524ef360ddSTaehee Yoo u64 size; 35355af753cSPablo Neira Ayuso enum nft_set_class lookup; 3540b5a7874SPablo Neira Ayuso enum nft_set_class space; 355c50b960cSPatrick McHardy }; 356c50b960cSPatrick McHardy 35792b211a2SPablo Neira Ayuso #define NFT_EXPR_MAXATTR 16 35892b211a2SPablo Neira Ayuso #define NFT_EXPR_SIZE(size) (sizeof(struct nft_expr) + \ 35992b211a2SPablo Neira Ayuso ALIGN(size, __alignof__(struct nft_expr))) 36092b211a2SPablo Neira Ayuso 36192b211a2SPablo Neira Ayuso /** 36292b211a2SPablo Neira Ayuso * struct nft_expr - nf_tables expression 36392b211a2SPablo Neira Ayuso * 36492b211a2SPablo Neira Ayuso * @ops: expression ops 36592b211a2SPablo Neira Ayuso * @data: expression private data 36692b211a2SPablo Neira Ayuso */ 36792b211a2SPablo Neira Ayuso struct nft_expr { 36892b211a2SPablo Neira Ayuso const struct nft_expr_ops *ops; 36992b211a2SPablo Neira Ayuso unsigned char data[] 37092b211a2SPablo Neira Ayuso __attribute__((aligned(__alignof__(u64)))); 37192b211a2SPablo Neira Ayuso }; 37292b211a2SPablo Neira Ayuso 37392b211a2SPablo Neira Ayuso static inline void *nft_expr_priv(const struct nft_expr *expr) 37492b211a2SPablo Neira Ayuso { 37592b211a2SPablo Neira Ayuso return (void *)expr->data; 37692b211a2SPablo Neira Ayuso } 37792b211a2SPablo Neira Ayuso 37892b211a2SPablo Neira Ayuso int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src); 37992b211a2SPablo Neira Ayuso void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr); 38092b211a2SPablo Neira Ayuso int nft_expr_dump(struct sk_buff *skb, unsigned int attr, 38192b211a2SPablo Neira Ayuso const struct nft_expr *expr); 382be5650f8SPablo Neira Ayuso bool nft_expr_reduce_bitwise(struct nft_regs_track *track, 383be5650f8SPablo Neira Ayuso const struct nft_expr *expr); 38492b211a2SPablo Neira Ayuso 385b2832dd6SPatrick McHardy struct nft_set_ext; 386b2832dd6SPatrick McHardy 387c50b960cSPatrick McHardy /** 38820a69341SPatrick McHardy * struct nft_set_ops - nf_tables set operations 38920a69341SPatrick McHardy * 39020a69341SPatrick McHardy * @lookup: look up an element within the set 391d0a8d877SAnder Juaristi * @update: update an element if exists, add it if doesn't exist 392d0a8d877SAnder Juaristi * @delete: delete an element 39320a69341SPatrick McHardy * @insert: insert new element into set 394cc02e457SPatrick McHardy * @activate: activate new element in the next generation 3958411b644SPablo Neira Ayuso * @deactivate: lookup for element and deactivate it in the next generation 3961ba1c414SPablo Neira Ayuso * @flush: deactivate element in the next generation 39720a69341SPatrick McHardy * @remove: remove element from set 398d0a8d877SAnder Juaristi * @walk: iterate over all set elements 399ba0e4d99SPablo Neira Ayuso * @get: get set elements 40020a69341SPatrick McHardy * @privsize: function to return size of set private data 40120a69341SPatrick McHardy * @init: initialize private data of new set instance 40220a69341SPatrick McHardy * @destroy: destroy private data of set instance 403fe2811ebSPatrick McHardy * @elemsize: element private size 404d0a8d877SAnder Juaristi * 405d0a8d877SAnder Juaristi * Operations lookup, update and delete have simpler interfaces, are faster 406d0a8d877SAnder Juaristi * and currently only used in the packet path. All the rest are slower, 407d0a8d877SAnder Juaristi * control plane functions. 40820a69341SPatrick McHardy */ 40920a69341SPatrick McHardy struct nft_set_ops { 41042a55769SPablo Neira Ayuso bool (*lookup)(const struct net *net, 41142a55769SPablo Neira Ayuso const struct nft_set *set, 4128cd8937aSPatrick McHardy const u32 *key, 413b2832dd6SPatrick McHardy const struct nft_set_ext **ext); 41422fe54d5SPatrick McHardy bool (*update)(struct nft_set *set, 4158cd8937aSPatrick McHardy const u32 *key, 41622fe54d5SPatrick McHardy void *(*new)(struct nft_set *, 41722fe54d5SPatrick McHardy const struct nft_expr *, 418a55e22e9SPatrick McHardy struct nft_regs *), 41922fe54d5SPatrick McHardy const struct nft_expr *expr, 420a55e22e9SPatrick McHardy struct nft_regs *regs, 42122fe54d5SPatrick McHardy const struct nft_set_ext **ext); 422d0a8d877SAnder Juaristi bool (*delete)(const struct nft_set *set, 423d0a8d877SAnder Juaristi const u32 *key); 42422fe54d5SPatrick McHardy 42542a55769SPablo Neira Ayuso int (*insert)(const struct net *net, 42642a55769SPablo Neira Ayuso const struct nft_set *set, 427c016c7e4SPablo Neira Ayuso const struct nft_set_elem *elem, 428c016c7e4SPablo Neira Ayuso struct nft_set_ext **ext); 42942a55769SPablo Neira Ayuso void (*activate)(const struct net *net, 43042a55769SPablo Neira Ayuso const struct nft_set *set, 431cc02e457SPatrick McHardy const struct nft_set_elem *elem); 43242a55769SPablo Neira Ayuso void * (*deactivate)(const struct net *net, 43342a55769SPablo Neira Ayuso const struct nft_set *set, 434cc02e457SPatrick McHardy const struct nft_set_elem *elem); 4351ba1c414SPablo Neira Ayuso bool (*flush)(const struct net *net, 4368411b644SPablo Neira Ayuso const struct nft_set *set, 4378411b644SPablo Neira Ayuso void *priv); 4385cb82a38SPablo Neira Ayuso void (*remove)(const struct net *net, 4395cb82a38SPablo Neira Ayuso const struct nft_set *set, 44020a69341SPatrick McHardy const struct nft_set_elem *elem); 44120a69341SPatrick McHardy void (*walk)(const struct nft_ctx *ctx, 442de70185dSPablo Neira Ayuso struct nft_set *set, 44320a69341SPatrick McHardy struct nft_set_iter *iter); 444ba0e4d99SPablo Neira Ayuso void * (*get)(const struct net *net, 445ba0e4d99SPablo Neira Ayuso const struct nft_set *set, 446ba0e4d99SPablo Neira Ayuso const struct nft_set_elem *elem, 447ba0e4d99SPablo Neira Ayuso unsigned int flags); 44820a69341SPatrick McHardy 4494ef360ddSTaehee Yoo u64 (*privsize)(const struct nlattr * const nla[], 450347b408dSPablo Neira Ayuso const struct nft_set_desc *desc); 451c50b960cSPatrick McHardy bool (*estimate)(const struct nft_set_desc *desc, 452c50b960cSPatrick McHardy u32 features, 453c50b960cSPatrick McHardy struct nft_set_estimate *est); 45420a69341SPatrick McHardy int (*init)(const struct nft_set *set, 455c50b960cSPatrick McHardy const struct nft_set_desc *desc, 45620a69341SPatrick McHardy const struct nlattr * const nla[]); 45720a69341SPatrick McHardy void (*destroy)(const struct nft_set *set); 45879b174adSPablo Neira Ayuso void (*gc_init)(const struct nft_set *set); 45920a69341SPatrick McHardy 460fe2811ebSPatrick McHardy unsigned int elemsize; 46120a69341SPatrick McHardy }; 46220a69341SPatrick McHardy 46371cc0873SPhil Sutter /** 46471cc0873SPhil Sutter * struct nft_set_type - nf_tables set type 46571cc0873SPhil Sutter * 46671cc0873SPhil Sutter * @ops: set ops for this type 46771cc0873SPhil Sutter * @features: features supported by the implementation 46871cc0873SPhil Sutter */ 46971cc0873SPhil Sutter struct nft_set_type { 47071cc0873SPhil Sutter const struct nft_set_ops ops; 47171cc0873SPhil Sutter u32 features; 47271cc0873SPhil Sutter }; 47371cc0873SPhil Sutter #define to_set_type(o) container_of(o, struct nft_set_type, ops) 47471cc0873SPhil Sutter 475563125a7SPablo Neira Ayuso struct nft_set_elem_expr { 476563125a7SPablo Neira Ayuso u8 size; 477563125a7SPablo Neira Ayuso unsigned char data[] 478563125a7SPablo Neira Ayuso __attribute__((aligned(__alignof__(struct nft_expr)))); 479563125a7SPablo Neira Ayuso }; 480563125a7SPablo Neira Ayuso 481563125a7SPablo Neira Ayuso #define nft_setelem_expr_at(__elem_expr, __offset) \ 482563125a7SPablo Neira Ayuso ((struct nft_expr *)&__elem_expr->data[__offset]) 483563125a7SPablo Neira Ayuso 484563125a7SPablo Neira Ayuso #define nft_setelem_expr_foreach(__expr, __elem_expr, __size) \ 485563125a7SPablo Neira Ayuso for (__expr = nft_setelem_expr_at(__elem_expr, 0), __size = 0; \ 486563125a7SPablo Neira Ayuso __size < (__elem_expr)->size; \ 487563125a7SPablo Neira Ayuso __size += (__expr)->ops->size, __expr = ((void *)(__expr)) + (__expr)->ops->size) 488563125a7SPablo Neira Ayuso 4898cfd9b0fSPablo Neira Ayuso #define NFT_SET_EXPR_MAX 2 4908cfd9b0fSPablo Neira Ayuso 49120a69341SPatrick McHardy /** 49220a69341SPatrick McHardy * struct nft_set - nf_tables set instance 49320a69341SPatrick McHardy * 49420a69341SPatrick McHardy * @list: table set list node 49520a69341SPatrick McHardy * @bindings: list of set bindings 4963453c927SPablo Neira Ayuso * @table: table this set belongs to 4973453c927SPablo Neira Ayuso * @net: netnamespace this set belongs to 49820a69341SPatrick McHardy * @name: name of the set 4993ecbfd65SHarsha Sharma * @handle: unique handle of the set 50020a69341SPatrick McHardy * @ktype: key type (numeric type defined by userspace, not used in the kernel) 50120a69341SPatrick McHardy * @dtype: data type (verdict or numeric type defined by userspace) 5028aeff920SPablo Neira Ayuso * @objtype: object type (see NFT_OBJECT_* definitions) 503c50b960cSPatrick McHardy * @size: maximum set size 504f3a2181eSStefano Brivio * @field_len: length of each field in concatenation, bytes 505f3a2181eSStefano Brivio * @field_count: number of concatenated fields in element 506273fe3f1SPablo Neira Ayuso * @use: number of rules references to this set 507c50b960cSPatrick McHardy * @nelems: number of elements 5083dd0673aSPatrick McHardy * @ndeact: number of deactivated elements queued for removal 509d3e2a111SAnders K. Pedersen * @timeout: default timeout value in jiffies 510761da293SPatrick McHardy * @gc_int: garbage collection interval in msecs 5119363dc4bSArturo Borrero * @policy: set parameterization (see enum nft_set_policies) 512e6d8ecacSCarlos Falgueras García * @udlen: user data length 513e6d8ecacSCarlos Falgueras García * @udata: user data 51465038428SPablo Neira Ayuso * @expr: stateful expression 51520a69341SPatrick McHardy * @ops: set ops 51620a69341SPatrick McHardy * @flags: set flags 51737a9cc52SPablo Neira Ayuso * @genmask: generation mask 51820a69341SPatrick McHardy * @klen: key length 51920a69341SPatrick McHardy * @dlen: data length 52020a69341SPatrick McHardy * @data: private set data 52120a69341SPatrick McHardy */ 52220a69341SPatrick McHardy struct nft_set { 52320a69341SPatrick McHardy struct list_head list; 52420a69341SPatrick McHardy struct list_head bindings; 5253453c927SPablo Neira Ayuso struct nft_table *table; 5263453c927SPablo Neira Ayuso possible_net_t net; 52738745490SPhil Sutter char *name; 5283ecbfd65SHarsha Sharma u64 handle; 52920a69341SPatrick McHardy u32 ktype; 53020a69341SPatrick McHardy u32 dtype; 5318aeff920SPablo Neira Ayuso u32 objtype; 532c50b960cSPatrick McHardy u32 size; 533f3a2181eSStefano Brivio u8 field_len[NFT_REG32_COUNT]; 534f3a2181eSStefano Brivio u8 field_count; 535273fe3f1SPablo Neira Ayuso u32 use; 5363dd0673aSPatrick McHardy atomic_t nelems; 5373dd0673aSPatrick McHardy u32 ndeact; 538761da293SPatrick McHardy u64 timeout; 539761da293SPatrick McHardy u32 gc_int; 5409363dc4bSArturo Borrero u16 policy; 541e6d8ecacSCarlos Falgueras García u16 udlen; 542e6d8ecacSCarlos Falgueras García unsigned char *udata; 54320a69341SPatrick McHardy /* runtime data below here */ 54420a69341SPatrick McHardy const struct nft_set_ops *ops ____cacheline_aligned; 5456a0a8d10SPablo Neira Ayuso u16 flags:14, 54637a9cc52SPablo Neira Ayuso genmask:2; 54720a69341SPatrick McHardy u8 klen; 54820a69341SPatrick McHardy u8 dlen; 5498cfd9b0fSPablo Neira Ayuso u8 num_exprs; 5508cfd9b0fSPablo Neira Ayuso struct nft_expr *exprs[NFT_SET_EXPR_MAX]; 551aaa31047SPablo Neira Ayuso struct list_head catchall_list; 55220a69341SPatrick McHardy unsigned char data[] 55320a69341SPatrick McHardy __attribute__((aligned(__alignof__(u64)))); 55420a69341SPatrick McHardy }; 55520a69341SPatrick McHardy 556408070d6SPablo Neira Ayuso static inline bool nft_set_is_anonymous(const struct nft_set *set) 557408070d6SPablo Neira Ayuso { 558408070d6SPablo Neira Ayuso return set->flags & NFT_SET_ANONYMOUS; 559408070d6SPablo Neira Ayuso } 560408070d6SPablo Neira Ayuso 56120a69341SPatrick McHardy static inline void *nft_set_priv(const struct nft_set *set) 56220a69341SPatrick McHardy { 56320a69341SPatrick McHardy return (void *)set->data; 56420a69341SPatrick McHardy } 56520a69341SPatrick McHardy 5669d098292SPatrick McHardy static inline struct nft_set *nft_set_container_of(const void *priv) 5679d098292SPatrick McHardy { 5689d098292SPatrick McHardy return (void *)priv - offsetof(struct nft_set, data); 5699d098292SPatrick McHardy } 5709d098292SPatrick McHardy 57110659cbaSPablo Neira Ayuso struct nft_set *nft_set_lookup_global(const struct net *net, 572c7a72e3fSPablo Neira Ayuso const struct nft_table *table, 573c7a72e3fSPablo Neira Ayuso const struct nlattr *nla_set_name, 574c7a72e3fSPablo Neira Ayuso const struct nlattr *nla_set_id, 575c7a72e3fSPablo Neira Ayuso u8 genmask); 57620a69341SPatrick McHardy 577aaa31047SPablo Neira Ayuso struct nft_set_ext *nft_set_catchall_lookup(const struct net *net, 578aaa31047SPablo Neira Ayuso const struct nft_set *set); 579aaa31047SPablo Neira Ayuso void *nft_set_catchall_gc(const struct nft_set *set); 580aaa31047SPablo Neira Ayuso 581761da293SPatrick McHardy static inline unsigned long nft_set_gc_interval(const struct nft_set *set) 582761da293SPatrick McHardy { 583761da293SPatrick McHardy return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ; 584761da293SPatrick McHardy } 585761da293SPatrick McHardy 58620a69341SPatrick McHardy /** 58720a69341SPatrick McHardy * struct nft_set_binding - nf_tables set binding 58820a69341SPatrick McHardy * 58920a69341SPatrick McHardy * @list: set bindings list node 59020a69341SPatrick McHardy * @chain: chain containing the rule bound to the set 59111113e19SPatrick McHardy * @flags: set action flags 59220a69341SPatrick McHardy * 59320a69341SPatrick McHardy * A set binding contains all information necessary for validation 59420a69341SPatrick McHardy * of new elements added to a bound set. 59520a69341SPatrick McHardy */ 59620a69341SPatrick McHardy struct nft_set_binding { 59720a69341SPatrick McHardy struct list_head list; 59820a69341SPatrick McHardy const struct nft_chain *chain; 59911113e19SPatrick McHardy u32 flags; 60020a69341SPatrick McHardy }; 60120a69341SPatrick McHardy 602273fe3f1SPablo Neira Ayuso enum nft_trans_phase; 603273fe3f1SPablo Neira Ayuso void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, 604273fe3f1SPablo Neira Ayuso struct nft_set_binding *binding, 605273fe3f1SPablo Neira Ayuso enum nft_trans_phase phase); 6065eccdfaaSJoe Perches int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, 60720a69341SPatrick McHardy struct nft_set_binding *binding); 608cd5125d8SFlorian Westphal void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set); 60920a69341SPatrick McHardy 6103ac4c07aSPatrick McHardy /** 6113ac4c07aSPatrick McHardy * enum nft_set_extensions - set extension type IDs 6123ac4c07aSPatrick McHardy * 6133ac4c07aSPatrick McHardy * @NFT_SET_EXT_KEY: element key 6147b225d0bSPablo Neira Ayuso * @NFT_SET_EXT_KEY_END: upper bound element key, for ranges 6153ac4c07aSPatrick McHardy * @NFT_SET_EXT_DATA: mapping data 6163ac4c07aSPatrick McHardy * @NFT_SET_EXT_FLAGS: element flags 617c3e1b005SPatrick McHardy * @NFT_SET_EXT_TIMEOUT: element timeout 618c3e1b005SPatrick McHardy * @NFT_SET_EXT_EXPIRATION: element expiration time 61968e942e8SPatrick McHardy * @NFT_SET_EXT_USERDATA: user data associated with the element 620563125a7SPablo Neira Ayuso * @NFT_SET_EXT_EXPRESSIONS: expressions assiciated with the element 6218aeff920SPablo Neira Ayuso * @NFT_SET_EXT_OBJREF: stateful object reference associated with element 6223ac4c07aSPatrick McHardy * @NFT_SET_EXT_NUM: number of extension types 6233ac4c07aSPatrick McHardy */ 6243ac4c07aSPatrick McHardy enum nft_set_extensions { 6253ac4c07aSPatrick McHardy NFT_SET_EXT_KEY, 6267b225d0bSPablo Neira Ayuso NFT_SET_EXT_KEY_END, 6273ac4c07aSPatrick McHardy NFT_SET_EXT_DATA, 6283ac4c07aSPatrick McHardy NFT_SET_EXT_FLAGS, 629c3e1b005SPatrick McHardy NFT_SET_EXT_TIMEOUT, 630c3e1b005SPatrick McHardy NFT_SET_EXT_EXPIRATION, 63168e942e8SPatrick McHardy NFT_SET_EXT_USERDATA, 632563125a7SPablo Neira Ayuso NFT_SET_EXT_EXPRESSIONS, 6338aeff920SPablo Neira Ayuso NFT_SET_EXT_OBJREF, 6343ac4c07aSPatrick McHardy NFT_SET_EXT_NUM 6353ac4c07aSPatrick McHardy }; 6363ac4c07aSPatrick McHardy 6373ac4c07aSPatrick McHardy /** 6383ac4c07aSPatrick McHardy * struct nft_set_ext_type - set extension type 6393ac4c07aSPatrick McHardy * 6403ac4c07aSPatrick McHardy * @len: fixed part length of the extension 6413ac4c07aSPatrick McHardy * @align: alignment requirements of the extension 6423ac4c07aSPatrick McHardy */ 6433ac4c07aSPatrick McHardy struct nft_set_ext_type { 6443ac4c07aSPatrick McHardy u8 len; 6453ac4c07aSPatrick McHardy u8 align; 6463ac4c07aSPatrick McHardy }; 6473ac4c07aSPatrick McHardy 6483ac4c07aSPatrick McHardy extern const struct nft_set_ext_type nft_set_ext_types[]; 6493ac4c07aSPatrick McHardy 6503ac4c07aSPatrick McHardy /** 6513ac4c07aSPatrick McHardy * struct nft_set_ext_tmpl - set extension template 6523ac4c07aSPatrick McHardy * 6533ac4c07aSPatrick McHardy * @len: length of extension area 6543ac4c07aSPatrick McHardy * @offset: offsets of individual extension types 6553ac4c07aSPatrick McHardy */ 6563ac4c07aSPatrick McHardy struct nft_set_ext_tmpl { 6573ac4c07aSPatrick McHardy u16 len; 6583ac4c07aSPatrick McHardy u8 offset[NFT_SET_EXT_NUM]; 65934aae2c2SPablo Neira Ayuso u8 ext_len[NFT_SET_EXT_NUM]; 6603ac4c07aSPatrick McHardy }; 6613ac4c07aSPatrick McHardy 6623ac4c07aSPatrick McHardy /** 6633ac4c07aSPatrick McHardy * struct nft_set_ext - set extensions 6643ac4c07aSPatrick McHardy * 665cc02e457SPatrick McHardy * @genmask: generation mask 6663ac4c07aSPatrick McHardy * @offset: offsets of individual extension types 6673ac4c07aSPatrick McHardy * @data: beginning of extension data 6683ac4c07aSPatrick McHardy */ 6693ac4c07aSPatrick McHardy struct nft_set_ext { 670cc02e457SPatrick McHardy u8 genmask; 6713ac4c07aSPatrick McHardy u8 offset[NFT_SET_EXT_NUM]; 6726daf1414SGustavo A. R. Silva char data[]; 6733ac4c07aSPatrick McHardy }; 6743ac4c07aSPatrick McHardy 6753ac4c07aSPatrick McHardy static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl) 6763ac4c07aSPatrick McHardy { 6773ac4c07aSPatrick McHardy memset(tmpl, 0, sizeof(*tmpl)); 6783ac4c07aSPatrick McHardy tmpl->len = sizeof(struct nft_set_ext); 6793ac4c07aSPatrick McHardy } 6803ac4c07aSPatrick McHardy 681c39ba4deSPablo Neira Ayuso static inline int nft_set_ext_add_length(struct nft_set_ext_tmpl *tmpl, u8 id, 6823ac4c07aSPatrick McHardy unsigned int len) 6833ac4c07aSPatrick McHardy { 6843ac4c07aSPatrick McHardy tmpl->len = ALIGN(tmpl->len, nft_set_ext_types[id].align); 685c39ba4deSPablo Neira Ayuso if (tmpl->len > U8_MAX) 686c39ba4deSPablo Neira Ayuso return -EINVAL; 687c39ba4deSPablo Neira Ayuso 6883ac4c07aSPatrick McHardy tmpl->offset[id] = tmpl->len; 68934aae2c2SPablo Neira Ayuso tmpl->ext_len[id] = nft_set_ext_types[id].len + len; 69034aae2c2SPablo Neira Ayuso tmpl->len += tmpl->ext_len[id]; 691c39ba4deSPablo Neira Ayuso 692c39ba4deSPablo Neira Ayuso return 0; 6933ac4c07aSPatrick McHardy } 6943ac4c07aSPatrick McHardy 695c39ba4deSPablo Neira Ayuso static inline int nft_set_ext_add(struct nft_set_ext_tmpl *tmpl, u8 id) 6963ac4c07aSPatrick McHardy { 697c39ba4deSPablo Neira Ayuso return nft_set_ext_add_length(tmpl, id, 0); 6983ac4c07aSPatrick McHardy } 6993ac4c07aSPatrick McHardy 7003ac4c07aSPatrick McHardy static inline void nft_set_ext_init(struct nft_set_ext *ext, 7013ac4c07aSPatrick McHardy const struct nft_set_ext_tmpl *tmpl) 7023ac4c07aSPatrick McHardy { 7033ac4c07aSPatrick McHardy memcpy(ext->offset, tmpl->offset, sizeof(ext->offset)); 7043ac4c07aSPatrick McHardy } 7053ac4c07aSPatrick McHardy 7063ac4c07aSPatrick McHardy static inline bool __nft_set_ext_exists(const struct nft_set_ext *ext, u8 id) 7073ac4c07aSPatrick McHardy { 7083ac4c07aSPatrick McHardy return !!ext->offset[id]; 7093ac4c07aSPatrick McHardy } 7103ac4c07aSPatrick McHardy 7113ac4c07aSPatrick McHardy static inline bool nft_set_ext_exists(const struct nft_set_ext *ext, u8 id) 7123ac4c07aSPatrick McHardy { 7133ac4c07aSPatrick McHardy return ext && __nft_set_ext_exists(ext, id); 7143ac4c07aSPatrick McHardy } 7153ac4c07aSPatrick McHardy 7163ac4c07aSPatrick McHardy static inline void *nft_set_ext(const struct nft_set_ext *ext, u8 id) 7173ac4c07aSPatrick McHardy { 7183ac4c07aSPatrick McHardy return (void *)ext + ext->offset[id]; 7193ac4c07aSPatrick McHardy } 7203ac4c07aSPatrick McHardy 7213ac4c07aSPatrick McHardy static inline struct nft_data *nft_set_ext_key(const struct nft_set_ext *ext) 7223ac4c07aSPatrick McHardy { 7233ac4c07aSPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_KEY); 7243ac4c07aSPatrick McHardy } 7253ac4c07aSPatrick McHardy 7267b225d0bSPablo Neira Ayuso static inline struct nft_data *nft_set_ext_key_end(const struct nft_set_ext *ext) 7277b225d0bSPablo Neira Ayuso { 7287b225d0bSPablo Neira Ayuso return nft_set_ext(ext, NFT_SET_EXT_KEY_END); 7297b225d0bSPablo Neira Ayuso } 7307b225d0bSPablo Neira Ayuso 7313ac4c07aSPatrick McHardy static inline struct nft_data *nft_set_ext_data(const struct nft_set_ext *ext) 7323ac4c07aSPatrick McHardy { 7333ac4c07aSPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_DATA); 7343ac4c07aSPatrick McHardy } 7353ac4c07aSPatrick McHardy 7363ac4c07aSPatrick McHardy static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext) 7373ac4c07aSPatrick McHardy { 7383ac4c07aSPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_FLAGS); 7393ac4c07aSPatrick McHardy } 740ef1f7df9SPatrick McHardy 741c3e1b005SPatrick McHardy static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext) 742c3e1b005SPatrick McHardy { 743c3e1b005SPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT); 744c3e1b005SPatrick McHardy } 745c3e1b005SPatrick McHardy 7468e1102d5SFlorian Westphal static inline u64 *nft_set_ext_expiration(const struct nft_set_ext *ext) 747c3e1b005SPatrick McHardy { 748c3e1b005SPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION); 749c3e1b005SPatrick McHardy } 750c3e1b005SPatrick McHardy 75168e942e8SPatrick McHardy static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext) 75268e942e8SPatrick McHardy { 75368e942e8SPatrick McHardy return nft_set_ext(ext, NFT_SET_EXT_USERDATA); 75468e942e8SPatrick McHardy } 75568e942e8SPatrick McHardy 756563125a7SPablo Neira Ayuso static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ext *ext) 757f25ad2e9SPatrick McHardy { 758563125a7SPablo Neira Ayuso return nft_set_ext(ext, NFT_SET_EXT_EXPRESSIONS); 759f25ad2e9SPatrick McHardy } 760f25ad2e9SPatrick McHardy 761c3e1b005SPatrick McHardy static inline bool nft_set_elem_expired(const struct nft_set_ext *ext) 762c3e1b005SPatrick McHardy { 763c3e1b005SPatrick McHardy return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) && 7648e1102d5SFlorian Westphal time_is_before_eq_jiffies64(*nft_set_ext_expiration(ext)); 765c3e1b005SPatrick McHardy } 766c3e1b005SPatrick McHardy 767fe2811ebSPatrick McHardy static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set, 768fe2811ebSPatrick McHardy void *elem) 769fe2811ebSPatrick McHardy { 770fe2811ebSPatrick McHardy return elem + set->ops->elemsize; 771fe2811ebSPatrick McHardy } 772fe2811ebSPatrick McHardy 7738aeff920SPablo Neira Ayuso static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext) 7748aeff920SPablo Neira Ayuso { 7758aeff920SPablo Neira Ayuso return nft_set_ext(ext, NFT_SET_EXT_OBJREF); 7768aeff920SPablo Neira Ayuso } 7778aeff920SPablo Neira Ayuso 778a7fc9368SPablo Neira Ayuso struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx, 779a7fc9368SPablo Neira Ayuso const struct nft_set *set, 780a7fc9368SPablo Neira Ayuso const struct nlattr *attr); 781a7fc9368SPablo Neira Ayuso 78222fe54d5SPatrick McHardy void *nft_set_elem_init(const struct nft_set *set, 78322fe54d5SPatrick McHardy const struct nft_set_ext_tmpl *tmpl, 7847b225d0bSPablo Neira Ayuso const u32 *key, const u32 *key_end, const u32 *data, 78579ebb5bbSLaura Garcia Liebana u64 timeout, u64 expiration, gfp_t gfp); 786fca05d4dSPablo Neira Ayuso int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, 787fca05d4dSPablo Neira Ayuso struct nft_expr *expr_array[]); 78861f9e292SLiping Zhang void nft_set_elem_destroy(const struct nft_set *set, void *elem, 78961f9e292SLiping Zhang bool destroy_expr); 79061edafbbSPatrick McHardy 79120a69341SPatrick McHardy /** 792cfed7e1bSPatrick McHardy * struct nft_set_gc_batch_head - nf_tables set garbage collection batch 793cfed7e1bSPatrick McHardy * 794cfed7e1bSPatrick McHardy * @rcu: rcu head 795cfed7e1bSPatrick McHardy * @set: set the elements belong to 796cfed7e1bSPatrick McHardy * @cnt: count of elements 797cfed7e1bSPatrick McHardy */ 798cfed7e1bSPatrick McHardy struct nft_set_gc_batch_head { 799cfed7e1bSPatrick McHardy struct rcu_head rcu; 800cfed7e1bSPatrick McHardy const struct nft_set *set; 801cfed7e1bSPatrick McHardy unsigned int cnt; 802cfed7e1bSPatrick McHardy }; 803cfed7e1bSPatrick McHardy 804cfed7e1bSPatrick McHardy #define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \ 805cfed7e1bSPatrick McHardy sizeof(struct nft_set_gc_batch_head)) / \ 806cfed7e1bSPatrick McHardy sizeof(void *)) 807cfed7e1bSPatrick McHardy 808cfed7e1bSPatrick McHardy /** 809cfed7e1bSPatrick McHardy * struct nft_set_gc_batch - nf_tables set garbage collection batch 810cfed7e1bSPatrick McHardy * 811cfed7e1bSPatrick McHardy * @head: GC batch head 812cfed7e1bSPatrick McHardy * @elems: garbage collection elements 813cfed7e1bSPatrick McHardy */ 814cfed7e1bSPatrick McHardy struct nft_set_gc_batch { 815cfed7e1bSPatrick McHardy struct nft_set_gc_batch_head head; 816cfed7e1bSPatrick McHardy void *elems[NFT_SET_GC_BATCH_SIZE]; 817cfed7e1bSPatrick McHardy }; 818cfed7e1bSPatrick McHardy 819cfed7e1bSPatrick McHardy struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set, 820cfed7e1bSPatrick McHardy gfp_t gfp); 821cfed7e1bSPatrick McHardy void nft_set_gc_batch_release(struct rcu_head *rcu); 822cfed7e1bSPatrick McHardy 823cfed7e1bSPatrick McHardy static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb) 824cfed7e1bSPatrick McHardy { 825cfed7e1bSPatrick McHardy if (gcb != NULL) 826cfed7e1bSPatrick McHardy call_rcu(&gcb->head.rcu, nft_set_gc_batch_release); 827cfed7e1bSPatrick McHardy } 828cfed7e1bSPatrick McHardy 829cfed7e1bSPatrick McHardy static inline struct nft_set_gc_batch * 830cfed7e1bSPatrick McHardy nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb, 831cfed7e1bSPatrick McHardy gfp_t gfp) 832cfed7e1bSPatrick McHardy { 833cfed7e1bSPatrick McHardy if (gcb != NULL) { 834cfed7e1bSPatrick McHardy if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems)) 835cfed7e1bSPatrick McHardy return gcb; 836cfed7e1bSPatrick McHardy nft_set_gc_batch_complete(gcb); 837cfed7e1bSPatrick McHardy } 838cfed7e1bSPatrick McHardy return nft_set_gc_batch_alloc(set, gfp); 839cfed7e1bSPatrick McHardy } 840cfed7e1bSPatrick McHardy 841cfed7e1bSPatrick McHardy static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb, 842cfed7e1bSPatrick McHardy void *elem) 843cfed7e1bSPatrick McHardy { 844cfed7e1bSPatrick McHardy gcb->elems[gcb->head.cnt++] = elem; 845cfed7e1bSPatrick McHardy } 846cfed7e1bSPatrick McHardy 847b8e20400SPablo Neira Ayuso struct nft_expr_ops; 848cfed7e1bSPatrick McHardy /** 849ef1f7df9SPatrick McHardy * struct nft_expr_type - nf_tables expression type 85096518518SPatrick McHardy * 851ef1f7df9SPatrick McHardy * @select_ops: function to select nft_expr_ops 852b8e20400SPablo Neira Ayuso * @release_ops: release nft_expr_ops 853ef1f7df9SPatrick McHardy * @ops: default ops, used when no select_ops functions is present 85496518518SPatrick McHardy * @list: used internally 85596518518SPatrick McHardy * @name: Identifier 85696518518SPatrick McHardy * @owner: module reference 85796518518SPatrick McHardy * @policy: netlink attribute policy 85896518518SPatrick McHardy * @maxattr: highest netlink attribute number 85964d46806SPatrick McHardy * @family: address family for AF-specific types 860151d799aSPatrick McHardy * @flags: expression type flags 861ef1f7df9SPatrick McHardy */ 862ef1f7df9SPatrick McHardy struct nft_expr_type { 8630ca743a5SPablo Neira Ayuso const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *, 8640ca743a5SPablo Neira Ayuso const struct nlattr * const tb[]); 865b8e20400SPablo Neira Ayuso void (*release_ops)(const struct nft_expr_ops *ops); 866ef1f7df9SPatrick McHardy const struct nft_expr_ops *ops; 867ef1f7df9SPatrick McHardy struct list_head list; 868ef1f7df9SPatrick McHardy const char *name; 869ef1f7df9SPatrick McHardy struct module *owner; 870ef1f7df9SPatrick McHardy const struct nla_policy *policy; 871ef1f7df9SPatrick McHardy unsigned int maxattr; 87264d46806SPatrick McHardy u8 family; 873151d799aSPatrick McHardy u8 flags; 874ef1f7df9SPatrick McHardy }; 875ef1f7df9SPatrick McHardy 876151d799aSPatrick McHardy #define NFT_EXPR_STATEFUL 0x1 87779b174adSPablo Neira Ayuso #define NFT_EXPR_GC 0x2 878151d799aSPatrick McHardy 879f6ac8585SPablo Neira Ayuso enum nft_trans_phase { 880f6ac8585SPablo Neira Ayuso NFT_TRANS_PREPARE, 881f6ac8585SPablo Neira Ayuso NFT_TRANS_ABORT, 882f6ac8585SPablo Neira Ayuso NFT_TRANS_COMMIT, 883f6ac8585SPablo Neira Ayuso NFT_TRANS_RELEASE 884f6ac8585SPablo Neira Ayuso }; 885f6ac8585SPablo Neira Ayuso 886c9626a2cSPablo Neira Ayuso struct nft_flow_rule; 887c9626a2cSPablo Neira Ayuso struct nft_offload_ctx; 888c9626a2cSPablo Neira Ayuso 889ef1f7df9SPatrick McHardy /** 890ef1f7df9SPatrick McHardy * struct nft_expr_ops - nf_tables expression operations 891ef1f7df9SPatrick McHardy * 892ef1f7df9SPatrick McHardy * @eval: Expression evaluation function 89396518518SPatrick McHardy * @size: full expression size, including private data size 894ef1f7df9SPatrick McHardy * @init: initialization function 895cd5125d8SFlorian Westphal * @activate: activate expression in the next generation 896cd5125d8SFlorian Westphal * @deactivate: deactivate expression in next generation 897cd5125d8SFlorian Westphal * @destroy: destruction function, called after synchronize_rcu 898ef1f7df9SPatrick McHardy * @dump: function to dump parameters 899ef1f7df9SPatrick McHardy * @type: expression type 9000ca743a5SPablo Neira Ayuso * @validate: validate expression, called during loop detection 9010ca743a5SPablo Neira Ayuso * @data: extra data to attach to this expression operation 90296518518SPatrick McHardy */ 90396518518SPatrick McHardy struct nft_expr_ops { 90496518518SPatrick McHardy void (*eval)(const struct nft_expr *expr, 905a55e22e9SPatrick McHardy struct nft_regs *regs, 90696518518SPatrick McHardy const struct nft_pktinfo *pkt); 907086f3321SPablo Neira Ayuso int (*clone)(struct nft_expr *dst, 908086f3321SPablo Neira Ayuso const struct nft_expr *src); 909ef1f7df9SPatrick McHardy unsigned int size; 910ef1f7df9SPatrick McHardy 91196518518SPatrick McHardy int (*init)(const struct nft_ctx *ctx, 91296518518SPatrick McHardy const struct nft_expr *expr, 91396518518SPatrick McHardy const struct nlattr * const tb[]); 914bb7b40aeSPablo Neira Ayuso void (*activate)(const struct nft_ctx *ctx, 915bb7b40aeSPablo Neira Ayuso const struct nft_expr *expr); 916bb7b40aeSPablo Neira Ayuso void (*deactivate)(const struct nft_ctx *ctx, 917f6ac8585SPablo Neira Ayuso const struct nft_expr *expr, 918f6ac8585SPablo Neira Ayuso enum nft_trans_phase phase); 91962472bceSPatrick McHardy void (*destroy)(const struct nft_ctx *ctx, 92062472bceSPatrick McHardy const struct nft_expr *expr); 921371ebcbbSPablo Neira Ayuso void (*destroy_clone)(const struct nft_ctx *ctx, 922371ebcbbSPablo Neira Ayuso const struct nft_expr *expr); 92396518518SPatrick McHardy int (*dump)(struct sk_buff *skb, 92496518518SPatrick McHardy const struct nft_expr *expr); 9250ca743a5SPablo Neira Ayuso int (*validate)(const struct nft_ctx *ctx, 9260ca743a5SPablo Neira Ayuso const struct nft_expr *expr, 9270ca743a5SPablo Neira Ayuso const struct nft_data **data); 92812e4ecfaSPablo Neira Ayuso bool (*reduce)(struct nft_regs_track *track, 92912e4ecfaSPablo Neira Ayuso const struct nft_expr *expr); 93079b174adSPablo Neira Ayuso bool (*gc)(struct net *net, 93179b174adSPablo Neira Ayuso const struct nft_expr *expr); 932c9626a2cSPablo Neira Ayuso int (*offload)(struct nft_offload_ctx *ctx, 933c9626a2cSPablo Neira Ayuso struct nft_flow_rule *flow, 934c9626a2cSPablo Neira Ayuso const struct nft_expr *expr); 935b1a5983fSPablo Neira Ayuso bool (*offload_action)(const struct nft_expr *expr); 936b72920f6SPablo Neira Ayuso void (*offload_stats)(struct nft_expr *expr, 937b72920f6SPablo Neira Ayuso const struct flow_stats *stats); 938ef1f7df9SPatrick McHardy const struct nft_expr_type *type; 9390ca743a5SPablo Neira Ayuso void *data; 94096518518SPatrick McHardy }; 94196518518SPatrick McHardy 94296518518SPatrick McHardy /** 94396518518SPatrick McHardy * struct nft_rule - nf_tables rule 94496518518SPatrick McHardy * 94596518518SPatrick McHardy * @list: used internally 94696518518SPatrick McHardy * @handle: rule handle 9470628b123SPablo Neira Ayuso * @genmask: generation mask 94896518518SPatrick McHardy * @dlen: length of expression data 94986f1ec32SPatrick McHardy * @udata: user data is appended to the rule 95096518518SPatrick McHardy * @data: expression data 95196518518SPatrick McHardy */ 95296518518SPatrick McHardy struct nft_rule { 95396518518SPatrick McHardy struct list_head list; 9540768b3b3SPablo Neira Ayuso u64 handle:42, 9550628b123SPablo Neira Ayuso genmask:2, 9560768b3b3SPablo Neira Ayuso dlen:12, 95786f1ec32SPatrick McHardy udata:1; 95896518518SPatrick McHardy unsigned char data[] 95996518518SPatrick McHardy __attribute__((aligned(__alignof__(struct nft_expr)))); 96096518518SPatrick McHardy }; 96196518518SPatrick McHardy 96296518518SPatrick McHardy static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule) 96396518518SPatrick McHardy { 96496518518SPatrick McHardy return (struct nft_expr *)&rule->data[0]; 96596518518SPatrick McHardy } 96696518518SPatrick McHardy 96796518518SPatrick McHardy static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr) 96896518518SPatrick McHardy { 96996518518SPatrick McHardy return ((void *)expr) + expr->ops->size; 97096518518SPatrick McHardy } 97196518518SPatrick McHardy 97296518518SPatrick McHardy static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule) 97396518518SPatrick McHardy { 97496518518SPatrick McHardy return (struct nft_expr *)&rule->data[rule->dlen]; 97596518518SPatrick McHardy } 97696518518SPatrick McHardy 97731cc578aSSaeed Mirzamohammadi static inline bool nft_expr_more(const struct nft_rule *rule, 97831cc578aSSaeed Mirzamohammadi const struct nft_expr *expr) 97931cc578aSSaeed Mirzamohammadi { 98031cc578aSSaeed Mirzamohammadi return expr != nft_expr_last(rule) && expr->ops; 98131cc578aSSaeed Mirzamohammadi } 98231cc578aSSaeed Mirzamohammadi 98386f1ec32SPatrick McHardy static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule) 9840768b3b3SPablo Neira Ayuso { 9850768b3b3SPablo Neira Ayuso return (void *)&rule->data[rule->dlen]; 9860768b3b3SPablo Neira Ayuso } 9870768b3b3SPablo Neira Ayuso 988d0e2c7deSPablo Neira Ayuso void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule); 989d0e2c7deSPablo Neira Ayuso 99076adfafeSPablo Neira Ayuso static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext, 99176adfafeSPablo Neira Ayuso struct nft_regs *regs, 99276adfafeSPablo Neira Ayuso const struct nft_pktinfo *pkt) 99376adfafeSPablo Neira Ayuso { 994563125a7SPablo Neira Ayuso struct nft_set_elem_expr *elem_expr; 99576adfafeSPablo Neira Ayuso struct nft_expr *expr; 996563125a7SPablo Neira Ayuso u32 size; 99776adfafeSPablo Neira Ayuso 998563125a7SPablo Neira Ayuso if (__nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS)) { 999563125a7SPablo Neira Ayuso elem_expr = nft_set_ext_expr(ext); 1000563125a7SPablo Neira Ayuso nft_setelem_expr_foreach(expr, elem_expr, size) { 100176adfafeSPablo Neira Ayuso expr->ops->eval(expr, regs, pkt); 1002563125a7SPablo Neira Ayuso if (regs->verdict.code == NFT_BREAK) 1003563125a7SPablo Neira Ayuso return; 1004563125a7SPablo Neira Ayuso } 100576adfafeSPablo Neira Ayuso } 100676adfafeSPablo Neira Ayuso } 100776adfafeSPablo Neira Ayuso 100896518518SPatrick McHardy /* 100996518518SPatrick McHardy * The last pointer isn't really necessary, but the compiler isn't able to 101096518518SPatrick McHardy * determine that the result of nft_expr_last() is always the same since it 101196518518SPatrick McHardy * can't assume that the dlen value wasn't changed within calls in the loop. 101296518518SPatrick McHardy */ 101396518518SPatrick McHardy #define nft_rule_for_each_expr(expr, last, rule) \ 101496518518SPatrick McHardy for ((expr) = nft_expr_first(rule), (last) = nft_expr_last(rule); \ 101596518518SPatrick McHardy (expr) != (last); \ 101696518518SPatrick McHardy (expr) = nft_expr_next(expr)) 101796518518SPatrick McHardy 1018ad652f38SPablo Neira Ayuso #define NFT_CHAIN_POLICY_UNSET U8_MAX 1019ad652f38SPablo Neira Ayuso 10202c865a8aSPablo Neira Ayuso struct nft_rule_dp { 10212c865a8aSPablo Neira Ayuso u64 is_last:1, 10222c865a8aSPablo Neira Ayuso dlen:12, 10232c865a8aSPablo Neira Ayuso handle:42; /* for tracing */ 10242c865a8aSPablo Neira Ayuso unsigned char data[] 10252c865a8aSPablo Neira Ayuso __attribute__((aligned(__alignof__(struct nft_expr)))); 10262c865a8aSPablo Neira Ayuso }; 10272c865a8aSPablo Neira Ayuso 10282c865a8aSPablo Neira Ayuso struct nft_rule_blob { 10292c865a8aSPablo Neira Ayuso unsigned long size; 10302c865a8aSPablo Neira Ayuso unsigned char data[] 10312c865a8aSPablo Neira Ayuso __attribute__((aligned(__alignof__(struct nft_rule_dp)))); 10322c865a8aSPablo Neira Ayuso }; 10332c865a8aSPablo Neira Ayuso 103496518518SPatrick McHardy /** 103596518518SPatrick McHardy * struct nft_chain - nf_tables chain 103696518518SPatrick McHardy * 103796518518SPatrick McHardy * @rules: list of rules in the chain 103896518518SPatrick McHardy * @list: used internally 10391b2470e5SFlorian Westphal * @rhlhead: used internally 1040b5bc89bfSPablo Neira Ayuso * @table: table that this chain belongs to 104196518518SPatrick McHardy * @handle: chain handle 104296518518SPatrick McHardy * @use: number of jump references to this chain 1043a0a7379eSPablo Neira Ayuso * @flags: bitmask of enum nft_chain_flags 104496518518SPatrick McHardy * @name: name of the chain 104596518518SPatrick McHardy */ 104696518518SPatrick McHardy struct nft_chain { 10472c865a8aSPablo Neira Ayuso struct nft_rule_blob __rcu *blob_gen_0; 10482c865a8aSPablo Neira Ayuso struct nft_rule_blob __rcu *blob_gen_1; 104996518518SPatrick McHardy struct list_head rules; 105096518518SPatrick McHardy struct list_head list; 10511b2470e5SFlorian Westphal struct rhlist_head rhlhead; 1052b5bc89bfSPablo Neira Ayuso struct nft_table *table; 105396518518SPatrick McHardy u64 handle; 1054a0a7379eSPablo Neira Ayuso u32 use; 1055d0e2c7deSPablo Neira Ayuso u8 flags:5, 1056d0e2c7deSPablo Neira Ayuso bound:1, 1057664b0f8cSPablo Neira Ayuso genmask:2; 1058b7263e07SPhil Sutter char *name; 1059002f2176SJose M. Guisado Gomez u16 udlen; 1060002f2176SJose M. Guisado Gomez u8 *udata; 10610cbc06b3SFlorian Westphal 10620cbc06b3SFlorian Westphal /* Only used during control plane commit phase: */ 10632c865a8aSPablo Neira Ayuso struct nft_rule_blob *blob_next; 106496518518SPatrick McHardy }; 106596518518SPatrick McHardy 1066a654de8fSPablo Neira Ayuso int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain); 1067a654de8fSPablo Neira Ayuso 106832537e91SPablo Neira Ayuso enum nft_chain_types { 10699370761cSPablo Neira Ayuso NFT_CHAIN_T_DEFAULT = 0, 10709370761cSPablo Neira Ayuso NFT_CHAIN_T_ROUTE, 10719370761cSPablo Neira Ayuso NFT_CHAIN_T_NAT, 10729370761cSPablo Neira Ayuso NFT_CHAIN_T_MAX 10739370761cSPablo Neira Ayuso }; 10749370761cSPablo Neira Ayuso 10751a1e1a12SPatrick McHardy /** 107632537e91SPablo Neira Ayuso * struct nft_chain_type - nf_tables chain type info 10771a1e1a12SPatrick McHardy * 10781a1e1a12SPatrick McHardy * @name: name of the type 10791a1e1a12SPatrick McHardy * @type: numeric identifier 10801a1e1a12SPatrick McHardy * @family: address family 10811a1e1a12SPatrick McHardy * @owner: module owner 10821a1e1a12SPatrick McHardy * @hook_mask: mask of valid hooks 1083c2f9eafeSPablo Neira Ayuso * @hooks: array of hook functions 10844e25ceb8SFlorian Westphal * @ops_register: base chain register function 10854e25ceb8SFlorian Westphal * @ops_unregister: base chain unregister function 10861a1e1a12SPatrick McHardy */ 108732537e91SPablo Neira Ayuso struct nft_chain_type { 10881a1e1a12SPatrick McHardy const char *name; 108932537e91SPablo Neira Ayuso enum nft_chain_types type; 10901a1e1a12SPatrick McHardy int family; 10911a1e1a12SPatrick McHardy struct module *owner; 10921a1e1a12SPatrick McHardy unsigned int hook_mask; 1093d25e2e93SPablo Neira Ayuso nf_hookfn *hooks[NFT_MAX_HOOKS]; 10944e25ceb8SFlorian Westphal int (*ops_register)(struct net *net, const struct nf_hook_ops *ops); 10954e25ceb8SFlorian Westphal void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops); 10961a1e1a12SPatrick McHardy }; 10971a1e1a12SPatrick McHardy 10987210e4e3SPablo Neira Ayuso int nft_chain_validate_dependency(const struct nft_chain *chain, 109932537e91SPablo Neira Ayuso enum nft_chain_types type); 110075e8d06dSPablo Neira Ayuso int nft_chain_validate_hooks(const struct nft_chain *chain, 110175e8d06dSPablo Neira Ayuso unsigned int hook_flags); 11027210e4e3SPablo Neira Ayuso 1103d0e2c7deSPablo Neira Ayuso static inline bool nft_chain_is_bound(struct nft_chain *chain) 1104d0e2c7deSPablo Neira Ayuso { 1105d0e2c7deSPablo Neira Ayuso return (chain->flags & NFT_CHAIN_BINDING) && chain->bound; 1106d0e2c7deSPablo Neira Ayuso } 1107d0e2c7deSPablo Neira Ayuso 1108d0e2c7deSPablo Neira Ayuso void nft_chain_del(struct nft_chain *chain); 1109d0e2c7deSPablo Neira Ayuso void nf_tables_chain_destroy(struct nft_ctx *ctx); 1110d0e2c7deSPablo Neira Ayuso 11110ca743a5SPablo Neira Ayuso struct nft_stats { 11120ca743a5SPablo Neira Ayuso u64 bytes; 11130ca743a5SPablo Neira Ayuso u64 pkts; 1114ce355e20SEric Dumazet struct u64_stats_sync syncp; 11150ca743a5SPablo Neira Ayuso }; 11160ca743a5SPablo Neira Ayuso 11173f0465a9SPablo Neira Ayuso struct nft_hook { 11183f0465a9SPablo Neira Ayuso struct list_head list; 11193f0465a9SPablo Neira Ayuso struct nf_hook_ops ops; 11203f0465a9SPablo Neira Ayuso struct rcu_head rcu; 11213f0465a9SPablo Neira Ayuso }; 11223f0465a9SPablo Neira Ayuso 112396518518SPatrick McHardy /** 112496518518SPatrick McHardy * struct nft_base_chain - nf_tables base chain 112596518518SPatrick McHardy * 112696518518SPatrick McHardy * @ops: netfilter hook ops 1127d54725cdSPablo Neira Ayuso * @hook_list: list of netfilter hooks (for NFPROTO_NETDEV family) 11289370761cSPablo Neira Ayuso * @type: chain type 11290ca743a5SPablo Neira Ayuso * @policy: default policy 11300ca743a5SPablo Neira Ayuso * @stats: per-cpu chain stats 113196518518SPatrick McHardy * @chain: the chain 113214bfb13fSPablo Neira Ayuso * @flow_block: flow block (for hardware offload) 113396518518SPatrick McHardy */ 113496518518SPatrick McHardy struct nft_base_chain { 1135c974a3a3SPablo Neira Ayuso struct nf_hook_ops ops; 1136d54725cdSPablo Neira Ayuso struct list_head hook_list; 113732537e91SPablo Neira Ayuso const struct nft_chain_type *type; 11380ca743a5SPablo Neira Ayuso u8 policy; 1139835b8033SPablo Neira Ayuso u8 flags; 11400ca743a5SPablo Neira Ayuso struct nft_stats __percpu *stats; 114196518518SPatrick McHardy struct nft_chain chain; 114214bfb13fSPablo Neira Ayuso struct flow_block flow_block; 114396518518SPatrick McHardy }; 114496518518SPatrick McHardy 114596518518SPatrick McHardy static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chain) 114696518518SPatrick McHardy { 114796518518SPatrick McHardy return container_of(chain, struct nft_base_chain, chain); 114896518518SPatrick McHardy } 114996518518SPatrick McHardy 1150f323d954SPablo Neira Ayuso static inline bool nft_is_base_chain(const struct nft_chain *chain) 1151f323d954SPablo Neira Ayuso { 115267c49de4SPablo Neira Ayuso return chain->flags & NFT_CHAIN_BASE; 1153f323d954SPablo Neira Ayuso } 1154f323d954SPablo Neira Ayuso 11555ebe0b0eSPablo Neira Ayuso int __nft_release_basechain(struct nft_ctx *ctx); 1156835b8033SPablo Neira Ayuso 115706198b34SEric W. Biederman unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); 115896518518SPatrick McHardy 115996518518SPatrick McHardy /** 116096518518SPatrick McHardy * struct nft_table - nf_tables table 116196518518SPatrick McHardy * 116296518518SPatrick McHardy * @list: used internally 11631b2470e5SFlorian Westphal * @chains_ht: chains in the table 11641b2470e5SFlorian Westphal * @chains: same, for stable walks 116596518518SPatrick McHardy * @sets: sets in the table 1166e5009240SPablo Neira Ayuso * @objects: stateful objects in the table 11673b49e2e9SPablo Neira Ayuso * @flowtables: flow tables in the table 116896518518SPatrick McHardy * @hgenerator: handle generator state 11693ecbfd65SHarsha Sharma * @handle: table handle 117096518518SPatrick McHardy * @use: number of chain references to this table 117196518518SPatrick McHardy * @flags: table flag (see enum nft_table_flags) 1172f2a6d766SPablo Neira Ayuso * @genmask: generation mask 117336596dadSPablo Neira Ayuso * @afinfo: address family info 117496518518SPatrick McHardy * @name: name of the table 117596518518SPatrick McHardy */ 117696518518SPatrick McHardy struct nft_table { 117796518518SPatrick McHardy struct list_head list; 11781b2470e5SFlorian Westphal struct rhltable chains_ht; 117996518518SPatrick McHardy struct list_head chains; 118096518518SPatrick McHardy struct list_head sets; 1181e5009240SPablo Neira Ayuso struct list_head objects; 11823b49e2e9SPablo Neira Ayuso struct list_head flowtables; 118396518518SPatrick McHardy u64 hgenerator; 11843ecbfd65SHarsha Sharma u64 handle; 118596518518SPatrick McHardy u32 use; 118698319cb9SPablo Neira Ayuso u16 family:6, 118798319cb9SPablo Neira Ayuso flags:8, 1188f2a6d766SPablo Neira Ayuso genmask:2; 11896001a930SPablo Neira Ayuso u32 nlpid; 1190e46abbccSPhil Sutter char *name; 11917a81575bSJose M. Guisado Gomez u16 udlen; 11927a81575bSJose M. Guisado Gomez u8 *udata; 1193ebddf1a8SPablo Neira Ayuso }; 1194ebddf1a8SPablo Neira Ayuso 11956001a930SPablo Neira Ayuso static inline bool nft_table_has_owner(const struct nft_table *table) 11966001a930SPablo Neira Ayuso { 11976001a930SPablo Neira Ayuso return table->flags & NFT_TABLE_F_OWNER; 11986001a930SPablo Neira Ayuso } 11996001a930SPablo Neira Ayuso 1200d3519cb8SPablo Neira Ayuso static inline bool nft_base_chain_netdev(int family, u32 hooknum) 1201d3519cb8SPablo Neira Ayuso { 1202d3519cb8SPablo Neira Ayuso return family == NFPROTO_NETDEV || 1203d3519cb8SPablo Neira Ayuso (family == NFPROTO_INET && hooknum == NF_INET_INGRESS); 1204d3519cb8SPablo Neira Ayuso } 1205d3519cb8SPablo Neira Ayuso 1206cc07eeb0SPablo Neira Ayuso void nft_register_chain_type(const struct nft_chain_type *); 120732537e91SPablo Neira Ayuso void nft_unregister_chain_type(const struct nft_chain_type *); 120896518518SPatrick McHardy 12095eccdfaaSJoe Perches int nft_register_expr(struct nft_expr_type *); 12105eccdfaaSJoe Perches void nft_unregister_expr(struct nft_expr_type *); 121196518518SPatrick McHardy 121233d5a7b1SFlorian Westphal int nft_verdict_dump(struct sk_buff *skb, int type, 121333d5a7b1SFlorian Westphal const struct nft_verdict *v); 121433d5a7b1SFlorian Westphal 121533d5a7b1SFlorian Westphal /** 1216d152159bSFlorian Westphal * struct nft_object_hash_key - key to lookup nft_object 1217d152159bSFlorian Westphal * 1218d152159bSFlorian Westphal * @name: name of the stateful object to look up 1219d152159bSFlorian Westphal * @table: table the object belongs to 1220d152159bSFlorian Westphal */ 1221d152159bSFlorian Westphal struct nft_object_hash_key { 1222d152159bSFlorian Westphal const char *name; 1223d152159bSFlorian Westphal const struct nft_table *table; 1224d152159bSFlorian Westphal }; 1225d152159bSFlorian Westphal 1226d152159bSFlorian Westphal /** 1227e5009240SPablo Neira Ayuso * struct nft_object - nf_tables stateful object 1228e5009240SPablo Neira Ayuso * 1229e5009240SPablo Neira Ayuso * @list: table stateful object list node 1230d152159bSFlorian Westphal * @key: keys that identify this object 12314d44175aSFlorian Westphal * @rhlhead: nft_objname_ht node 1232e5009240SPablo Neira Ayuso * @genmask: generation mask 1233e5009240SPablo Neira Ayuso * @use: number of references to this stateful object 12343ecbfd65SHarsha Sharma * @handle: unique object handle 1235dfc46034SPablo M. Bermudo Garay * @ops: object operations 12363ecbfd65SHarsha Sharma * @data: object data, layout depends on type 1237e5009240SPablo Neira Ayuso */ 1238e5009240SPablo Neira Ayuso struct nft_object { 1239e5009240SPablo Neira Ayuso struct list_head list; 12404d44175aSFlorian Westphal struct rhlist_head rhlhead; 1241d152159bSFlorian Westphal struct nft_object_hash_key key; 1242e5009240SPablo Neira Ayuso u32 genmask:2, 1243e5009240SPablo Neira Ayuso use:30; 12443ecbfd65SHarsha Sharma u64 handle; 1245b131c964SJose M. Guisado Gomez u16 udlen; 1246b131c964SJose M. Guisado Gomez u8 *udata; 1247e5009240SPablo Neira Ayuso /* runtime data below here */ 1248dfc46034SPablo M. Bermudo Garay const struct nft_object_ops *ops ____cacheline_aligned; 1249e5009240SPablo Neira Ayuso unsigned char data[] 1250e5009240SPablo Neira Ayuso __attribute__((aligned(__alignof__(u64)))); 1251e5009240SPablo Neira Ayuso }; 1252e5009240SPablo Neira Ayuso 1253e5009240SPablo Neira Ayuso static inline void *nft_obj_data(const struct nft_object *obj) 1254e5009240SPablo Neira Ayuso { 1255e5009240SPablo Neira Ayuso return (void *)obj->data; 1256e5009240SPablo Neira Ayuso } 1257e5009240SPablo Neira Ayuso 1258e5009240SPablo Neira Ayuso #define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr)) 1259e5009240SPablo Neira Ayuso 12604d44175aSFlorian Westphal struct nft_object *nft_obj_lookup(const struct net *net, 12614d44175aSFlorian Westphal const struct nft_table *table, 1262e5009240SPablo Neira Ayuso const struct nlattr *nla, u32 objtype, 1263e5009240SPablo Neira Ayuso u8 genmask); 1264e5009240SPablo Neira Ayuso 1265d152159bSFlorian Westphal void nft_obj_notify(struct net *net, const struct nft_table *table, 12662599e989SPablo Neira Ayuso struct nft_object *obj, u32 portid, u32 seq, 12676fb721cfSPablo Neira Ayuso int event, u16 flags, int family, int report, gfp_t gfp); 12682599e989SPablo Neira Ayuso 1269e5009240SPablo Neira Ayuso /** 1270e5009240SPablo Neira Ayuso * struct nft_object_type - stateful object type 1271e5009240SPablo Neira Ayuso * 1272dfc46034SPablo M. Bermudo Garay * @select_ops: function to select nft_object_ops 1273dfc46034SPablo M. Bermudo Garay * @ops: default ops, used when no select_ops functions is present 1274e5009240SPablo Neira Ayuso * @list: list node in list of object types 1275e5009240SPablo Neira Ayuso * @type: stateful object numeric type 1276e5009240SPablo Neira Ayuso * @owner: module owner 1277e5009240SPablo Neira Ayuso * @maxattr: maximum netlink attribute 1278e5009240SPablo Neira Ayuso * @policy: netlink attribute policy 1279dfc46034SPablo M. Bermudo Garay */ 1280dfc46034SPablo M. Bermudo Garay struct nft_object_type { 1281dfc46034SPablo M. Bermudo Garay const struct nft_object_ops *(*select_ops)(const struct nft_ctx *, 1282dfc46034SPablo M. Bermudo Garay const struct nlattr * const tb[]); 1283dfc46034SPablo M. Bermudo Garay const struct nft_object_ops *ops; 1284dfc46034SPablo M. Bermudo Garay struct list_head list; 1285dfc46034SPablo M. Bermudo Garay u32 type; 1286dfc46034SPablo M. Bermudo Garay unsigned int maxattr; 1287dfc46034SPablo M. Bermudo Garay struct module *owner; 1288dfc46034SPablo M. Bermudo Garay const struct nla_policy *policy; 1289dfc46034SPablo M. Bermudo Garay }; 1290dfc46034SPablo M. Bermudo Garay 1291dfc46034SPablo M. Bermudo Garay /** 1292dfc46034SPablo M. Bermudo Garay * struct nft_object_ops - stateful object operations 1293dfc46034SPablo M. Bermudo Garay * 1294dfc46034SPablo M. Bermudo Garay * @eval: stateful object evaluation function 1295dfc46034SPablo M. Bermudo Garay * @size: stateful object size 1296e5009240SPablo Neira Ayuso * @init: initialize object from netlink attributes 1297e5009240SPablo Neira Ayuso * @destroy: release existing stateful object 1298e5009240SPablo Neira Ayuso * @dump: netlink dump stateful object 1299d62d0ba9SFernando Fernandez Mancera * @update: update stateful object 1300e5009240SPablo Neira Ayuso */ 1301dfc46034SPablo M. Bermudo Garay struct nft_object_ops { 1302e5009240SPablo Neira Ayuso void (*eval)(struct nft_object *obj, 1303e5009240SPablo Neira Ayuso struct nft_regs *regs, 1304e5009240SPablo Neira Ayuso const struct nft_pktinfo *pkt); 1305e5009240SPablo Neira Ayuso unsigned int size; 130684fba055SFlorian Westphal int (*init)(const struct nft_ctx *ctx, 130784fba055SFlorian Westphal const struct nlattr *const tb[], 1308e5009240SPablo Neira Ayuso struct nft_object *obj); 130900bfb320SPablo Neira Ayuso void (*destroy)(const struct nft_ctx *ctx, 131000bfb320SPablo Neira Ayuso struct nft_object *obj); 1311e5009240SPablo Neira Ayuso int (*dump)(struct sk_buff *skb, 131243da04a5SPablo Neira Ayuso struct nft_object *obj, 131343da04a5SPablo Neira Ayuso bool reset); 1314d62d0ba9SFernando Fernandez Mancera void (*update)(struct nft_object *obj, 1315d62d0ba9SFernando Fernandez Mancera struct nft_object *newobj); 1316dfc46034SPablo M. Bermudo Garay const struct nft_object_type *type; 1317e5009240SPablo Neira Ayuso }; 1318e5009240SPablo Neira Ayuso 1319e5009240SPablo Neira Ayuso int nft_register_obj(struct nft_object_type *obj_type); 1320e5009240SPablo Neira Ayuso void nft_unregister_obj(struct nft_object_type *obj_type); 1321e5009240SPablo Neira Ayuso 1322cb662ac6SPablo Neira Ayuso #define NFT_NETDEVICE_MAX 256 1323d92191aaSPablo Neira Ayuso 1324e5009240SPablo Neira Ayuso /** 13253b49e2e9SPablo Neira Ayuso * struct nft_flowtable - nf_tables flow table 13263b49e2e9SPablo Neira Ayuso * 13273b49e2e9SPablo Neira Ayuso * @list: flow table list node in table list 13283b49e2e9SPablo Neira Ayuso * @table: the table the flow table is contained in 13293b49e2e9SPablo Neira Ayuso * @name: name of this flow table 13303b49e2e9SPablo Neira Ayuso * @hooknum: hook number 13313b49e2e9SPablo Neira Ayuso * @ops_len: number of hooks in array 13323b49e2e9SPablo Neira Ayuso * @genmask: generation mask 13333b49e2e9SPablo Neira Ayuso * @use: number of references to this flow table 13343ecbfd65SHarsha Sharma * @handle: unique object handle 1335d92191aaSPablo Neira Ayuso * @dev_name: array of device names 13363b49e2e9SPablo Neira Ayuso * @data: rhashtable and garbage collector 13373b49e2e9SPablo Neira Ayuso * @ops: array of hooks 13383b49e2e9SPablo Neira Ayuso */ 13393b49e2e9SPablo Neira Ayuso struct nft_flowtable { 13403b49e2e9SPablo Neira Ayuso struct list_head list; 13413b49e2e9SPablo Neira Ayuso struct nft_table *table; 13423b49e2e9SPablo Neira Ayuso char *name; 13433b49e2e9SPablo Neira Ayuso int hooknum; 13443b49e2e9SPablo Neira Ayuso int ops_len; 13453b49e2e9SPablo Neira Ayuso u32 genmask:2, 13463b49e2e9SPablo Neira Ayuso use:30; 13473ecbfd65SHarsha Sharma u64 handle; 13483b49e2e9SPablo Neira Ayuso /* runtime data below here */ 13493f0465a9SPablo Neira Ayuso struct list_head hook_list ____cacheline_aligned; 13503b49e2e9SPablo Neira Ayuso struct nf_flowtable data; 13513b49e2e9SPablo Neira Ayuso }; 13523b49e2e9SPablo Neira Ayuso 1353cac20fcdSPablo Neira Ayuso struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table, 13543b49e2e9SPablo Neira Ayuso const struct nlattr *nla, 13553b49e2e9SPablo Neira Ayuso u8 genmask); 13563b49e2e9SPablo Neira Ayuso 13579b05b6e1SLaura Garcia Liebana void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx, 13589b05b6e1SLaura Garcia Liebana struct nft_flowtable *flowtable, 13599b05b6e1SLaura Garcia Liebana enum nft_trans_phase phase); 13609b05b6e1SLaura Garcia Liebana 13613b49e2e9SPablo Neira Ayuso void nft_register_flowtable_type(struct nf_flowtable_type *type); 13623b49e2e9SPablo Neira Ayuso void nft_unregister_flowtable_type(struct nf_flowtable_type *type); 13633b49e2e9SPablo Neira Ayuso 13643b49e2e9SPablo Neira Ayuso /** 136533d5a7b1SFlorian Westphal * struct nft_traceinfo - nft tracing information and state 136633d5a7b1SFlorian Westphal * 1367e34b9ed9SFlorian Westphal * @trace: other struct members are initialised 1368e34b9ed9SFlorian Westphal * @nf_trace: copy of skb->nf_trace before rule evaluation 1369e34b9ed9SFlorian Westphal * @type: event type (enum nft_trace_types) 1370e34b9ed9SFlorian Westphal * @skbid: hash of skb to be used as trace id 1371e34b9ed9SFlorian Westphal * @packet_dumped: packet headers sent in a previous traceinfo message 137233d5a7b1SFlorian Westphal * @pkt: pktinfo currently processed 137333d5a7b1SFlorian Westphal * @basechain: base chain currently processed 137433d5a7b1SFlorian Westphal * @chain: chain currently processed 137533d5a7b1SFlorian Westphal * @rule: rule that was evaluated 137633d5a7b1SFlorian Westphal * @verdict: verdict given by rule 137733d5a7b1SFlorian Westphal */ 137833d5a7b1SFlorian Westphal struct nft_traceinfo { 1379e34b9ed9SFlorian Westphal bool trace; 1380e34b9ed9SFlorian Westphal bool nf_trace; 1381e34b9ed9SFlorian Westphal bool packet_dumped; 1382e34b9ed9SFlorian Westphal enum nft_trace_types type:8; 1383e34b9ed9SFlorian Westphal u32 skbid; 138433d5a7b1SFlorian Westphal const struct nft_pktinfo *pkt; 138533d5a7b1SFlorian Westphal const struct nft_base_chain *basechain; 138633d5a7b1SFlorian Westphal const struct nft_chain *chain; 13872c865a8aSPablo Neira Ayuso const struct nft_rule_dp *rule; 138833d5a7b1SFlorian Westphal const struct nft_verdict *verdict; 138933d5a7b1SFlorian Westphal }; 139033d5a7b1SFlorian Westphal 139133d5a7b1SFlorian Westphal void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt, 139233d5a7b1SFlorian Westphal const struct nft_verdict *verdict, 139333d5a7b1SFlorian Westphal const struct nft_chain *basechain); 139433d5a7b1SFlorian Westphal 139533d5a7b1SFlorian Westphal void nft_trace_notify(struct nft_traceinfo *info); 139633d5a7b1SFlorian Westphal 13979370761cSPablo Neira Ayuso #define MODULE_ALIAS_NFT_CHAIN(family, name) \ 13989370761cSPablo Neira Ayuso MODULE_ALIAS("nft-chain-" __stringify(family) "-" name) 139996518518SPatrick McHardy 140064d46806SPatrick McHardy #define MODULE_ALIAS_NFT_AF_EXPR(family, name) \ 140164d46806SPatrick McHardy MODULE_ALIAS("nft-expr-" __stringify(family) "-" name) 140264d46806SPatrick McHardy 140396518518SPatrick McHardy #define MODULE_ALIAS_NFT_EXPR(name) \ 140496518518SPatrick McHardy MODULE_ALIAS("nft-expr-" name) 140596518518SPatrick McHardy 1406e5009240SPablo Neira Ayuso #define MODULE_ALIAS_NFT_OBJ(type) \ 1407e5009240SPablo Neira Ayuso MODULE_ALIAS("nft-obj-" __stringify(type)) 1408e5009240SPablo Neira Ayuso 140947e640afSJeremy Sowden #if IS_ENABLED(CONFIG_NF_TABLES) 141047e640afSJeremy Sowden 1411ea4bd995SPatrick McHardy /* 1412ea4bd995SPatrick McHardy * The gencursor defines two generations, the currently active and the 1413ea4bd995SPatrick McHardy * next one. Objects contain a bitmask of 2 bits specifying the generations 1414ea4bd995SPatrick McHardy * they're active in. A set bit means they're inactive in the generation 1415ea4bd995SPatrick McHardy * represented by that bit. 1416ea4bd995SPatrick McHardy * 1417ea4bd995SPatrick McHardy * New objects start out as inactive in the current and active in the 1418ea4bd995SPatrick McHardy * next generation. When committing the ruleset the bitmask is cleared, 1419ea4bd995SPatrick McHardy * meaning they're active in all generations. When removing an object, 1420ea4bd995SPatrick McHardy * it is set inactive in the next generation. After committing the ruleset, 1421ea4bd995SPatrick McHardy * the objects are removed. 1422ea4bd995SPatrick McHardy */ 1423ea4bd995SPatrick McHardy static inline unsigned int nft_gencursor_next(const struct net *net) 1424ea4bd995SPatrick McHardy { 1425ea4bd995SPatrick McHardy return net->nft.gencursor + 1 == 1 ? 1 : 0; 1426ea4bd995SPatrick McHardy } 1427ea4bd995SPatrick McHardy 1428ea4bd995SPatrick McHardy static inline u8 nft_genmask_next(const struct net *net) 1429ea4bd995SPatrick McHardy { 1430ea4bd995SPatrick McHardy return 1 << nft_gencursor_next(net); 1431ea4bd995SPatrick McHardy } 1432ea4bd995SPatrick McHardy 1433ea4bd995SPatrick McHardy static inline u8 nft_genmask_cur(const struct net *net) 1434ea4bd995SPatrick McHardy { 143514cd5d4aSMark Rutland /* Use READ_ONCE() to prevent refetching the value for atomicity */ 143614cd5d4aSMark Rutland return 1 << READ_ONCE(net->nft.gencursor); 1437ea4bd995SPatrick McHardy } 1438ea4bd995SPatrick McHardy 143922fe54d5SPatrick McHardy #define NFT_GENMASK_ANY ((1 << 0) | (1 << 1)) 144022fe54d5SPatrick McHardy 1441cc02e457SPatrick McHardy /* 1442889f7ee7SPablo Neira Ayuso * Generic transaction helpers 1443889f7ee7SPablo Neira Ayuso */ 1444889f7ee7SPablo Neira Ayuso 1445889f7ee7SPablo Neira Ayuso /* Check if this object is currently active. */ 1446889f7ee7SPablo Neira Ayuso #define nft_is_active(__net, __obj) \ 1447889f7ee7SPablo Neira Ayuso (((__obj)->genmask & nft_genmask_cur(__net)) == 0) 1448889f7ee7SPablo Neira Ayuso 1449889f7ee7SPablo Neira Ayuso /* Check if this object is active in the next generation. */ 1450889f7ee7SPablo Neira Ayuso #define nft_is_active_next(__net, __obj) \ 1451889f7ee7SPablo Neira Ayuso (((__obj)->genmask & nft_genmask_next(__net)) == 0) 1452889f7ee7SPablo Neira Ayuso 1453889f7ee7SPablo Neira Ayuso /* This object becomes active in the next generation. */ 1454889f7ee7SPablo Neira Ayuso #define nft_activate_next(__net, __obj) \ 1455889f7ee7SPablo Neira Ayuso (__obj)->genmask = nft_genmask_cur(__net) 1456889f7ee7SPablo Neira Ayuso 1457889f7ee7SPablo Neira Ayuso /* This object becomes inactive in the next generation. */ 1458889f7ee7SPablo Neira Ayuso #define nft_deactivate_next(__net, __obj) \ 1459889f7ee7SPablo Neira Ayuso (__obj)->genmask = nft_genmask_next(__net) 1460889f7ee7SPablo Neira Ayuso 1461889f7ee7SPablo Neira Ayuso /* After committing the ruleset, clear the stale generation bit. */ 1462889f7ee7SPablo Neira Ayuso #define nft_clear(__net, __obj) \ 1463889f7ee7SPablo Neira Ayuso (__obj)->genmask &= ~nft_genmask_next(__net) 1464f2a6d766SPablo Neira Ayuso #define nft_active_genmask(__obj, __genmask) \ 1465f2a6d766SPablo Neira Ayuso !((__obj)->genmask & __genmask) 1466889f7ee7SPablo Neira Ayuso 1467889f7ee7SPablo Neira Ayuso /* 1468cc02e457SPatrick McHardy * Set element transaction helpers 1469cc02e457SPatrick McHardy */ 1470cc02e457SPatrick McHardy 1471cc02e457SPatrick McHardy static inline bool nft_set_elem_active(const struct nft_set_ext *ext, 1472cc02e457SPatrick McHardy u8 genmask) 1473cc02e457SPatrick McHardy { 1474cc02e457SPatrick McHardy return !(ext->genmask & genmask); 1475cc02e457SPatrick McHardy } 1476cc02e457SPatrick McHardy 147742a55769SPablo Neira Ayuso static inline void nft_set_elem_change_active(const struct net *net, 147842a55769SPablo Neira Ayuso const struct nft_set *set, 1479cc02e457SPatrick McHardy struct nft_set_ext *ext) 1480cc02e457SPatrick McHardy { 148142a55769SPablo Neira Ayuso ext->genmask ^= nft_genmask_next(net); 1482cc02e457SPatrick McHardy } 1483cc02e457SPatrick McHardy 148447e640afSJeremy Sowden #endif /* IS_ENABLED(CONFIG_NF_TABLES) */ 148547e640afSJeremy Sowden 148669086658SPatrick McHardy /* 148769086658SPatrick McHardy * We use a free bit in the genmask field to indicate the element 148869086658SPatrick McHardy * is busy, meaning it is currently being processed either by 148969086658SPatrick McHardy * the netlink API or GC. 149069086658SPatrick McHardy * 149169086658SPatrick McHardy * Even though the genmask is only a single byte wide, this works 149269086658SPatrick McHardy * because the extension structure if fully constant once initialized, 149369086658SPatrick McHardy * so there are no non-atomic write accesses unless it is already 149469086658SPatrick McHardy * marked busy. 149569086658SPatrick McHardy */ 149669086658SPatrick McHardy #define NFT_SET_ELEM_BUSY_MASK (1 << 2) 149769086658SPatrick McHardy 149869086658SPatrick McHardy #if defined(__LITTLE_ENDIAN_BITFIELD) 149969086658SPatrick McHardy #define NFT_SET_ELEM_BUSY_BIT 2 150069086658SPatrick McHardy #elif defined(__BIG_ENDIAN_BITFIELD) 150169086658SPatrick McHardy #define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2) 150269086658SPatrick McHardy #else 150369086658SPatrick McHardy #error 150469086658SPatrick McHardy #endif 150569086658SPatrick McHardy 150669086658SPatrick McHardy static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext) 150769086658SPatrick McHardy { 150869086658SPatrick McHardy unsigned long *word = (unsigned long *)ext; 150969086658SPatrick McHardy 151069086658SPatrick McHardy BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0); 151169086658SPatrick McHardy return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word); 151269086658SPatrick McHardy } 151369086658SPatrick McHardy 151469086658SPatrick McHardy static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext) 151569086658SPatrick McHardy { 151669086658SPatrick McHardy unsigned long *word = (unsigned long *)ext; 151769086658SPatrick McHardy 151869086658SPatrick McHardy clear_bit(NFT_SET_ELEM_BUSY_BIT, word); 151969086658SPatrick McHardy } 152069086658SPatrick McHardy 15211a1e1a12SPatrick McHardy /** 15221a1e1a12SPatrick McHardy * struct nft_trans - nf_tables object update in transaction 15231a1e1a12SPatrick McHardy * 15241a1e1a12SPatrick McHardy * @list: used internally 15251a1e1a12SPatrick McHardy * @msg_type: message type 15260935d558SFlorian Westphal * @put_net: ctx->net needs to be put 15271a1e1a12SPatrick McHardy * @ctx: transaction context 15281a1e1a12SPatrick McHardy * @data: internal information related to the transaction 15291a1e1a12SPatrick McHardy */ 15301a1e1a12SPatrick McHardy struct nft_trans { 15311a1e1a12SPatrick McHardy struct list_head list; 15321a1e1a12SPatrick McHardy int msg_type; 15330935d558SFlorian Westphal bool put_net; 15341a1e1a12SPatrick McHardy struct nft_ctx ctx; 15356daf1414SGustavo A. R. Silva char data[]; 15361a1e1a12SPatrick McHardy }; 15371a1e1a12SPatrick McHardy 15381a1e1a12SPatrick McHardy struct nft_trans_rule { 15391a1e1a12SPatrick McHardy struct nft_rule *rule; 1540c9626a2cSPablo Neira Ayuso struct nft_flow_rule *flow; 15411a94e38dSPablo Neira Ayuso u32 rule_id; 15421a1e1a12SPatrick McHardy }; 15431a1e1a12SPatrick McHardy 15441a1e1a12SPatrick McHardy #define nft_trans_rule(trans) \ 15451a1e1a12SPatrick McHardy (((struct nft_trans_rule *)trans->data)->rule) 1546c9626a2cSPablo Neira Ayuso #define nft_trans_flow_rule(trans) \ 1547c9626a2cSPablo Neira Ayuso (((struct nft_trans_rule *)trans->data)->flow) 15481a94e38dSPablo Neira Ayuso #define nft_trans_rule_id(trans) \ 15491a94e38dSPablo Neira Ayuso (((struct nft_trans_rule *)trans->data)->rule_id) 15501a1e1a12SPatrick McHardy 15511a1e1a12SPatrick McHardy struct nft_trans_set { 15521a1e1a12SPatrick McHardy struct nft_set *set; 15531a1e1a12SPatrick McHardy u32 set_id; 15546a0a8d10SPablo Neira Ayuso bool bound; 15551a1e1a12SPatrick McHardy }; 15561a1e1a12SPatrick McHardy 15571a1e1a12SPatrick McHardy #define nft_trans_set(trans) \ 15581a1e1a12SPatrick McHardy (((struct nft_trans_set *)trans->data)->set) 15591a1e1a12SPatrick McHardy #define nft_trans_set_id(trans) \ 15601a1e1a12SPatrick McHardy (((struct nft_trans_set *)trans->data)->set_id) 15616a0a8d10SPablo Neira Ayuso #define nft_trans_set_bound(trans) \ 15626a0a8d10SPablo Neira Ayuso (((struct nft_trans_set *)trans->data)->bound) 15631a1e1a12SPatrick McHardy 15641a1e1a12SPatrick McHardy struct nft_trans_chain { 15651a1e1a12SPatrick McHardy bool update; 1566b7263e07SPhil Sutter char *name; 15671a1e1a12SPatrick McHardy struct nft_stats __percpu *stats; 15681a1e1a12SPatrick McHardy u8 policy; 156974cccc3dSPablo Neira Ayuso u32 chain_id; 15701a1e1a12SPatrick McHardy }; 15711a1e1a12SPatrick McHardy 15721a1e1a12SPatrick McHardy #define nft_trans_chain_update(trans) \ 15731a1e1a12SPatrick McHardy (((struct nft_trans_chain *)trans->data)->update) 15741a1e1a12SPatrick McHardy #define nft_trans_chain_name(trans) \ 15751a1e1a12SPatrick McHardy (((struct nft_trans_chain *)trans->data)->name) 15761a1e1a12SPatrick McHardy #define nft_trans_chain_stats(trans) \ 15771a1e1a12SPatrick McHardy (((struct nft_trans_chain *)trans->data)->stats) 15781a1e1a12SPatrick McHardy #define nft_trans_chain_policy(trans) \ 15791a1e1a12SPatrick McHardy (((struct nft_trans_chain *)trans->data)->policy) 158074cccc3dSPablo Neira Ayuso #define nft_trans_chain_id(trans) \ 158174cccc3dSPablo Neira Ayuso (((struct nft_trans_chain *)trans->data)->chain_id) 15821a1e1a12SPatrick McHardy 15831a1e1a12SPatrick McHardy struct nft_trans_table { 15841a1e1a12SPatrick McHardy bool update; 15851a1e1a12SPatrick McHardy }; 15861a1e1a12SPatrick McHardy 15871a1e1a12SPatrick McHardy #define nft_trans_table_update(trans) \ 15881a1e1a12SPatrick McHardy (((struct nft_trans_table *)trans->data)->update) 15891a1e1a12SPatrick McHardy 15901a1e1a12SPatrick McHardy struct nft_trans_elem { 15911a1e1a12SPatrick McHardy struct nft_set *set; 15921a1e1a12SPatrick McHardy struct nft_set_elem elem; 15936a0a8d10SPablo Neira Ayuso bool bound; 15941a1e1a12SPatrick McHardy }; 15951a1e1a12SPatrick McHardy 15961a1e1a12SPatrick McHardy #define nft_trans_elem_set(trans) \ 15971a1e1a12SPatrick McHardy (((struct nft_trans_elem *)trans->data)->set) 15981a1e1a12SPatrick McHardy #define nft_trans_elem(trans) \ 15991a1e1a12SPatrick McHardy (((struct nft_trans_elem *)trans->data)->elem) 16006a0a8d10SPablo Neira Ayuso #define nft_trans_elem_set_bound(trans) \ 16016a0a8d10SPablo Neira Ayuso (((struct nft_trans_elem *)trans->data)->bound) 16021a1e1a12SPatrick McHardy 1603e5009240SPablo Neira Ayuso struct nft_trans_obj { 1604e5009240SPablo Neira Ayuso struct nft_object *obj; 1605d62d0ba9SFernando Fernandez Mancera struct nft_object *newobj; 1606d62d0ba9SFernando Fernandez Mancera bool update; 1607e5009240SPablo Neira Ayuso }; 1608e5009240SPablo Neira Ayuso 1609e5009240SPablo Neira Ayuso #define nft_trans_obj(trans) \ 1610e5009240SPablo Neira Ayuso (((struct nft_trans_obj *)trans->data)->obj) 1611d62d0ba9SFernando Fernandez Mancera #define nft_trans_obj_newobj(trans) \ 1612d62d0ba9SFernando Fernandez Mancera (((struct nft_trans_obj *)trans->data)->newobj) 1613d62d0ba9SFernando Fernandez Mancera #define nft_trans_obj_update(trans) \ 1614d62d0ba9SFernando Fernandez Mancera (((struct nft_trans_obj *)trans->data)->update) 1615e5009240SPablo Neira Ayuso 16163b49e2e9SPablo Neira Ayuso struct nft_trans_flowtable { 16173b49e2e9SPablo Neira Ayuso struct nft_flowtable *flowtable; 161878d9f48fSPablo Neira Ayuso bool update; 161978d9f48fSPablo Neira Ayuso struct list_head hook_list; 16207b35582cSPablo Neira Ayuso u32 flags; 16213b49e2e9SPablo Neira Ayuso }; 16223b49e2e9SPablo Neira Ayuso 16233b49e2e9SPablo Neira Ayuso #define nft_trans_flowtable(trans) \ 16243b49e2e9SPablo Neira Ayuso (((struct nft_trans_flowtable *)trans->data)->flowtable) 162578d9f48fSPablo Neira Ayuso #define nft_trans_flowtable_update(trans) \ 162678d9f48fSPablo Neira Ayuso (((struct nft_trans_flowtable *)trans->data)->update) 162778d9f48fSPablo Neira Ayuso #define nft_trans_flowtable_hooks(trans) \ 162878d9f48fSPablo Neira Ayuso (((struct nft_trans_flowtable *)trans->data)->hook_list) 16297b35582cSPablo Neira Ayuso #define nft_trans_flowtable_flags(trans) \ 16307b35582cSPablo Neira Ayuso (((struct nft_trans_flowtable *)trans->data)->flags) 16313b49e2e9SPablo Neira Ayuso 163202c7b25eSPablo Neira Ayuso int __init nft_chain_filter_init(void); 1633d209df3eSFlorian Westphal void nft_chain_filter_fini(void); 163402c7b25eSPablo Neira Ayuso 1635c1deb065SFlorian Westphal void __init nft_chain_route_init(void); 1636c1deb065SFlorian Westphal void nft_chain_route_fini(void); 1637ffe8923fSFlorian Westphal 1638ffe8923fSFlorian Westphal void nf_tables_trans_destroy_flush_work(void); 1639917d80d3SPablo Neira Ayuso 1640917d80d3SPablo Neira Ayuso int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result); 1641917d80d3SPablo Neira Ayuso __be64 nf_jiffies64_to_msecs(u64 input); 1642917d80d3SPablo Neira Ayuso 1643cefa31a9SFlorian Westphal #ifdef CONFIG_MODULES 1644cefa31a9SFlorian Westphal __printf(2, 3) int nft_request_module(struct net *net, const char *fmt, ...); 1645cefa31a9SFlorian Westphal #else 1646cefa31a9SFlorian Westphal static inline int nft_request_module(struct net *net, const char *fmt, ...) { return -ENOENT; } 1647cefa31a9SFlorian Westphal #endif 16480854db2aSFlorian Westphal 16490854db2aSFlorian Westphal struct nftables_pernet { 16500854db2aSFlorian Westphal struct list_head tables; 16510854db2aSFlorian Westphal struct list_head commit_list; 16520854db2aSFlorian Westphal struct list_head module_list; 16530854db2aSFlorian Westphal struct list_head notify_list; 16540854db2aSFlorian Westphal struct mutex commit_mutex; 1655*ab482c6bSPablo Neira Ayuso u64 table_handle; 16560854db2aSFlorian Westphal unsigned int base_seq; 16570854db2aSFlorian Westphal u8 validate_state; 16580854db2aSFlorian Westphal }; 16590854db2aSFlorian Westphal 1660d59d2f82SPablo Neira Ayuso extern unsigned int nf_tables_net_id; 1661d59d2f82SPablo Neira Ayuso 1662d59d2f82SPablo Neira Ayuso static inline struct nftables_pernet *nft_pernet(const struct net *net) 1663d59d2f82SPablo Neira Ayuso { 1664d59d2f82SPablo Neira Ayuso return net_generic(net, nf_tables_net_id); 1665d59d2f82SPablo Neira Ayuso } 1666d59d2f82SPablo Neira Ayuso 1667b2d30654SPablo Neira Ayuso #define __NFT_REDUCE_READONLY 1UL 1668b2d30654SPablo Neira Ayuso #define NFT_REDUCE_READONLY (void *)__NFT_REDUCE_READONLY 1669b2d30654SPablo Neira Ayuso 1670b2d30654SPablo Neira Ayuso static inline bool nft_reduce_is_readonly(const struct nft_expr *expr) 1671b2d30654SPablo Neira Ayuso { 1672b2d30654SPablo Neira Ayuso return expr->ops->reduce == NFT_REDUCE_READONLY; 1673b2d30654SPablo Neira Ayuso } 1674b2d30654SPablo Neira Ayuso 167534cc9e52SPablo Neira Ayuso void nft_reg_track_update(struct nft_regs_track *track, 167634cc9e52SPablo Neira Ayuso const struct nft_expr *expr, u8 dreg, u8 len); 167734cc9e52SPablo Neira Ayuso void nft_reg_track_cancel(struct nft_regs_track *track, u8 dreg, u8 len); 167834cc9e52SPablo Neira Ayuso void __nft_reg_track_cancel(struct nft_regs_track *track, u8 dreg); 167934cc9e52SPablo Neira Ayuso 168034cc9e52SPablo Neira Ayuso static inline bool nft_reg_track_cmp(struct nft_regs_track *track, 168134cc9e52SPablo Neira Ayuso const struct nft_expr *expr, u8 dreg) 168234cc9e52SPablo Neira Ayuso { 168334cc9e52SPablo Neira Ayuso return track->regs[dreg].selector && 168434cc9e52SPablo Neira Ayuso track->regs[dreg].selector->ops == expr->ops && 168534cc9e52SPablo Neira Ayuso track->regs[dreg].num_reg == 0; 168634cc9e52SPablo Neira Ayuso } 168734cc9e52SPablo Neira Ayuso 168896518518SPatrick McHardy #endif /* _NET_NF_TABLES_H */ 1689