linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch net-next v2 1/8] net: introduce generic union inet_addr
       [not found] <1375427674-21735-1-git-send-email-amwang@redhat.com>
@ 2013-08-02  7:14 ` Cong Wang
  2013-08-02 21:50   ` David Miller
  2013-08-02  7:14 ` [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions Cong Wang
  2013-08-02  7:14 ` [Patch net-next v2 8/8] selinux: use generic union inet_addr Cong Wang
  2 siblings, 1 reply; 9+ messages in thread
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Daniel Borkmann, Joe Perches, linux-kernel, Cong Wang

From: Cong Wang <amwang@redhat.com>

Introduce a generic IP address type, union inet_addr, so that
subsystems don't have to use their own definitions. Because
netpoll already defines union inet_addr, just move it to global.
Some of the helper functions will be used by VXLAN IPv6 code too.

This patch also reuses the "%pIS" specifier, to make it accept
union inet_addr instead of struct sockaddr.

Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: Joe Perches <joe@perches.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 Documentation/printk-formats.txt |   20 ++++++------
 drivers/net/netconsole.c         |   22 ++++++-------
 include/linux/netpoll.h          |    9 +-----
 include/net/inet_addr.h          |   62 ++++++++++++++++++++++++++++++++++++++
 lib/vsprintf.c                   |   29 ++++++++----------
 net/core/netpoll.c               |   52 ++++++++++++++-----------------
 net/sctp/associola.c             |    6 ++--
 net/sctp/protocol.c              |    6 ++--
 net/sctp/sm_sideeffect.c         |    2 +-
 net/sctp/socket.c                |    4 +-
 10 files changed, 129 insertions(+), 83 deletions(-)
 create mode 100644 include/net/inet_addr.h

diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt
index 3e8cb73..3521cc9 100644
--- a/Documentation/printk-formats.txt
+++ b/Documentation/printk-formats.txt
@@ -123,15 +123,15 @@ IPv6 addresses:
 
 IPv4/IPv6 addresses (generic, with port, flowinfo, scope):
 
-	%pIS	1.2.3.4		or 0001:0002:0003:0004:0005:0006:0007:0008
-	%piS	001.002.003.004	or 00010002000300040005000600070008
-	%pISc	1.2.3.4		or 1:2:3:4:5:6:7:8
-	%pISpc	1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345
-	%p[Ii]S[pfschnbl]
+	%pIA	1.2.3.4		or 0001:0002:0003:0004:0005:0006:0007:0008
+	%piA	001.002.003.004	or 00010002000300040005000600070008
+	%pIAc	1.2.3.4		or 1:2:3:4:5:6:7:8
+	%pIApc	1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345
+	%p[Ii]A[pfschnbl]
 
 	For printing an IP address without the need to distinguish whether it's
-	of type AF_INET or AF_INET6, a pointer to a valid 'struct sockaddr',
-	specified through 'IS' or 'iS', can be passed to this format specifier.
+	of type AF_INET or AF_INET6, a pointer to a valid 'union inet_addr',
+	specified through 'IA' or 'iA', can be passed to this format specifier.
 
 	The additional 'p', 'f', and 's' specifiers are used to specify port
 	(IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ':' prefix,
@@ -149,9 +149,9 @@ IPv4/IPv6 addresses (generic, with port, flowinfo, scope):
 
 	Further examples:
 
-	%pISfc		1.2.3.4		or [1:2:3:4:5:6:7:8]/123456789
-	%pISsc		1.2.3.4		or [1:2:3:4:5:6:7:8]%1234567890
-	%pISpfc		1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345/123456789
+	%pIAfc		1.2.3.4		or [1:2:3:4:5:6:7:8]/123456789
+	%pIAsc		1.2.3.4		or [1:2:3:4:5:6:7:8]%1234567890
+	%pIApfc		1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345/123456789
 
 UUID/GUID addresses:
 
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 4822aaf..28234f8 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -270,18 +270,12 @@ static ssize_t show_remote_port(struct netconsole_target *nt, char *buf)
 
 static ssize_t show_local_ip(struct netconsole_target *nt, char *buf)
 {
-	if (nt->np.ipv6)
-		return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.local_ip.in6);
-	else
-		return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
+	return snprintf(buf, PAGE_SIZE, "%pIA\n", &nt->np.local_ip);
 }
 
 static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 {
-	if (nt->np.ipv6)
-		return snprintf(buf, PAGE_SIZE, "%pI6c\n", &nt->np.remote_ip.in6);
-	else
-		return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
+	return snprintf(buf, PAGE_SIZE, "%pIA\n", &nt->np.remote_ip);
 }
 
 static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
@@ -419,17 +413,19 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
 
 	if (strnchr(buf, count, ':')) {
 		const char *end;
-		if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
+		if (in6_pton(buf, count, nt->np.local_ip.sin6.sin6_addr.s6_addr, -1, &end) > 0) {
 			if (*end && *end != '\n') {
 				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end);
 				return -EINVAL;
 			}
+			nt->np.local_ip.sa.sa_family = AF_INET6;
 			nt->np.ipv6 = true;
 		} else
 			return -EINVAL;
 	} else {
 		if (!nt->np.ipv6) {
-			nt->np.local_ip.ip = in_aton(buf);
+			nt->np.local_ip.sin.sin_addr.s_addr = in_aton(buf);
+			nt->np.local_ip.sa.sa_family = AF_INET;
 		} else
 			return -EINVAL;
 	}
@@ -450,17 +446,19 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
 
 	if (strnchr(buf, count, ':')) {
 		const char *end;
-		if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
+		if (in6_pton(buf, count, nt->np.remote_ip.sin6.sin6_addr.s6_addr, -1, &end) > 0) {
 			if (*end && *end != '\n') {
 				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end);
 				return -EINVAL;
 			}
+			nt->np.remote_ip.sa.sa_family = AF_INET6;
 			nt->np.ipv6 = true;
 		} else
 			return -EINVAL;
 	} else {
 		if (!nt->np.ipv6) {
-			nt->np.remote_ip.ip = in_aton(buf);
+			nt->np.remote_ip.sin.sin_addr.s_addr = in_aton(buf);
+			nt->np.remote_ip.sa.sa_family = AF_INET;
 		} else
 			return -EINVAL;
 	}
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index f3c7c24..3884834 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -11,14 +11,7 @@
 #include <linux/interrupt.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
