Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
1
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
40451fd
Documentation
arch
block
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
6lowpan
802
8021q
9p
appletalk
atm
ax25
batman-adv
bluetooth
bridge
caif
can
ceph
core
dcb
dccp
decnet
dns_resolver
dsa
ethernet
hsr
ieee802154
ipv4
ipv6
ipx
irda
iucv
key
l2tp
lapb
llc
mac80211
mac802154
mpls
netfilter
ipset
ipvs
Kconfig
Makefile
core.c
nf_conntrack_acct.c
nf_conntrack_amanda.c
nf_conntrack_broadcast.c
nf_conntrack_core.c
nf_conntrack_ecache.c
nf_conntrack_expect.c
nf_conntrack_extend.c
nf_conntrack_ftp.c
nf_conntrack_h323_asn1.c
nf_conntrack_h323_main.c
nf_conntrack_h323_types.c
nf_conntrack_helper.c
nf_conntrack_irc.c
nf_conntrack_l3proto_generic.c
nf_conntrack_labels.c
nf_conntrack_netbios_ns.c
nf_conntrack_netlink.c
nf_conntrack_pptp.c
nf_conntrack_proto.c
nf_conntrack_proto_dccp.c
nf_conntrack_proto_generic.c
nf_conntrack_proto_gre.c
nf_conntrack_proto_sctp.c
nf_conntrack_proto_tcp.c
nf_conntrack_proto_udp.c
nf_conntrack_proto_udplite.c
nf_conntrack_sane.c
nf_conntrack_seqadj.c
nf_conntrack_sip.c
nf_conntrack_snmp.c
nf_conntrack_standalone.c
nf_conntrack_tftp.c
nf_conntrack_timeout.c
nf_conntrack_timestamp.c
nf_internals.h
nf_log.c
nf_log_common.c
nf_nat_amanda.c
nf_nat_core.c
nf_nat_ftp.c
nf_nat_helper.c
nf_nat_irc.c
nf_nat_proto_common.c
nf_nat_proto_dccp.c
nf_nat_proto_sctp.c
nf_nat_proto_tcp.c
nf_nat_proto_udp.c
nf_nat_proto_udplite.c
nf_nat_proto_unknown.c
nf_nat_redirect.c
nf_nat_sip.c
nf_nat_tftp.c
nf_queue.c
nf_sockopt.c
nf_synproxy_core.c
nf_tables_api.c
nf_tables_core.c
nf_tables_inet.c
nfnetlink.c
nfnetlink_acct.c
nfnetlink_cthelper.c
nfnetlink_cttimeout.c
nfnetlink_log.c
nfnetlink_queue_core.c
nfnetlink_queue_ct.c
nft_bitwise.c
nft_byteorder.c
nft_cmp.c
nft_compat.c
nft_counter.c
nft_ct.c
nft_expr_template.c
nft_exthdr.c
nft_hash.c
nft_immediate.c
nft_limit.c
nft_log.c
nft_lookup.c
nft_masq.c
nft_meta.c
nft_nat.c
nft_payload.c
nft_queue.c
nft_rbtree.c
nft_redir.c
nft_reject.c
nft_reject_inet.c
x_tables.c
xt_AUDIT.c
xt_CHECKSUM.c
xt_CLASSIFY.c
xt_CONNSECMARK.c
xt_CT.c
xt_DSCP.c
xt_HL.c
xt_HMARK.c
xt_IDLETIMER.c
xt_LED.c
xt_LOG.c
xt_NETMAP.c
xt_NFLOG.c
xt_NFQUEUE.c
xt_RATEEST.c
xt_REDIRECT.c
xt_SECMARK.c
xt_TCPMSS.c
xt_TCPOPTSTRIP.c
xt_TEE.c
xt_TPROXY.c
xt_TRACE.c
xt_addrtype.c
xt_bpf.c
xt_cgroup.c
xt_cluster.c
xt_comment.c
xt_connbytes.c
xt_connlabel.c
xt_connlimit.c
xt_connmark.c
xt_conntrack.c
xt_cpu.c
xt_dccp.c
xt_devgroup.c
xt_dscp.c
xt_ecn.c
xt_esp.c
xt_hashlimit.c
xt_helper.c
xt_hl.c
xt_ipcomp.c
xt_iprange.c
xt_ipvs.c
xt_l2tp.c
xt_length.c
xt_limit.c
xt_mac.c
xt_mark.c
xt_multiport.c
xt_nat.c
xt_nfacct.c
xt_osf.c
xt_owner.c
xt_physdev.c
xt_pkttype.c
xt_policy.c
xt_quota.c
xt_rateest.c
xt_realm.c
xt_recent.c
xt_repldata.h
xt_sctp.c
xt_set.c
xt_socket.c
xt_state.c
xt_statistic.c
xt_string.c
xt_tcpmss.c
xt_tcpudp.c
xt_time.c
xt_u32.c
netlabel
netlink
netrom
nfc
openvswitch
packet
phonet
rds
rfkill
rose
rxrpc
sched
sctp
sunrpc
switchdev
tipc
unix
vmw_vsock
wimax
wireless
x25
xfrm
Kconfig
Makefile
compat.c
socket.c
sysctl_net.c
samples
scripts
security
sound
tools
usr
virt
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
net
/
netfilter
/
nft_rbtree.c
Copy path
Blame
Blame
Latest commit
History
History
290 lines (247 loc) · 6.88 KB
Breadcrumbs
linux
/
net
/
netfilter
/
nft_rbtree.c
Top
File metadata and controls
Code
Blame
290 lines (247 loc) · 6.88 KB
Raw
/* * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Development of this code funded by Astaro AG (http://www.astaro.com/) */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/list.h> #include <linux/rbtree.h> #include <linux/netlink.h> #include <linux/netfilter.h> #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> static DEFINE_SPINLOCK(nft_rbtree_lock); struct nft_rbtree { struct rb_root root; }; struct nft_rbtree_elem { struct rb_node node; u16 flags; struct nft_data key; struct nft_data data[]; }; static bool nft_rbtree_lookup(const struct nft_set *set, const struct nft_data *key, struct nft_data *data) { const struct nft_rbtree *priv = nft_set_priv(set); const struct nft_rbtree_elem *rbe, *interval = NULL; const struct rb_node *parent; int d; spin_lock_bh(&nft_rbtree_lock); parent = priv->root.rb_node; while (parent != NULL) { rbe = rb_entry(parent, struct nft_rbtree_elem, node); d = nft_data_cmp(&rbe->key, key, set->klen); if (d < 0) { parent = parent->rb_left; interval = rbe; } else if (d > 0) parent = parent->rb_right; else { found: if (rbe->flags & NFT_SET_ELEM_INTERVAL_END) goto out; if (set->flags & NFT_SET_MAP) nft_data_copy(data, rbe->data); spin_unlock_bh(&nft_rbtree_lock); return true; } } if (set->flags & NFT_SET_INTERVAL && interval != NULL) { rbe = interval; goto found; } out: spin_unlock_bh(&nft_rbtree_lock); return false; } static void nft_rbtree_elem_destroy(const struct nft_set *set, struct nft_rbtree_elem *rbe) { nft_data_uninit(&rbe->key, NFT_DATA_VALUE); if (set->flags & NFT_SET_MAP && !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) nft_data_uninit(rbe->data, set->dtype); kfree(rbe); } static int __nft_rbtree_insert(const struct nft_set *set, struct nft_rbtree_elem *new) { struct nft_rbtree *priv = nft_set_priv(set); struct nft_rbtree_elem *rbe; struct rb_node *parent, **p; int d; parent = NULL; p = &priv->root.rb_node; while (*p != NULL) { parent = *p; rbe = rb_entry(parent, struct nft_rbtree_elem, node); d = nft_data_cmp(&rbe->key, &new->key, set->klen); if (d < 0) p = &parent->rb_left; else if (d > 0) p = &parent->rb_right; else return -EEXIST; } rb_link_node(&new->node, parent, p); rb_insert_color(&new->node, &priv->root); return 0; } static int nft_rbtree_insert(const struct nft_set *set, const struct nft_set_elem *elem) { struct nft_rbtree_elem *rbe; unsigned int size; int err; size = sizeof(*rbe); if (set->flags & NFT_SET_MAP && !(elem->flags & NFT_SET_ELEM_INTERVAL_END)) size += sizeof(rbe->data[0]); rbe = kzalloc(size, GFP_KERNEL); if (rbe == NULL) return -ENOMEM; rbe->flags = elem->flags; nft_data_copy(&rbe->key, &elem->key); if (set->flags & NFT_SET_MAP && !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) nft_data_copy(rbe->data, &elem->data); spin_lock_bh(&nft_rbtree_lock); err = __nft_rbtree_insert(set, rbe); if (err < 0) kfree(rbe); spin_unlock_bh(&nft_rbtree_lock); return err; } static void nft_rbtree_remove(const struct nft_set *set, const struct nft_set_elem *elem) { struct nft_rbtree *priv = nft_set_priv(set); struct nft_rbtree_elem *rbe = elem->cookie; spin_lock_bh(&nft_rbtree_lock); rb_erase(&rbe->node, &priv->root); spin_unlock_bh(&nft_rbtree_lock); kfree(rbe); } static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem) { const struct nft_rbtree *priv = nft_set_priv(set); const struct rb_node *parent = priv->root.rb_node; struct nft_rbtree_elem *rbe; int d; while (parent != NULL) { rbe = rb_entry(parent, struct nft_rbtree_elem, node); d = nft_data_cmp(&rbe->key, &elem->key, set->klen); if (d < 0) parent = parent->rb_left; else if (d > 0) parent = parent->rb_right; else { elem->cookie = rbe; if (set->flags & NFT_SET_MAP && !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) nft_data_copy(&elem->data, rbe->data); elem->flags = rbe->flags; return 0; } } return -ENOENT; } static void nft_rbtree_walk(const struct nft_ctx *ctx, const struct nft_set *set, struct nft_set_iter *iter) { const struct nft_rbtree *priv = nft_set_priv(set); const struct nft_rbtree_elem *rbe; struct nft_set_elem elem; struct rb_node *node; spin_lock_bh(&nft_rbtree_lock); for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { if (iter->count < iter->skip) goto cont; rbe = rb_entry(node, struct nft_rbtree_elem, node); nft_data_copy(&elem.key, &rbe->key); if (set->flags & NFT_SET_MAP && !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) nft_data_copy(&elem.data, rbe->data); elem.flags = rbe->flags; iter->err = iter->fn(ctx, set, iter, &elem); if (iter->err < 0) { spin_unlock_bh(&nft_rbtree_lock); return; } cont: iter->count++; } spin_unlock_bh(&nft_rbtree_lock); } static unsigned int nft_rbtree_privsize(const struct nlattr * const nla[]) { return sizeof(struct nft_rbtree); } static int nft_rbtree_init(const struct nft_set *set, const struct nft_set_desc *desc, const struct nlattr * const nla[]) { struct nft_rbtree *priv = nft_set_priv(set); priv->root = RB_ROOT; return 0; } static void nft_rbtree_destroy(const struct nft_set *set) { struct nft_rbtree *priv = nft_set_priv(set); struct nft_rbtree_elem *rbe; struct rb_node *node; while ((node = priv->root.rb_node) != NULL) { rb_erase(node, &priv->root); rbe = rb_entry(node, struct nft_rbtree_elem, node); nft_rbtree_elem_destroy(set, rbe); } } static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features, struct nft_set_estimate *est) { unsigned int nsize; nsize = sizeof(struct nft_rbtree_elem); if (features & NFT_SET_MAP) nsize += FIELD_SIZEOF(struct nft_rbtree_elem, data[0]); if (desc->size) est->size = sizeof(struct nft_rbtree) + desc->size * nsize; else est->size = nsize; est->class = NFT_SET_CLASS_O_LOG_N; return true; } static struct nft_set_ops nft_rbtree_ops __read_mostly = { .privsize = nft_rbtree_privsize, .estimate = nft_rbtree_estimate, .init = nft_rbtree_init, .destroy = nft_rbtree_destroy, .insert = nft_rbtree_insert, .remove = nft_rbtree_remove, .get = nft_rbtree_get, .lookup = nft_rbtree_lookup, .walk = nft_rbtree_walk, .features = NFT_SET_INTERVAL | NFT_SET_MAP, .owner = THIS_MODULE, }; static int __init nft_rbtree_module_init(void) { return nft_register_set(&nft_rbtree_ops); } static void __exit nft_rbtree_module_exit(void) { nft_unregister_set(&nft_rbtree_ops); } module_init(nft_rbtree_module_init); module_exit(nft_rbtree_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); MODULE_ALIAS_NFT_SET();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
You can’t perform that action at this time.