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