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