netlabel_addrlist.c revision d484ff154c7a9623ecfe4a5ceb91c981fa227476
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 * 982c21bfab41a77bc01affe21bea9727d776774a7Paul Moore * Author: Paul Moore <paul@paul-moore.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 27d484ff154c7a9623ecfe4a5ceb91c981fa227476Jeff Kirsher * along with this program; if not, see <http://www.gnu.org/licenses/>. 2861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 2961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 3061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 3161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/types.h> 3261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/rcupdate.h> 3361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/list.h> 3461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/spinlock.h> 3561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/in.h> 3661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/in6.h> 3761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/ip.h> 3861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <linux/ipv6.h> 3961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <net/ip.h> 4061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include <net/ipv6.h> 4163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore#include <linux/audit.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 7263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/** 7363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af4list_search_exact - Search for an exact IPv4 address entry 7463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IPv4 address 7563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IPv4 address mask 7663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @head: the list head 7763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 7863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description: 7963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Searches the IPv4 address list given by @head. If an exact match if found 8063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * it is returned, otherwise NULL is returned. The caller is responsible for 8163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * calling the rcu_read_[un]lock() functions. 8263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 8363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */ 8463c41688743760631188cf0f4ae986a6793ccb0aPaul Moorestruct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, 8563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore __be32 mask, 8663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore struct list_head *head) 8763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{ 8863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore struct netlbl_af4list *iter; 8963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 9063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore list_for_each_entry_rcu(iter, head, list) 9163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (iter->valid && iter->addr == addr && iter->mask == mask) 9263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore return iter; 9363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 9463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore return NULL; 9563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore} 9663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 9763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 98dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6) 9961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 10061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_search - Search for a matching IPv6 address entry 10161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IPv6 address 10261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 10361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 10461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 10561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Searches the IPv6 address list given by @head. If a matching address entry 10661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * is found it is returned, otherwise NULL is returned. The caller is 10761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * responsible for calling the rcu_read_[un]lock() functions. 10861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 10961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 11061e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, 11161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 11261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 11361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *iter; 11461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 11561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 11661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 11761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0) 11861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return iter; 11961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 12061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return NULL; 12161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 12263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 12363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/** 12463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af6list_search_exact - Search for an exact IPv6 address entry 12563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IPv6 address 12663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IPv6 address mask 12763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @head: the list head 12863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 12963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description: 13063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Searches the IPv6 address list given by @head. If an exact match if found 13163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * it is returned, otherwise NULL is returned. The caller is responsible for 13263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * calling the rcu_read_[un]lock() functions. 13363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 13463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */ 13563c41688743760631188cf0f4ae986a6793ccb0aPaul Moorestruct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, 13663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore const struct in6_addr *mask, 13763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore struct list_head *head) 13863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{ 13963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore struct netlbl_af6list *iter; 14063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 14163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore list_for_each_entry_rcu(iter, head, list) 14263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (iter->valid && 14363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore ipv6_addr_equal(&iter->addr, addr) && 14463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore ipv6_addr_equal(&iter->mask, mask)) 14563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore return iter; 14663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 14763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore return NULL; 14863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore} 14961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 15061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 15161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 15261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_add - Add a new IPv4 address entry to a list 15361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 15461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 15561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 15661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 15761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head. On success zero is 15861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned. The caller is responsible 15961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions. 16061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 16161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 16261e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head) 16361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 16461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af4list *iter; 16561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 16661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter = netlbl_af4list_search(entry->addr, head); 16761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter != NULL && 16861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->addr == entry->addr && iter->mask == entry->mask) 16961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return -EEXIST; 17061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 17161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore /* in order to speed up address searches through the list (the common 17261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * case) we need to keep the list in order based on the size of the 17361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * address mask such that the entry with the widest mask (smallest 17461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * numerical value) appears first in the list */ 17561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 17661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 17761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ntohl(entry->mask) > ntohl(iter->mask)) { 17861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore __list_add_rcu(&entry->list, 17961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->list.prev, 18061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore &iter->list); 18161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 18261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 18361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_add_tail_rcu(&entry->list, head); 18461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 18561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 18661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 187dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6) 18861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 18961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_add - Add a new IPv6 address entry to a list 19061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 19161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 19261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 19361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 19461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head. On success zero is 19561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned. The caller is responsible 19661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions. 19761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 19861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 19961e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head) 20061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 20161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *iter; 20261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 20361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter = netlbl_af6list_search(&entry->addr, head); 20461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter != NULL && 20561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&iter->addr, &entry->addr) && 20661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_equal(&iter->mask, &entry->mask)) 20761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return -EEXIST; 20861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 20961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore /* in order to speed up address searches through the list (the common 21061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * case) we need to keep the list in order based on the size of the 21161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * address mask such that the entry with the widest mask (smallest 21261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * numerical value) appears first in the list */ 21361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_for_each_entry_rcu(iter, head, list) 21461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore if (iter->valid && 21561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) { 21661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore __list_add_rcu(&entry->list, 21761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore iter->list.prev, 21861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore &iter->list); 21961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 22061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore } 22161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_add_tail_rcu(&entry->list, head); 22261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore return 0; 22361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 22461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 22561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 22661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 22761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove_entry - Remove an IPv4 address entry 22861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 22961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 23061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 23161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry. The caller is responsible for 23261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions. 23361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 23461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 23561e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af4list_remove_entry(struct netlbl_af4list *entry) 23661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 23761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry->valid = 0; 23861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_del_rcu(&entry->list); 23961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 24061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 24161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 24261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove - Remove an IPv4 address entry 24361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address 24461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask 24561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 24661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 24761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 24861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head. Returns the 24961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure. The caller is responsible for calling 25061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions. 25161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 25261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 25361e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask, 25461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 25561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 25661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af4list *entry; 25761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 25850b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore entry = netlbl_af4list_search_exact(addr, mask, head); 25950b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore if (entry == NULL) 26050b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore return NULL; 26150b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore netlbl_af4list_remove_entry(entry); 26250b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore return entry; 26361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 26461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 265dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6) 26661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 26761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove_entry - Remove an IPv6 address entry 26861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry 26961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 27061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 27161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry. The caller is responsible for 27261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions. 27361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 27461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 27561e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af6list_remove_entry(struct netlbl_af6list *entry) 27661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 27761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore entry->valid = 0; 27861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore list_del_rcu(&entry->list); 27961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 28061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 28161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/** 28261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove - Remove an IPv6 address entry 28361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address 28461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask 28561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head 28661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 28761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description: 28861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head. Returns the 28961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure. The caller is responsible for calling 29061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions. 29161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * 29261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */ 29361e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, 29461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore const struct in6_addr *mask, 29561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct list_head *head) 29661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{ 29761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore struct netlbl_af6list *entry; 29861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore 29950b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore entry = netlbl_af6list_search_exact(addr, mask, head); 30050b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore if (entry == NULL) 30150b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore return NULL; 30250b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore netlbl_af6list_remove_entry(entry); 30350b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore return entry; 30461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore} 30561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */ 30663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 30763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/* 30863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Audit Helper Functions 30963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */ 31063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 31147b676c0e03dcfd88de91f6f24a06653cfdf32afManish Katiyar#ifdef CONFIG_AUDIT 31263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/** 31363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af4list_audit_addr - Audit an IPv4 address 31463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @audit_buf: audit buffer 31563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @src: true if source address, false if destination 31663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @dev: network interface 31763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IP address 31863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IP address mask 31963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 32063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description: 32163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Write the IPv4 address and address mask, if necessary, to @audit_buf. 32263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 32363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */ 32463c41688743760631188cf0f4ae986a6793ccb0aPaul Moorevoid netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, 32563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore int src, const char *dev, 32663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore __be32 addr, __be32 mask) 32763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{ 32863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore u32 mask_val = ntohl(mask); 32963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore char *dir = (src ? "src" : "dst"); 33063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 33163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (dev != NULL) 33263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore audit_log_format(audit_buf, " netif=%s", dev); 33321454aaad30651ba0dcc16fe5271bc12ee21f132Harvey Harrison audit_log_format(audit_buf, " %s=%pI4", dir, &addr); 33463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (mask_val != 0xffffffff) { 33563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore u32 mask_len = 0; 33663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore while (mask_val > 0) { 33763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_val <<= 1; 33863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_len++; 33963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore } 34063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len); 34163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore } 34263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore} 34363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 344dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6) 34563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/** 34663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af6list_audit_addr - Audit an IPv6 address 34763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @audit_buf: audit buffer 34863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @src: true if source address, false if destination 34963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @dev: network interface 35063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IP address 35163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IP address mask 35263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 35363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description: 35463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Write the IPv6 address and address mask, if necessary, to @audit_buf. 35563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * 35663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */ 35763c41688743760631188cf0f4ae986a6793ccb0aPaul Moorevoid netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, 35863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore int src, 35963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore const char *dev, 36063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore const struct in6_addr *addr, 36163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore const struct in6_addr *mask) 36263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{ 36363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore char *dir = (src ? "src" : "dst"); 36463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore 36563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (dev != NULL) 36663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore audit_log_format(audit_buf, " netif=%s", dev); 3675b095d98928fdb9e3b75be20a54b7a6cbf6ca9adHarvey Harrison audit_log_format(audit_buf, " %s=%pI6", dir, addr); 36863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore if (ntohl(mask->s6_addr32[3]) != 0xffffffff) { 36963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore u32 mask_len = 0; 37063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore u32 mask_val; 37163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore int iter = -1; 37263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff) 37363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_len += 32; 37463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_val = ntohl(mask->s6_addr32[iter]); 37563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore while (mask_val > 0) { 37663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_val <<= 1; 37763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore mask_len++; 37863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore } 37963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len); 38063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore } 38163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore} 38263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore#endif /* IPv6 */ 38347b676c0e03dcfd88de91f6f24a06653cfdf32afManish Katiyar#endif /* CONFIG_AUDIT */ 384