treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500
[sfrench/cifs-2.6.git] / include / linux / netfilter / ipset / ip_set_comment.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef _IP_SET_COMMENT_H
3 #define _IP_SET_COMMENT_H
4
5 /* Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
6  */
7
8 #ifdef __KERNEL__
9
10 static inline char*
11 ip_set_comment_uget(struct nlattr *tb)
12 {
13         return nla_data(tb);
14 }
15
16 /* Called from uadd only, protected by the set spinlock.
17  * The kadt functions don't use the comment extensions in any way.
18  */
19 static inline void
20 ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment,
21                     const struct ip_set_ext *ext)
22 {
23         struct ip_set_comment_rcu *c = rcu_dereference_protected(comment->c, 1);
24         size_t len = ext->comment ? strlen(ext->comment) : 0;
25
26         if (unlikely(c)) {
27                 set->ext_size -= sizeof(*c) + strlen(c->str) + 1;
28                 kfree_rcu(c, rcu);
29                 rcu_assign_pointer(comment->c, NULL);
30         }
31         if (!len)
32                 return;
33         if (unlikely(len > IPSET_MAX_COMMENT_SIZE))
34                 len = IPSET_MAX_COMMENT_SIZE;
35         c = kmalloc(sizeof(*c) + len + 1, GFP_ATOMIC);
36         if (unlikely(!c))
37                 return;
38         strlcpy(c->str, ext->comment, len + 1);
39         set->ext_size += sizeof(*c) + strlen(c->str) + 1;
40         rcu_assign_pointer(comment->c, c);
41 }
42
43 /* Used only when dumping a set, protected by rcu_read_lock() */
44 static inline int
45 ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment)
46 {
47         struct ip_set_comment_rcu *c = rcu_dereference(comment->c);
48
49         if (!c)
50                 return 0;
51         return nla_put_string(skb, IPSET_ATTR_COMMENT, c->str);
52 }
53
54 /* Called from uadd/udel, flush or the garbage collectors protected
55  * by the set spinlock.
56  * Called when the set is destroyed and when there can't be any user
57  * of the set data anymore.
58  */
59 static inline void
60 ip_set_comment_free(struct ip_set *set, struct ip_set_comment *comment)
61 {
62         struct ip_set_comment_rcu *c;
63
64         c = rcu_dereference_protected(comment->c, 1);
65         if (unlikely(!c))
66                 return;
67         set->ext_size -= sizeof(*c) + strlen(c->str) + 1;
68         kfree_rcu(c, rcu);
69         rcu_assign_pointer(comment->c, NULL);
70 }
71
72 #endif
73 #endif