Commit | Line | Data |
---|---|---|
1ccea77e | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
61e10682 PM |
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 | * | |
82c21bfa | 10 | * Author: Paul Moore <paul@paul-moore.com> |
61e10682 PM |
11 | */ |
12 | ||
13 | /* | |
14 | * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 | |
61e10682 PM |
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> | |
63c41688 | 24 | #include <linux/audit.h> |
61e10682 PM |
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) { | |
17e48577 | 76 | i = rcu_dereference(list_next_rcu(i)); |
61e10682 PM |
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); \ | |
a1e4891f | 84 | &iter->list != (head); \ |
61e10682 PM |
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); \ | |
a1e4891f | 89 | &iter->list != (head); \ |
61e10682 PM |
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); | |
63c41688 PM |
105 | struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, |
106 | __be32 mask, | |
107 | struct list_head *head); | |
47b676c0 MK |
108 | |
109 | #ifdef CONFIG_AUDIT | |
63c41688 PM |
110 | void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, |
111 | int src, const char *dev, | |
112 | __be32 addr, __be32 mask); | |
47b676c0 MK |
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 | { | |
47b676c0 MK |
118 | } |
119 | #endif | |
61e10682 | 120 | |
dfd56b8b | 121 | #if IS_ENABLED(CONFIG_IPV6) |
61e10682 PM |
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) { | |
17e48577 | 143 | i = rcu_dereference(list_next_rcu(i)); |
61e10682 PM |
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); \ | |
a1e4891f | 151 | &iter->list != (head); \ |
61e10682 PM |
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); \ | |
a1e4891f | 156 | &iter->list != (head); \ |
61e10682 PM |
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); | |
63c41688 PM |
173 | struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, |
174 | const struct in6_addr *mask, | |
175 | struct list_head *head); | |
47b676c0 MK |
176 | |
177 | #ifdef CONFIG_AUDIT | |
63c41688 PM |
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); | |
47b676c0 MK |
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 | { | |
47b676c0 MK |
190 | } |
191 | #endif | |
61e10682 PM |
192 | #endif /* IPV6 */ |
193 | ||
194 | #endif |