FILE
x_tables.h
File preview with syntax highlighting.
linux-6.19.14/include/linux/netfilter/x_tables.h
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _X_TABLES_H 3#define _X_TABLES_H 4 5 6#include <linux/netdevice.h> 7#include <linux/static_key.h> 8#include <linux/netfilter.h> 9#include <uapi/linux/netfilter/x_tables.h> 10 11/* Test a struct->invflags and a boolean for inequality */ 12#define NF_INVF(ptr, flag, boolean) \ 13 ((boolean) ^ !!((ptr)->invflags & (flag))) 14 15/** 16 * struct xt_action_param - parameters for matches/targets 17 * 18 * @match: the match extension 19 * @target: the target extension 20 * @matchinfo: per-match data 21 * @targetinfo: per-target data 22 * @state: pointer to hook state this packet came from 23 * @fragoff: packet is a fragment, this is the data offset 24 * @thoff: position of transport header relative to skb->data 25 * 26 * Fields written to by extensions: 27 * 28 * @hotdrop: drop packet if we had inspection problems 29 */ 30struct xt_action_param { 31 union { 32 const struct xt_match *match; 33 const struct xt_target *target; 34 }; 35 union { 36 const void *matchinfo, *targinfo; 37 }; 38 const struct nf_hook_state *state; 39 unsigned int thoff; 40 u16 fragoff; 41 bool hotdrop; 42}; 43 44static inline struct net *xt_net(const struct xt_action_param *par) 45{ 46 return par->state->net; 47} 48 49static inline struct net_device *xt_in(const struct xt_action_param *par) 50{ 51 return par->state->in; 52} 53 54static inline struct net_device *xt_out(const struct xt_action_param *par) 55{ 56 return par->state->out; 57} 58 59static inline unsigned int xt_hooknum(const struct xt_action_param *par) 60{ 61 return par->state->hook; 62} 63 64static inline u_int8_t xt_family(const struct xt_action_param *par) 65{ 66 return par->state->pf; 67} 68 69/** 70 * struct xt_mtchk_param - parameters for match extensions' 71 * checkentry functions 72 * 73 * @net: network namespace through which the check was invoked 74 * @table: table the rule is tried to be inserted into 75 * @entryinfo: the family-specific rule data 76 * (struct ipt_ip, ip6t_ip, arpt_arp or (note) ebt_entry) 77 * @match: struct xt_match through which this function was invoked 78 * @matchinfo: per-match data 79 * @hook_mask: via which hooks the new rule is reachable 80 * Other fields as above. 81 */ 82struct xt_mtchk_param { 83 struct net *net; 84 const char *table; 85 const void *entryinfo; 86 const struct xt_match *match; 87 void *matchinfo; 88 unsigned int hook_mask; 89 u_int8_t family; 90 bool nft_compat; 91}; 92 93/** 94 * struct xt_mdtor_param - match destructor parameters 95 * Fields as above. 96 */ 97struct xt_mtdtor_param { 98 struct net *net; 99 const struct xt_match *match; 100 void *matchinfo; 101 u_int8_t family; 102}; 103 104/** 105 * struct xt_tgchk_param - parameters for target extensions' 106 * checkentry functions 107 * 108 * @entryinfo: the family-specific rule data 109 * (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry) 110 * 111 * Other fields see above. 112 */ 113struct xt_tgchk_param { 114 struct net *net; 115 const char *table; 116 const void *entryinfo; 117 const struct xt_target *target; 118 void *targinfo; 119 unsigned int hook_mask; 120 u_int8_t family; 121 bool nft_compat; 122}; 123 124/* Target destructor parameters */ 125struct xt_tgdtor_param { 126 struct net *net; 127 const struct xt_target *target; 128 void *targinfo; 129 u_int8_t family; 130}; 131 132struct xt_match { 133 struct list_head list; 134 135 const char name[XT_EXTENSION_MAXNAMELEN]; 136 u_int8_t revision; 137 138 /* Return true or false: return FALSE and set *hotdrop = 1 to 139 force immediate packet drop. */ 140 /* Arguments changed since 2.6.9, as this must now handle 141 non-linear skb, using skb_header_pointer and 142 skb_ip_make_writable. */ 143 bool (*match)(const struct sk_buff *skb, 144 struct xt_action_param *); 145 146 /* Called when user tries to insert an entry of this type. */ 147 int (*checkentry)(const struct xt_mtchk_param *); 148 149 /* Called when entry of this type deleted. */ 150 void (*destroy)(const struct xt_mtdtor_param *); 151#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 152 /* Called when userspace align differs from kernel space one */ 153 void (*compat_from_user)(void *dst, const void *src); 154 int (*compat_to_user)(void __user *dst, const void *src); 155#endif 156 /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 157 struct module *me; 158 159 const char *table; 160 unsigned int matchsize; 161 unsigned int usersize; 162#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 163 unsigned int compatsize; 164#endif 165 unsigned int hooks; 166 unsigned short proto; 167 168 unsigned short family; 169}; 170 171/* Registration hooks for targets. */ 172struct xt_target { 173 struct list_head list; 174 175 const char name[XT_EXTENSION_MAXNAMELEN]; 176 u_int8_t revision; 177 178 /* Returns verdict. Argument order changed since 2.6.9, as this 179 must now handle non-linear skbs, using skb_copy_bits and 180 skb_ip_make_writable. */ 181 unsigned int (*target)(struct sk_buff *skb, 182 const struct xt_action_param *); 183 184 /* Called when user tries to insert an entry of this type: 185 hook_mask is a bitmask of hooks from which it can be 186 called. */ 187 /* Should return 0 on success or an error code otherwise (-Exxxx). */ 188 int (*checkentry)(const struct xt_tgchk_param *); 189 190 /* Called when entry of this type deleted. */ 191 void (*destroy)(const struct xt_tgdtor_param *); 192#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 193 /* Called when userspace align differs from kernel space one */ 194 void (*compat_from_user)(void *dst, const void *src); 195 int (*compat_to_user)(void __user *dst, const void *src); 196#endif 197 /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 198 struct module *me; 199 200 const char *table; 201 unsigned int targetsize; 202 unsigned int usersize; 203#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 204 unsigned int compatsize; 205#endif 206 unsigned int hooks; 207 unsigned short proto; 208 209 unsigned short family; 210}; 211 212/* Furniture shopping... */ 213struct xt_table { 214 struct list_head list; 215 216 /* What hooks you will enter on */ 217 unsigned int valid_hooks; 218 219 /* Man behind the curtain... */ 220 struct xt_table_info *private; 221 222 /* hook ops that register the table with the netfilter core */ 223 struct nf_hook_ops *ops; 224 225 /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 226 struct module *me; 227 228 u_int8_t af; /* address/protocol family */ 229 int priority; /* hook order */ 230 231 /* A unique name... */ 232 const char name[XT_TABLE_MAXNAMELEN]; 233}; 234 235#include <linux/netfilter_ipv4.h> 236 237/* The table itself */ 238struct xt_table_info { 239 /* Size per table */ 240 unsigned int size; 241 /* Number of entries: FIXME. --RR */ 242 unsigned int number; 243 /* Initial number of entries. Needed for module usage count */ 244 unsigned int initial_entries; 245 246 /* Entry points and underflows */ 247 unsigned int hook_entry[NF_INET_NUMHOOKS]; 248 unsigned int underflow[NF_INET_NUMHOOKS]; 249 250 /* 251 * Number of user chains. Since tables cannot have loops, at most 252 * @stacksize jumps (number of user chains) can possibly be made. 253 */ 254 unsigned int stacksize; 255 void ***jumpstack; 256 257 unsigned char entries[] __aligned(8); 258}; 259 260int xt_register_target(struct xt_target *target); 261void xt_unregister_target(struct xt_target *target); 262int xt_register_targets(struct xt_target *target, unsigned int n); 263void xt_unregister_targets(struct xt_target *target, unsigned int n); 264 265int xt_register_match(struct xt_match *target); 266void xt_unregister_match(struct xt_match *target); 267int xt_register_matches(struct xt_match *match, unsigned int n); 268void xt_unregister_matches(struct xt_match *match, unsigned int n); 269 270int xt_check_entry_offsets(const void *base, const char *elems, 271 unsigned int target_offset, 272 unsigned int next_offset); 273 274int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_hooks); 275 276unsigned int *xt_alloc_entry_offsets(unsigned int size); 277bool xt_find_jump_offset(const unsigned int *offsets, 278 unsigned int target, unsigned int size); 279 280int xt_check_proc_name(const char *name, unsigned int size); 281 282int xt_check_match(struct xt_mtchk_param *, unsigned int size, u16 proto, 283 bool inv_proto); 284int xt_check_target(struct xt_tgchk_param *, unsigned int size, u16 proto, 285 bool inv_proto); 286 287int xt_match_to_user(const struct xt_entry_match *m, 288 struct xt_entry_match __user *u); 289int xt_target_to_user(const struct xt_entry_target *t, 290 struct xt_entry_target __user *u); 291int xt_data_to_user(void __user *dst, const void *src, 292 int usersize, int size, int aligned_size); 293 294void *xt_copy_counters(sockptr_t arg, unsigned int len, 295 struct xt_counters_info *info); 296struct xt_counters *xt_counters_alloc(unsigned int counters); 297 298struct xt_table *xt_register_table(struct net *net, 299 const struct xt_table *table, 300 struct xt_table_info *bootstrap, 301 struct xt_table_info *newinfo); 302void *xt_unregister_table(struct xt_table *table); 303 304struct xt_table_info *xt_replace_table(struct xt_table *table, 305 unsigned int num_counters, 306 struct xt_table_info *newinfo, 307 int *error); 308 309struct xt_match *xt_find_match(u8 af, const char *name, u8 revision); 310struct xt_match *xt_request_find_match(u8 af, const char *name, u8 revision); 311struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision); 312int xt_find_revision(u8 af, const char *name, u8 revision, int target, 313 int *err); 314 315struct xt_table *xt_find_table(struct net *net, u8 af, const char *name); 316struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af, 317 const char *name); 318struct xt_table *xt_request_find_table_lock(struct net *net, u_int8_t af, 319 const char *name); 320void xt_table_unlock(struct xt_table *t); 321 322int xt_proto_init(struct net *net, u_int8_t af); 323void xt_proto_fini(struct net *net, u_int8_t af); 324 325struct xt_table_info *xt_alloc_table_info(unsigned int size); 326void xt_free_table_info(struct xt_table_info *info); 327 328/** 329 * xt_recseq - recursive seqcount for netfilter use 330 * 331 * Packet processing changes the seqcount only if no recursion happened 332 * get_counters() can use read_seqcount_begin()/read_seqcount_retry(), 333 * because we use the normal seqcount convention : 334 * Low order bit set to 1 if a writer is active. 335 */ 336DECLARE_PER_CPU(seqcount_t, xt_recseq); 337 338/* xt_tee_enabled - true if x_tables needs to handle reentrancy 339 * 340 * Enabled if current ip(6)tables ruleset has at least one -j TEE rule. 341 */ 342extern struct static_key xt_tee_enabled; 343 344/** 345 * xt_write_recseq_begin - start of a write section 346 * 347 * Begin packet processing : all readers must wait the end 348 * 1) Must be called with preemption disabled 349 * 2) softirqs must be disabled too (or we should use this_cpu_add()) 350 * Returns: 351 * 1 if no recursion on this cpu 352 * 0 if recursion detected 353 */ 354static inline unsigned int xt_write_recseq_begin(void) 355{ 356 unsigned int addend; 357 358 /* 359 * Low order bit of sequence is set if we already 360 * called xt_write_recseq_begin(). 361 */ 362 addend = (__this_cpu_read(xt_recseq.sequence) + 1) & 1; 363 364 /* 365 * This is kind of a write_seqcount_begin(), but addend is 0 or 1 366 * We dont check addend value to avoid a test and conditional jump, 367 * since addend is most likely 1 368 */ 369 __this_cpu_add(xt_recseq.sequence, addend); 370 smp_mb(); 371 372 return addend; 373} 374 375/** 376 * xt_write_recseq_end - end of a write section 377 * @addend: return value from previous xt_write_recseq_begin() 378 * 379 * End packet processing : all readers can proceed 380 * 1) Must be called with preemption disabled 381 * 2) softirqs must be disabled too (or we should use this_cpu_add()) 382 */ 383static inline void xt_write_recseq_end(unsigned int addend) 384{ 385 /* this is kind of a write_seqcount_end(), but addend is 0 or 1 */ 386 smp_wmb(); 387 __this_cpu_add(xt_recseq.sequence, addend); 388} 389 390/* 391 * This helper is performance critical and must be inlined 392 */ 393static inline unsigned long ifname_compare_aligned(const char *_a, 394 const char *_b, 395 const char *_mask) 396{ 397 const unsigned long *a = (const unsigned long *)_a; 398 const unsigned long *b = (const unsigned long *)_b; 399 const unsigned long *mask = (const unsigned long *)_mask; 400 unsigned long ret; 401 402 ret = (a[0] ^ b[0]) & mask[0]; 403 if (IFNAMSIZ > sizeof(unsigned long)) 404 ret |= (a[1] ^ b[1]) & mask[1]; 405 if (IFNAMSIZ > 2 * sizeof(unsigned long)) 406 ret |= (a[2] ^ b[2]) & mask[2]; 407 if (IFNAMSIZ > 3 * sizeof(unsigned long)) 408 ret |= (a[3] ^ b[3]) & mask[3]; 409 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long)); 410 return ret; 411} 412 413struct xt_percpu_counter_alloc_state { 414 unsigned int off; 415 const char __percpu *mem; 416}; 417 418bool xt_percpu_counter_alloc(struct xt_percpu_counter_alloc_state *state, 419 struct xt_counters *counter); 420void xt_percpu_counter_free(struct xt_counters *cnt); 421 422static inline struct xt_counters * 423xt_get_this_cpu_counter(struct xt_counters *cnt) 424{ 425 if (nr_cpu_ids > 1) 426 return this_cpu_ptr((void __percpu *) (unsigned long) cnt->pcnt); 427 428 return cnt; 429} 430 431static inline struct xt_counters * 432xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu) 433{ 434 if (nr_cpu_ids > 1) 435 return per_cpu_ptr((void __percpu *) (unsigned long) cnt->pcnt, cpu); 436 437 return cnt; 438} 439 440struct nf_hook_ops *xt_hook_ops_alloc(const struct xt_table *, nf_hookfn *); 441 442int xt_register_template(const struct xt_table *t, int(*table_init)(struct net *net)); 443void xt_unregister_template(const struct xt_table *t); 444 445#ifdef CONFIG_NETFILTER_XTABLES_COMPAT 446#include <net/compat.h> 447 448struct compat_xt_entry_match { 449 union { 450 struct { 451 u_int16_t match_size; 452 char name[XT_FUNCTION_MAXNAMELEN - 1]; 453 u_int8_t revision; 454 } user; 455 struct { 456 u_int16_t match_size; 457 compat_uptr_t match; 458 } kernel; 459 u_int16_t match_size; 460 } u; 461 unsigned char data[]; 462}; 463 464struct compat_xt_entry_target { 465 union { 466 struct { 467 u_int16_t target_size; 468 char name[XT_FUNCTION_MAXNAMELEN - 1]; 469 u_int8_t revision; 470 } user; 471 struct { 472 u_int16_t target_size; 473 compat_uptr_t target; 474 } kernel; 475 u_int16_t target_size; 476 } u; 477 unsigned char data[]; 478}; 479 480/* FIXME: this works only on 32 bit tasks 481 * need to change whole approach in order to calculate align as function of 482 * current task alignment */ 483 484struct compat_xt_counters { 485 compat_u64 pcnt, bcnt; /* Packet and byte counters */ 486}; 487 488struct compat_xt_counters_info { 489 char name[XT_TABLE_MAXNAMELEN]; 490 compat_uint_t num_counters; 491 struct compat_xt_counters counters[]; 492}; 493 494struct _compat_xt_align { 495 __u8 u8; 496 __u16 u16; 497 __u32 u32; 498 compat_u64 u64; 499}; 500 501#define COMPAT_XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _compat_xt_align)) 502 503void xt_compat_lock(u_int8_t af); 504void xt_compat_unlock(u_int8_t af); 505 506int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta); 507void xt_compat_flush_offsets(u_int8_t af); 508int xt_compat_init_offsets(u8 af, unsigned int number); 509int xt_compat_calc_jump(u_int8_t af, unsigned int offset); 510 511int xt_compat_match_offset(const struct xt_match *match); 512void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr, 513 unsigned int *size); 514int xt_compat_match_to_user(const struct xt_entry_match *m, 515 void __user **dstptr, unsigned int *size); 516 517int xt_compat_target_offset(const struct xt_target *target); 518void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr, 519 unsigned int *size); 520int xt_compat_target_to_user(const struct xt_entry_target *t, 521 void __user **dstptr, unsigned int *size); 522int xt_compat_check_entry_offsets(const void *base, const char *elems, 523 unsigned int target_offset, 524 unsigned int next_offset); 525 526#endif /* CONFIG_NETFILTER_XTABLES_COMPAT */ 527#endif /* _X_TABLES_H */
~/
Read-only file preview.