netlabel_addrlist.c revision dfd56b8b38fff3586f36232db58e1e9f7885a605
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
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>
4263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore#include <linux/audit.h>
4361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
4461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#include "netlabel_addrlist.h"
4561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
4661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/*
4761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Address List Functions
4861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
4961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
5061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
5161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_search - Search for a matching IPv4 address entry
5261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IPv4 address
5361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
5461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
5561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
5661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Searches the IPv4 address list given by @head.  If a matching address entry
5761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * is found it is returned, otherwise NULL is returned.  The caller is
5861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * responsible for calling the rcu_read_[un]lock() functions.
5961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
6061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
6161e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af4list *netlbl_af4list_search(__be32 addr,
6261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore					     struct list_head *head)
6361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
6461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af4list *iter;
6561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
6661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_for_each_entry_rcu(iter, head, list)
6761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		if (iter->valid && (addr & iter->mask) == iter->addr)
6861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			return iter;
6961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
7061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	return NULL;
7161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
7261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
7363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/**
7463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af4list_search_exact - Search for an exact IPv4 address entry
7563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IPv4 address
7663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IPv4 address mask
7763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @head: the list head
7863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
7963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description:
8063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Searches the IPv4 address list given by @head.  If an exact match if found
8163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * it is returned, otherwise NULL is returned.  The caller is responsible for
8263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * calling the rcu_read_[un]lock() functions.
8363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
8463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */
8563c41688743760631188cf0f4ae986a6793ccb0aPaul Moorestruct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
8663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore						   __be32 mask,
8763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore						   struct list_head *head)
8863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{
8963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	struct netlbl_af4list *iter;
9063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
9163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	list_for_each_entry_rcu(iter, head, list)
9263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		if (iter->valid && iter->addr == addr && iter->mask == mask)
9363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			return iter;
9463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
9563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	return NULL;
9663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore}
9763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
9863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
99dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6)
10061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
10161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_search - Search for a matching IPv6 address entry
10261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IPv6 address
10361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
10461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
10561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
10661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Searches the IPv6 address list given by @head.  If a matching address entry
10761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * is found it is returned, otherwise NULL is returned.  The caller is
10861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * responsible for calling the rcu_read_[un]lock() functions.
10961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
11061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
11161e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
11261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore					     struct list_head *head)
11361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
11461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af6list *iter;
11561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
11661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_for_each_entry_rcu(iter, head, list)
11761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		if (iter->valid &&
11861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		    ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
11961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			return iter;
12061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
12161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	return NULL;
12261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
12363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
12463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/**
12563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af6list_search_exact - Search for an exact IPv6 address entry
12663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IPv6 address
12763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IPv6 address mask
12863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @head: the list head
12963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
13063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description:
13163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Searches the IPv6 address list given by @head.  If an exact match if found
13263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * it is returned, otherwise NULL is returned.  The caller is responsible for
13363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * calling the rcu_read_[un]lock() functions.
13463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
13563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */
13663c41688743760631188cf0f4ae986a6793ccb0aPaul Moorestruct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
13763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore						   const struct in6_addr *mask,
13863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore						   struct list_head *head)
13963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{
14063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	struct netlbl_af6list *iter;
14163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
14263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	list_for_each_entry_rcu(iter, head, list)
14363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		if (iter->valid &&
14463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		    ipv6_addr_equal(&iter->addr, addr) &&
14563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		    ipv6_addr_equal(&iter->mask, mask))
14663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			return iter;
14763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
14863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	return NULL;
14963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore}
15061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */
15161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
15261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
15361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_add - Add a new IPv4 address entry to a list
15461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry
15561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
15661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
15761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
15861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head.  On success zero is
15961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned.  The caller is responsible
16061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions.
16161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
16261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
16361e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head)
16461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
16561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af4list *iter;
16661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
16761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	iter = netlbl_af4list_search(entry->addr, head);
16861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	if (iter != NULL &&
16961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	    iter->addr == entry->addr && iter->mask == entry->mask)
17061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		return -EEXIST;
17161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
17261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	/* in order to speed up address searches through the list (the common
17361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * case) we need to keep the list in order based on the size of the
17461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * address mask such that the entry with the widest mask (smallest
17561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * numerical value) appears first in the list */
17661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_for_each_entry_rcu(iter, head, list)
17761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		if (iter->valid &&
17861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		    ntohl(entry->mask) > ntohl(iter->mask)) {
17961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			__list_add_rcu(&entry->list,
18061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore				       iter->list.prev,
18161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore				       &iter->list);
18261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			return 0;
18361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		}
18461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_add_tail_rcu(&entry->list, head);
18561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	return 0;
18661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
18761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
188dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6)
18961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
19061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_add - Add a new IPv6 address entry to a list
19161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry
19261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
19361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
19461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
19561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Add a new address entry to the list pointed to by @head.  On success zero is
19661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * returned, otherwise a negative value is returned.  The caller is responsible
19761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * for calling the necessary locking functions.
19861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
19961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
20061e1068219950c672ce979719ad2be3aadb00d7dPaul Mooreint netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head)
20161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
20261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af6list *iter;
20361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
20461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	iter = netlbl_af6list_search(&entry->addr, head);
20561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	if (iter != NULL &&
20661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	    ipv6_addr_equal(&iter->addr, &entry->addr) &&
20761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	    ipv6_addr_equal(&iter->mask, &entry->mask))
20861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		return -EEXIST;
20961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
21061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	/* in order to speed up address searches through the list (the common
21161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * case) we need to keep the list in order based on the size of the
21261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * address mask such that the entry with the widest mask (smallest
21361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	 * numerical value) appears first in the list */
21461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_for_each_entry_rcu(iter, head, list)
21561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		if (iter->valid &&
21661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		    ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
21761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			__list_add_rcu(&entry->list,
21861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore				       iter->list.prev,
21961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore				       &iter->list);
22061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore			return 0;
22161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore		}
22261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_add_tail_rcu(&entry->list, head);
22361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	return 0;
22461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
22561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */
22661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
22761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
22861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove_entry - Remove an IPv4 address entry
22961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry
23061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
23161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
23261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry.  The caller is responsible for
23361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions.
23461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
23561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
23661e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af4list_remove_entry(struct netlbl_af4list *entry)
23761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
23861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	entry->valid = 0;
23961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_del_rcu(&entry->list);
24061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
24161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
24261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
24361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af4list_remove - Remove an IPv4 address entry
24461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address
24561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask
24661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
24761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
24861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
24961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head.  Returns the
25061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure.  The caller is responsible for calling
25161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions.
25261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
25361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
25461e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
25561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore					     struct list_head *head)
25661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
25761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af4list *entry;
25861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
25950b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	entry = netlbl_af4list_search_exact(addr, mask, head);
26050b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	if (entry == NULL)
26150b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore		return NULL;
26250b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	netlbl_af4list_remove_entry(entry);
26350b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	return entry;
26461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
26561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
266dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6)
26761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
26861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove_entry - Remove an IPv6 address entry
26961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @entry: address entry
27061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
27161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
27261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove the specified IP address entry.  The caller is responsible for
27361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * calling the necessary locking functions.
27461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
27561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
27661e1068219950c672ce979719ad2be3aadb00d7dPaul Moorevoid netlbl_af6list_remove_entry(struct netlbl_af6list *entry)
27761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
27861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	entry->valid = 0;
27961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	list_del_rcu(&entry->list);
28061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
28161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
28261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore/**
28361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * netlbl_af6list_remove - Remove an IPv6 address entry
28461e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @addr: IP address
28561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @mask: IP address mask
28661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * @head: the list head
28761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
28861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Description:
28961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * Remove an IP address entry from the list pointed to by @head.  Returns the
29061e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * entry on success, NULL on failure.  The caller is responsible for calling
29161e1068219950c672ce979719ad2be3aadb00d7dPaul Moore * the necessary locking functions.
29261e1068219950c672ce979719ad2be3aadb00d7dPaul Moore *
29361e1068219950c672ce979719ad2be3aadb00d7dPaul Moore */
29461e1068219950c672ce979719ad2be3aadb00d7dPaul Moorestruct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
29561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore					     const struct in6_addr *mask,
29661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore					     struct list_head *head)
29761e1068219950c672ce979719ad2be3aadb00d7dPaul Moore{
29861e1068219950c672ce979719ad2be3aadb00d7dPaul Moore	struct netlbl_af6list *entry;
29961e1068219950c672ce979719ad2be3aadb00d7dPaul Moore
30050b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	entry = netlbl_af6list_search_exact(addr, mask, head);
30150b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	if (entry == NULL)
30250b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore		return NULL;
30350b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	netlbl_af6list_remove_entry(entry);
30450b2ff1bc47baacb8e9882b2b2a74b240ddbeecfPaul Moore	return entry;
30561e1068219950c672ce979719ad2be3aadb00d7dPaul Moore}
30661e1068219950c672ce979719ad2be3aadb00d7dPaul Moore#endif /* IPv6 */
30763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
30863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/*
30963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Audit Helper Functions
31063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */
31163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
31247b676c0e03dcfd88de91f6f24a06653cfdf32afManish Katiyar#ifdef CONFIG_AUDIT
31363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/**
31463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af4list_audit_addr - Audit an IPv4 address
31563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @audit_buf: audit buffer
31663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @src: true if source address, false if destination
31763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @dev: network interface
31863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IP address
31963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IP address mask
32063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
32163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description:
32263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Write the IPv4 address and address mask, if necessary, to @audit_buf.
32363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
32463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */
32563c41688743760631188cf0f4ae986a6793ccb0aPaul Moorevoid netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
32663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore					int src, const char *dev,
32763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore					__be32 addr, __be32 mask)
32863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{
32963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	u32 mask_val = ntohl(mask);
33063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	char *dir = (src ? "src" : "dst");
33163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
33263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	if (dev != NULL)
33363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		audit_log_format(audit_buf, " netif=%s", dev);
33421454aaad30651ba0dcc16fe5271bc12ee21f132Harvey Harrison	audit_log_format(audit_buf, " %s=%pI4", dir, &addr);
33563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	if (mask_val != 0xffffffff) {
33663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		u32 mask_len = 0;
33763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		while (mask_val > 0) {
33863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			mask_val <<= 1;
33963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			mask_len++;
34063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		}
34163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
34263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	}
34363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore}
34463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
345dfd56b8b38fff3586f36232db58e1e9f7885a605Eric Dumazet#if IS_ENABLED(CONFIG_IPV6)
34663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore/**
34763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * netlbl_af6list_audit_addr - Audit an IPv6 address
34863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @audit_buf: audit buffer
34963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @src: true if source address, false if destination
35063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @dev: network interface
35163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @addr: IP address
35263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * @mask: IP address mask
35363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
35463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Description:
35563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore * Write the IPv6 address and address mask, if necessary, to @audit_buf.
35663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore *
35763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore */
35863c41688743760631188cf0f4ae986a6793ccb0aPaul Moorevoid netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
35963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore				 int src,
36063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore				 const char *dev,
36163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore				 const struct in6_addr *addr,
36263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore				 const struct in6_addr *mask)
36363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore{
36463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	char *dir = (src ? "src" : "dst");
36563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore
36663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	if (dev != NULL)
36763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		audit_log_format(audit_buf, " netif=%s", dev);
3685b095d98928fdb9e3b75be20a54b7a6cbf6ca9adHarvey Harrison	audit_log_format(audit_buf, " %s=%pI6", dir, addr);
36963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
37063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		u32 mask_len = 0;
37163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		u32 mask_val;
37263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		int iter = -1;
37363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
37463c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			mask_len += 32;
37563c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		mask_val = ntohl(mask->s6_addr32[iter]);
37663c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		while (mask_val > 0) {
37763c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			mask_val <<= 1;
37863c41688743760631188cf0f4ae986a6793ccb0aPaul Moore			mask_len++;
37963c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		}
38063c41688743760631188cf0f4ae986a6793ccb0aPaul Moore		audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
38163c41688743760631188cf0f4ae986a6793ccb0aPaul Moore	}
38263c41688743760631188cf0f4ae986a6793ccb0aPaul Moore}
38363c41688743760631188cf0f4ae986a6793ccb0aPaul Moore#endif /* IPv6 */
38447b676c0e03dcfd88de91f6f24a06653cfdf32afManish Katiyar#endif /* CONFIG_AUDIT */
385