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.moore@hp.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, write to the Free Software 28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29 * 30 */ 31 32 #ifndef _NETLABEL_ADDRLIST_H 33 #define _NETLABEL_ADDRLIST_H 34 35 #include <linux/types.h> 36 #include <linux/rcupdate.h> 37 #include <linux/list.h> 38 #include <linux/in6.h> 39 #include <linux/audit.h> 40 41 /** 42 * struct netlbl_af4list - NetLabel IPv4 address list 43 * @addr: IPv4 address 44 * @mask: IPv4 address mask 45 * @valid: valid flag 46 * @list: list structure, used internally 47 */ 48 struct netlbl_af4list { 49 __be32 addr; 50 __be32 mask; 51 52 u32 valid; 53 struct list_head list; 54 }; 55 56 /** 57 * struct netlbl_af6list - NetLabel IPv6 address list 58 * @addr: IPv6 address 59 * @mask: IPv6 address mask 60 * @valid: valid flag 61 * @list: list structure, used internally 62 */ 63 struct netlbl_af6list { 64 struct in6_addr addr; 65 struct in6_addr mask; 66 67 u32 valid; 68 struct list_head list; 69 }; 70 71 #define __af4list_entry(ptr) container_of(ptr, struct netlbl_af4list, list) 72 73 static inline struct netlbl_af4list *__af4list_valid(struct list_head *s, 74 struct list_head *h) 75 { 76 struct list_head *i = s; 77 struct netlbl_af4list *n = __af4list_entry(s); 78 while (i != h && !n->valid) { 79 i = i->next; 80 n = __af4list_entry(i); 81 } 82 return n; 83 } 84 85 static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s, 86 struct list_head *h) 87 { 88 struct list_head *i = s; 89 struct netlbl_af4list *n = __af4list_entry(s); 90 while (i != h && !n->valid) { 91 i = rcu_dereference(i->next); 92 n = __af4list_entry(i); 93 } 94 return n; 95 } 96 97 #define netlbl_af4list_foreach(iter, head) \ 98 for (iter = __af4list_valid((head)->next, head); \ 99 prefetch(iter->list.next), &iter->list != (head); \ 100 iter = __af4list_valid(iter->list.next, head)) 101 102 #define netlbl_af4list_foreach_rcu(iter, head) \ 103 for (iter = __af4list_valid_rcu((head)->next, head); \ 104 prefetch(iter->list.next), &iter->list != (head); \ 105 iter = __af4list_valid_rcu(iter->list.next, head)) 106 107 #define netlbl_af4list_foreach_safe(iter, tmp, head) \ 108 for (iter = __af4list_valid((head)->next, head), \ 109 tmp = __af4list_valid(iter->list.next, head); \ 110 &iter->list != (head); \ 111 iter = tmp, tmp = __af4list_valid(iter->list.next, head)) 112 113 int netlbl_af4list_add(struct netlbl_af4list *entry, 114 struct list_head *head); 115 struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask, 116 struct list_head *head); 117 void netlbl_af4list_remove_entry(struct netlbl_af4list *entry); 118 struct netlbl_af4list *netlbl_af4list_search(__be32 addr, 119 struct list_head *head); 120 struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, 121 __be32 mask, 122 struct list_head *head); 123 124 #ifdef CONFIG_AUDIT 125 void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, 126 int src, const char *dev, 127 __be32 addr, __be32 mask); 128 #else 129 static inline void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, 130 int src, const char *dev, 131 __be32 addr, __be32 mask) 132 { 133 return; 134 } 135 #endif 136 137 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 138 139 #define __af6list_entry(ptr) container_of(ptr, struct netlbl_af6list, list) 140 141 static inline struct netlbl_af6list *__af6list_valid(struct list_head *s, 142 struct list_head *h) 143 { 144 struct list_head *i = s; 145 struct netlbl_af6list *n = __af6list_entry(s); 146 while (i != h && !n->valid) { 147 i = i->next; 148 n = __af6list_entry(i); 149 } 150 return n; 151 } 152 153 static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s, 154 struct list_head *h) 155 { 156 struct list_head *i = s; 157 struct netlbl_af6list *n = __af6list_entry(s); 158 while (i != h && !n->valid) { 159 i = rcu_dereference(i->next); 160 n = __af6list_entry(i); 161 } 162 return n; 163 } 164 165 #define netlbl_af6list_foreach(iter, head) \ 166 for (iter = __af6list_valid((head)->next, head); \ 167 prefetch(iter->list.next), &iter->list != (head); \ 168 iter = __af6list_valid(iter->list.next, head)) 169 170 #define netlbl_af6list_foreach_rcu(iter, head) \ 171 for (iter = __af6list_valid_rcu((head)->next, head); \ 172 prefetch(iter->list.next), &iter->list != (head); \ 173 iter = __af6list_valid_rcu(iter->list.next, head)) 174 175 #define netlbl_af6list_foreach_safe(iter, tmp, head) \ 176 for (iter = __af6list_valid((head)->next, head), \ 177 tmp = __af6list_valid(iter->list.next, head); \ 178 &iter->list != (head); \ 179 iter = tmp, tmp = __af6list_valid(iter->list.next, head)) 180 181 int netlbl_af6list_add(struct netlbl_af6list *entry, 182 struct list_head *head); 183 struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, 184 const struct in6_addr *mask, 185 struct list_head *head); 186 void netlbl_af6list_remove_entry(struct netlbl_af6list *entry); 187 struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, 188 struct list_head *head); 189 struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, 190 const struct in6_addr *mask, 191 struct list_head *head); 192 193 #ifdef CONFIG_AUDIT 194 void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, 195 int src, 196 const char *dev, 197 const struct in6_addr *addr, 198 const struct in6_addr *mask); 199 #else 200 static inline void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, 201 int src, 202 const char *dev, 203 const struct in6_addr *addr, 204 const struct in6_addr *mask) 205 { 206 return; 207 } 208 #endif 209 #endif /* IPV6 */ 210 211 #endif 212