History

netfilter: nf_tables: add netlink set API

This patch adds the new netlink API for maintaining nf_tables sets independently of the ruleset. The API supports the following operations: - creation of sets - deletion of sets - querying of specific sets - dumping of all sets - addition of set elements - removal of set elements - dumping of all set elements Sets are identified by name, each table defines an individual namespace. The name of a set may be allocated automatically, this is mostly useful in combination with the NFT_SET_ANONYMOUS flag, which destroys a set automatically once the last reference has been released. Sets can be marked constant, meaning they're not allowed to change while linked to a rule. This allows to perform lockless operation for set types that would otherwise require locking. Additionally, if the implementation supports it, sets can (as before) be used as maps, associating a data value with each key (or range), by specifying the NFT_SET_MAP flag and can be used for interval queries by specifying the NFT_SET_INTERVAL flag. Set elements are added and removed incrementally. All element operations support batching, reducing netlink message and set lookup overhead. The old "set" and "hash" expressions are replaced by a generic "lookup" expression, which binds to the specified set. Userspace is not aware of the actual set implementation used by the kernel anymore, all configuration options are generic. Currently the implementation selection logic is largely missing and the kernel will simply use the first registered implementation supporting the requested operation. Eventually, the plan is to have userspace supply a description of the data characteristics and select the implementation based on expected performance and memory use. This patch includes the new 'lookup' expression to look up for element matching in the set. This patch includes kernel-doc descriptions for this set API and it also includes the following fixes. From Patrick McHardy: * netfilter: nf_tables: fix set element data type in dumps * netfilter: nf_tables: fix indentation of struct nft_set_elem comments * netfilter: nf_tables: fix oops in nft_validate_data_load() * netfilter: nf_tables: fix oops while listing sets of built-in tables * netfilter: nf_tables: destroy anonymous sets immediately if binding fails * netfilter: nf_tables: propagate context to set iter callback * netfilter: nf_tables: add loop detection From Pablo Neira Ayuso: * netfilter: nf_tables: allow to dump all existing sets * netfilter: nf_tables: fix wrong type for flags variable in newelem

Patrick McHardy committed 13 years ago

Commit 20a69341 parent 965185111 files · +1854 −677Browse files

Showing the changes to include/uapi/linux (1 of 11 files). Show all

Unified · Split