-
-union inet_addr {
-	__u32		all[4];
-	__be32		ip;
-	__be32		ip6[4];
-	struct in_addr	in;
-	struct in6_addr	in6;
-};
+#include <net/inet_addr.h>
 
 struct netpoll {
 	struct net_device *dev;
diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
new file mode 100644
index 0000000..66a16fe
--- /dev/null
+++ b/include/net/inet_addr.h
@@ -0,0 +1,62 @@
+#ifndef _INET_ADDR_H
+#define _INET_ADDR_H
+
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#include <net/addrconf.h>
+
+union inet_addr {
+	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
+	struct sockaddr sa;
+};
+
+#if IS_ENABLED(CONFIG_IPV6)
+static inline
+bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
+{
+	if (a->sa.sa_family != b->sa.sa_family)
+		return false;
+	if (a->sa.sa_family == AF_INET6)
+		return ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
+	else
+		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
+}
+
+static inline bool inet_addr_any(const union inet_addr *ipa)
+{
+	if (ipa->sa.sa_family == AF_INET6)
+		return ipv6_addr_any(&ipa->sin6.sin6_addr);
+	else
+		return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
+}
+
+static inline bool inet_addr_multicast(const union inet_addr *ipa)
+{
+	if (ipa->sa.sa_family == AF_INET6)
+		return ipv6_addr_is_multicast(&ipa->sin6.sin6_addr);
+	else
+		return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
+}
+
+#else /* !CONFIG_IPV6 */
+
+static inline
+bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
+{
+	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
+}
+
+static inline bool inet_addr_any(const union inet_addr *ipa)
+{
+	return ipa->sin.sin_addr.s_addr == htonl(INADDR_ANY);
+}
+
+static inline bool inet_addr_multicast(const union inet_addr *ipa)
+{
+	return IN_MULTICAST(ntohl(ipa->sin.sin_addr.s_addr));
+}
+#endif
+
+#endif
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 739a363..49618d0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -27,6 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/ioport.h>
 #include <net/addrconf.h>
+#include <net/inet_addr.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
 #include <asm/sections.h>	/* for dereference_function_descriptor() */
@@ -1104,14 +1105,14 @@ int kptr_restrict __read_mostly;
  * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
  *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
  *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
- *       [S][pfs]
- *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
+ *       [A][pfs]
+ *       Generic IPv4/IPv6 address (union inet_addr *) that falls back to
  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
  * - 'i' [46] for 'raw' IPv4/IPv6 addresses
  *       IPv6 omits the colons (01020304...0f)
  *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
- *       [S][pfs]
- *       Generic IPv4/IPv6 address (struct sockaddr *) that falls back to
+ *       [A][pfs]
+ *       Generic IPv4/IPv6 address (union inet_addr *) that falls back to
  *       [4] or [6] and is able to print port [p], flowinfo [f], scope [s]
  * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order
  * - 'I[6S]c' for IPv6 addresses printed as specified by
@@ -1196,18 +1197,14 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 			return ip6_addr_string(buf, end, ptr, spec, fmt);
 		case '4':
 			return ip4_addr_string(buf, end, ptr, spec, fmt);
-		case 'S': {
-			const union {
-				struct sockaddr		raw;
-				struct sockaddr_in	v4;
-				struct sockaddr_in6	v6;
-			} *sa = ptr;
-
-			switch (sa->raw.sa_family) {
+		case 'A': {
+			const union inet_addr *sa = ptr;
+
+			switch (sa->sa.sa_family) {
 			case AF_INET:
-				return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt);
+				return ip4_addr_string_sa(buf, end, &sa->sin, spec, fmt);
 			case AF_INET6:
-				return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt);
+				return ip6_addr_string_sa(buf, end, &sa->sin6, spec, fmt);
 			default:
 				return string(buf, end, "(invalid address)", spec);
 			}}
@@ -1488,8 +1485,8 @@ qualifier:
  * %pI6 print an IPv6 address with colons
  * %pi6 print an IPv6 address without colons
  * %pI6c print an IPv6 address as specified by RFC 5952
- * %pIS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
- * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address
+ * %pIA depending on sa_family of 'union inet_addr *' print IPv4/IPv6 address
+ * %piA depending on sa_family of 'union inet_addr *' print IPv4/IPv6 address
  * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper
  *   case.
  * %*ph[CDN] a variable-length hex string with a separator (supports up to 64
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 2c637e9..e7d4388 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -456,8 +456,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 
 	if (np->ipv6) {
 		udph->check = 0;
-		udph->check = csum_ipv6_magic(&np->local_ip.in6,
-					      &np->remote_ip.in6,
+		udph->check = csum_ipv6_magic(&np->local_ip.sin6.sin6_addr,
+					      &np->remote_ip.sin6.sin6_addr,
 					      udp_len, IPPROTO_UDP,
 					      csum_partial(udph, udp_len, 0));
 		if (udph->check == 0)
@@ -476,16 +476,16 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 		ip6h->payload_len = htons(sizeof(struct udphdr) + len);
 		ip6h->nexthdr = IPPROTO_UDP;
 		ip6h->hop_limit = 32;
-		ip6h->saddr = np->local_ip.in6;
-		ip6h->daddr = np->remote_ip.in6;
+		ip6h->saddr = np->local_ip.sin6.sin6_addr;
+		ip6h->daddr = np->remote_ip.sin6.sin6_addr;
 
 		eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
 		skb_reset_mac_header(skb);
 		skb->protocol = eth->h_proto = htons(ETH_P_IPV6);
 	} else {
 		udph->check = 0;
-		udph->check = csum_tcpudp_magic(np->local_ip.ip,
-						np->remote_ip.ip,
+		udph->check = csum_tcpudp_magic(np->local_ip.sin.sin_addr.s_addr,
+						np->remote_ip.sin.sin_addr.s_addr,
 						udp_len, IPPROTO_UDP,
 						csum_partial(udph, udp_len, 0));
 		if (udph->check == 0)
@@ -504,8 +504,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 		iph->ttl      = 64;
 		iph->protocol = IPPROTO_UDP;
 		iph->check    = 0;
-		put_unaligned(np->local_ip.ip, &(iph->saddr));
-		put_unaligned(np->remote_ip.ip, &(iph->daddr));
+		put_unaligned(np->local_ip.sin.sin_addr.s_addr, &(iph->saddr));
+		put_unaligned(np->remote_ip.sin.sin_addr.s_addr, &(iph->daddr));
 		iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
 
 		eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
@@ -589,7 +589,7 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
 		spin_lock_irqsave(&npinfo->rx_lock, flags);
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (tip != np->local_ip.ip)
+			if (tip != np->local_ip.sin.sin_addr.s_addr)
 				continue;
 
 			hlen = LL_RESERVED_SPACE(np->dev);
@@ -677,7 +677,7 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
 
 		spin_lock_irqsave(&npinfo->rx_lock, flags);
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (!ipv6_addr_equal(daddr, &np->local_ip.in6))
+			if (!ipv6_addr_equal(daddr, &np->local_ip.sin6.sin6_addr))
 				continue;
 
 			hlen = LL_RESERVED_SPACE(np->dev);
@@ -827,9 +827,11 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 		if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr))
 			goto out;
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (np->local_ip.ip && np->local_ip.ip != iph->daddr)
+			__be32 daddr = np->local_ip.sin.sin_addr.s_addr;
+			__be32 saddr = np->remote_ip.sin.sin_addr.s_addr;
+			if (daddr && daddr != iph->daddr)
 				continue;
-			if (np->remote_ip.ip && np->remote_ip.ip != iph->saddr)
+			if (saddr && saddr != iph->saddr)
 				continue;
 			if (np->local_port && np->local_port != ntohs(uh->dest))
 				continue;
@@ -865,9 +867,9 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo)
 		if (udp6_csum_init(skb, uh, IPPROTO_UDP))
 			goto out;
 		list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) {
-			if (!ipv6_addr_equal(&np->local_ip.in6, &ip6h->daddr))
+			if (!ipv6_addr_equal(&np->local_ip.sin6.sin6_addr, &ip6h->daddr))
 				continue;
-			if (!ipv6_addr_equal(&np->remote_ip.in6, &ip6h->saddr))
+			if (!ipv6_addr_equal(&np->remote_ip.sin6.sin6_addr, &ip6h->saddr))
 				continue;
 			if (np->local_port && np->local_port != ntohs(uh->dest))
 				continue;
@@ -898,16 +900,10 @@ out:
 void netpoll_print_options(struct netpoll *np)
 {
 	np_info(np, "local port %d\n", np->local_port);
-	if (np->ipv6)
-		np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6);
-	else
-		np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip);
+	np_info(np, "local IPv6 address %pIA\n", &np->local_ip);
 	np_info(np, "interface '%s'\n", np->dev_name);
 	np_info(np, "remote port %d\n", np->remote_port);
-	if (np->ipv6)
-		np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6);
-	else
-		np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip);
+	np_info(np, "remote IPv6 address %pIA\n", &np->remote_ip);
 	np_info(np, "remote ethernet address %pM\n", np->remote_mac);
 }
 EXPORT_SYMBOL(netpoll_print_options);
@@ -921,7 +917,7 @@ static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr)
 		if (!*end)
 			return 0;
 	}
