1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * NetLabel Network Address Lists |
4 | * |
5 | * This file contains network address list functions used to manage ordered |
6 | * lists of network addresses for use by the NetLabel subsystem. The NetLabel |
7 | * system manages static and dynamic label mappings for network protocols such |
8 | * as CIPSO and RIPSO. |
9 | * |
10 | * Author: Paul Moore <paul@paul-moore.com> |
11 | */ |
12 | |
13 | /* |
14 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 |
15 | */ |
16 | |
17 | #ifndef _NETLABEL_ADDRLIST_H |
18 | #define _NETLABEL_ADDRLIST_H |
19 | |
20 | #include <linux/types.h> |
21 | #include <linux/rcupdate.h> |
22 | #include <linux/list.h> |
23 | #include <linux/in6.h> |
24 | #include <linux/audit.h> |
25 | |
26 | /** |
27 | * struct netlbl_af4list - NetLabel IPv4 address list |
28 | * @addr: IPv4 address |
29 | * @mask: IPv4 address mask |
30 | * @valid: valid flag |
31 | * @list: list structure, used internally |
32 | */ |
33 | struct netlbl_af4list { |
34 | __be32 addr; |
35 | __be32 mask; |
36 | |
37 | u32 valid; |
38 | struct list_head list; |
39 | }; |
40 | |
41 | /** |
42 | * struct netlbl_af6list - NetLabel IPv6 address list |
43 | * @addr: IPv6 address |
44 | * @mask: IPv6 address mask |
45 | * @valid: valid flag |
46 | * @list: list structure, used internally |
47 | */ |
48 | struct netlbl_af6list { |
49 | struct in6_addr addr; |
50 | struct in6_addr mask; |
51 | |
52 | u32 valid; |
53 | struct list_head list; |
54 | }; |
55 | |
56 | #define __af4list_entry(ptr) container_of(ptr, struct netlbl_af4list, list) |
57 | |
58 | static inline struct netlbl_af4list *__af4list_valid(struct list_head *s, |
59 | struct list_head *h) |
60 | { |
61 | struct list_head *i = s; |
62 | struct netlbl_af4list *n = __af4list_entry(s); |
63 | while (i != h && !n->valid) { |
64 | i = i->next; |
65 | n = __af4list_entry(i); |
66 | } |
67 | return n; |
68 | } |
69 | |
70 | static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s, |
71 | struct list_head *h) |
72 | { |
73 | struct list_head *i = s; |
74 | struct netlbl_af4list *n = __af4list_entry(s); |
75 | while (i != h && !n->valid) { |
76 | i = rcu_dereference(list_next_rcu(i)); |
77 | n = __af4list_entry(i); |
78 | } |
79 | return n; |
80 | } |
81 | |
82 | #define netlbl_af4list_foreach(iter, head) \ |
83 | for (iter = __af4list_valid((head)->next, head); \ |
84 | &iter->list != (head); \ |
85 | iter = __af4list_valid(iter->list.next, head)) |
86 | |
87 | #define netlbl_af4list_foreach_rcu(iter, head) \ |
88 | for (iter = __af4list_valid_rcu((head)->next, head); \ |
89 | &iter->list != (head); \ |
90 | iter = __af4list_valid_rcu(iter->list.next, head)) |
91 | |
92 | #define netlbl_af4list_foreach_safe(iter, tmp, head) \ |
93 | for (iter = __af4list_valid((head)->next, head), \ |
94 | tmp = __af4list_valid(iter->list.next, head); \ |
95 | &iter->list != (head); \ |
96 | iter = tmp, tmp = __af4list_valid(iter->list.next, head)) |
97 | |
98 | int netlbl_af4list_add(struct netlbl_af4list *entry, |
99 | struct list_head *head); |
100 | struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask, |
101 | struct list_head *head); |
102 | void netlbl_af4list_remove_entry(struct netlbl_af4list *entry); |
103 | struct netlbl_af4list *netlbl_af4list_search(__be32 addr, |
104 | struct list_head *head); |
105 | struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, |
106 | __be32 mask, |
107 | struct list_head *head); |
108 | |
109 | #ifdef CONFIG_AUDIT |
110 | void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, |
111 | int src, const char *dev, |
112 | __be32 addr, __be32 mask); |
113 | #else |
114 | static inline void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, |
115 | int src, const char *dev, |
116 | __be32 addr, __be32 mask) |
117 | { |
118 | } |
119 | #endif |
120 | |
121 | #if IS_ENABLED(CONFIG_IPV6) |
122 | |
123 | #define __af6list_entry(ptr) container_of(ptr, struct netlbl_af6list, list) |
124 | |
125 | static inline struct netlbl_af6list *__af6list_valid(struct list_head *s, |
126 | struct list_head *h) |
127 | { |
128 | struct list_head *i = s; |
129 | struct netlbl_af6list *n = __af6list_entry(s); |
130 | while (i != h && !n->valid) { |
131 | i = i->next; |
132 | n = __af6list_entry(i); |
133 | } |
134 | return n; |
135 | } |
136 | |
137 | static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s, |
138 | struct list_head *h) |
139 | { |
140 | struct list_head *i = s; |
141 | struct netlbl_af6list *n = __af6list_entry(s); |
142 | while (i != h && !n->valid) { |
143 | i = rcu_dereference(list_next_rcu(i)); |
144 | n = __af6list_entry(i); |
145 | } |
146 | return n; |
147 | } |
148 | |
149 | #define netlbl_af6list_foreach(iter, head) \ |
150 | for (iter = __af6list_valid((head)->next, head); \ |
151 | &iter->list != (head); \ |
152 | iter = __af6list_valid(iter->list.next, head)) |
153 | |
154 | #define netlbl_af6list_foreach_rcu(iter, head) \ |
155 | for (iter = __af6list_valid_rcu((head)->next, head); \ |
156 | &iter->list != (head); \ |
157 | iter = __af6list_valid_rcu(iter->list.next, head)) |
158 | |
159 | #define netlbl_af6list_foreach_safe(iter, tmp, head) \ |
160 | for (iter = __af6list_valid((head)->next, head), \ |
161 | tmp = __af6list_valid(iter->list.next, head); \ |
162 | &iter->list != (head); \ |
163 | iter = tmp, tmp = __af6list_valid(iter->list.next, head)) |
164 | |
165 | int netlbl_af6list_add(struct netlbl_af6list *entry, |
166 | struct list_head *head); |
167 | struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, |
168 | const struct in6_addr *mask, |
169 | struct list_head *head); |
170 | void netlbl_af6list_remove_entry(struct netlbl_af6list *entry); |
171 | struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, |
172 | struct list_head *head); |
173 | struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, |
174 | const struct in6_addr *mask, |
175 | struct list_head *head); |
176 | |
177 | #ifdef CONFIG_AUDIT |
178 | void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, |
179 | int src, |
180 | const char *dev, |
181 | const struct in6_addr *addr, |
182 | const struct in6_addr *mask); |
183 | #else |
184 | static inline void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, |
185 | int src, |
186 | const char *dev, |
187 | const struct in6_addr *addr, |
188 | const struct in6_addr *mask) |
189 | { |
190 | } |
191 | #endif |
192 | #endif /* IPV6 */ |
193 | |
194 | #endif |
195 | |