Skip to content

Commit

Permalink
netlabel: Add network address selectors to the NetLabel/LSM domain ma…
Browse files Browse the repository at this point in the history
…pping

This patch extends the NetLabel traffic labeling capabilities to individual
packets based not only on the LSM domain but the by the destination address
as well.  The changes here only affect the core NetLabel infrastructre,
changes to the NetLabel KAPI and individial protocol engines are also
required but are split out into a different patch to ease review.

Signed-off-by: Paul Moore <[email protected]>
Reviewed-by: James Morris <[email protected]>
  • Loading branch information
pcmoore committed Oct 10, 2008
1 parent 61e1068 commit 63c4168
Show file tree
Hide file tree
Showing 9 changed files with 816 additions and 224 deletions.
7 changes: 5 additions & 2 deletions include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -72,8 +72,9 @@ struct cipso_v4_doi;
/* NetLabel NETLINK protocol version
* 1: initial version
* 2: added static labels for unlabeled connections
* 3: network selectors added to the NetLabel/LSM domain mapping
*/
#define NETLBL_PROTO_VERSION 2
#define NETLBL_PROTO_VERSION 3

/* NetLabel NETLINK types/families */
#define NETLBL_NLTYPE_NONE 0
Expand All @@ -87,6 +88,8 @@ struct cipso_v4_doi;
#define NETLBL_NLTYPE_CIPSOV6_NAME "NLBL_CIPSOv6"
#define NETLBL_NLTYPE_UNLABELED 5
#define NETLBL_NLTYPE_UNLABELED_NAME "NLBL_UNLBL"
#define NETLBL_NLTYPE_ADDRSELECT 6
#define NETLBL_NLTYPE_ADDRSELECT_NAME "NLBL_ADRSEL"

/*
* NetLabel - Kernel API for accessing the network packet label mappings.
Expand Down
130 changes: 130 additions & 0 deletions net/netlabel/netlabel_addrlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/ipv6.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/audit.h>

#include "netlabel_addrlist.h"

Expand Down Expand Up @@ -69,6 +70,32 @@ struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
return NULL;
}

/**
* netlbl_af4list_search_exact - Search for an exact IPv4 address entry
* @addr: IPv4 address
* @mask: IPv4 address mask
* @head: the list head
*
* Description:
* Searches the IPv4 address list given by @head. If an exact match if found
* it is returned, otherwise NULL is returned. The caller is responsible for
* calling the rcu_read_[un]lock() functions.
*
*/
struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
__be32 mask,
struct list_head *head)
{
struct netlbl_af4list *iter;

list_for_each_entry_rcu(iter, head, list)
if (iter->valid && iter->addr == addr && iter->mask == mask)
return iter;

return NULL;
}


#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/**
* netlbl_af6list_search - Search for a matching IPv6 address entry
Expand All @@ -93,6 +120,33 @@ struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,

return NULL;
}

/**
* netlbl_af6list_search_exact - Search for an exact IPv6 address entry
* @addr: IPv6 address
* @mask: IPv6 address mask
* @head: the list head
*
* Description:
* Searches the IPv6 address list given by @head. If an exact match if found
* it is returned, otherwise NULL is returned. The caller is responsible for
* calling the rcu_read_[un]lock() functions.
*
*/
struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
const struct in6_addr *mask,
struct list_head *head)
{
struct netlbl_af6list *iter;

list_for_each_entry_rcu(iter, head, list)
if (iter->valid &&
ipv6_addr_equal(&iter->addr, addr) &&
ipv6_addr_equal(&iter->mask, mask))
return iter;

return NULL;
}
#endif /* IPv6 */

/**
Expand Down Expand Up @@ -256,3 +310,79 @@ struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
return NULL;
}
#endif /* IPv6 */

/*
* Audit Helper Functions
*/

/**
* netlbl_af4list_audit_addr - Audit an IPv4 address
* @audit_buf: audit buffer
* @src: true if source address, false if destination
* @dev: network interface
* @addr: IP address
* @mask: IP address mask
*
* Description:
* Write the IPv4 address and address mask, if necessary, to @audit_buf.
*
*/
void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
int src, const char *dev,
__be32 addr, __be32 mask)
{
u32 mask_val = ntohl(mask);
char *dir = (src ? "src" : "dst");

if (dev != NULL)
audit_log_format(audit_buf, " netif=%s", dev);
audit_log_format(audit_buf, " %s=" NIPQUAD_FMT, dir, NIPQUAD(addr));
if (mask_val != 0xffffffff) {
u32 mask_len = 0;
while (mask_val > 0) {
mask_val <<= 1;
mask_len++;
}
audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
}
}

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
/**
* netlbl_af6list_audit_addr - Audit an IPv6 address
* @audit_buf: audit buffer
* @src: true if source address, false if destination
* @dev: network interface
* @addr: IP address
* @mask: IP address mask
*
* Description:
* Write the IPv6 address and address mask, if necessary, to @audit_buf.
*
*/
void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
int src,
const char *dev,
const struct in6_addr *addr,
const struct in6_addr *mask)
{
char *dir = (src ? "src" : "dst");

if (dev != NULL)
audit_log_format(audit_buf, " netif=%s", dev);
audit_log_format(audit_buf, " %s=" NIP6_FMT, dir, NIP6(*addr));
if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
u32 mask_len = 0;
u32 mask_val;
int iter = -1;
while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
mask_len += 32;
mask_val = ntohl(mask->s6_addr32[iter]);
while (mask_val > 0) {
mask_val <<= 1;
mask_len++;
}
audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
}
}
#endif /* IPv6 */
15 changes: 15 additions & 0 deletions net/netlabel/netlabel_addrlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/in6.h>
#include <linux/audit.h>

/**
* struct netlbl_af4list - NetLabel IPv4 address list
Expand Down Expand Up @@ -116,6 +117,12 @@ struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
void netlbl_af4list_remove_entry(struct netlbl_af4list *entry);
struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
struct list_head *head);
struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
__be32 mask,
struct list_head *head);
void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
int src, const char *dev,
__be32 addr, __be32 mask);

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)

Expand Down Expand Up @@ -169,6 +176,14 @@ struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
void netlbl_af6list_remove_entry(struct netlbl_af6list *entry);
struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
struct list_head *head);
struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
const struct in6_addr *mask,
struct list_head *head);
void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
int src,
const char *dev,
const struct in6_addr *addr,
const struct in6_addr *mask);
#endif /* IPV6 */

#endif
Loading

0 comments on commit 63c4168

Please sign in to comment.