-	if (in6_pton(str, -1, addr->in6.s6_addr, -1, &end) > 0) {
+	if (in6_pton(str, -1, addr->sin6.sin6_addr.s6_addr, -1, &end) > 0) {
 #if IS_ENABLED(CONFIG_IPV6)
 		if (!*end)
 			return 1;
@@ -1140,7 +1136,7 @@ int netpoll_setup(struct netpoll *np)
 		rtnl_lock();
 	}
 
-	if (!np->local_ip.ip) {
+	if (!np->local_ip.sin.sin_addr.s_addr) {
 		if (!np->ipv6) {
 			in_dev = __in_dev_get_rtnl(ndev);
 
@@ -1151,8 +1147,8 @@ int netpoll_setup(struct netpoll *np)
 				goto put;
 			}
 
-			np->local_ip.ip = in_dev->ifa_list->ifa_local;
-			np_info(np, "local IP %pI4\n", &np->local_ip.ip);
+			np->local_ip.sin.sin_addr.s_addr = in_dev->ifa_list->ifa_local;
+			np_info(np, "local IP %pI4\n", &np->local_ip.sin.sin_addr.s_addr);
 		} else {
 #if IS_ENABLED(CONFIG_IPV6)
 			struct inet6_dev *idev;
@@ -1166,7 +1162,7 @@ int netpoll_setup(struct netpoll *np)
 				list_for_each_entry(ifp, &idev->addr_list, if_list) {
 					if (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)
 						continue;
-					np->local_ip.in6 = ifp->addr;
+					np->local_ip.sin6.sin6_addr = ifp->addr;
 					err = 0;
 					break;
 				}
@@ -1177,7 +1173,7 @@ int netpoll_setup(struct netpoll *np)
 				       np->dev_name);
 				goto put;
 			} else
-				np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
+				np_info(np, "local IPv6 %pI6c\n", &np->local_ip.sin6.sin6_addr);
 #else
 			np_err(np, "IPv6 is not supported %s, aborting\n",
 			       np->dev_name);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index e425ba0..07aff2b 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -540,7 +540,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
 	struct list_head	*pos;
 	struct sctp_transport	*transport;
 
-	pr_debug("%s: association:%p addr:%pISpc\n",
+	pr_debug("%s: association:%p addr:%pIApc\n",
 		 __func__, asoc, &peer->ipaddr.sa);
 
 	/* If we are to remove the current retran_path, update it
@@ -637,7 +637,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 	/* AF_INET and AF_INET6 share common port field. */
 	port = ntohs(addr->v4.sin_port);
 
-	pr_debug("%s: association:%p addr:%pISpc state:%d\n", __func__,
+	pr_debug("%s: association:%p addr:%pIApc state:%d\n", __func__,
 		 asoc, &addr->sa, peer_state);
 
 	/* Set the port if it has not been set yet.  */
@@ -1347,7 +1347,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
 	else
 		t = asoc->peer.retran_path;
 
-	pr_debug("%s: association:%p addr:%pISpc\n", __func__, asoc,
+	pr_debug("%s: association:%p addr:%pIApc\n", __func__, asoc,
 		 &t->ipaddr.sa);
 }
 
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index b52ec25..1928862 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -604,7 +604,7 @@ static void sctp_addr_wq_timeout_handler(unsigned long arg)
 	spin_lock_bh(&net->sctp.addr_wq_lock);
 
 	list_for_each_entry_safe(addrw, temp, &net->sctp.addr_waitq, list) {
-		pr_debug("%s: the first ent in wq:%p is addr:%pISc for cmd:%d at "
+		pr_debug("%s: the first ent in wq:%p is addr:%pIAc for cmd:%d at "
 			 "entry:%p\n", __func__, &net->sctp.addr_waitq, &addrw->a.sa,
 			 addrw->state, addrw);
 
@@ -709,7 +709,7 @@ void sctp_addr_wq_mgmt(struct net *net, struct sctp_sockaddr_entry *addr, int cm
 	addrw = sctp_addr_wq_lookup(net, addr);
 	if (addrw) {
 		if (addrw->state != cmd) {
-			pr_debug("%s: offsets existing entry for %d, addr:%pISc "
+			pr_debug("%s: offsets existing entry for %d, addr:%pIAc "
 				 "in wq:%p\n", __func__, addrw->state, &addrw->a.sa,
 				 &net->sctp.addr_waitq);
 
@@ -729,7 +729,7 @@ void sctp_addr_wq_mgmt(struct net *net, struct sctp_sockaddr_entry *addr, int cm
 	addrw->state = cmd;
 	list_add_tail(&addrw->list, &net->sctp.addr_waitq);
 
-	pr_debug("%s: add new entry for cmd:%d, addr:%pISc in wq:%p\n",
+	pr_debug("%s: add new entry for cmd:%d, addr:%pIAc in wq:%p\n",
 		 __func__, addrw->state, &addrw->a.sa, &net->sctp.addr_waitq);
 
 	if (!timer_pending(&net->sctp.addr_wq_timer)) {
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index f1f3aac..fae93e7 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -520,7 +520,7 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands,
 
 	if (transport->state != SCTP_INACTIVE &&
 	    (transport->error_count > transport->pathmaxrxt)) {
-		pr_debug("%s: association:%p transport addr:%pISpc failed\n",
+		pr_debug("%s: association:%p transport addr:%pIApc failed\n",
 			 __func__, asoc, &transport->ipaddr.sa);
 
 		sctp_assoc_control_transport(asoc, transport,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0245712..851093f 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -349,7 +349,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 
 	snum = ntohs(addr->v4.sin_port);
 
-	pr_debug("%s: sk:%p, new addr:%pISc, port:%d, new port:%d, len:%d\n",
+	pr_debug("%s: sk:%p, new addr:%pIAc, port:%d, new port:%d, len:%d\n",
 		 __func__, sk, &addr->sa, bp->port, snum, len);
 
 	/* PF specific bind() address verification. */
@@ -803,7 +803,7 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 				asoc->asconf_addr_del_pending->v6.sin6_addr = sin6->sin6_addr;
 			}
 
-			pr_debug("%s: keep the last address asoc:%p %pISc at %p\n",
+			pr_debug("%s: keep the last address asoc:%p %pIAc at %p\n",
 				 __func__, asoc, &asoc->asconf_addr_del_pending->sa,
 				 asoc->asconf_addr_del_pending);
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions
       [not found] <1375427674-21735-1-git-send-email-amwang@redhat.com>
  2013-08-02  7:14 ` [Patch net-next v2 1/8] net: introduce generic union inet_addr Cong Wang
@ 2013-08-02  7:14 ` Cong Wang
  2013-08-02 10:31   ` [Cluster-devel] " Christoph Hellwig
  2013-08-02  7:14 ` [Patch net-next v2 8/8] selinux: use generic union inet_addr Cong Wang
  2 siblings, 1 reply; 9+ messages in thread
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Steve French, Christine Caulfield,
	David Teigland, Trond Myklebust, linux-cifs, linux-kernel,
	cluster-devel, linux-nfs, Cong Wang

From: Cong Wang <amwang@redhat.com>

nfs and cifs define some helper functions for sockaddr,
they can use the generic functions for union inet_addr too.

Since some dlm code needs to compare ->sin_port, introduce a
generic function inet_addr_equal_strict() for it.

Cc: Steve French <sfrench@samba.org>
Cc: Christine Caulfield <ccaulfie@redhat.com>
Cc: David Teigland <teigland@redhat.com>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: linux-cifs@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: cluster-devel@redhat.com
Cc: linux-nfs@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 fs/cifs/connect.c          |   39 ++++--------------
 fs/dlm/lowcomms.c          |   24 ++---------
 fs/nfs/client.c            |   94 ++-----------------------------------------
 fs/nfs/nfs4filelayoutdev.c |   37 ++---------------
 fs/nfs/super.c             |   31 +-------------
 include/net/inet_addr.h    |    1 +
 net/core/utils.c           |   23 +++++++++++
 7 files changed, 50 insertions(+), 199 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index fa68813..f5c310e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <keys/user-type.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 #include <linux/parser.h>
 
 #include "cifspdu.h"
@@ -1899,17 +1900,10 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
 {
 	switch (srcaddr->sa_family) {
 	case AF_UNSPEC:
-		return (rhs->sa_family == AF_UNSPEC);
-	case AF_INET: {
-		struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
-		struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
-		return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
-	}
-	case AF_INET6: {
-		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
-		struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
-		return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
-	}
+	case AF_INET:
+	case AF_INET6:
+		return inet_addr_equal((union inet_addr *)srcaddr,
+				       (union inet_addr *)rhs);
 	default:
 		WARN_ON(1);
 		return false; /* don't expect to be here */
@@ -1956,27 +1950,12 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
 	      struct sockaddr *srcaddr)
 {
 	switch (addr->sa_family) {
-	case AF_INET: {
-		struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
-		struct sockaddr_in *srv_addr4 =
-					(struct sockaddr_in *)&server->dstaddr;
-
-		if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
-			return false;
-		break;
-	}
-	case AF_INET6: {
-		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
-		struct sockaddr_in6 *srv_addr6 =
-					(struct sockaddr_in6 *)&server->dstaddr;
-
-		if (!ipv6_addr_equal(&addr6->sin6_addr,
-				     &srv_addr6->sin6_addr))
-			return false;
-		if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
+	case AF_INET:
+	case AF_INET6:
+		if (!inet_addr_equal((union inet_addr *)addr,
+				     (union inet_addr *)&server->dstaddr))
 			return false;
 		break;
-	}
 	default:
 		WARN_ON(1);
 		return false; /* don't expect to be here */
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index d90909e..c051237 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -54,6 +54,7 @@
 #include <linux/slab.h>
 #include <net/sctp/sctp.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 
 #include "dlm_internal.h"
 #include "lowcomms.h"
@@ -286,28 +287,13 @@ static struct dlm_node_addr *find_node_addr(int nodeid)
 static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y)
 {
 	switch (x->ss_family) {
-	case AF_INET: {
-		struct sockaddr_in *sinx = (struct sockaddr_in *)x;
-		struct sockaddr_in *siny = (struct sockaddr_in *)y;
-		if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr)
-			return 0;
-		if (sinx->sin_port != siny->sin_port)
-			return 0;
-		break;
-	}
-	case AF_INET6: {
-		struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x;
-		struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y;
-		if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr))
-			return 0;
-		if (sinx->sin6_port != siny->sin6_port)
-			return 0;
-		break;
-	}
+	case AF_INET:
+	case AF_INET6:
+		return inet_addr_equal_strict((union inet_addr *)x,
+					      (union inet_addr *)y);
 	default:
 		return 0;
 	}
-	return 1;
 }
 
 static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 340b1ef..a050be6 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/idr.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/bc_xprt.h>
 #include <linux/nsproxy.h>
@@ -283,75 +284,6 @@ void nfs_put_client(struct nfs_client *clp)
 }
 EXPORT_SYMBOL_GPL(nfs_put_client);
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-/*
- * Test if two ip6 socket addresses refer to the same socket by
- * comparing relevant fields. The padding bytes specifically, are not
- * compared. sin6_flowinfo is not compared because it only affects QoS
- * and sin6_scope_id is only compared if the address is "link local"
- * because "link local" addresses need only be unique to a specific
- * link. Conversely, ordinary unicast addresses might have different
- * sin6_scope_id.
- *
- * The caller should ensure both socket addresses are AF_INET6.
- */
-static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
-				      const struct sockaddr *sa2)
-{
-	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
-	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
-
-	if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
-		return 0;
-	else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-		return sin1->sin6_scope_id == sin2->sin6_scope_id;
-
-	return 1;
-}
-#else	/* !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE) */
-static int nfs_sockaddr_match_ipaddr6(const struct sockaddr *sa1,
-				      const struct sockaddr *sa2)
-{
-	return 0;
-}
-#endif
-
-/*
- * Test if two ip4 socket addresses refer to the same socket, by
- * comparing relevant fields. The padding bytes specifically, are
- * not compared.
- *
- * The caller should ensure both socket addresses are AF_INET.
- */
-static int nfs_sockaddr_match_ipaddr4(const struct sockaddr *sa1,
-				      const struct sockaddr *sa2)
-{
-	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
-	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
-
-	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
-}
-
-static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1,
-				const struct sockaddr *sa2)
-{
-	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sa1;
-	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sa2;
-
-	return nfs_sockaddr_match_ipaddr6(sa1, sa2) &&
-		(sin1->sin6_port == sin2->sin6_port);
-}
-
-static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
-				const struct sockaddr *sa2)
-{
-	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
-	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
-
-	return nfs_sockaddr_match_ipaddr4(sa1, sa2) &&
-		(sin1->sin_port == sin2->sin_port);
-}
-
 #if defined(CONFIG_NFS_V4_1)
 /*
  * Test if two socket addresses represent the same actual socket,
@@ -360,16 +292,8 @@ static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1,
 int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
 			      const struct sockaddr *sa2)
 {
-	if (sa1->sa_family != sa2->sa_family)
-		return 0;
-
-	switch (sa1->sa_family) {
-	case AF_INET:
-		return nfs_sockaddr_match_ipaddr4(sa1, sa2);
-	case AF_INET6:
-		return nfs_sockaddr_match_ipaddr6(sa1, sa2);
-	}
-	return 0;
+	return inet_addr_equal((const union inet_addr *)sa1,
+			       (const union inet_addr *)sa2);
 }
 EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
 #endif /* CONFIG_NFS_V4_1 */
@@ -381,16 +305,8 @@ EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
 static int nfs_sockaddr_cmp(const struct sockaddr *sa1,
 			    const struct sockaddr *sa2)
 {
-	if (sa1->sa_family != sa2->sa_family)
-		return 0;
-
-	switch (sa1->sa_family) {
-	case AF_INET:
-		return nfs_sockaddr_cmp_ip4(sa1, sa2);
-	case AF_INET6:
-		return nfs_sockaddr_cmp_ip6(sa1, sa2);
-	}
-	return 0;
+	return inet_addr_equal_strict((union inet_addr *)sa1,
+				      (union inet_addr *)sa2);
 }
 
 /*
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 95604f6..955494cb 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -32,6 +32,7 @@
 #include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/sunrpc/addr.h>
+#include <net/inet_addr.h>
 
 #include "internal.h"
 #include "nfs4session.h"
@@ -74,44 +75,14 @@ print_ds(struct nfs4_pnfs_ds *ds)
 static bool
 same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
 {
-	struct sockaddr_in *a, *b;
-	struct sockaddr_in6 *a6, *b6;
-
-	if (addr1->sa_family != addr2->sa_family)
-		return false;
-
-	switch (addr1->sa_family) {
-	case AF_INET:
-		a = (struct sockaddr_in *)addr1;
-		b = (struct sockaddr_in *)addr2;
-
-		if (a->sin_addr.s_addr == b->sin_addr.s_addr &&
-		    a->sin_port == b->sin_port)
-			return true;
-		break;
-
-	case AF_INET6:
-		a6 = (struct sockaddr_in6 *)addr1;
-		b6 = (struct sockaddr_in6 *)addr2;
-
-		/* LINKLOCAL addresses must have matching scope_id */
-		if (ipv6_addr_scope(&a6->sin6_addr) ==
-		    IPV6_ADDR_SCOPE_LINKLOCAL &&
-		    a6->sin6_scope_id != b6->sin6_scope_id)
-			return false;
-
-		if (ipv6_addr_equal(&a6->sin6_addr, &b6->sin6_addr) &&
-		    a6->sin6_port == b6->sin6_port)
-			return true;
-		break;
-
-	default:
+	if (addr1->sa_family != AF_INET && addr1->sa_family != AF_INET6) {
 		dprintk("%s: unhandled address family: %u\n",
 			__func__, addr1->sa_family);
 		return false;
 	}
 
-	return false;
+	return inet_addr_equal_strict((union inet_addr *)addr1,
+				      (union inet_addr *)addr2);
 }
 
 static bool
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 71fdc0d..f7d5914 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -49,6 +49,7 @@
 #include <linux/in6.h>
 #include <linux/slab.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 #include <linux/netdevice.h>
 #include <linux/nfs_xdr.h>
 #include <linux/magic.h>
@@ -2335,34 +2336,8 @@ static int nfs_compare_super_address(struct nfs_server *server1,
 
 	sap1 = (struct sockaddr *)&server1->nfs_client->cl_addr;
 	sap2 = (struct sockaddr *)&server2->nfs_client->cl_addr;
-
-	if (sap1->sa_family != sap2->sa_family)
-		return 0;
-
-	switch (sap1->sa_family) {
-	case AF_INET: {
-		struct sockaddr_in *sin1 = (struct sockaddr_in *)sap1;
-		struct sockaddr_in *sin2 = (struct sockaddr_in *)sap2;
-		if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
-			return 0;
-		if (sin1->sin_port != sin2->sin_port)
-			return 0;
-		break;
-	}
-	case AF_INET6: {
-		struct sockaddr_in6 *sin1 = (struct sockaddr_in6 *)sap1;
-		struct sockaddr_in6 *sin2 = (struct sockaddr_in6 *)sap2;
-		if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
-			return 0;
-		if (sin1->sin6_port != sin2->sin6_port)
-			return 0;
-		break;
-	}
-	default:
-		return 0;
-	}
-
-	return 1;
+	return inet_addr_equal_strict((union inet_addr *)sap1,
+				      (union inet_addr *)sap2);
 }
 
 static int nfs_compare_super(struct super_block *sb, void *data)
diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
index e846050..2fab98c 100644
--- a/include/net/inet_addr.h
+++ b/include/net/inet_addr.h
@@ -122,6 +122,7 @@ void inet_addr_set_port(union inet_addr *sap,
 }
 
 bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b);
+bool inet_addr_equal_strict(const union inet_addr *a, const union inet_addr *b);
 int simple_inet_pton(const char *str, union inet_addr *addr);
 
 #endif
diff --git a/net/core/utils.c b/net/core/utils.c
index 837bb18..489bc8d 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -380,6 +380,8 @@ bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
 {
 	if (a->sa.sa_family != b->sa.sa_family)
 		return false;
+	if (a->sa.sa_family == AF_UNSPEC)
+		return true;
 	else if (a->sa.sa_family == AF_INET6) {
 		if (!ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr))
 			return false;
@@ -399,3 +401,24 @@ bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
 }
 #endif
 EXPORT_SYMBOL(inet_addr_equal);
+
+/*
+ * Unlike inet_addr_equal(), this function compares ->sin_port too.
+ */
+bool inet_addr_equal_strict(const union inet_addr *a, const union inet_addr *b)
+{
+	if (inet_addr_equal(a, b)) {
+		switch (a->sa.sa_family) {
+#if IS_ENABLED(CONFIG_IPV6)
+		case AF_INET6:
+			return a->sin6.sin6_port == b->sin6.sin6_port;
+#endif
+		case AF_INET:
+			return a->sin.sin_port == b->sin.sin_port;
+		default:
+			return true;
+		}
+	} else
+		return false;
+}
+EXPORT_SYMBOL(inet_addr_equal_strict);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Patch net-next v2 8/8] selinux: use generic union inet_addr
       [not found] <1375427674-21735-1-git-send-email-amwang@redhat.com>
  2013-08-02  7:14 ` [Patch net-next v2 1/8] net: introduce generic union inet_addr Cong Wang
  2013-08-02  7:14 ` [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions Cong Wang
@ 2013-08-02  7:14 ` Cong Wang
  2013-08-02 14:34   ` Paul Moore
  2 siblings, 1 reply; 9+ messages in thread
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, James Morris, Stephen Smalley, Eric Paris,
	Paul Moore, linux-kernel, linux-security-module, Cong Wang

From: Cong Wang <amwang@redhat.com>

selinux has some similar definition like union inet_addr,
it can re-use the generic union inet_addr too.

Cc: James Morris <james.l.morris@oracle.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Eric Paris <eparis@parisplace.org>
Cc: Paul Moore <pmoore@redhat.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-security-module@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 include/linux/lsm_audit.h          |   19 +-----
 security/lsm_audit.c               |   58 ++++++++--------
 security/selinux/hooks.c           |  130 +++++++++++++++++-------------------
 security/selinux/include/netnode.h |    4 +-
 security/selinux/include/objsec.h  |    7 +--
 security/selinux/netnode.c         |  102 ++++++++--------------------
 security/smack/smack_lsm.c         |   19 +++---
 7 files changed, 138 insertions(+), 201 deletions(-)

diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 1cc89e9..48cab1e 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -21,23 +21,13 @@
 #include <linux/path.h>
 #include <linux/key.h>
 #include <linux/skbuff.h>
+#include <net/inet_addr.h>
 
 struct lsm_network_audit {
 	int netif;
 	struct sock *sk;
-	u16 family;
-	__be16 dport;
-	__be16 sport;
-	union {
-		struct {
-			__be32 daddr;
-			__be32 saddr;
-		} v4;
-		struct {
-			struct in6_addr daddr;
-			struct in6_addr saddr;
-		} v6;
-	} fam;
+	union inet_addr saddr;
+	union inet_addr daddr;
 };
 
 /* Auxiliary data to use in generating the audit record. */
@@ -83,9 +73,6 @@ struct common_audit_data {
 	}; /* per LSM data pointer union */
 };
 
-#define v4info fam.v4
-#define v6info fam.v6
-
 int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		struct common_audit_data *ad, u8 *proto);
 
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 8d8d97d..244c2a1 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 	if (ih == NULL)
 		return -EINVAL;
 
-	ad->u.net->v4info.saddr = ih->saddr;
-	ad->u.net->v4info.daddr = ih->daddr;
+	ad->u.net->saddr.sin.sin_addr.s_addr = ih->saddr;
+	ad->u.net->daddr.sin.sin_addr.s_addr = ih->daddr;
 
 	if (proto)
 		*proto = ih->protocol;
@@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 	case IPPROTO_UDP: {
@@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 	case IPPROTO_DCCP: {
@@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 	case IPPROTO_SCTP: {
 		struct sctphdr *sh = sctp_hdr(skb);
 		if (sh == NULL)
 			break;
-		ad->u.net->sport = sh->source;
-		ad->u.net->dport = sh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(sh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(sh->dest));
 		break;
 	}
 	default:
@@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 	ip6 = ipv6_hdr(skb);
 	if (ip6 == NULL)
 		return -EINVAL;
-	ad->u.net->v6info.saddr = ip6->saddr;
-	ad->u.net->v6info.daddr = ip6->daddr;
+	ad->u.net->saddr.sin6.sin6_addr = ip6->saddr;
+	ad->u.net->daddr.sin6.sin6_addr = ip6->daddr;
 	ret = 0;
 	/* IPv6 can have several extension header before the Transport header
 	 * skip them */
@@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 	case IPPROTO_UDP: {
@@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 	case IPPROTO_DCCP: {
@@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 	case IPPROTO_SCTP: {
@@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb,
 		sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph);
 		if (sh == NULL)
 			break;
-		ad->u.net->sport = sh->source;
-		ad->u.net->dport = sh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(sh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(sh->dest));
 		break;
 	}
 	default:
@@ -333,21 +333,21 @@ static void dump_common_audit_data(struct audit_buffer *ab,
 			}
 		}
 
-		switch (a->u.net->family) {
+		switch (a->u.net->saddr.sa.sa_family) {
 		case AF_INET:
-			print_ipv4_addr(ab, a->u.net->v4info.saddr,
-					a->u.net->sport,
+			print_ipv4_addr(ab, a->u.net->saddr.sin.sin_addr.s_addr,
+					a->u.net->saddr.sin.sin_port,
 					"saddr", "src");
-			print_ipv4_addr(ab, a->u.net->v4info.daddr,
-					a->u.net->dport,
+			print_ipv4_addr(ab, a->u.net->daddr.sin.sin_addr.s_addr,
+					a->u.net->daddr.sin.sin_port,
 					"daddr", "dest");
 			break;
 		case AF_INET6:
-			print_ipv6_addr(ab, &a->u.net->v6info.saddr,
-					a->u.net->sport,
+			print_ipv6_addr(ab, &a->u.net->saddr.sin6.sin6_addr,
+					a->u.net->saddr.sin.sin_port,
 					"saddr", "src");
-			print_ipv6_addr(ab, &a->u.net->v6info.daddr,
-					a->u.net->dport,
+			print_ipv6_addr(ab, &a->u.net->daddr.sin6.sin6_addr,
+					a->u.net->daddr.sin.sin_port,
 					"daddr", "dest");
 			break;
 		}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c956390..f9959c0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3595,8 +3595,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 	if (ihlen < sizeof(_iph))
 		goto out;
 
-	ad->u.net->v4info.saddr = ih->saddr;
-	ad->u.net->v4info.daddr = ih->daddr;
+	ad->u.net->saddr.sin.sin_addr.s_addr = ih->saddr;
+	ad->u.net->daddr.sin.sin_addr.s_addr = ih->daddr;
 	ret = 0;
 
 	if (proto)
@@ -3614,8 +3614,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 
@@ -3630,8 +3630,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 
@@ -3646,8 +3646,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 
@@ -3674,8 +3674,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 	if (ip6 == NULL)
 		goto out;
 
-	ad->u.net->v6info.saddr = ip6->saddr;
-	ad->u.net->v6info.daddr = ip6->daddr;
+	ad->u.net->saddr.sin6.sin6_addr = ip6->saddr;
+	ad->u.net->daddr.sin6.sin6_addr = ip6->daddr;
 	ret = 0;
 
 	nexthdr = ip6->nexthdr;
@@ -3695,8 +3695,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (th == NULL)
 			break;
 
-		ad->u.net->sport = th->source;
-		ad->u.net->dport = th->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(th->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(th->dest));
 		break;
 	}
 
@@ -3707,8 +3707,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (uh == NULL)
 			break;
 
-		ad->u.net->sport = uh->source;
-		ad->u.net->dport = uh->dest;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(uh->source));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(uh->dest));
 		break;
 	}
 
@@ -3719,8 +3719,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb,
 		if (dh == NULL)
 			break;
 
-		ad->u.net->sport = dh->dccph_sport;
-		ad->u.net->dport = dh->dccph_dport;
+		inet_addr_set_port(&ad->u.net->saddr, ntohs(dh->dccph_sport));
+		inet_addr_set_port(&ad->u.net->daddr, ntohs(dh->dccph_dport));
 		break;
 	}
 
@@ -3735,18 +3735,17 @@ out:
 #endif /* IPV6 */
 
 static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
-			     char **_addrp, int src, u8 *proto)
+			     union inet_addr **_addrp, int src, u8 *proto)
 {
-	char *addrp;
+	union inet_addr *addrp;
 	int ret;
+	sa_family_t family = src ? ad->u.net->saddr.sa.sa_family : ad->u.net->daddr.sa.sa_family;
 
-	switch (ad->u.net->family) {
+	switch (family) {
 	case PF_INET:
 		ret = selinux_parse_skb_ipv4(skb, ad, proto);
 		if (ret)
 			goto parse_error;
-		addrp = (char *)(src ? &ad->u.net->v4info.saddr :
-				       &ad->u.net->v4info.daddr);
 		goto okay;
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -3754,13 +3753,11 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad,
 		ret = selinux_parse_skb_ipv6(skb, ad, proto);
 		if (ret)
 			goto parse_error;
-		addrp = (char *)(src ? &ad->u.net->v6info.saddr :
-				       &ad->u.net->v6info.daddr);
 		goto okay;
 #endif	/* IPV6 */
 	default:
 		addrp = NULL;
-		goto okay;
+		goto save;
 	}
 
 parse_error:
@@ -3770,6 +3767,8 @@ parse_error:
 	return ret;
 
 okay:
+	addrp = src ? &ad->u.net->saddr : &ad->u.net->daddr;
+save:
 	if (_addrp)
 		*_addrp = addrp;
 	return 0;
@@ -3912,25 +3911,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 	 */
 	family = sk->sk_family;
 	if (family == PF_INET || family == PF_INET6) {
-		char *addrp;
+		union inet_addr *addrp = (union inet_addr *)address;
 		struct sk_security_struct *sksec = sk->sk_security;
 		struct common_audit_data ad;
 		struct lsm_network_audit net = {0,};
-		struct sockaddr_in *addr4 = NULL;
-		struct sockaddr_in6 *addr6 = NULL;
 		unsigned short snum;
 		u32 sid, node_perm;
 
-		if (family == PF_INET) {
-			addr4 = (struct sockaddr_in *)address;
-			snum = ntohs(addr4->sin_port);
-			addrp = (char *)&addr4->sin_addr.s_addr;
-		} else {
-			addr6 = (struct sockaddr_in6 *)address;
-			snum = ntohs(addr6->sin6_port);
-			addrp = (char *)&addr6->sin6_addr.s6_addr;
-		}
-
+		addrp->sa.sa_family = family;
+		snum = inet_addr_get_port(addrp);
 		if (snum) {
 			int low, high;
 
@@ -3943,8 +3932,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 					goto out;
 				ad.type = LSM_AUDIT_DATA_NET;
 				ad.u.net = &net;
-				ad.u.net->sport = htons(snum);
-				ad.u.net->family = family;
+				inet_addr_set_port(&ad.u.net->saddr, snum);
+				ad.u.net->saddr.sa.sa_family = family;
+				ad.u.net->daddr.sa.sa_family = family;
 				err = avc_has_perm(sksec->sid, sid,
 						   sksec->sclass,
 						   SOCKET__NAME_BIND, &ad);
@@ -3971,19 +3961,17 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 			break;
 		}
 
-		err = sel_netnode_sid(addrp, family, &sid);
+		err = sel_netnode_sid(addrp, &sid);
 		if (err)
 			goto out;
 
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.u.net = &net;
-		ad.u.net->sport = htons(snum);
-		ad.u.net->family = family;
+		inet_addr_set_port(&ad.u.net->saddr, snum);
+		ad.u.net->saddr.sa.sa_family = family;
+		ad.u.net->daddr.sa.sa_family = family;
 
-		if (family == PF_INET)
-			ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
-		else
-			ad.u.net->v6info.saddr = addr6->sin6_addr;
+		ad.u.net->saddr = *addrp;
 
 		err = avc_has_perm(sksec->sid, sid,
 				   sksec->sclass, node_perm, &ad);
@@ -4011,22 +3999,18 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 	    sksec->sclass == SECCLASS_DCCP_SOCKET) {
 		struct common_audit_data ad;
 		struct lsm_network_audit net = {0,};
-		struct sockaddr_in *addr4 = NULL;
-		struct sockaddr_in6 *addr6 = NULL;
+		union inet_addr *addrp = (union inet_addr *)address;
 		unsigned short snum;
 		u32 sid, perm;
 
 		if (sk->sk_family == PF_INET) {
-			addr4 = (struct sockaddr_in *)address;
 			if (addrlen < sizeof(struct sockaddr_in))
 				return -EINVAL;
-			snum = ntohs(addr4->sin_port);
 		} else {
-			addr6 = (struct sockaddr_in6 *)address;
 			if (addrlen < SIN6_LEN_RFC2133)
 				return -EINVAL;
-			snum = ntohs(addr6->sin6_port);
 		}
+		snum = inet_addr_get_port(addrp);
 
 		err = sel_netport_sid(sk->sk_protocol, snum, &sid);
 		if (err)
@@ -4037,8 +4021,9 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
 
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.u.net = &net;
-		ad.u.net->dport = htons(snum);
-		ad.u.net->family = sk->sk_family;
+		inet_addr_set_port(&ad.u.net->daddr, snum);
+		ad.u.net->saddr.sa.sa_family = sk->sk_family;
+		ad.u.net->daddr.sa.sa_family = sk->sk_family;
 		err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
 		if (err)
 			goto out;
@@ -4169,7 +4154,7 @@ static int selinux_socket_unix_may_send(struct socket *sock,
 			    &ad);
 }
 
-static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
+static int selinux_inet_sys_rcv_skb(int ifindex, union inet_addr *addrp,
 				    u32 peer_sid,
 				    struct common_audit_data *ad)
 {
@@ -4185,7 +4170,7 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
 	if (err)
 		return err;
 
-	err = sel_netnode_sid(addrp, family, &node_sid);
+	err = sel_netnode_sid(addrp, &node_sid);
 	if (err)
 		return err;
 	return avc_has_perm(peer_sid, node_sid,
@@ -4200,12 +4185,13 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
 	u32 sk_sid = sksec->sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = skb->skb_iif;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
 	if (err)
 		return err;
@@ -4233,7 +4219,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	u32 sk_sid = sksec->sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 secmark_active;
 	u8 peerlbl_active;
 
@@ -4259,7 +4245,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = skb->skb_iif;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
 	if (err)
 		return err;
@@ -4270,7 +4257,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
 		if (err)
 			return err;
-		err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp, family,
+		addrp->sa.sa_family = family;
+		err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp,
 					       peer_sid, &ad);
 		if (err) {
 			selinux_netlbl_err(skb, err, 0);
@@ -4621,7 +4609,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
 				       u16 family)
 {
 	int err;
-	char *addrp;
+	union inet_addr *addrp;
 	u32 peer_sid;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
@@ -4644,12 +4632,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
 		return NF_DROP;
 
 	if (peerlbl_active) {
-		err = selinux_inet_sys_rcv_skb(ifindex, addrp, family,
+		addrp->sa.sa_family = family;
+		err = selinux_inet_sys_rcv_skb(ifindex, addrp,
 					       peer_sid, &ad);
 		if (err) {
 			selinux_netlbl_err(skb, err, 1);
@@ -4732,7 +4722,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 	struct sk_security_struct *sksec;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 proto;
 
 	if (sk == NULL)
@@ -4742,7 +4732,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
 		return NF_DROP;
 
@@ -4765,7 +4756,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 	struct sock *sk;
 	struct common_audit_data ad;
 	struct lsm_network_audit net = {0,};
-	char *addrp;
+	union inet_addr *addrp;
 	u8 secmark_active;
 	u8 peerlbl_active;
 
@@ -4813,7 +4804,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 	ad.type = LSM_AUDIT_DATA_NET;
 	ad.u.net = &net;
 	ad.u.net->netif = ifindex;
-	ad.u.net->family = family;
+	ad.u.net->saddr.sa.sa_family = family;
+	ad.u.net->daddr.sa.sa_family = family;
 	if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL))
 		return NF_DROP;
 
@@ -4832,7 +4824,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
 				 SECCLASS_NETIF, NETIF__EGRESS, &ad))
 			return NF_DROP_ERR(-ECONNREFUSED);
 
-		if (sel_netnode_sid(addrp, family, &node_sid))
+		if (sel_netnode_sid(addrp, &node_sid))
 			return NF_DROP;
 		if (avc_has_perm(peer_sid, node_sid,
 				 SECCLASS_NODE, NODE__SENDTO, &ad))
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index df7a5ed..f32c909 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -27,6 +27,8 @@
 #ifndef _SELINUX_NETNODE_H
 #define _SELINUX_NETNODE_H
 
-int sel_netnode_sid(void *addr, u16 family, u32 *sid);
+#include <net/inet_addr.h>
+
+int sel_netnode_sid(union inet_addr *addr, u32 *sid);
 
 #endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index aa47bca..a46caaf 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -24,6 +24,7 @@
 #include <linux/binfmts.h>
 #include <linux/in.h>
 #include <linux/spinlock.h>
+#include <net/inet_addr.h>
 #include "flask.h"
 #include "avc.h"
 
@@ -80,12 +81,8 @@ struct netif_security_struct {
 };
 
 struct netnode_security_struct {
-	union {
-		__be32 ipv4;		/* IPv4 node address */
-		struct in6_addr ipv6;	/* IPv6 node address */
-	} addr;
+	union inet_addr addr;
 	u32 sid;			/* SID for this node */
-	u16 family;			/* address family */
 };
 
 struct netport_security_struct {
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index c5454c0..713f14e 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -68,79 +68,49 @@ static LIST_HEAD(sel_netnode_list);
 static DEFINE_SPINLOCK(sel_netnode_lock);
 static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE];
 
-/**
- * sel_netnode_hashfn_ipv4 - IPv4 hashing function for the node table
- * @addr: IPv4 address
- *
- * Description:
- * This is the IPv4 hashing function for the node interface table, it returns
- * the bucket number for the given IP address.
- *
- */
-static unsigned int sel_netnode_hashfn_ipv4(__be32 addr)
-{
-	/* at some point we should determine if the mismatch in byte order
-	 * affects the hash function dramatically */
-	return (addr & (SEL_NETNODE_HASH_SIZE - 1));
-}
 
 /**
- * sel_netnode_hashfn_ipv6 - IPv6 hashing function for the node table
- * @addr: IPv6 address
+ * sel_netnode_hashfn - IPv4/IPv6 hashing function for the node table
+ * @addr: generic IP address
  *
  * Description:
- * This is the IPv6 hashing function for the node interface table, it returns
+ * This is the IP hashing function for the node interface table, it returns
  * the bucket number for the given IP address.
  *
  */
-static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr)
+static unsigned int sel_netnode_hashfn(const union inet_addr *addr)
 {
-	/* just hash the least significant 32 bits to keep things fast (they
-	 * are the most likely to be different anyway), we can revisit this
-	 * later if needed */
-	return (addr->s6_addr32[3] & (SEL_NETNODE_HASH_SIZE - 1));
+	if (addr->sa.sa_family == PF_INET)
+		/* at some point we should determine if the mismatch in byte order
+		 * affects the hash function dramatically */
+		return (addr->sin.sin_addr.s_addr & (SEL_NETNODE_HASH_SIZE - 1));
+	else if (addr->sa.sa_family == PF_INET6)
+		/* just hash the least significant 32 bits to keep things fast (they
+		 * are the most likely to be different anyway), we can revisit this
+		 * later if needed */
+		return (addr->sin6.sin6_addr.s6_addr32[3] & (SEL_NETNODE_HASH_SIZE - 1));
+	else
+		BUG();
 }
 
 /**
  * sel_netnode_find - Search for a node record
  * @addr: IP address
- * @family: address family
  *
  * Description:
  * Search the network node table and return the record matching @addr.  If an
  * entry can not be found in the table return NULL.
  *
  */
-static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
+static struct sel_netnode *sel_netnode_find(const union inet_addr *addr)
 {
 	unsigned int idx;
 	struct sel_netnode *node;
 
-	switch (family) {
-	case PF_INET:
-		idx = sel_netnode_hashfn_ipv4(*(__be32 *)addr);
-		break;
-	case PF_INET6:
-		idx = sel_netnode_hashfn_ipv6(addr);
-		break;
-	default:
-		BUG();
-		return NULL;
-	}
-
+	idx = sel_netnode_hashfn(addr);
 	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
-		if (node->nsec.family == family)
-			switch (family) {
-			case PF_INET:
-				if (node->nsec.addr.ipv4 == *(__be32 *)addr)
-					return node;
-				break;
-			case PF_INET6:
-				if (ipv6_addr_equal(&node->nsec.addr.ipv6,
-						    addr))
-					return node;
-				break;
-			}
+		if (inet_addr_equal(&node->nsec.addr, addr))
+			return node;
 
 	return NULL;
 }
@@ -156,18 +126,9 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
 static void sel_netnode_insert(struct sel_netnode *node)
 {
 	unsigned int idx;
+	union inet_addr *addr = &node->nsec.addr;
 
-	switch (node->nsec.family) {
-	case PF_INET:
-		idx = sel_netnode_hashfn_ipv4(node->nsec.addr.ipv4);
-		break;
-	case PF_INET6:
-		idx = sel_netnode_hashfn_ipv6(&node->nsec.addr.ipv6);
-		break;
-	default:
-		BUG();
-	}
-
+	idx = sel_netnode_hashfn(addr);
 	/* we need to impose a limit on the growth of the hash table so check
 	 * this bucket to make sure it is within the specified bounds */
 	list_add_rcu(&node->list, &sel_netnode_hash[idx].list);
@@ -186,7 +147,6 @@ static void sel_netnode_insert(struct sel_netnode *node)
 /**
  * sel_netnode_sid_slow - Lookup the SID of a network address using the policy
  * @addr: the IP address
- * @family: the address family
  * @sid: node SID
  *
  * Description:
@@ -196,14 +156,14 @@ static void sel_netnode_insert(struct sel_netnode *node)
  * failure.
  *
  */
-static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
+static int sel_netnode_sid_slow(union inet_addr *addr, u32 *sid)
 {
 	int ret = -ENOMEM;
 	struct sel_netnode *node;
 	struct sel_netnode *new = NULL;
 
 	spin_lock_bh(&sel_netnode_lock);
-	node = sel_netnode_find(addr, family);
+	node = sel_netnode_find(addr);
 	if (node != NULL) {
 		*sid = node->nsec.sid;
 		spin_unlock_bh(&sel_netnode_lock);
@@ -212,16 +172,16 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
 	new = kzalloc(sizeof(*new), GFP_ATOMIC);
 	if (new == NULL)
 		goto out;
-	switch (family) {
+	switch (addr->sa.sa_family) {
 	case PF_INET:
 		ret = security_node_sid(PF_INET,
 					addr, sizeof(struct in_addr), sid);
-		new->nsec.addr.ipv4 = *(__be32 *)addr;
+		new->nsec.addr = *addr;
 		break;
 	case PF_INET6:
 		ret = security_node_sid(PF_INET6,
 					addr, sizeof(struct in6_addr), sid);
-		new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
+		new->nsec.addr = *addr;
 		break;
 	default:
 		BUG();
@@ -229,7 +189,6 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
 	if (ret != 0)
 		goto out;
 
-	new->nsec.family = family;
 	new->nsec.sid = *sid;
 	sel_netnode_insert(new);
 
@@ -246,8 +205,7 @@ out:
 
 /**
  * sel_netnode_sid - Lookup the SID of a network address
- * @addr: the IP address
- * @family: the address family
+ * @addr: the generic IP address
  * @sid: node SID
  *
  * Description:
@@ -258,12 +216,12 @@ out:
  * on failure.
  *
  */
-int sel_netnode_sid(void *addr, u16 family, u32 *sid)
+int sel_netnode_sid(union inet_addr *addr, u32 *sid)
 {
 	struct sel_netnode *node;
 
 	rcu_read_lock();
-	node = sel_netnode_find(addr, family);
+	node = sel_netnode_find(addr);
 	if (node != NULL) {
 		*sid = node->nsec.sid;
 		rcu_read_unlock();
@@ -271,7 +229,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
 	}
 	rcu_read_unlock();
 
-	return sel_netnode_sid_slow(addr, family, sid);
+	return sel_netnode_sid_slow(addr, sid);
 }
 
 /**
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 3f7682a..07a7184 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1900,9 +1900,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap)
 		struct lsm_network_audit net;
 
 		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-		ad.a.u.net->family = sap->sin_family;
-		ad.a.u.net->dport = sap->sin_port;
-		ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr;
+		ad.a.u.net->daddr = (union inet_addr )*sap;
 #endif
 		sk_lbl = SMACK_UNLABELED_SOCKET;
 		skp = ssp->smk_out;
@@ -2057,12 +2055,13 @@ auditout:
 
 #ifdef CONFIG_AUDIT
 	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-	ad.a.u.net->family = sk->sk_family;
-	ad.a.u.net->dport = port;
+	inet_addr_set_port(&ad.a.u.net->daddr, port);
+	ad.a.u.net->saddr.sa.sa_family = sk->sk_family;
+	ad.a.u.net->daddr.sa.sa_family = sk->sk_family;
 	if (act == SMK_RECEIVING)
-		ad.a.u.net->v6info.saddr = addr6->sin6_addr;
+		ad.a.u.net->saddr.sin6.sin6_addr = addr6->sin6_addr;
 	else
-		ad.a.u.net->v6info.daddr = addr6->sin6_addr;
+		ad.a.u.net->daddr.sin6.sin6_addr = addr6->sin6_addr;
 #endif
 	return smk_access(skp, object, MAY_WRITE, &ad);
 }
@@ -3204,7 +3203,8 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 
 #ifdef CONFIG_AUDIT
 		smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-		ad.a.u.net->family = sk->sk_family;
+		ad.a.u.net->saddr.sa.sa_family = sk->sk_family;
+		ad.a.u.net->daddr.sa.sa_family = sk->sk_family;
 		ad.a.u.net->netif = skb->skb_iif;
 		ipv4_skb_to_auditdata(skb, &ad.a, NULL);
 #endif
@@ -3386,7 +3386,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 
 #ifdef CONFIG_AUDIT
 	smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net);
-	ad.a.u.net->family = family;
+	ad.a.u.net->saddr.sa.sa_family = family;
+	ad.a.u.net->daddr.sa.sa_family = family;
 	ad.a.u.net->netif = skb->skb_iif;
 	ipv4_skb_to_auditdata(skb, &ad.a, NULL);
 #endif
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Cluster-devel] [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions
  2013-08-02  7:14 ` [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions Cong Wang
@ 2013-08-02 10:31   ` Christoph Hellwig
  2013-08-05  3:16     ` Cong Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2013-08-02 10:31 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev, linux-cifs, linux-nfs, cluster-devel, Trond Myklebust,
	linux-kernel, Steve French, David S. Miller

On Fri, Aug 02, 2013 at 03:14:32PM +0800, Cong Wang wrote:
> From: Cong Wang <amwang@redhat.com>
> 
> nfs and cifs define some helper functions for sockaddr,
> they can use the generic functions for union inet_addr too.
> 
> Since some dlm code needs to compare ->sin_port, introduce a
> generic function inet_addr_equal_strict() for it.

Would sound more useful to have a sockaddr_equal case that can be used
on any sockaddr.  For cases that no current user handles just return
false.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch net-next v2 8/8] selinux: use generic union inet_addr
  2013-08-02  7:14 ` [Patch net-next v2 8/8] selinux: use generic union inet_addr Cong Wang
@ 2013-08-02 14:34   ` Paul Moore
  2013-08-02 21:51     ` David Miller
  0 siblings, 1 reply; 9+ messages in thread
From: Paul Moore @ 2013-08-02 14:34 UTC (permalink / raw)
  To: Cong Wang
  Cc: netdev, David S. Miller, James Morris, Stephen Smalley,
	Eric Paris, linux-kernel, linux-security-module

On Friday, August 02, 2013 03:14:34 PM Cong Wang wrote:
> From: Cong Wang <amwang@redhat.com>
> 
> selinux has some similar definition like union inet_addr,
> it can re-use the generic union inet_addr too.
> 
> Cc: James Morris <james.l.morris@oracle.com>
> Cc: Stephen Smalley <sds@tycho.nsa.gov>
> Cc: Eric Paris <eparis@parisplace.org>
> Cc: Paul Moore <pmoore@redhat.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-security-module@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>

Perhaps I'm confusing this with another patch but I though DaveM said he 
wasn't going to merge these patches?

-- 
paul moore
security and virtualization @ redhat


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch net-next v2 1/8] net: introduce generic union inet_addr
  2013-08-02  7:14 ` [Patch net-next v2 1/8] net: introduce generic union inet_addr Cong Wang
@ 2013-08-02 21:50   ` David Miller
  2013-08-05  3:09     ` Cong Wang
  0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2013-08-02 21:50 UTC (permalink / raw)
  To: amwang; +Cc: netdev, dborkman, joe, linux-kernel

From: Cong Wang <amwang@redhat.com>
Date: Fri,  2 Aug 2013 15:14:27 +0800

> From: Cong Wang <amwang@redhat.com>
> 
> Introduce a generic IP address type, union inet_addr, so that
> subsystems don't have to use their own definitions. Because
> netpoll already defines union inet_addr, just move it to global.
> Some of the helper functions will be used by VXLAN IPv6 code too.
> 
> This patch also reuses the "%pIS" specifier, to make it accept
> union inet_addr instead of struct sockaddr.
> 
> Cc: Daniel Borkmann <dborkman@redhat.com>
> Cc: Joe Perches <joe@perches.com>
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>

Changing %pIS to %pIA is pure churn, and of zero value that I can see.

Every time I review this patch set I discover some new thing that I'm
very disappointed with.

You're going to have to stop being so ambitious, and start very small.

Maybe one tiny patch at a time if needed.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch net-next v2 8/8] selinux: use generic union inet_addr
  2013-08-02 14:34   ` Paul Moore
@ 2013-08-02 21:51     ` David Miller
  0 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2013-08-02 21:51 UTC (permalink / raw)
  To: pmoore
  Cc: amwang, netdev, james.l.morris, sds, eparis, linux-kernel,
	linux-security-module

From: Paul Moore <pmoore@redhat.com>
Date: Fri, 02 Aug 2013 10:34:07 -0400

> On Friday, August 02, 2013 03:14:34 PM Cong Wang wrote:
>> From: Cong Wang <amwang@redhat.com>
>> 
>> selinux has some similar definition like union inet_addr,
>> it can re-use the generic union inet_addr too.
>> 
>> Cc: James Morris <james.l.morris@oracle.com>
>> Cc: Stephen Smalley <sds@tycho.nsa.gov>
>> Cc: Eric Paris <eparis@parisplace.org>
>> Cc: Paul Moore <pmoore@redhat.com>
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-security-module@vger.kernel.org
>> Signed-off-by: Cong Wang <amwang@redhat.com>
> 
> Perhaps I'm confusing this with another patch but I though DaveM said he 
> wasn't going to merge these patches?

I didn't like how he added completely unused bloat to various
datastructures because he unconditionally put a port field into
there.

He removed that problem this time, but there are still a lot of
things I don't like about this patch series.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch net-next v2 1/8] net: introduce generic union inet_addr
  2013-08-02 21:50   ` David Miller
@ 2013-08-05  3:09     ` Cong Wang
  0 siblings, 0 replies; 9+ messages in thread
From: Cong Wang @ 2013-08-05  3:09 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, dborkman, joe, linux-kernel

On Fri, 2013-08-02 at 14:50 -0700, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Fri,  2 Aug 2013 15:14:27 +0800
> 
> > From: Cong Wang <amwang@redhat.com>
> > 
> > Introduce a generic IP address type, union inet_addr, so that
> > subsystems don't have to use their own definitions. Because
> > netpoll already defines union inet_addr, just move it to global.
> > Some of the helper functions will be used by VXLAN IPv6 code too.
> > 
> > This patch also reuses the "%pIS" specifier, to make it accept
> > union inet_addr instead of struct sockaddr.
> > 
> > Cc: Daniel Borkmann <dborkman@redhat.com>
> > Cc: Joe Perches <joe@perches.com>
> > Cc: linux-kernel@vger.kernel.org
> > Signed-off-by: Cong Wang <amwang@redhat.com>
> 
> Changing %pIS to %pIA is pure churn, and of zero value that I can see.

'S' in %pIS is for Sockaddr, since this patch makes it accept union
inet_addr instead of struct sockaddr, I don't think 'S' is meaningful
any more.

> 
> Every time I review this patch set I discover some new thing that I'm
> very disappointed with.

The "%pIS" change exists in v1, I don't know why you think it is new in
v2. Also, if you can point all what you dislike at one time, it would
save time for both of us, I prefer to fix them all in one update.

> 
> You're going to have to stop being so ambitious, and start very small.
> 
> Maybe one tiny patch at a time if needed.

Ok, I will split the %pIS change from this patch.

Thanks!


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Cluster-devel] [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions
  2013-08-02 10:31   ` [Cluster-devel] " Christoph Hellwig
@ 2013-08-05  3:16     ` Cong Wang
  0 siblings, 0 replies; 9+ messages in thread
From: Cong Wang @ 2013-08-05  3:16 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: netdev, linux-cifs, linux-nfs, cluster-devel, Trond Myklebust,
	linux-kernel, Steve French, David S. Miller

On Fri, 2013-08-02 at 03:31 -0700, Christoph Hellwig wrote:
> On Fri, Aug 02, 2013 at 03:14:32PM +0800, Cong Wang wrote:
> > From: Cong Wang <amwang@redhat.com>
> > 
> > nfs and cifs define some helper functions for sockaddr,
> > they can use the generic functions for union inet_addr too.
> > 
> > Since some dlm code needs to compare ->sin_port, introduce a
> > generic function inet_addr_equal_strict() for it.
> 
> Would sound more useful to have a sockaddr_equal case that can be used
> on any sockaddr.  For cases that no current user handles just return
> false.
> 

Ok, since you and other people ask for it.

Thanks.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-08-05  3:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1375427674-21735-1-git-send-email-amwang@redhat.com>
2013-08-02  7:14 ` [Patch net-next v2 1/8] net: introduce generic union inet_addr Cong Wang
2013-08-02 21:50   ` David Miller
2013-08-05  3:09     ` Cong Wang
2013-08-02  7:14 ` [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions Cong Wang
2013-08-02 10:31   ` [Cluster-devel] " Christoph Hellwig
2013-08-05  3:16     ` Cong Wang
2013-08-02  7:14 ` [Patch net-next v2 8/8] selinux: use generic union inet_addr Cong Wang
2013-08-02 14:34   ` Paul Moore
2013-08-02 21:51     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).