netlabel_addrlist.c revision 61e1068219950c672ce979719ad2be3aadb00d7d
161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/* 261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * NetLabel Network Address Lists 361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * This file contains network address list functions used to manage ordered 561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * lists of network addresses for use by the NetLabel subsystem. The NetLabel 661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * system manages static and dynamic label mappings for network protocols such 761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * as CIPSO and RIPSO. 861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Author: Paul Moore <paul.moore@hp.com> 1061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 1161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 1261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 1361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/* 1461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * (c) Copyright Hewlett-Packard Development Company, L.P., 2008 1561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 1661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * This program is free software; you can redistribute it and/or modify 1761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * it under the terms of the GNU General Public License as published by 1861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the Free Software Foundation; either version 2 of the License, or 1961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * (at your option) any later version. 2061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 2161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * This program is distributed in the hope that it will be useful, 2261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * but WITHOUT ANY WARRANTY; without even the implied warranty of 2361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 2461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the GNU General Public License for more details. 2561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 2661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * You should have received a copy of the GNU General Public License 2761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * along with this program; if not, write to the Free Software 2861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 3061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 3161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 3261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/types.h> 3361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/rcupdate.h> 3461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/list.h> 3561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/spinlock.h> 3661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/in.h> 3761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/in6.h> 3861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/ip.h> 3961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/ipv6.h> 4061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <net/ip.h> 4161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <net/ipv6.h> 4261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 4361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include "netlabel_addrlist.h" 4461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 4561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/* 4661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Address List Functions 4761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 4861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 4961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 5061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_search - Search for a matching IPv4 address entry 5161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IPv4 address 5261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 5361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 5461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 5561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Searches the IPv4 address list given by @head. If a matching address entry 5661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * is found it is returned, otherwise NULL is returned. The caller is 5761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * responsible for calling the rcu_read_[un]lock() functions. 5861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 5961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 6061e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af4list *netlbl_af4list_search(__be32 addr, 6161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 6261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 6361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af4list *iter; 6461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 6561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 6661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && (addr & iter->mask) == iter->addr) 6761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return iter; 6861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 6961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return NULL; 7061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 7161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 7261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 7361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 7461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_search - Search for a matching IPv6 address entry 7561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IPv6 address 7661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 7761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 7861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 7961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Searches the IPv6 address list given by @head. If a matching address entry 8061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * is found it is returned, otherwise NULL is returned. The caller is 8161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * responsible for calling the rcu_read_[un]lock() functions. 8261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 8361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 8461e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, 8561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 8661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 8761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *iter; 8861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 8961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 9061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 9161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0) 9261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return iter; 9361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 9461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return NULL; 9561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 9661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 9761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 9861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 9961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_add - Add a new IPv4 address entry to a list 10061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 10161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 10261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 10361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 10461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head. On success zero is 10561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned. The caller is responsible 10661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions. 10761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 10861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 10961e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head) 11061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 11161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af4list *iter; 11261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 11361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter = netlbl_af4list_search(entry->addr, head); 11461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter != NULL && 11561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->addr == entry->addr && iter->mask == entry->mask) 11661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return -EEXIST; 11761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 11861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore /* in order to speed up address searches through the list (the common 11961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * case) we need to keep the list in order based on the size of the 12061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * address mask such that the entry with the widest mask (smallest 12161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * numerical value) appears first in the list */ 12261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 12361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 12461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ntohl(entry->mask) > ntohl(iter->mask)) { 12561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore __list_add_rcu(&entry->list, 12661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->list.prev, 12761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore &iter->list); 12861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 12961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 13061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_add_tail_rcu(&entry->list, head); 13161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 13261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 13361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 13461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 13561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 13661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_add - Add a new IPv6 address entry to a list 13761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 13861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 13961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 14061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 14161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head. On success zero is 14261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned. The caller is responsible 14361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions. 14461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 14561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 14661e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head) 14761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 14861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *iter; 14961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 15061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter = netlbl_af6list_search(&entry->addr, head); 15161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter != NULL && 15261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&iter->addr, &entry->addr) && 15361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&iter->mask, &entry->mask)) 15461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return -EEXIST; 15561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 15661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore /* in order to speed up address searches through the list (the common 15761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * case) we need to keep the list in order based on the size of the 15861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * address mask such that the entry with the widest mask (smallest 15961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * numerical value) appears first in the list */ 16061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 16161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 16261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) { 16361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore __list_add_rcu(&entry->list, 16461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->list.prev, 16561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore &iter->list); 16661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 16761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 16861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_add_tail_rcu(&entry->list, head); 16961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 17061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 17161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 17261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 17361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 17461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove_entry - Remove an IPv4 address entry 17561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 17661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 17761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 17861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry. The caller is responsible for 17961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions. 18061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 18161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 18261e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af4list_remove_entry(struct netlbl_af4list *entry) 18361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 18461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry->valid = 0; 18561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_del_rcu(&entry->list); 18661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 18761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 18861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 18961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove - Remove an IPv4 address entry 19061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address 19161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask 19261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 19361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 19461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 19561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head. Returns the 19661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure. The caller is responsible for calling 19761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions. 19861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 19961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 20061e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask, 20161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 20261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 20361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af4list *entry; 20461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 20561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry = netlbl_af4list_search(addr, head); 20661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (entry != NULL && entry->addr == addr && entry->mask == mask) { 20761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore netlbl_af4list_remove_entry(entry); 20861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return entry; 20961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 21061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 21161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return NULL; 21261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 21361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 21461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 21561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 21661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove_entry - Remove an IPv6 address entry 21761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 21861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 21961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 22061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry. The caller is responsible for 22161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions. 22261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 22361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 22461e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af6list_remove_entry(struct netlbl_af6list *entry) 22561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 22661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry->valid = 0; 22761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_del_rcu(&entry->list); 22861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 22961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 23061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 23161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove - Remove an IPv6 address entry 23261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address 23361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask 23461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 23561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 23661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 23761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head. Returns the 23861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure. The caller is responsible for calling 23961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions. 24061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 24161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 24261e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, 24361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore const struct in6_addr *mask, 24461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 24561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 24661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *entry; 24761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 24861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry = netlbl_af6list_search(addr, head); 24961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (entry != NULL && 25061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&entry->addr, addr) && 25161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&entry->mask, mask)) { 25261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore netlbl_af6list_remove_entry(entry); 25361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return entry; 25461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 25561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 25661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return NULL; 25761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 25861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 259