include/uapi/linux/netfilter/nf_tables.h+139−52
@@ -44,6 +44,12 @@ enum nft_verdicts { · 43 unmodified lines
4444 * @NFT_MSG_NEWRULE: create a new rule (enum nft_rule_attributes)
4545 * @NFT_MSG_GETRULE: get a rule (enum nft_rule_attributes)
4646 * @NFT_MSG_DELRULE: delete a rule (enum nft_rule_attributes)
47+ * @NFT_MSG_NEWSET: create a new set (enum nft_set_attributes)
48+ * @NFT_MSG_GETSET: get a set (enum nft_set_attributes)
49+ * @NFT_MSG_DELSET: delete a set (enum nft_set_attributes)
50+ * @NFT_MSG_NEWSETELEM: create a new set element (enum nft_set_elem_attributes)
51+ * @NFT_MSG_GETSETELEM: get a set element (enum nft_set_elem_attributes)
52+ * @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes)
4753 */
4854 enum nf_tables_msg_types {
4955 NFT_MSG_NEWTABLE,
@@ -55,9 +61,20 @@ enum nf_tables_msg_types { · 5 unmodified lines
5561 NFT_MSG_NEWRULE,
5662 NFT_MSG_GETRULE,
5763 NFT_MSG_DELRULE,
64+ NFT_MSG_NEWSET,
65+ NFT_MSG_GETSET,
66+ NFT_MSG_DELSET,
67+ NFT_MSG_NEWSETELEM,
68+ NFT_MSG_GETSETELEM,
69+ NFT_MSG_DELSETELEM,
5870 NFT_MSG_MAX,
5971 };
6072
73+/**
74+ * enum nft_list_attributes - nf_tables generic list netlink attributes
75+ *
76+ * @NFTA_LIST_ELEM: list element (NLA_NESTED)
77+ */
6178 enum nft_list_attributes {
6279 NFTA_LIST_UNPEC,
6380 NFTA_LIST_ELEM,
@@ -127,6 +144,113 @@ enum nft_rule_attributes { · 63 unmodified lines
127144 };
128145 #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
129146
147+/**
148+ * enum nft_set_flags - nf_tables set flags
149+ *
150+ * @NFT_SET_ANONYMOUS: name allocation, automatic cleanup on unlink
151+ * @NFT_SET_CONSTANT: set contents may not change while bound
152+ * @NFT_SET_INTERVAL: set contains intervals
153+ * @NFT_SET_MAP: set is used as a dictionary
154+ */
155+enum nft_set_flags {
156+ NFT_SET_ANONYMOUS = 0x1,
157+ NFT_SET_CONSTANT = 0x2,
158+ NFT_SET_INTERVAL = 0x4,
159+ NFT_SET_MAP = 0x8,
160+};
161+
162+/**
163+ * enum nft_set_attributes - nf_tables set netlink attributes
164+ *
165+ * @NFTA_SET_TABLE: table name (NLA_STRING)
166+ * @NFTA_SET_NAME: set name (NLA_STRING)
167+ * @NFTA_SET_FLAGS: bitmask of enum nft_set_flags (NLA_U32)
168+ * @NFTA_SET_KEY_TYPE: key data type, informational purpose only (NLA_U32)
169+ * @NFTA_SET_KEY_LEN: key data length (NLA_U32)
170+ * @NFTA_SET_DATA_TYPE: mapping data type (NLA_U32)
171+ * @NFTA_SET_DATA_LEN: mapping data length (NLA_U32)
172+ */
173+enum nft_set_attributes {
174+ NFTA_SET_UNSPEC,
175+ NFTA_SET_TABLE,
176+ NFTA_SET_NAME,
177+ NFTA_SET_FLAGS,
178+ NFTA_SET_KEY_TYPE,
179+ NFTA_SET_KEY_LEN,
180+ NFTA_SET_DATA_TYPE,
181+ NFTA_SET_DATA_LEN,
182+ __NFTA_SET_MAX
183+};
184+#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
185+
186+/**
187+ * enum nft_set_elem_flags - nf_tables set element flags
188+ *
189+ * @NFT_SET_ELEM_INTERVAL_END: element ends the previous interval
190+ */
191+enum nft_set_elem_flags {
192+ NFT_SET_ELEM_INTERVAL_END = 0x1,
193+};
194+
195+/**
196+ * enum nft_set_elem_attributes - nf_tables set element netlink attributes
197+ *
198+ * @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data)
199+ * @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes)
200+ * @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32)
201+ */
202+enum nft_set_elem_attributes {
203+ NFTA_SET_ELEM_UNSPEC,
204+ NFTA_SET_ELEM_KEY,
205+ NFTA_SET_ELEM_DATA,
206+ NFTA_SET_ELEM_FLAGS,
207+ __NFTA_SET_ELEM_MAX
208+};
209+#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
210+
211+/**
212+ * enum nft_set_elem_list_attributes - nf_tables set element list netlink attributes
213+ *
214+ * @NFTA_SET_ELEM_LIST_TABLE: table of the set to be changed (NLA_STRING)
215+ * @NFTA_SET_ELEM_LIST_SET: name of the set to be changed (NLA_STRING)
216+ * @NFTA_SET_ELEM_LIST_ELEMENTS: list of set elements (NLA_NESTED: nft_set_elem_attributes)
217+ */
218+enum nft_set_elem_list_attributes {
219+ NFTA_SET_ELEM_LIST_UNSPEC,
220+ NFTA_SET_ELEM_LIST_TABLE,
221+ NFTA_SET_ELEM_LIST_SET,
222+ NFTA_SET_ELEM_LIST_ELEMENTS,
223+ __NFTA_SET_ELEM_LIST_MAX
224+};
225+#define NFTA_SET_ELEM_LIST_MAX (__NFTA_SET_ELEM_LIST_MAX - 1)
226+
227+/**
228+ * enum nft_data_types - nf_tables data types
229+ *
230+ * @NFT_DATA_VALUE: generic data
231+ * @NFT_DATA_VERDICT: netfilter verdict
232+ *
233+ * The type of data is usually determined by the kernel directly and is not
234+ * explicitly specified by userspace. The only difference are sets, where
235+ * userspace specifies the key and mapping data types.
236+ *
237+ * The values 0xffffff00-0xffffffff are reserved for internally used types.
238+ * The remaining range can be freely used by userspace to encode types, all
239+ * values are equivalent to NFT_DATA_VALUE.
240+ */
241+enum nft_data_types {
242+ NFT_DATA_VALUE,
243+ NFT_DATA_VERDICT = 0xffffff00U,
244+};
245+
246+#define NFT_DATA_RESERVED_MASK 0xffffff00U
247+
248+/**
249+ * enum nft_data_attributes - nf_tables data netlink attributes
250+ *
251+ * @NFTA_DATA_VALUE: generic data (NLA_BINARY)
252+ * @NFTA_DATA_VERDICT: nf_tables verdict (NLA_NESTED: nft_verdict_attributes)
253+ */
130254 enum nft_data_attributes {
131255 NFTA_DATA_UNSPEC,
132256 NFTA_DATA_VALUE,
@@ -275,58 +399,21 @@ enum nft_cmp_attributes { · 142 unmodified lines
275399 };
276400 #define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
277401
278−enum nft_set_elem_flags {
279− NFT_SE_INTERVAL_END = 0x1,
280−};
281−
282−enum nft_set_elem_attributes {
283− NFTA_SE_UNSPEC,
284− NFTA_SE_KEY,
285− NFTA_SE_DATA,
286− NFTA_SE_FLAGS,
287− __NFTA_SE_MAX
288−};
289−#define NFTA_SE_MAX (__NFTA_SE_MAX - 1)
290−
291−enum nft_set_flags {
292− NFT_SET_INTERVAL = 0x1,
293− NFT_SET_MAP = 0x2,
294−};
295−
296−enum nft_set_attributes {
297− NFTA_SET_UNSPEC,
298− NFTA_SET_FLAGS,
299− NFTA_SET_SREG,
300− NFTA_SET_DREG,
301− NFTA_SET_KLEN,
302− NFTA_SET_DLEN,
303− NFTA_SET_ELEMENTS,
304− __NFTA_SET_MAX
305−};
306−#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
307−
308−enum nft_hash_flags {
309− NFT_HASH_MAP = 0x1,
310−};
311−
312−enum nft_hash_elem_attributes {
313− NFTA_HE_UNSPEC,
314− NFTA_HE_KEY,
315− NFTA_HE_DATA,
316− __NFTA_HE_MAX
317−};
318−#define NFTA_HE_MAX (__NFTA_HE_MAX - 1)
319−
320−enum nft_hash_attributes {
321− NFTA_HASH_UNSPEC,
322− NFTA_HASH_FLAGS,
323− NFTA_HASH_SREG,
324− NFTA_HASH_DREG,
325− NFTA_HASH_KLEN,
326− NFTA_HASH_ELEMENTS,
327− __NFTA_HASH_MAX
328−};
329−#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
402+/**
403+ * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes
404+ *
405+ * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING)
406+ * @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
407+ * @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
408+ */
409+enum nft_lookup_attributes {
410+ NFTA_LOOKUP_UNSPEC,
411+ NFTA_LOOKUP_SET,
412+ NFTA_LOOKUP_SREG,
413+ NFTA_LOOKUP_DREG,
414+ __NFTA_LOOKUP_MAX
415+};
416+#define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1)
330417
331418 /**
332419 * enum nft_payload_bases - nf_tables payload expression offset bases