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 */ 47struct 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 */ 62struct 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 72static 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 84static 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(i->next); 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 112int netlbl_af4list_add(struct netlbl_af4list *entry, 113 struct list_head *head); 114struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask, 115 struct list_head *head); 116void netlbl_af4list_remove_entry(struct netlbl_af4list *entry); 117struct netlbl_af4list *netlbl_af4list_search(__be32 addr, 118 struct list_head *head); 119struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, 120 __be32 mask, 121 struct list_head *head); 122 123#ifdef CONFIG_AUDIT 124void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, 125 int src, const char *dev, 126 __be32 addr, __be32 mask); 127#else 128static 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 139static 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 151static 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(i->next); 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 179int netlbl_af6list_add(struct netlbl_af6list *entry, 180 struct list_head *head); 181struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, 182 const struct in6_addr *mask, 183 struct list_head *head); 184void netlbl_af6list_remove_entry(struct netlbl_af6list *entry); 185struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, 186 struct list_head *head); 187struct 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 192void 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 198static 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