0001
0002 #ifndef _NET_NF_TABLES_H
0003 #define _NET_NF_TABLES_H
0004
0005 #include <asm/unaligned.h>
0006 #include <linux/list.h>
0007 #include <linux/netfilter.h>
0008 #include <linux/netfilter/nfnetlink.h>
0009 #include <linux/netfilter/x_tables.h>
0010 #include <linux/netfilter/nf_tables.h>
0011 #include <linux/u64_stats_sync.h>
0012 #include <linux/rhashtable.h>
0013 #include <net/netfilter/nf_flow_table.h>
0014 #include <net/netlink.h>
0015 #include <net/flow_offload.h>
0016 #include <net/netns/generic.h>
0017
0018 #define NFT_MAX_HOOKS (NF_INET_INGRESS + 1)
0019
0020 struct module;
0021
0022 #define NFT_JUMP_STACK_SIZE 16
0023
0024 enum {
0025 NFT_PKTINFO_L4PROTO = (1 << 0),
0026 NFT_PKTINFO_INNER = (1 << 1),
0027 };
0028
0029 struct nft_pktinfo {
0030 struct sk_buff *skb;
0031 const struct nf_hook_state *state;
0032 u8 flags;
0033 u8 tprot;
0034 u16 fragoff;
0035 unsigned int thoff;
0036 unsigned int inneroff;
0037 };
0038
0039 static inline struct sock *nft_sk(const struct nft_pktinfo *pkt)
0040 {
0041 return pkt->state->sk;
0042 }
0043
0044 static inline unsigned int nft_thoff(const struct nft_pktinfo *pkt)
0045 {
0046 return pkt->thoff;
0047 }
0048
0049 static inline struct net *nft_net(const struct nft_pktinfo *pkt)
0050 {
0051 return pkt->state->net;
0052 }
0053
0054 static inline unsigned int nft_hook(const struct nft_pktinfo *pkt)
0055 {
0056 return pkt->state->hook;
0057 }
0058
0059 static inline u8 nft_pf(const struct nft_pktinfo *pkt)
0060 {
0061 return pkt->state->pf;
0062 }
0063
0064 static inline const struct net_device *nft_in(const struct nft_pktinfo *pkt)
0065 {
0066 return pkt->state->in;
0067 }
0068
0069 static inline const struct net_device *nft_out(const struct nft_pktinfo *pkt)
0070 {
0071 return pkt->state->out;
0072 }
0073
0074 static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
0075 struct sk_buff *skb,
0076 const struct nf_hook_state *state)
0077 {
0078 pkt->skb = skb;
0079 pkt->state = state;
0080 }
0081
0082 static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt)
0083 {
0084 pkt->flags = 0;
0085 pkt->tprot = 0;
0086 pkt->thoff = 0;
0087 pkt->fragoff = 0;
0088 }
0089
0090
0091
0092
0093
0094
0095
0096 struct nft_verdict {
0097 u32 code;
0098 struct nft_chain *chain;
0099 };
0100
0101 struct nft_data {
0102 union {
0103 u32 data[4];
0104 struct nft_verdict verdict;
0105 };
0106 } __attribute__((aligned(__alignof__(u64))));
0107
0108 #define NFT_REG32_NUM 20
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 struct nft_regs {
0119 union {
0120 u32 data[NFT_REG32_NUM];
0121 struct nft_verdict verdict;
0122 };
0123 };
0124
0125 struct nft_regs_track {
0126 struct {
0127 const struct nft_expr *selector;
0128 const struct nft_expr *bitwise;
0129 u8 num_reg;
0130 } regs[NFT_REG32_NUM];
0131
0132 const struct nft_expr *cur;
0133 const struct nft_expr *last;
0134 };
0135
0136
0137
0138
0139
0140
0141
0142
0143 static inline void nft_reg_store8(u32 *dreg, u8 val)
0144 {
0145 *dreg = 0;
0146 *(u8 *)dreg = val;
0147 }
0148
0149 static inline u8 nft_reg_load8(const u32 *sreg)
0150 {
0151 return *(u8 *)sreg;
0152 }
0153
0154 static inline void nft_reg_store16(u32 *dreg, u16 val)
0155 {
0156 *dreg = 0;
0157 *(u16 *)dreg = val;
0158 }
0159
0160 static inline void nft_reg_store_be16(u32 *dreg, __be16 val)
0161 {
0162 nft_reg_store16(dreg, (__force __u16)val);
0163 }
0164
0165 static inline u16 nft_reg_load16(const u32 *sreg)
0166 {
0167 return *(u16 *)sreg;
0168 }
0169
0170 static inline __be16 nft_reg_load_be16(const u32 *sreg)
0171 {
0172 return (__force __be16)nft_reg_load16(sreg);
0173 }
0174
0175 static inline __be32 nft_reg_load_be32(const u32 *sreg)
0176 {
0177 return *(__force __be32 *)sreg;
0178 }
0179
0180 static inline void nft_reg_store64(u32 *dreg, u64 val)
0181 {
0182 put_unaligned(val, (u64 *)dreg);
0183 }
0184
0185 static inline u64 nft_reg_load64(const u32 *sreg)
0186 {
0187 return get_unaligned((u64 *)sreg);
0188 }
0189
0190 static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
0191 unsigned int len)
0192 {
0193 if (len % NFT_REG32_SIZE)
0194 dst[len / NFT_REG32_SIZE] = 0;
0195 memcpy(dst, src, len);
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 struct nft_ctx {
0212 struct net *net;
0213 struct nft_table *table;
0214 struct nft_chain *chain;
0215 const struct nlattr * const *nla;
0216 u32 portid;
0217 u32 seq;
0218 u16 flags;
0219 u8 family;
0220 u8 level;
0221 bool report;
0222 };
0223
0224 enum nft_data_desc_flags {
0225 NFT_DATA_DESC_SETELEM = (1 << 0),
0226 };
0227
0228 struct nft_data_desc {
0229 enum nft_data_types type;
0230 unsigned int size;
0231 unsigned int len;
0232 unsigned int flags;
0233 };
0234
0235 int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
0236 struct nft_data_desc *desc, const struct nlattr *nla);
0237 void nft_data_hold(const struct nft_data *data, enum nft_data_types type);
0238 void nft_data_release(const struct nft_data *data, enum nft_data_types type);
0239 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
0240 enum nft_data_types type, unsigned int len);
0241
0242 static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg)
0243 {
0244 return reg == NFT_REG_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE;
0245 }
0246
0247 static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
0248 {
0249 return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE;
0250 }
0251
0252 int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
0253 int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
0254
0255 int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
0256 int nft_parse_register_store(const struct nft_ctx *ctx,
0257 const struct nlattr *attr, u8 *dreg,
0258 const struct nft_data *data,
0259 enum nft_data_types type, unsigned int len);
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 struct nft_userdata {
0272 u8 len;
0273 unsigned char data[];
0274 };
0275
0276
0277
0278
0279
0280
0281
0282
0283 struct nft_set_elem {
0284 union {
0285 u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
0286 struct nft_data val;
0287 } key;
0288 union {
0289 u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
0290 struct nft_data val;
0291 } key_end;
0292 union {
0293 u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
0294 struct nft_data val;
0295 } data;
0296 void *priv;
0297 };
0298
0299 struct nft_set;
0300 struct nft_set_iter {
0301 u8 genmask;
0302 unsigned int count;
0303 unsigned int skip;
0304 int err;
0305 int (*fn)(const struct nft_ctx *ctx,
0306 struct nft_set *set,
0307 const struct nft_set_iter *iter,
0308 struct nft_set_elem *elem);
0309 };
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321 struct nft_set_desc {
0322 unsigned int klen;
0323 unsigned int dlen;
0324 unsigned int size;
0325 u8 field_len[NFT_REG32_COUNT];
0326 u8 field_count;
0327 bool expr;
0328 };
0329
0330
0331
0332
0333
0334
0335
0336
0337 enum nft_set_class {
0338 NFT_SET_CLASS_O_1,
0339 NFT_SET_CLASS_O_LOG_N,
0340 NFT_SET_CLASS_O_N,
0341 };
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 struct nft_set_estimate {
0352 u64 size;
0353 enum nft_set_class lookup;
0354 enum nft_set_class space;
0355 };
0356
0357 #define NFT_EXPR_MAXATTR 16
0358 #define NFT_EXPR_SIZE(size) (sizeof(struct nft_expr) + \
0359 ALIGN(size, __alignof__(struct nft_expr)))
0360
0361
0362
0363
0364
0365
0366
0367 struct nft_expr {
0368 const struct nft_expr_ops *ops;
0369 unsigned char data[]
0370 __attribute__((aligned(__alignof__(u64))));
0371 };
0372
0373 static inline void *nft_expr_priv(const struct nft_expr *expr)
0374 {
0375 return (void *)expr->data;
0376 }
0377
0378 int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src);
0379 void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
0380 int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
0381 const struct nft_expr *expr);
0382 bool nft_expr_reduce_bitwise(struct nft_regs_track *track,
0383 const struct nft_expr *expr);
0384
0385 struct nft_set_ext;
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409 struct nft_set_ops {
0410 bool (*lookup)(const struct net *net,
0411 const struct nft_set *set,
0412 const u32 *key,
0413 const struct nft_set_ext **ext);
0414 bool (*update)(struct nft_set *set,
0415 const u32 *key,
0416 void *(*new)(struct nft_set *,
0417 const struct nft_expr *,
0418 struct nft_regs *),
0419 const struct nft_expr *expr,
0420 struct nft_regs *regs,
0421 const struct nft_set_ext **ext);
0422 bool (*delete)(const struct nft_set *set,
0423 const u32 *key);
0424
0425 int (*insert)(const struct net *net,
0426 const struct nft_set *set,
0427 const struct nft_set_elem *elem,
0428 struct nft_set_ext **ext);
0429 void (*activate)(const struct net *net,
0430 const struct nft_set *set,
0431 const struct nft_set_elem *elem);
0432 void * (*deactivate)(const struct net *net,
0433 const struct nft_set *set,
0434 const struct nft_set_elem *elem);
0435 bool (*flush)(const struct net *net,
0436 const struct nft_set *set,
0437 void *priv);
0438 void (*remove)(const struct net *net,
0439 const struct nft_set *set,
0440 const struct nft_set_elem *elem);
0441 void (*walk)(const struct nft_ctx *ctx,
0442 struct nft_set *set,
0443 struct nft_set_iter *iter);
0444 void * (*get)(const struct net *net,
0445 const struct nft_set *set,
0446 const struct nft_set_elem *elem,
0447 unsigned int flags);
0448
0449 u64 (*privsize)(const struct nlattr * const nla[],
0450 const struct nft_set_desc *desc);
0451 bool (*estimate)(const struct nft_set_desc *desc,
0452 u32 features,
0453 struct nft_set_estimate *est);
0454 int (*init)(const struct nft_set *set,
0455 const struct nft_set_desc *desc,
0456 const struct nlattr * const nla[]);
0457 void (*destroy)(const struct nft_set *set);
0458 void (*gc_init)(const struct nft_set *set);
0459
0460 unsigned int elemsize;
0461 };
0462
0463
0464
0465
0466
0467
0468
0469 struct nft_set_type {
0470 const struct nft_set_ops ops;
0471 u32 features;
0472 };
0473 #define to_set_type(o) container_of(o, struct nft_set_type, ops)
0474
0475 struct nft_set_elem_expr {
0476 u8 size;
0477 unsigned char data[]
0478 __attribute__((aligned(__alignof__(struct nft_expr))));
0479 };
0480
0481 #define nft_setelem_expr_at(__elem_expr, __offset) \
0482 ((struct nft_expr *)&__elem_expr->data[__offset])
0483
0484 #define nft_setelem_expr_foreach(__expr, __elem_expr, __size) \
0485 for (__expr = nft_setelem_expr_at(__elem_expr, 0), __size = 0; \
0486 __size < (__elem_expr)->size; \
0487 __size += (__expr)->ops->size, __expr = ((void *)(__expr)) + (__expr)->ops->size)
0488
0489 #define NFT_SET_EXPR_MAX 2
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522 struct nft_set {
0523 struct list_head list;
0524 struct list_head bindings;
0525 struct nft_table *table;
0526 possible_net_t net;
0527 char *name;
0528 u64 handle;
0529 u32 ktype;
0530 u32 dtype;
0531 u32 objtype;
0532 u32 size;
0533 u8 field_len[NFT_REG32_COUNT];
0534 u8 field_count;
0535 u32 use;
0536 atomic_t nelems;
0537 u32 ndeact;
0538 u64 timeout;
0539 u32 gc_int;
0540 u16 policy;
0541 u16 udlen;
0542 unsigned char *udata;
0543
0544 const struct nft_set_ops *ops ____cacheline_aligned;
0545 u16 flags:14,
0546 genmask:2;
0547 u8 klen;
0548 u8 dlen;
0549 u8 num_exprs;
0550 struct nft_expr *exprs[NFT_SET_EXPR_MAX];
0551 struct list_head catchall_list;
0552 unsigned char data[]
0553 __attribute__((aligned(__alignof__(u64))));
0554 };
0555
0556 static inline bool nft_set_is_anonymous(const struct nft_set *set)
0557 {
0558 return set->flags & NFT_SET_ANONYMOUS;
0559 }
0560
0561 static inline void *nft_set_priv(const struct nft_set *set)
0562 {
0563 return (void *)set->data;
0564 }
0565
0566 static inline struct nft_set *nft_set_container_of(const void *priv)
0567 {
0568 return (void *)priv - offsetof(struct nft_set, data);
0569 }
0570
0571 struct nft_set *nft_set_lookup_global(const struct net *net,
0572 const struct nft_table *table,
0573 const struct nlattr *nla_set_name,
0574 const struct nlattr *nla_set_id,
0575 u8 genmask);
0576
0577 struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
0578 const struct nft_set *set);
0579 void *nft_set_catchall_gc(const struct nft_set *set);
0580
0581 static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
0582 {
0583 return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
0584 }
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596 struct nft_set_binding {
0597 struct list_head list;
0598 const struct nft_chain *chain;
0599 u32 flags;
0600 };
0601
0602 enum nft_trans_phase;
0603 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
0604 struct nft_set_binding *binding,
0605 enum nft_trans_phase phase);
0606 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
0607 struct nft_set_binding *binding);
0608 void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set);
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 enum nft_set_extensions {
0625 NFT_SET_EXT_KEY,
0626 NFT_SET_EXT_KEY_END,
0627 NFT_SET_EXT_DATA,
0628 NFT_SET_EXT_FLAGS,
0629 NFT_SET_EXT_TIMEOUT,
0630 NFT_SET_EXT_EXPIRATION,
0631 NFT_SET_EXT_USERDATA,
0632 NFT_SET_EXT_EXPRESSIONS,
0633 NFT_SET_EXT_OBJREF,
0634 NFT_SET_EXT_NUM
0635 };
0636
0637
0638
0639
0640
0641
0642
0643 struct nft_set_ext_type {
0644 u8 len;
0645 u8 align;
0646 };
0647
0648 extern const struct nft_set_ext_type nft_set_ext_types[];
0649
0650
0651
0652
0653
0654
0655
0656 struct nft_set_ext_tmpl {
0657 u16 len;
0658 u8 offset[NFT_SET_EXT_NUM];
0659 u8 ext_len[NFT_SET_EXT_NUM];
0660 };
0661
0662
0663
0664
0665
0666
0667
0668
0669 struct nft_set_ext {
0670 u8 genmask;
0671 u8 offset[NFT_SET_EXT_NUM];
0672 char data[];
0673 };
0674
0675 static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl)
0676 {
0677 memset(tmpl, 0, sizeof(*tmpl));
0678 tmpl->len = sizeof(struct nft_set_ext);
0679 }
0680
0681 static inline int nft_set_ext_add_length(struct nft_set_ext_tmpl *tmpl, u8 id,
0682 unsigned int len)
0683 {
0684 tmpl->len = ALIGN(tmpl->len, nft_set_ext_types[id].align);
0685 if (tmpl->len > U8_MAX)
0686 return -EINVAL;
0687
0688 tmpl->offset[id] = tmpl->len;
0689 tmpl->ext_len[id] = nft_set_ext_types[id].len + len;
0690 tmpl->len += tmpl->ext_len[id];
0691
0692 return 0;
0693 }
0694
0695 static inline int nft_set_ext_add(struct nft_set_ext_tmpl *tmpl, u8 id)
0696 {
0697 return nft_set_ext_add_length(tmpl, id, 0);
0698 }
0699
0700 static inline void nft_set_ext_init(struct nft_set_ext *ext,
0701 const struct nft_set_ext_tmpl *tmpl)
0702 {
0703 memcpy(ext->offset, tmpl->offset, sizeof(ext->offset));
0704 }
0705
0706 static inline bool __nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
0707 {
0708 return !!ext->offset[id];
0709 }
0710
0711 static inline bool nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
0712 {
0713 return ext && __nft_set_ext_exists(ext, id);
0714 }
0715
0716 static inline void *nft_set_ext(const struct nft_set_ext *ext, u8 id)
0717 {
0718 return (void *)ext + ext->offset[id];
0719 }
0720
0721 static inline struct nft_data *nft_set_ext_key(const struct nft_set_ext *ext)
0722 {
0723 return nft_set_ext(ext, NFT_SET_EXT_KEY);
0724 }
0725
0726 static inline struct nft_data *nft_set_ext_key_end(const struct nft_set_ext *ext)
0727 {
0728 return nft_set_ext(ext, NFT_SET_EXT_KEY_END);
0729 }
0730
0731 static inline struct nft_data *nft_set_ext_data(const struct nft_set_ext *ext)
0732 {
0733 return nft_set_ext(ext, NFT_SET_EXT_DATA);
0734 }
0735
0736 static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
0737 {
0738 return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
0739 }
0740
0741 static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
0742 {
0743 return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
0744 }
0745
0746 static inline u64 *nft_set_ext_expiration(const struct nft_set_ext *ext)
0747 {
0748 return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
0749 }
0750
0751 static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext)
0752 {
0753 return nft_set_ext(ext, NFT_SET_EXT_USERDATA);
0754 }
0755
0756 static inline struct nft_set_elem_expr *nft_set_ext_expr(const struct nft_set_ext *ext)
0757 {
0758 return nft_set_ext(ext, NFT_SET_EXT_EXPRESSIONS);
0759 }
0760
0761 static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
0762 {
0763 return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
0764 time_is_before_eq_jiffies64(*nft_set_ext_expiration(ext));
0765 }
0766
0767 static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
0768 void *elem)
0769 {
0770 return elem + set->ops->elemsize;
0771 }
0772
0773 static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext)
0774 {
0775 return nft_set_ext(ext, NFT_SET_EXT_OBJREF);
0776 }
0777
0778 struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
0779 const struct nft_set *set,
0780 const struct nlattr *attr);
0781
0782 void *nft_set_elem_init(const struct nft_set *set,
0783 const struct nft_set_ext_tmpl *tmpl,
0784 const u32 *key, const u32 *key_end, const u32 *data,
0785 u64 timeout, u64 expiration, gfp_t gfp);
0786 int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
0787 struct nft_expr *expr_array[]);
0788 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
0789 bool destroy_expr);
0790
0791
0792
0793
0794
0795
0796
0797
0798 struct nft_set_gc_batch_head {
0799 struct rcu_head rcu;
0800 const struct nft_set *set;
0801 unsigned int cnt;
0802 };
0803
0804 #define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \
0805 sizeof(struct nft_set_gc_batch_head)) / \
0806 sizeof(void *))
0807
0808
0809
0810
0811
0812
0813
0814 struct nft_set_gc_batch {
0815 struct nft_set_gc_batch_head head;
0816 void *elems[NFT_SET_GC_BATCH_SIZE];
0817 };
0818
0819 struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
0820 gfp_t gfp);
0821 void nft_set_gc_batch_release(struct rcu_head *rcu);
0822
0823 static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
0824 {
0825 if (gcb != NULL)
0826 call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
0827 }
0828
0829 static inline struct nft_set_gc_batch *
0830 nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
0831 gfp_t gfp)
0832 {
0833 if (gcb != NULL) {
0834 if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
0835 return gcb;
0836 nft_set_gc_batch_complete(gcb);
0837 }
0838 return nft_set_gc_batch_alloc(set, gfp);
0839 }
0840
0841 static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
0842 void *elem)
0843 {
0844 gcb->elems[gcb->head.cnt++] = elem;
0845 }
0846
0847 struct nft_expr_ops;
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862 struct nft_expr_type {
0863 const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
0864 const struct nlattr * const tb[]);
0865 void (*release_ops)(const struct nft_expr_ops *ops);
0866 const struct nft_expr_ops *ops;
0867 struct list_head list;
0868 const char *name;
0869 struct module *owner;
0870 const struct nla_policy *policy;
0871 unsigned int maxattr;
0872 u8 family;
0873 u8 flags;
0874 };
0875
0876 #define NFT_EXPR_STATEFUL 0x1
0877 #define NFT_EXPR_GC 0x2
0878
0879 enum nft_trans_phase {
0880 NFT_TRANS_PREPARE,
0881 NFT_TRANS_ABORT,
0882 NFT_TRANS_COMMIT,
0883 NFT_TRANS_RELEASE
0884 };
0885
0886 struct nft_flow_rule;
0887 struct nft_offload_ctx;
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903 struct nft_expr_ops {
0904 void (*eval)(const struct nft_expr *expr,
0905 struct nft_regs *regs,
0906 const struct nft_pktinfo *pkt);
0907 int (*clone)(struct nft_expr *dst,
0908 const struct nft_expr *src);
0909 unsigned int size;
0910
0911 int (*init)(const struct nft_ctx *ctx,
0912 const struct nft_expr *expr,
0913 const struct nlattr * const tb[]);
0914 void (*activate)(const struct nft_ctx *ctx,
0915 const struct nft_expr *expr);
0916 void (*deactivate)(const struct nft_ctx *ctx,
0917 const struct nft_expr *expr,
0918 enum nft_trans_phase phase);
0919 void (*destroy)(const struct nft_ctx *ctx,
0920 const struct nft_expr *expr);
0921 void (*destroy_clone)(const struct nft_ctx *ctx,
0922 const struct nft_expr *expr);
0923 int (*dump)(struct sk_buff *skb,
0924 const struct nft_expr *expr);
0925 int (*validate)(const struct nft_ctx *ctx,
0926 const struct nft_expr *expr,
0927 const struct nft_data **data);
0928 bool (*reduce)(struct nft_regs_track *track,
0929 const struct nft_expr *expr);
0930 bool (*gc)(struct net *net,
0931 const struct nft_expr *expr);
0932 int (*offload)(struct nft_offload_ctx *ctx,
0933 struct nft_flow_rule *flow,
0934 const struct nft_expr *expr);
0935 bool (*offload_action)(const struct nft_expr *expr);
0936 void (*offload_stats)(struct nft_expr *expr,
0937 const struct flow_stats *stats);
0938 const struct nft_expr_type *type;
0939 void *data;
0940 };
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952 struct nft_rule {
0953 struct list_head list;
0954 u64 handle:42,
0955 genmask:2,
0956 dlen:12,
0957 udata:1;
0958 unsigned char data[]
0959 __attribute__((aligned(__alignof__(struct nft_expr))));
0960 };
0961
0962 static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
0963 {
0964 return (struct nft_expr *)&rule->data[0];
0965 }
0966
0967 static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr)
0968 {
0969 return ((void *)expr) + expr->ops->size;
0970 }
0971
0972 static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
0973 {
0974 return (struct nft_expr *)&rule->data[rule->dlen];
0975 }
0976
0977 static inline bool nft_expr_more(const struct nft_rule *rule,
0978 const struct nft_expr *expr)
0979 {
0980 return expr != nft_expr_last(rule) && expr->ops;
0981 }
0982
0983 static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
0984 {
0985 return (void *)&rule->data[rule->dlen];
0986 }
0987
0988 void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule);
0989
0990 static inline void nft_set_elem_update_expr(const struct nft_set_ext *ext,
0991 struct nft_regs *regs,
0992 const struct nft_pktinfo *pkt)
0993 {
0994 struct nft_set_elem_expr *elem_expr;
0995 struct nft_expr *expr;
0996 u32 size;
0997
0998 if (__nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS)) {
0999 elem_expr = nft_set_ext_expr(ext);
1000 nft_setelem_expr_foreach(expr, elem_expr, size) {
1001 expr->ops->eval(expr, regs, pkt);
1002 if (regs->verdict.code == NFT_BREAK)
1003 return;
1004 }
1005 }
1006 }
1007
1008
1009
1010
1011
1012
1013 #define nft_rule_for_each_expr(expr, last, rule) \
1014 for ((expr) = nft_expr_first(rule), (last) = nft_expr_last(rule); \
1015 (expr) != (last); \
1016 (expr) = nft_expr_next(expr))
1017
1018 #define NFT_CHAIN_POLICY_UNSET U8_MAX
1019
1020 struct nft_rule_dp {
1021 u64 is_last:1,
1022 dlen:12,
1023 handle:42;
1024 unsigned char data[]
1025 __attribute__((aligned(__alignof__(struct nft_expr))));
1026 };
1027
1028 struct nft_rule_blob {
1029 unsigned long size;
1030 unsigned char data[]
1031 __attribute__((aligned(__alignof__(struct nft_rule_dp))));
1032 };
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 struct nft_chain {
1047 struct nft_rule_blob __rcu *blob_gen_0;
1048 struct nft_rule_blob __rcu *blob_gen_1;
1049 struct list_head rules;
1050 struct list_head list;
1051 struct rhlist_head rhlhead;
1052 struct nft_table *table;
1053 u64 handle;
1054 u32 use;
1055 u8 flags:5,
1056 bound:1,
1057 genmask:2;
1058 char *name;
1059 u16 udlen;
1060 u8 *udata;
1061
1062
1063 struct nft_rule_blob *blob_next;
1064 };
1065
1066 int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain);
1067
1068 enum nft_chain_types {
1069 NFT_CHAIN_T_DEFAULT = 0,
1070 NFT_CHAIN_T_ROUTE,
1071 NFT_CHAIN_T_NAT,
1072 NFT_CHAIN_T_MAX
1073 };
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 struct nft_chain_type {
1088 const char *name;
1089 enum nft_chain_types type;
1090 int family;
1091 struct module *owner;
1092 unsigned int hook_mask;
1093 nf_hookfn *hooks[NFT_MAX_HOOKS];
1094 int (*ops_register)(struct net *net, const struct nf_hook_ops *ops);
1095 void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops);
1096 };
1097
1098 int nft_chain_validate_dependency(const struct nft_chain *chain,
1099 enum nft_chain_types type);
1100 int nft_chain_validate_hooks(const struct nft_chain *chain,
1101 unsigned int hook_flags);
1102
1103 static inline bool nft_chain_is_bound(struct nft_chain *chain)
1104 {
1105 return (chain->flags & NFT_CHAIN_BINDING) && chain->bound;
1106 }
1107
1108 void nft_chain_del(struct nft_chain *chain);
1109 void nf_tables_chain_destroy(struct nft_ctx *ctx);
1110
1111 struct nft_stats {
1112 u64 bytes;
1113 u64 pkts;
1114 struct u64_stats_sync syncp;
1115 };
1116
1117 struct nft_hook {
1118 struct list_head list;
1119 struct nf_hook_ops ops;
1120 struct rcu_head rcu;
1121 };
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 struct nft_base_chain {
1135 struct nf_hook_ops ops;
1136 struct list_head hook_list;
1137 const struct nft_chain_type *type;
1138 u8 policy;
1139 u8 flags;
1140 struct nft_stats __percpu *stats;
1141 struct nft_chain chain;
1142 struct flow_block flow_block;
1143 };
1144
1145 static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chain)
1146 {
1147 return container_of(chain, struct nft_base_chain, chain);
1148 }
1149
1150 static inline bool nft_is_base_chain(const struct nft_chain *chain)
1151 {
1152 return chain->flags & NFT_CHAIN_BASE;
1153 }
1154
1155 int __nft_release_basechain(struct nft_ctx *ctx);
1156
1157 unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 struct nft_table {
1177 struct list_head list;
1178 struct rhltable chains_ht;
1179 struct list_head chains;
1180 struct list_head sets;
1181 struct list_head objects;
1182 struct list_head flowtables;
1183 u64 hgenerator;
1184 u64 handle;
1185 u32 use;
1186 u16 family:6,
1187 flags:8,
1188 genmask:2;
1189 u32 nlpid;
1190 char *name;
1191 u16 udlen;
1192 u8 *udata;
1193 };
1194
1195 static inline bool nft_table_has_owner(const struct nft_table *table)
1196 {
1197 return table->flags & NFT_TABLE_F_OWNER;
1198 }
1199
1200 static inline bool nft_base_chain_netdev(int family, u32 hooknum)
1201 {
1202 return family == NFPROTO_NETDEV ||
1203 (family == NFPROTO_INET && hooknum == NF_INET_INGRESS);
1204 }
1205
1206 void nft_register_chain_type(const struct nft_chain_type *);
1207 void nft_unregister_chain_type(const struct nft_chain_type *);
1208
1209 int nft_register_expr(struct nft_expr_type *);
1210 void nft_unregister_expr(struct nft_expr_type *);
1211
1212 int nft_verdict_dump(struct sk_buff *skb, int type,
1213 const struct nft_verdict *v);
1214
1215
1216
1217
1218
1219
1220
1221 struct nft_object_hash_key {
1222 const char *name;
1223 const struct nft_table *table;
1224 };
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238 struct nft_object {
1239 struct list_head list;
1240 struct rhlist_head rhlhead;
1241 struct nft_object_hash_key key;
1242 u32 genmask:2,
1243 use:30;
1244 u64 handle;
1245 u16 udlen;
1246 u8 *udata;
1247
1248 const struct nft_object_ops *ops ____cacheline_aligned;
1249 unsigned char data[]
1250 __attribute__((aligned(__alignof__(u64))));
1251 };
1252
1253 static inline void *nft_obj_data(const struct nft_object *obj)
1254 {
1255 return (void *)obj->data;
1256 }
1257
1258 #define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr))
1259
1260 struct nft_object *nft_obj_lookup(const struct net *net,
1261 const struct nft_table *table,
1262 const struct nlattr *nla, u32 objtype,
1263 u8 genmask);
1264
1265 void nft_obj_notify(struct net *net, const struct nft_table *table,
1266 struct nft_object *obj, u32 portid, u32 seq,
1267 int event, u16 flags, int family, int report, gfp_t gfp);
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280 struct nft_object_type {
1281 const struct nft_object_ops *(*select_ops)(const struct nft_ctx *,
1282 const struct nlattr * const tb[]);
1283 const struct nft_object_ops *ops;
1284 struct list_head list;
1285 u32 type;
1286 unsigned int maxattr;
1287 struct module *owner;
1288 const struct nla_policy *policy;
1289 };
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301 struct nft_object_ops {
1302 void (*eval)(struct nft_object *obj,
1303 struct nft_regs *regs,
1304 const struct nft_pktinfo *pkt);
1305 unsigned int size;
1306 int (*init)(const struct nft_ctx *ctx,
1307 const struct nlattr *const tb[],
1308 struct nft_object *obj);
1309 void (*destroy)(const struct nft_ctx *ctx,
1310 struct nft_object *obj);
1311 int (*dump)(struct sk_buff *skb,
1312 struct nft_object *obj,
1313 bool reset);
1314 void (*update)(struct nft_object *obj,
1315 struct nft_object *newobj);
1316 const struct nft_object_type *type;
1317 };
1318
1319 int nft_register_obj(struct nft_object_type *obj_type);
1320 void nft_unregister_obj(struct nft_object_type *obj_type);
1321
1322 #define NFT_NETDEVICE_MAX 256
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 struct nft_flowtable {
1340 struct list_head list;
1341 struct nft_table *table;
1342 char *name;
1343 int hooknum;
1344 int ops_len;
1345 u32 genmask:2,
1346 use:30;
1347 u64 handle;
1348
1349 struct list_head hook_list ____cacheline_aligned;
1350 struct nf_flowtable data;
1351 };
1352
1353 struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
1354 const struct nlattr *nla,
1355 u8 genmask);
1356
1357 void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
1358 struct nft_flowtable *flowtable,
1359 enum nft_trans_phase phase);
1360
1361 void nft_register_flowtable_type(struct nf_flowtable_type *type);
1362 void nft_unregister_flowtable_type(struct nf_flowtable_type *type);
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 struct nft_traceinfo {
1379 bool trace;
1380 bool nf_trace;
1381 bool packet_dumped;
1382 enum nft_trace_types type:8;
1383 u32 skbid;
1384 const struct nft_pktinfo *pkt;
1385 const struct nft_base_chain *basechain;
1386 const struct nft_chain *chain;
1387 const struct nft_rule_dp *rule;
1388 const struct nft_verdict *verdict;
1389 };
1390
1391 void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt,
1392 const struct nft_verdict *verdict,
1393 const struct nft_chain *basechain);
1394
1395 void nft_trace_notify(struct nft_traceinfo *info);
1396
1397 #define MODULE_ALIAS_NFT_CHAIN(family, name) \
1398 MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
1399
1400 #define MODULE_ALIAS_NFT_AF_EXPR(family, name) \
1401 MODULE_ALIAS("nft-expr-" __stringify(family) "-" name)
1402
1403 #define MODULE_ALIAS_NFT_EXPR(name) \
1404 MODULE_ALIAS("nft-expr-" name)
1405
1406 #define MODULE_ALIAS_NFT_OBJ(type) \
1407 MODULE_ALIAS("nft-obj-" __stringify(type))
1408
1409 #if IS_ENABLED(CONFIG_NF_TABLES)
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423 static inline unsigned int nft_gencursor_next(const struct net *net)
1424 {
1425 return net->nft.gencursor + 1 == 1 ? 1 : 0;
1426 }
1427
1428 static inline u8 nft_genmask_next(const struct net *net)
1429 {
1430 return 1 << nft_gencursor_next(net);
1431 }
1432
1433 static inline u8 nft_genmask_cur(const struct net *net)
1434 {
1435
1436 return 1 << READ_ONCE(net->nft.gencursor);
1437 }
1438
1439 #define NFT_GENMASK_ANY ((1 << 0) | (1 << 1))
1440
1441
1442
1443
1444
1445
1446 #define nft_is_active(__net, __obj) \
1447 (((__obj)->genmask & nft_genmask_cur(__net)) == 0)
1448
1449
1450 #define nft_is_active_next(__net, __obj) \
1451 (((__obj)->genmask & nft_genmask_next(__net)) == 0)
1452
1453
1454 #define nft_activate_next(__net, __obj) \
1455 (__obj)->genmask = nft_genmask_cur(__net)
1456
1457
1458 #define nft_deactivate_next(__net, __obj) \
1459 (__obj)->genmask = nft_genmask_next(__net)
1460
1461
1462 #define nft_clear(__net, __obj) \
1463 (__obj)->genmask &= ~nft_genmask_next(__net)
1464 #define nft_active_genmask(__obj, __genmask) \
1465 !((__obj)->genmask & __genmask)
1466
1467
1468
1469
1470
1471 static inline bool nft_set_elem_active(const struct nft_set_ext *ext,
1472 u8 genmask)
1473 {
1474 return !(ext->genmask & genmask);
1475 }
1476
1477 static inline void nft_set_elem_change_active(const struct net *net,
1478 const struct nft_set *set,
1479 struct nft_set_ext *ext)
1480 {
1481 ext->genmask ^= nft_genmask_next(net);
1482 }
1483
1484 #endif
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496 #define NFT_SET_ELEM_BUSY_MASK (1 << 2)
1497
1498 #if defined(__LITTLE_ENDIAN_BITFIELD)
1499 #define NFT_SET_ELEM_BUSY_BIT 2
1500 #elif defined(__BIG_ENDIAN_BITFIELD)
1501 #define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2)
1502 #else
1503 #error
1504 #endif
1505
1506 static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
1507 {
1508 unsigned long *word = (unsigned long *)ext;
1509
1510 BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
1511 return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
1512 }
1513
1514 static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
1515 {
1516 unsigned long *word = (unsigned long *)ext;
1517
1518 clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530 struct nft_trans {
1531 struct list_head list;
1532 int msg_type;
1533 bool put_net;
1534 struct nft_ctx ctx;
1535 char data[];
1536 };
1537
1538 struct nft_trans_rule {
1539 struct nft_rule *rule;
1540 struct nft_flow_rule *flow;
1541 u32 rule_id;
1542 };
1543
1544 #define nft_trans_rule(trans) \
1545 (((struct nft_trans_rule *)trans->data)->rule)
1546 #define nft_trans_flow_rule(trans) \
1547 (((struct nft_trans_rule *)trans->data)->flow)
1548 #define nft_trans_rule_id(trans) \
1549 (((struct nft_trans_rule *)trans->data)->rule_id)
1550
1551 struct nft_trans_set {
1552 struct nft_set *set;
1553 u32 set_id;
1554 bool bound;
1555 };
1556
1557 #define nft_trans_set(trans) \
1558 (((struct nft_trans_set *)trans->data)->set)
1559 #define nft_trans_set_id(trans) \
1560 (((struct nft_trans_set *)trans->data)->set_id)
1561 #define nft_trans_set_bound(trans) \
1562 (((struct nft_trans_set *)trans->data)->bound)
1563
1564 struct nft_trans_chain {
1565 bool update;
1566 char *name;
1567 struct nft_stats __percpu *stats;
1568 u8 policy;
1569 u32 chain_id;
1570 };
1571
1572 #define nft_trans_chain_update(trans) \
1573 (((struct nft_trans_chain *)trans->data)->update)
1574 #define nft_trans_chain_name(trans) \
1575 (((struct nft_trans_chain *)trans->data)->name)
1576 #define nft_trans_chain_stats(trans) \
1577 (((struct nft_trans_chain *)trans->data)->stats)
1578 #define nft_trans_chain_policy(trans) \
1579 (((struct nft_trans_chain *)trans->data)->policy)
1580 #define nft_trans_chain_id(trans) \
1581 (((struct nft_trans_chain *)trans->data)->chain_id)
1582
1583 struct nft_trans_table {
1584 bool update;
1585 };
1586
1587 #define nft_trans_table_update(trans) \
1588 (((struct nft_trans_table *)trans->data)->update)
1589
1590 struct nft_trans_elem {
1591 struct nft_set *set;
1592 struct nft_set_elem elem;
1593 bool bound;
1594 };
1595
1596 #define nft_trans_elem_set(trans) \
1597 (((struct nft_trans_elem *)trans->data)->set)
1598 #define nft_trans_elem(trans) \
1599 (((struct nft_trans_elem *)trans->data)->elem)
1600 #define nft_trans_elem_set_bound(trans) \
1601 (((struct nft_trans_elem *)trans->data)->bound)
1602
1603 struct nft_trans_obj {
1604 struct nft_object *obj;
1605 struct nft_object *newobj;
1606 bool update;
1607 };
1608
1609 #define nft_trans_obj(trans) \
1610 (((struct nft_trans_obj *)trans->data)->obj)
1611 #define nft_trans_obj_newobj(trans) \
1612 (((struct nft_trans_obj *)trans->data)->newobj)
1613 #define nft_trans_obj_update(trans) \
1614 (((struct nft_trans_obj *)trans->data)->update)
1615
1616 struct nft_trans_flowtable {
1617 struct nft_flowtable *flowtable;
1618 bool update;
1619 struct list_head hook_list;
1620 u32 flags;
1621 };
1622
1623 #define nft_trans_flowtable(trans) \
1624 (((struct nft_trans_flowtable *)trans->data)->flowtable)
1625 #define nft_trans_flowtable_update(trans) \
1626 (((struct nft_trans_flowtable *)trans->data)->update)
1627 #define nft_trans_flowtable_hooks(trans) \
1628 (((struct nft_trans_flowtable *)trans->data)->hook_list)
1629 #define nft_trans_flowtable_flags(trans) \
1630 (((struct nft_trans_flowtable *)trans->data)->flags)
1631
1632 int __init nft_chain_filter_init(void);
1633 void nft_chain_filter_fini(void);
1634
1635 void __init nft_chain_route_init(void);
1636 void nft_chain_route_fini(void);
1637
1638 void nf_tables_trans_destroy_flush_work(void);
1639
1640 int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result);
1641 __be64 nf_jiffies64_to_msecs(u64 input);
1642
1643 #ifdef CONFIG_MODULES
1644 __printf(2, 3) int nft_request_module(struct net *net, const char *fmt, ...);
1645 #else
1646 static inline int nft_request_module(struct net *net, const char *fmt, ...) { return -ENOENT; }
1647 #endif
1648
1649 struct nftables_pernet {
1650 struct list_head tables;
1651 struct list_head commit_list;
1652 struct list_head module_list;
1653 struct list_head notify_list;
1654 struct mutex commit_mutex;
1655 u64 table_handle;
1656 unsigned int base_seq;
1657 u8 validate_state;
1658 };
1659
1660 extern unsigned int nf_tables_net_id;
1661
1662 static inline struct nftables_pernet *nft_pernet(const struct net *net)
1663 {
1664 return net_generic(net, nf_tables_net_id);
1665 }
1666
1667 #define __NFT_REDUCE_READONLY 1UL
1668 #define NFT_REDUCE_READONLY (void *)__NFT_REDUCE_READONLY
1669
1670 static inline bool nft_reduce_is_readonly(const struct nft_expr *expr)
1671 {
1672 return expr->ops->reduce == NFT_REDUCE_READONLY;
1673 }
1674
1675 void nft_reg_track_update(struct nft_regs_track *track,
1676 const struct nft_expr *expr, u8 dreg, u8 len);
1677 void nft_reg_track_cancel(struct nft_regs_track *track, u8 dreg, u8 len);
1678 void __nft_reg_track_cancel(struct nft_regs_track *track, u8 dreg);
1679
1680 static inline bool nft_reg_track_cmp(struct nft_regs_track *track,
1681 const struct nft_expr *expr, u8 dreg)
1682 {
1683 return track->regs[dreg].selector &&
1684 track->regs[dreg].selector->ops == expr->ops &&
1685 track->regs[dreg].num_reg == 0;
1686 }
1687
1688 #endif