Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 3/3] af_packet: simplify VLAN frame check in packet_snd
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <1375436261-6746-2-git-send-email-phil@nwl.cc>

For ethernet frames, eth_type_trans() already parses the header, so one
can skip this when checking the frame size.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/packet/af_packet.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ce7b4f0..bbe1ece 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2333,23 +2333,16 @@ static int packet_snd(struct socket *sock,
 
 	if (dev->type == ARPHRD_ETHER) {
 		skb->protocol = eth_type_trans(skb, dev);
+		if (skb->protocol == htons(ETH_P_8021Q))
+			reserve += VLAN_HLEN;
 	} else {
 		skb->protocol = proto;
 		skb->dev = dev;
 	}
 
 	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
-		/* Earlier code assumed this would be a VLAN pkt,
-		 * double-check this now that we have the actual
-		 * packet in hand.
-		 */
-		struct ethhdr *ehdr;
-		skb_reset_mac_header(skb);
-		ehdr = eth_hdr(skb);
-		if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-			err = -EMSGSIZE;
-			goto out_free;
-		}
+		err = -EMSGSIZE;
+		goto out_free;
 	}
 
 	skb->priority = sk->sk_priority;
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2 1/3] af_packet: when sending ethernet frames, parse header for skb->protocol
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20130801.181208.804928209108880255.davem@davemloft.net>

This may be necessary when the SKB is passed to other layers on the go,
which check the protocol field on their own. An example is a VLAN packet
sent out using AF_PACKET on a bridge interface. The bridging code checks
the SKB size, accounting for any VLAN header only if the protocol field
is set accordingly.

Note that eth_type_trans() sets skb->dev to the passed argument, so this
can be skipped in packet_snd() for ethernet frames, as well.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since V1:
- minor lingual review of the comment
- added note about setting skb->dev for non-ethernet frames only
---
 net/packet/af_packet.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 20a1bd0..e549e17 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -88,6 +88,7 @@
 #include <linux/virtio_net.h>
 #include <linux/errqueue.h>
 #include <linux/net_tstamp.h>
+#include <linux/if_arp.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -2005,6 +2006,9 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		if (unlikely(err))
 			return err;
 
+		if (dev->type == ARPHRD_ETHER)
+			skb->protocol = eth_type_trans(skb, dev);
+
 		data += dev->hard_header_len;
 		to_write -= dev->hard_header_len;
 	}
@@ -2324,6 +2328,13 @@ static int packet_snd(struct socket *sock,
 
 	sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
 
+	if (dev->type == ARPHRD_ETHER) {
+		skb->protocol = eth_type_trans(skb, dev);
+	} else {
+		skb->protocol = proto;
+		skb->dev = dev;
+	}
+
 	if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
 		/* Earlier code assumed this would be a VLAN pkt,
 		 * double-check this now that we have the actual
@@ -2338,8 +2349,6 @@ static int packet_snd(struct socket *sock,
 		}
 	}
 
-	skb->protocol = proto;
-	skb->dev = dev;
 	skb->priority = sk->sk_priority;
 	skb->mark = sk->sk_mark;
 
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2 2/3] af_packet: fix for sending VLAN frames via packet_mmap
From: Phil Sutter @ 2013-08-02  9:37 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <1375436261-6746-1-git-send-email-phil@nwl.cc>

Since tpacket_fill_skb() parses the protocol field in ethernet frames'
headers, it's easy to see if any passed frame is a VLAN one and account
for the extended size.

But as the real protocol does not turn up before tpacket_fill_skb()
runs which in turn also checks the frame length, move the max frame
length calculation into the function.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/packet/af_packet.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e549e17..ce7b4f0 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1924,7 +1924,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		__be16 proto, unsigned char *addr, int hlen)
 {
 	union tpacket_uhdr ph;
-	int to_write, offset, len, tp_len, nr_frags, len_max;
+	int to_write, offset, len, tp_len, nr_frags, len_max, max_frame_len;
 	struct socket *sock = po->sk.sk_socket;
 	struct page *page;
 	void *data;
@@ -1947,10 +1947,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		tp_len = ph.h1->tp_len;
 		break;
 	}
-	if (unlikely(tp_len > size_max)) {
-		pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
-		return -EMSGSIZE;
-	}
 
 	skb_reserve(skb, hlen);
 	skb_reset_network_header(skb);
@@ -2013,6 +2009,18 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
 		to_write -= dev->hard_header_len;
 	}
 
+	max_frame_len = dev->mtu + dev->hard_header_len;
+	if (skb->protocol == htons(ETH_P_8021Q))
+		max_frame_len += VLAN_HLEN;
+
+	if (size_max > max_frame_len)
+		size_max = max_frame_len;
+
+	if (unlikely(tp_len > size_max)) {
+		pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
+		return -EMSGSIZE;
+	}
+
 	offset = offset_in_page(data);
 	len_max = PAGE_SIZE - offset;
 	len = ((to_write > len_max) ? len_max : to_write);
@@ -2051,7 +2059,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	struct net_device *dev;
 	__be16 proto;
 	bool need_rls_dev = false;
-	int err, reserve = 0;
+	int err;
 	void *ph;
 	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
 	int tp_len, size_max;
@@ -2084,8 +2092,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	if (unlikely(dev == NULL))
 		goto out;
 
-	reserve = dev->hard_header_len;
-
 	err = -ENETDOWN;
 	if (unlikely(!(dev->flags & IFF_UP)))
 		goto out_put;
@@ -2093,9 +2099,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	size_max = po->tx_ring.frame_size
 		- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
-	if (size_max > dev->mtu + reserve)
-		size_max = dev->mtu + reserve;
-
 	do {
 		ph = packet_current_frame(po, &po->tx_ring,
 				TP_STATUS_SEND_REQUEST);
-- 
1.8.1.5

^ permalink raw reply related

* Re: bonding + arp monitoring fails if interface is a vlan
From: Santiago Garcia Mantinan @ 2013-08-02  9:33 UTC (permalink / raw)
  To: Erik Hugne; +Cc: netdev
In-Reply-To: <CAJk_L2H+Y4u=DtLXe_R9R79z6tUt8F3=16YwRvh12CxENm7Aaw@mail.gmail.com>

2013/8/2 Santiago Garcia Mantinan <manty@manty.net>:
> 2013/8/1 Erik Hugne <erik.hugne@ericsson.com>
>> This have helped me troubleshoot various bonding problems in the past:
>> mount -t debugfs none /sys/kernel/debug/
>> ln -s /sys/kernel/debug /debug
>> echo -n 'module bonding +p' > /debug/dynamic_debug/control
>
> I'm compiling a 3.11-rc3 version with dynamic_debug enabled in order
> to be able to test this.

Done with this, running 3.11-rc3 with this debug activated, what I see
is that I'm consistently getting failures 1/4 of the arp probes, so it
gets three ok and then one fails, then again 3 ok and then one fails.
I got the same 1/4 ratio when testing with 2 secs and 5 secs of
arp_interval.

I'm pasting here the debug output in case this can help find what is
going on to somebody else, it hasn't helped me at all :-(

11:16:29 [ 1510.493414] bonding: event_dev: eth0, event: 15
11:16:29 [ 1510.493459] bonding: event_dev: eth0.1002, event: 10
11:16:29 [ 1510.493979] bonding: event_dev: eth0.1002, event: 5
11:16:29 [ 1510.526266] bonding: bond0: adding ARP target 192.168.1.1.
11:16:29 [ 1510.526391] bonding: bond0: Setting ARP monitoring interval to 2000.
11:16:29 [ 1510.530093] bonding: bond0: setting mode to active-backup (1).
11:16:29 [ 1510.530217] bonding: bond0: setting arp_validate to none (0).
11:16:29 [ 1510.537106] bonding: bond0: Adding slave eth0.1002.
11:16:29 [ 1510.537119] bonding: eth0.1002: ! NETIF_F_VLAN_CHALLENGED
11:16:29 [ 1510.537136] bonding: event_dev: eth0.1002, event: 14
11:16:29 [ 1510.537147] bonding: bond_dev=f5581000 slave_dev=f4dcc000
slave_dev->addr_len=6
11:16:29 [ 1510.537206] bonding: event_dev: bond0, event: 8
11:16:29 [ 1510.537213] bonding: IFF_MASTER
11:16:29 [ 1510.537244] bonding: event_dev: eth0.1002, event: 8
11:16:29 [ 1510.537283] bonding: event_dev: eth0.1002, event: 15
11:16:29 [ 1510.537308] bonding: event_dev: eth0.1002, event: d
11:16:29 [ 1510.537389] bonding: event_dev: eth0.1002, event: 1
11:16:29 [ 1510.537424] bonding: event_dev: bond0, event: b
11:16:29 [ 1510.537430] bonding: IFF_MASTER
11:16:29 [ 1510.537945] bonding: Initial state of slave_dev is BOND_LINK_UP
11:16:29 [ 1510.537955] bonding: bond0: making interface eth0.1002 the
new active one.
11:16:29 [ 1510.538032] bonding: event_dev: bond0, event: c
11:16:29 [ 1510.538039] bonding: IFF_MASTER
11:16:29 [ 1510.538051] bonding: bond0: first active interface up!
11:16:29 [ 1510.538073] bonding: bond0: enslaving eth0.1002 as an
active interface with an up link.
11:16:29 [ 1510.565482] bonding: event_dev: bond0, event: d
11:16:29 [ 1510.565490] bonding: IFF_MASTER
11:16:29 [ 1510.565564] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:29 [ 1510.565572] bonding: basa: target 192.168.1.1
11:16:29 [ 1510.565577] bonding: basa: empty vlan: arp_send
11:16:29 [ 1510.565587] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:29 [ 1510.565789] 8021q: adding VLAN 0 to HW filter on device bond0
11:16:29 [ 1510.565798] bonding: bond: bond0, vlan id 0
11:16:29 [ 1510.565803] bonding: added VLAN ID 0 on bond bond0
11:16:29 [ 1510.565873] bonding: event_dev: bond0, event: 1
11:16:29 [ 1510.565876] bonding: IFF_MASTER
11:16:30 [ 1511.492281] bonding: event_dev: bond0, event: 4
11:16:30 [ 1511.492293] bonding: IFF_MASTER
11:16:31 [ 1512.568138] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:31 [ 1512.568154] bonding: basa: target 192.168.1.1
11:16:31 [ 1512.568174] bonding: basa: rtdev == bond->dev: arp_send
11:16:31 [ 1512.568189] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:33 [ 1514.572184] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:33 [ 1514.572203] bonding: basa: target 192.168.1.1
11:16:33 [ 1514.572224] bonding: basa: rtdev == bond->dev: arp_send
11:16:33 [ 1514.572238] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:35 [ 1516.576150] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:35 [ 1516.576171] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:16:35 [ 1516.576225] bonding: bond0: now running without any active
interface !
11:16:35 [ 1516.576237] bonding: basa: target 192.168.1.1
11:16:35 [ 1516.576254] bonding: basa: rtdev == bond->dev: arp_send
11:16:35 [ 1516.576266] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:35 [ 1516.576512] bonding: event_dev: bond0, event: 4
11:16:35 [ 1516.576520] bonding: IFF_MASTER
11:16:37 [ 1518.580153] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:16:37 [ 1518.580174] bonding: bond0: link status definitely up for
interface eth0.1002.
11:16:37 [ 1518.580187] bonding: bond0: making interface eth0.1002 the
new active one.
11:16:37 [ 1518.580232] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:37 [ 1518.580437] bonding: event_dev: bond0, event: c
11:16:37 [ 1518.580444] bonding: IFF_MASTER
11:16:37 [ 1518.580621] bonding: event_dev: bond0, event: 13
11:16:37 [ 1518.580629] bonding: IFF_MASTER
11:16:37 [ 1518.580658] bonding: bond0: first active interface up!
11:16:37 [ 1518.580673] bonding: basa: target 192.168.1.1
11:16:37 [ 1518.580696] bonding: basa: rtdev == bond->dev: arp_send
11:16:37 [ 1518.580715] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:37 [ 1518.580920] bonding: event_dev: bond0, event: 4
11:16:37 [ 1518.580927] bonding: IFF_MASTER
11:16:39 [ 1520.584150] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:39 [ 1520.584170] bonding: basa: target 192.168.1.1
11:16:39 [ 1520.584195] bonding: basa: rtdev == bond->dev: arp_send
11:16:39 [ 1520.584209] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:41 [ 1522.588153] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:41 [ 1522.588174] bonding: basa: target 192.168.1.1
11:16:41 [ 1522.588198] bonding: basa: rtdev == bond->dev: arp_send
11:16:41 [ 1522.588211] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:43 [ 1524.592161] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:43 [ 1524.592182] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:16:43 [ 1524.592227] bonding: bond0: now running without any active
interface !
11:16:43 [ 1524.592238] bonding: basa: target 192.168.1.1
11:16:43 [ 1524.592253] bonding: basa: rtdev == bond->dev: arp_send
11:16:43 [ 1524.592267] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:43 [ 1524.592507] bonding: event_dev: bond0, event: 4
11:16:43 [ 1524.592516] bonding: IFF_MASTER
11:16:45 [ 1526.596178] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:16:45 [ 1526.596199] bonding: bond0: link status definitely up for
interface eth0.1002.
11:16:45 [ 1526.596212] bonding: bond0: making interface eth0.1002 the
new active one.
11:16:45 [ 1526.596249] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:45 [ 1526.596449] bonding: event_dev: bond0, event: c
11:16:45 [ 1526.596457] bonding: IFF_MASTER
11:16:45 [ 1526.596638] bonding: event_dev: bond0, event: 13
11:16:45 [ 1526.596646] bonding: IFF_MASTER
11:16:45 [ 1526.596676] bonding: bond0: first active interface up!
11:16:45 [ 1526.596691] bonding: basa: target 192.168.1.1
11:16:45 [ 1526.596713] bonding: basa: rtdev == bond->dev: arp_send
11:16:45 [ 1526.596730] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:45 [ 1526.596939] bonding: event_dev: bond0, event: 4
11:16:45 [ 1526.596947] bonding: IFF_MASTER
11:16:47 [ 1528.600160] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:47 [ 1528.600181] bonding: basa: target 192.168.1.1
11:16:47 [ 1528.600207] bonding: basa: rtdev == bond->dev: arp_send
11:16:47 [ 1528.600220] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:49 [ 1530.604152] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:49 [ 1530.604172] bonding: basa: target 192.168.1.1
11:16:49 [ 1530.604196] bonding: basa: rtdev == bond->dev: arp_send
11:16:49 [ 1530.604210] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:51 [ 1532.608155] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:51 [ 1532.608176] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:16:51 [ 1532.608232] bonding: bond0: now running without any active
interface !
11:16:51 [ 1532.608244] bonding: basa: target 192.168.1.1
11:16:51 [ 1532.608259] bonding: basa: rtdev == bond->dev: arp_send
11:16:51 [ 1532.608272] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:51 [ 1532.608505] bonding: event_dev: bond0, event: 4
11:16:51 [ 1532.608513] bonding: IFF_MASTER
11:16:53 [ 1534.612150] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:16:53 [ 1534.612170] bonding: bond0: link status definitely up for
interface eth0.1002.
11:16:53 [ 1534.612183] bonding: bond0: making interface eth0.1002 the
new active one.
11:16:53 [ 1534.612220] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:53 [ 1534.612419] bonding: event_dev: bond0, event: c
11:16:53 [ 1534.612427] bonding: IFF_MASTER
11:16:53 [ 1534.612606] bonding: event_dev: bond0, event: 13
11:16:53 [ 1534.612614] bonding: IFF_MASTER
11:16:53 [ 1534.612643] bonding: bond0: first active interface up!
11:16:53 [ 1534.612658] bonding: basa: target 192.168.1.1
11:16:53 [ 1534.612676] bonding: basa: rtdev == bond->dev: arp_send
11:16:53 [ 1534.612691] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:53 [ 1534.612934] bonding: event_dev: bond0, event: 4
11:16:53 [ 1534.612942] bonding: IFF_MASTER
11:16:55 [ 1536.616158] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:55 [ 1536.616180] bonding: basa: target 192.168.1.1
11:16:55 [ 1536.616204] bonding: basa: rtdev == bond->dev: arp_send
11:16:55 [ 1536.616218] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:57 [ 1538.620145] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:57 [ 1538.620166] bonding: basa: target 192.168.1.1
11:16:57 [ 1538.620179] bonding: basa: rtdev == bond->dev: arp_send
11:16:57 [ 1538.620192] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:59 [ 1540.624155] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:16:59 [ 1540.624176] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:16:59 [ 1540.624227] bonding: bond0: now running without any active
interface !
11:16:59 [ 1540.624238] bonding: basa: target 192.168.1.1
11:16:59 [ 1540.624253] bonding: basa: rtdev == bond->dev: arp_send
11:16:59 [ 1540.624266] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:16:59 [ 1540.624501] bonding: event_dev: bond0, event: 4
11:16:59 [ 1540.624509] bonding: IFF_MASTER
11:17:01 [ 1542.628132] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:17:01 [ 1542.628148] bonding: bond0: link status definitely up for
interface eth0.1002.
11:17:01 [ 1542.628158] bonding: bond0: making interface eth0.1002 the
new active one.
11:17:01 [ 1542.628198] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:01 [ 1542.628396] bonding: event_dev: bond0, event: c
11:17:01 [ 1542.628404] bonding: IFF_MASTER
11:17:01 [ 1542.628581] bonding: event_dev: bond0, event: 13
11:17:01 [ 1542.628589] bonding: IFF_MASTER
11:17:01 [ 1542.628619] bonding: bond0: first active interface up!
11:17:01 [ 1542.628634] bonding: basa: target 192.168.1.1
11:17:01 [ 1542.628657] bonding: basa: rtdev == bond->dev: arp_send
11:17:01 [ 1542.628675] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:01 [ 1542.628846] bonding: event_dev: bond0, event: 4
11:17:01 [ 1542.628856] bonding: IFF_MASTER
11:17:03 [ 1544.632138] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:03 [ 1544.632154] bonding: basa: target 192.168.1.1
11:17:03 [ 1544.632177] bonding: basa: rtdev == bond->dev: arp_send
11:17:03 [ 1544.632190] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:05 [ 1546.636147] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:05 [ 1546.636167] bonding: basa: target 192.168.1.1
11:17:05 [ 1546.636186] bonding: basa: rtdev == bond->dev: arp_send
11:17:05 [ 1546.636201] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:07 [ 1548.640129] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:07 [ 1548.640150] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:17:07 [ 1548.640208] bonding: bond0: now running without any active
interface !
11:17:07 [ 1548.640221] bonding: basa: target 192.168.1.1
11:17:07 [ 1548.640235] bonding: basa: rtdev == bond->dev: arp_send
11:17:07 [ 1548.640249] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:07 [ 1548.640524] bonding: event_dev: bond0, event: 4
11:17:07 [ 1548.640532] bonding: IFF_MASTER
11:17:09 [ 1550.644152] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:17:09 [ 1550.644172] bonding: bond0: link status definitely up for
interface eth0.1002.
11:17:09 [ 1550.644184] bonding: bond0: making interface eth0.1002 the
new active one.
11:17:09 [ 1550.644226] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:09 [ 1550.644421] bonding: event_dev: bond0, event: c
11:17:09 [ 1550.644429] bonding: IFF_MASTER
11:17:09 [ 1550.644608] bonding: event_dev: bond0, event: 13
11:17:09 [ 1550.644616] bonding: IFF_MASTER
11:17:09 [ 1550.644645] bonding: bond0: first active interface up!
11:17:09 [ 1550.644659] bonding: basa: target 192.168.1.1
11:17:09 [ 1550.644683] bonding: basa: rtdev == bond->dev: arp_send
11:17:09 [ 1550.644697] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:09 [ 1550.644866] bonding: event_dev: bond0, event: 4
11:17:09 [ 1550.644875] bonding: IFF_MASTER
11:17:11 [ 1552.648128] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:11 [ 1552.648144] bonding: basa: target 192.168.1.1
11:17:11 [ 1552.648167] bonding: basa: rtdev == bond->dev: arp_send
11:17:11 [ 1552.648180] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:13 [ 1554.652132] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:13 [ 1554.652149] bonding: basa: target 192.168.1.1
11:17:13 [ 1554.652166] bonding: basa: rtdev == bond->dev: arp_send
11:17:13 [ 1554.652179] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:15 [ 1556.656131] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:15 [ 1556.656147] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:17:15 [ 1556.656198] bonding: bond0: now running without any active
interface !
11:17:15 [ 1556.656210] bonding: basa: target 192.168.1.1
11:17:15 [ 1556.656224] bonding: basa: rtdev == bond->dev: arp_send
11:17:15 [ 1556.656238] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:15 [ 1556.656488] bonding: event_dev: bond0, event: 4
11:17:15 [ 1556.656497] bonding: IFF_MASTER
11:17:17 [ 1558.660147] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:17:17 [ 1558.660168] bonding: bond0: link status definitely up for
interface eth0.1002.
11:17:17 [ 1558.660180] bonding: bond0: making interface eth0.1002 the
new active one.
11:17:17 [ 1558.660221] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:17 [ 1558.660424] bonding: event_dev: bond0, event: c
11:17:17 [ 1558.660432] bonding: IFF_MASTER
11:17:17 [ 1558.660611] bonding: event_dev: bond0, event: 13
11:17:17 [ 1558.660619] bonding: IFF_MASTER
11:17:17 [ 1558.660649] bonding: bond0: first active interface up!
11:17:17 [ 1558.660665] bonding: basa: target 192.168.1.1
11:17:17 [ 1558.660683] bonding: basa: rtdev == bond->dev: arp_send
11:17:17 [ 1558.660699] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:17 [ 1558.660905] bonding: event_dev: bond0, event: 4
11:17:17 [ 1558.660913] bonding: IFF_MASTER
11:17:19 [ 1560.664082] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:19 [ 1560.664103] bonding: basa: target 192.168.1.1
11:17:19 [ 1560.664128] bonding: basa: rtdev == bond->dev: arp_send
11:17:19 [ 1560.664141] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:21 [ 1562.668149] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:21 [ 1562.668169] bonding: basa: target 192.168.1.1
11:17:21 [ 1562.668189] bonding: basa: rtdev == bond->dev: arp_send
11:17:21 [ 1562.668202] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:23 [ 1564.672153] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:23 [ 1564.672174] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:17:23 [ 1564.672230] bonding: bond0: now running without any active
interface !
11:17:23 [ 1564.672243] bonding: basa: target 192.168.1.1
11:17:23 [ 1564.672258] bonding: basa: rtdev == bond->dev: arp_send
11:17:23 [ 1564.672271] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:23 [ 1564.672512] bonding: event_dev: bond0, event: 4
11:17:23 [ 1564.672520] bonding: IFF_MASTER
11:17:25 [ 1566.676149] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:17:25 [ 1566.676170] bonding: bond0: link status definitely up for
interface eth0.1002.
11:17:25 [ 1566.676182] bonding: bond0: making interface eth0.1002 the
new active one.
11:17:25 [ 1566.676222] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:25 [ 1566.676422] bonding: event_dev: bond0, event: c
11:17:25 [ 1566.676431] bonding: IFF_MASTER
11:17:25 [ 1566.676610] bonding: event_dev: bond0, event: 13
11:17:25 [ 1566.676617] bonding: IFF_MASTER
11:17:25 [ 1566.676646] bonding: bond0: first active interface up!
11:17:25 [ 1566.676660] bonding: basa: target 192.168.1.1
11:17:25 [ 1566.676678] bonding: basa: rtdev == bond->dev: arp_send
11:17:25 [ 1566.676695] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:25 [ 1566.676906] bonding: event_dev: bond0, event: 4
11:17:25 [ 1566.676914] bonding: IFF_MASTER
11:17:27 [ 1568.680155] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:27 [ 1568.680176] bonding: basa: target 192.168.1.1
11:17:27 [ 1568.680200] bonding: basa: rtdev == bond->dev: arp_send
11:17:27 [ 1568.680214] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:29 [ 1570.684149] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:29 [ 1570.684171] bonding: basa: target 192.168.1.1
11:17:29 [ 1570.684189] bonding: basa: rtdev == bond->dev: arp_send
11:17:29 [ 1570.684203] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:31 [ 1572.688152] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:31 [ 1572.688173] bonding: bond0: link status definitely down
for interface eth0.1002, disabling it
11:17:31 [ 1572.688225] bonding: bond0: now running without any active
interface !
11:17:31 [ 1572.688237] bonding: basa: target 192.168.1.1
11:17:31 [ 1572.688253] bonding: basa: rtdev == bond->dev: arp_send
11:17:31 [ 1572.688266] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:31 [ 1572.688505] bonding: event_dev: bond0, event: 4
11:17:31 [ 1572.688513] bonding: IFF_MASTER
11:17:33 [ 1574.692147] bonding: bond_should_notify_peers: bond bond0 slave NULL
11:17:33 [ 1574.692168] bonding: bond0: link status definitely up for
interface eth0.1002.
11:17:33 [ 1574.692179] bonding: bond0: making interface eth0.1002 the
new active one.
11:17:33 [ 1574.692221] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:33 [ 1574.692424] bonding: event_dev: bond0, event: c
11:17:33 [ 1574.692432] bonding: IFF_MASTER
11:17:33 [ 1574.692610] bonding: event_dev: bond0, event: 13
11:17:33 [ 1574.692618] bonding: IFF_MASTER
11:17:33 [ 1574.692648] bonding: bond0: first active interface up!
11:17:33 [ 1574.692664] bonding: basa: target 192.168.1.1
11:17:33 [ 1574.692681] bonding: basa: rtdev == bond->dev: arp_send
11:17:33 [ 1574.692697] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:33 [ 1574.692907] bonding: event_dev: bond0, event: 4
11:17:33 [ 1574.692915] bonding: IFF_MASTER
11:17:35 [ 1576.696156] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:35 [ 1576.696176] bonding: basa: target 192.168.1.1
11:17:35 [ 1576.696203] bonding: basa: rtdev == bond->dev: arp_send
11:17:35 [ 1576.696218] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0
11:17:37 [ 1578.700129] bonding: bond_should_notify_peers: bond bond0
slave eth0.1002
11:17:37 [ 1578.700145] bonding: basa: target 192.168.1.1
11:17:37 [ 1578.700162] bonding: basa: rtdev == bond->dev: arp_send
11:17:37 [ 1578.700175] bonding: arp 1 on slave eth0.1002: dst
192.168.1.1 src 192.168.1.2 vid 0

Regards.
-- 
Manty/BestiaTester -> http://manty.net

^ permalink raw reply

* [PATCH net] net: rtm_to_ifaddr: free ifa if ifa_cacheinfo processing fails
From: Daniel Borkmann @ 2013-08-02  9:32 UTC (permalink / raw)
  To: davem; +Cc: netdev, jiri

Commit 5c766d642 ("ipv4: introduce address lifetime") leaves the ifa
resource that was allocated via inet_alloc_ifa() unfreed when returning
the function with -EINVAL. Thus, free it first via inet_free_ifa().

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 net/ipv4/devinet.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 8d48c39..34ca6d5 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -772,7 +772,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
 		ci = nla_data(tb[IFA_CACHEINFO]);
 		if (!ci->ifa_valid || ci->ifa_prefered > ci->ifa_valid) {
 			err = -EINVAL;
-			goto errout;
+			goto errout_free;
 		}
 		*pvalid_lft = ci->ifa_valid;
 		*pprefered_lft = ci->ifa_prefered;
@@ -780,6 +780,8 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
 
 	return ifa;
 
+errout_free:
+	inet_free_ifa(ifa);
 errout:
 	return ERR_PTR(err);
 }
-- 
1.7.11.7

^ permalink raw reply related

* Re: [net-next 07/15] ixgbe: fix SFF data dumps of SFP+ modules
From: Ben Hutchings @ 2013-08-02  9:08 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, Emil Tantilov, netdev, gospo, sassmann
In-Reply-To: <1375102331-23905-8-git-send-email-jeffrey.t.kirsher@intel.com>

On Mon, 2013-07-29 at 05:52 -0700, Jeff Kirsher wrote:
> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> This patch fixes several issues with the previous implementation of the
> SFF data dump of SFP+ modules:
> 
> - removed the __IXGBE_READ_I2C flag - I2C access locking is handled in the
>   HW specific routines
> 
> - fixed the read loop to read data from ee->offset to ee->len
> 
> - the reads fail if __IXGBE_IN_SFP_INIT is set in the process - this is
>   needed because on some HW I2C operations can take long time and disrupt
>   the SFP and link detection process
> 
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Reported-by: Ben Hutchings <bhutchings@solarflare.com>
> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
[...]
> @@ -2969,48 +2955,25 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
>  	int i = 0;
>  	int ret_val = 0;
>  
> -	/* ixgbe_get_module_info is called before this function in all
> -	 * cases, so we do not need any checks we already do above,
> -	 * and can trust ee->len to be a known value.
> -	 */
> +	if (ee->len == 0)
> +		return -EINVAL;
>  
> -	while (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
> -		msleep(100);
> -	set_bit(__IXGBE_READ_I2C, &adapter->state);
> +	for (i = ee->offset; i < ee->len; i++) {

                               i < ee->offset + ee->len

> +		/* I2C reads can take long time */
> +		if (test_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
> +			return -EBUSY;
>  
> -	/* Read the first block, SFF-8079 */
> -	for (i = 0; i < ETH_MODULE_SFF_8079_LEN; i++) {
> -		status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
> -		if (status != 0) {
> -			/* Error occured while reading module */
> +		if (i < ETH_MODULE_SFF_8079_LEN)
> +			status  = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
> +		else
> +			status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);
[...]
                                                     i - ETH_MODULE_SFF_8079_LEN ?

But this works anyway because the address is truncated to u8.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH] net: ethernet: cpsw: drop IRQF_DISABLED
From: Mugunthan V N @ 2013-08-02  9:06 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: davem, netdev, Linux OMAP Mailing List
In-Reply-To: <1375429450-25454-1-git-send-email-balbi@ti.com>

On Friday 02 August 2013 01:14 PM, Felipe Balbi wrote:
> IRQF_DISABLED is a no-op by now and should be
> removed.
>
> Signed-off-by: Felipe Balbi<balbi@ti.com>
Acked-by: Mugunthan V N <mugunthanvnm@ti.com>

Regards
Mugunthan V N

^ permalink raw reply

* Re: How do I receive vlan tags on an AF_PACKET socket in 3.4 kernel?
From: Ronny Meeus @ 2013-08-02  9:03 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: Eric Dumazet, netdev
In-Reply-To: <51FB6A9D.2050002@redhat.com>

On Fri, Aug 2, 2013 at 10:15 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
> On 08/01/2013 11:24 AM, Ronny Meeus wrote:
>>
>> On Wed, Jul 31, 2013 at 10:47 PM, Eric Dumazet <eric.dumazet@gmail.com>
>> wrote:
>>>
>>> On Wed, 2013-07-31 at 22:01 +0200, Ronny Meeus wrote:
>>>>
>>>> On Wed, Jul 31, 2013 at 5:09 PM, Eric Dumazet <eric.dumazet@gmail.com>
>>>> wrote:
>>>>>
>>>>> On Wed, 2013-07-31 at 16:42 +0200, Daniel Borkmann wrote:
>>>>>
>>>>>> You can use bpfc (git://github.com/borkmann/netsniff-ng.git), it also
>>>>>> has
>>>>>> an extensive man page. That should probably do it:
>>>>>>
>>>>>> $ cat foo
>>>>>> ld vlant
>>>>>> jneq #4094, drop
>>>>>> ret #-1
>>>>>> drop: ret #0
>>>>>>
>>>>>> $ bpfc foo
>>>>>> { 0x20, 0, 0, 0xfffff02c },
>>>>>> { 0x15, 0, 1, 0x00000ffe },
>>>>>> { 0x6, 0, 0, 0xffffffff },
>>>>>> { 0x6, 0, 0, 0x00000000 },
>>>>>
>>>>>
>>>>
>>>> Thanks Daniel, this is very useful information.
>>>> I have cloned the repo and compiled the tool myself. It will be very
>>>> useful in the future.
>>>>
>>>>> Thanks Daniel.
>>>>>
>>>>> If the load of this BPF fails (because its an old kernel), then load
>>>>> your old filter.
>>>>>
>>>>
>>>> I created a small test application after I backported the filter code
>>>> to the 3.4 kernel.
>>>> I instrumented the kernel with a printk at the moment the
>>>> vlan_tx_tag_get call is done to see the actual value of the vlan tag
>>>> since it did not work initially.
>>>>
>>>> These are the packets displayed by tcpdump:
>>>>
>>>> tcpdump: WARNING: eth-ntb: no IPv4 address assigned
>>>> tcpdump: verbose output suppressed, use -v or -vv for full protocol
>>>> decode
>>>> listening on eth-ntb, link-type EN10MB (Ethernet), capture size 65535
>>>> bytes
>>>> 00:18:49.233283 06:00:00:00:00:80 > f7:00:00:00:ff:ff, ethertype
>>>> 802.1Q (0x8100), length 64:
>>>>          0x0000:  f700 0000 ffff 0600 0000 0080 8100 affe
>>>>          0x0010:  08ab 0014 0000 0000 0f00 0001 0096 6000
>>>>          0x0020:  0096 0000 0001 0000 000d 0000 0000 0000
>>>>          0x0030:  0000 0000 0000 0000 0000 0000 0000 0000
>>>>
>>>> So the Vlan is 0xffe and the priority/CFI field is 0xA.
>>>> Apparently the value I need to  use in the filter is 0xaffe to make it
>>>> work. Is this normal or is this a bug in the kernel?
>>>>
>>>> This is the filter I used:
>>>> { 0x20, 0, 0, 0xfffff02c }
>>>> { 0x15, 0, 1, 0x0000affe }
>>>> { 0x06, 0, 0, 0x00000800 }
>>>> { 0x06, 0, 0, 0x00000000 }
>>>>
>>>> And this is the trace of the kernel and my application:
>>>>
>>>> [12529.357172] BPF_S_ANC_VLAN_TAG: affe
>>>> packets received:          1
>>>> [12533.020743] BPF_S_ANC_VLAN_TAG: affe
>>>> packets received:          2
>>>> [12536.667159] BPF_S_ANC_VLAN_TAG: affe
>>>> packets received:          3
>>>> [12540.343857] BPF_S_ANC_VLAN_TAG: affe
>>>> packets received:          4
>>>
>>>
>>> Right, vlan_tx_tag_get() gets the whole tag, so you want to mask A with
>>> 0xfff before the compare (to strip the prio)
>>>
>>> ld vlant
>>> and #4095
>>> jneq #4094, drop
>>> ret #-1
>>> drop: ret #0
>>>
>>> or something like that.
>>
>>
>> OK the receiving side is clear now. Thanks.
>>
>> Now the sending side.
>> I created an application that sends packets using libpcap. These
>> packets are full Ethernet packets, including VLAN tags etc.
>> If I connect a PC running Wireshark to the Ethernet port I'm sending
>> on I receive the packets, no issues.
>>
>> If a start on the device that is sending the packets also the receive
>> application I created before I do not receive anything.
>> This is because the filter attached to the kernel by this application
>> is checking the VLAN tag in metadata of the buffer, which is in this
>> case not filled in.
>> If I do not attach a filter to the receiving application all packets I
>> send are also received by the receiving application, which is what I
>> expect since all packets sent on a raw socket are received by all
>> other sockets listening on the same interface.
>>
>> I have the feeling that there is something wrong with the current
>> implementation.
>> In my opinion, the same VLAN processing as done for packets received
>> from the network (strip vlan and put it in the meta data) should be
>> done on packets that are sent by an application just before passing
>> them to other sockets listening on the same interface.
>> Right?
>
>
> Nope, we already had this discussion in the past [1]. ;-)
>
> The vlan id is in skb->vlan_id when vlan accel is on, or in the packet
> itself when vlan accel off. Thus, you can distinguish accelerated traffic
> from non-accelerated one as well.
>

Not completely correct in my opinion.
The vlan is never present in the packet anymore. It is always put in
the skb->vlan_id, also for non-accelerated environments.

> If you want to filter for it, you need to extend your BPF filter by adding
> an ethernet type/vlan id check in the packet itself in case the loaded
> vlant instruction does not equal the id that you're looking for, thus this
> is being done as a fallback. And actually libpcap is supposed to do the same
> in their filter compiler.

This is an option, but it costs performance and like I said before,
the vlan is always removed by the kernel.

>  [1] http://article.gmane.org/gmane.linux.network/254454

^ permalink raw reply

* Re: changing dev->needed_headroom/needed_tailroom?
From: Ben Hutchings @ 2013-08-02  8:55 UTC (permalink / raw)
  To: Johannes Berg
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1374850210.8248.59.camel-8Nb76shvtaUJvtFkdXX2HixXY32XiHfO@public.gmane.org>

On Fri, 2013-07-26 at 16:50 +0200, Johannes Berg wrote:
> Does it seem reasonable to change dev->needed_headroom and
> dev->needed_tailroom on the fly?
> 
> We currently set needed_headroom to the max of what we need, but we
> could do better like making it depend on the interface type (e.g. only
> asking for mesh space on mesh interfaces). This would be done only when
> the interface isn't connected, I can't promise it would be down but the
> carrier would be off.
[...]

I don't think this is safe when the interface is running (even if
carrier is off).  Some functions may read dev->needed_headroom twice and
rely on getting the same value each time.

Also, stacked devices would need to adjust their own needed_headroom
accordingly.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v3] r8169: remove "PHY reset until link up" log spam
From: Peter Wu @ 2013-08-02  8:36 UTC (permalink / raw)
  To: Francois Romieu
  Cc: Sergei Shtylyov, David Miller, netdev, nic_swsd, lekensteyn

This message was added in commit a7154cb8 (June 2004, [PATCH] r8169:
link handling and phy reset rework) and is printed every ten seconds
when no cable is connected and runtime power management is disabled.
(Before that commit, "Reset RTL8169s PHY" would be printed instead.)

Signed-off-by: Peter Wu <lekensteyn@gmail.com>
---
 drivers/net/ethernet/realtek/r8169.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 880015c..b5eb419 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -3689,7 +3689,7 @@ static void rtl_phy_work(struct rtl8169_private *tp)
 	if (tp->link_ok(ioaddr))
 		return;
 
-	netif_warn(tp, link, tp->dev, "PHY reset until link up\n");
+	netif_dbg(tp, link, tp->dev, "PHY reset until link up\n");
 
 	tp->phy_reset_enable(tp);
 
-- 
1.8.3.3

^ permalink raw reply related

* Re: How do I receive vlan tags on an AF_PACKET socket in 3.4 kernel?
From: Daniel Borkmann @ 2013-08-02  8:15 UTC (permalink / raw)
  To: Ronny Meeus; +Cc: Eric Dumazet, netdev
In-Reply-To: <CAMJ=MEfZbCzQAzA-G9ooZQrwjR2vf7FGf4p66J0H6Eo2Xtdw0A@mail.gmail.com>

On 08/01/2013 11:24 AM, Ronny Meeus wrote:
> On Wed, Jul 31, 2013 at 10:47 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> On Wed, 2013-07-31 at 22:01 +0200, Ronny Meeus wrote:
>>> On Wed, Jul 31, 2013 at 5:09 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>>> On Wed, 2013-07-31 at 16:42 +0200, Daniel Borkmann wrote:
>>>>
>>>>> You can use bpfc (git://github.com/borkmann/netsniff-ng.git), it also has
>>>>> an extensive man page. That should probably do it:
>>>>>
>>>>> $ cat foo
>>>>> ld vlant
>>>>> jneq #4094, drop
>>>>> ret #-1
>>>>> drop: ret #0
>>>>>
>>>>> $ bpfc foo
>>>>> { 0x20, 0, 0, 0xfffff02c },
>>>>> { 0x15, 0, 1, 0x00000ffe },
>>>>> { 0x6, 0, 0, 0xffffffff },
>>>>> { 0x6, 0, 0, 0x00000000 },
>>>>
>>>
>>> Thanks Daniel, this is very useful information.
>>> I have cloned the repo and compiled the tool myself. It will be very
>>> useful in the future.
>>>
>>>> Thanks Daniel.
>>>>
>>>> If the load of this BPF fails (because its an old kernel), then load
>>>> your old filter.
>>>>
>>>
>>> I created a small test application after I backported the filter code
>>> to the 3.4 kernel.
>>> I instrumented the kernel with a printk at the moment the
>>> vlan_tx_tag_get call is done to see the actual value of the vlan tag
>>> since it did not work initially.
>>>
>>> These are the packets displayed by tcpdump:
>>>
>>> tcpdump: WARNING: eth-ntb: no IPv4 address assigned
>>> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
>>> listening on eth-ntb, link-type EN10MB (Ethernet), capture size 65535 bytes
>>> 00:18:49.233283 06:00:00:00:00:80 > f7:00:00:00:ff:ff, ethertype
>>> 802.1Q (0x8100), length 64:
>>>          0x0000:  f700 0000 ffff 0600 0000 0080 8100 affe
>>>          0x0010:  08ab 0014 0000 0000 0f00 0001 0096 6000
>>>          0x0020:  0096 0000 0001 0000 000d 0000 0000 0000
>>>          0x0030:  0000 0000 0000 0000 0000 0000 0000 0000
>>>
>>> So the Vlan is 0xffe and the priority/CFI field is 0xA.
>>> Apparently the value I need to  use in the filter is 0xaffe to make it
>>> work. Is this normal or is this a bug in the kernel?
>>>
>>> This is the filter I used:
>>> { 0x20, 0, 0, 0xfffff02c }
>>> { 0x15, 0, 1, 0x0000affe }
>>> { 0x06, 0, 0, 0x00000800 }
>>> { 0x06, 0, 0, 0x00000000 }
>>>
>>> And this is the trace of the kernel and my application:
>>>
>>> [12529.357172] BPF_S_ANC_VLAN_TAG: affe
>>> packets received:          1
>>> [12533.020743] BPF_S_ANC_VLAN_TAG: affe
>>> packets received:          2
>>> [12536.667159] BPF_S_ANC_VLAN_TAG: affe
>>> packets received:          3
>>> [12540.343857] BPF_S_ANC_VLAN_TAG: affe
>>> packets received:          4
>>
>> Right, vlan_tx_tag_get() gets the whole tag, so you want to mask A with
>> 0xfff before the compare (to strip the prio)
>>
>> ld vlant
>> and #4095
>> jneq #4094, drop
>> ret #-1
>> drop: ret #0
>>
>> or something like that.
>
> OK the receiving side is clear now. Thanks.
>
> Now the sending side.
> I created an application that sends packets using libpcap. These
> packets are full Ethernet packets, including VLAN tags etc.
> If I connect a PC running Wireshark to the Ethernet port I'm sending
> on I receive the packets, no issues.
>
> If a start on the device that is sending the packets also the receive
> application I created before I do not receive anything.
> This is because the filter attached to the kernel by this application
> is checking the VLAN tag in metadata of the buffer, which is in this
> case not filled in.
> If I do not attach a filter to the receiving application all packets I
> send are also received by the receiving application, which is what I
> expect since all packets sent on a raw socket are received by all
> other sockets listening on the same interface.
>
> I have the feeling that there is something wrong with the current
> implementation.
> In my opinion, the same VLAN processing as done for packets received
> from the network (strip vlan and put it in the meta data) should be
> done on packets that are sent by an application just before passing
> them to other sockets listening on the same interface.
> Right?

Nope, we already had this discussion in the past [1]. ;-)

The vlan id is in skb->vlan_id when vlan accel is on, or in the packet
itself when vlan accel off. Thus, you can distinguish accelerated traffic
from non-accelerated one as well.

If you want to filter for it, you need to extend your BPF filter by adding
an ethernet type/vlan id check in the packet itself in case the loaded
vlant instruction does not equal the id that you're looking for, thus this
is being done as a fallback. And actually libpcap is supposed to do the same
in their filter compiler.

  [1] http://article.gmane.org/gmane.linux.network/254454

^ permalink raw reply

* (unknown)
From: Анатолий @ 2013-08-02  7:41 UTC (permalink / raw)
  To: netdev



^ permalink raw reply

* Re: PROBLEM: 3.11.0-rc2+ lost of connectivity
From: Sebastiano Spicuglia @ 2013-08-02  7:44 UTC (permalink / raw)
  To: Sebastiano Spicuglia, linux-kernel, jeffrey.t.kirsher,
	jesse.brandeburg, bruce.w.allan, carolyn.wyborny,
	donald.c.skidmore, gregory.v.rose, peter.p.waskiewicz.jr,
	alexander.h.duyck, john.ronciak, tushar.n.dave, davem, netdev,
	Alexey Kuznetsov, jmorris, yoshfuji, Patrick McHardy,
	xiyou.wangcong
In-Reply-To: <CAOSRKdRTrORuV0zibXZT=P-aL98QOkouZ=PreFs7wWSjjaAFLA@mail.gmail.com>

Hello everyone,

I let the system running for almost 12 hours
but the failure didn't show up.

I'll provide you the dropwatch output once the
failure happens again.

- Sebastiano


On Thu, Aug 1, 2013 at 4:40 PM, Sebastiano Spicuglia
<spicuglia.sebastiano@gmail.com> wrote:
> Hi Hannes,
>
> here the info about the commit:
>
> commit 6c504ecf506705a6575541b28824e13090bd223b
> Merge: 2408c2e bf903e4
> Author: Linus Torvalds <torvalds@linux-foundation.org>
> Date:   Fri Jul 26 14:40:10 2013 -0700
>
> Regards
> Sebastiano
>
>
> On Thu, Aug 1, 2013 at 4:36 PM, Hannes Frederic Sowa
> <hannes@stressinduktion.org> wrote:
>> On Thu, Aug 01, 2013 at 04:34:00PM +0200, Sebastiano Spicuglia wrote:
>>> [Kernel version from /proc/version ]
>>>
>>> Linux version 3.11.0-rc2+ (root@cache.pdbg) (gcc version 4.7.2 (Debian
>>> 4.7.2-5) ) #5 SMP Thu Aug 1 14:20:35 CEST 2013
>>
>> Which commit exactly?
>>
>> Thanks,
>>
>>   Hannes
>>

^ permalink raw reply

* [PATCH] net: ethernet: cpsw: drop IRQF_DISABLED
From: Felipe Balbi @ 2013-08-02  7:44 UTC (permalink / raw)
  To: Mugunthan V N; +Cc: davem, netdev, Linux OMAP Mailing List, Felipe Balbi

IRQF_DISABLED is a no-op by now and should be
removed.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/net/ethernet/ti/cpsw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 05a1674..22a7a43 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1867,7 +1867,7 @@ static int cpsw_probe(struct platform_device *pdev)
 
 	while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
 		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, cpsw_interrupt, IRQF_DISABLED,
+			if (request_irq(i, cpsw_interrupt, 0,
 					dev_name(&pdev->dev), priv)) {
 				dev_err(priv->dev, "error attaching irq\n");
 				goto clean_ale_ret;
-- 
1.8.3.4.840.g6a90778

^ permalink raw reply related

* Re: bonding + arp monitoring fails if interface is a vlan
From: Santiago Garcia Mantinan @ 2013-08-02  7:30 UTC (permalink / raw)
  To: Veaceslav Falico; +Cc: netdev
In-Reply-To: <CAE3RKN=AoevKmRDewpmm8TjDasN8k=J4Sny8gCCv6dbOXwHADQ@mail.gmail.com>

2013/8/1 Veaceslav Falico <darkmag@gmail.com>:
>>         bond-slaves eth0.1002
>>         bond-mode active-backup
>>         bond-arp_validate 0
> Could you please try with arp_validate=1?

arp_validate=1 was what I first tried, then I thought that making
validations could be dropping packages so I went for the 0
validations, both had the same problem.

Regards.
-- 
Manty/BestiaTester -> http://manty.net

^ permalink raw reply

* Re: bonding + arp monitoring fails if interface is a vlan
From: Santiago Garcia Mantinan @ 2013-08-02  7:26 UTC (permalink / raw)
  To: Erik Hugne; +Cc: netdev
In-Reply-To: <20130801130058.GA13602@eerihug-hybrid.rnd.ki.sw.ericsson.se>

2013/8/1 Erik Hugne <erik.hugne@ericsson.com>
> This have helped me troubleshoot various bonding problems in the past:
> mount -t debugfs none /sys/kernel/debug/
> ln -s /sys/kernel/debug /debug
> echo -n 'module bonding +p' > /debug/dynamic_debug/control

I'm compiling a 3.11-rc3 version with dynamic_debug enabled in order
to be able to test this.

> Did you sniff externally, on the native device, bond slaves or on bond0?

The sniffing was done on both the bonding host (eth0 device) and the
remote host, the one with just the vlan.

Regards.
-- 
Manty/BestiaTester -> http://manty.net

^ permalink raw reply

* [Patch net-next v2 7/8] sctp: use generic union inet_addr
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Daniel Borkmann, Vlad Yasevich, Neil Horman,
	linux-sctp, Cong Wang
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

From: Cong Wang <amwang@redhat.com>

sctp has its own union sctp_addr which is nearly same
with the generic union inet_addr, so just convert it
to the generic one.

Sorry for the big patch, it is not easy to split it. Most
of the patch simply does s/union sctp_addr/union inet_addr/
and some adjustments for the fields.

The address family specific ops, ->cmp_addr(), ->is_any() etc.,
are removed, since we have generic helpers, they are unnecessary.

Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: linux-sctp@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 include/net/sctp/sctp.h    |   22 ++--
 include/net/sctp/sm.h      |    4 +-
 include/net/sctp/structs.h |  132 +++++++++++-------------
 net/sctp/associola.c       |   26 +++---
 net/sctp/bind_addr.c       |   61 ++++--------
 net/sctp/endpointola.c     |   12 +-
 net/sctp/input.c           |   56 +++++-----
 net/sctp/ipv6.c            |  240 +++++++++++++++++++-------------------------
 net/sctp/outqueue.c        |    4 +-
 net/sctp/proc.c            |   10 +-
 net/sctp/protocol.c        |  198 ++++++++++++++----------------------
 net/sctp/sm_make_chunk.c   |   54 +++++-----
 net/sctp/sm_statefuns.c    |   23 ++---
 net/sctp/socket.c          |  126 +++++++++++++-----------
 net/sctp/transport.c       |   12 +-
 net/sctp/ulpevent.c        |    2 +-
 16 files changed, 437 insertions(+), 545 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 554cf88..84f943a 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -590,22 +590,22 @@ static inline int __sctp_sstate(const struct sock *sk, sctp_sock_state_t state)
 }
 
 /* Map v4-mapped v6 address back to v4 address */
-static inline void sctp_v6_map_v4(union sctp_addr *addr)
+static inline void sctp_v6_map_v4(union inet_addr *addr)
 {
-	addr->v4.sin_family = AF_INET;
-	addr->v4.sin_port = addr->v6.sin6_port;
-	addr->v4.sin_addr.s_addr = addr->v6.sin6_addr.s6_addr32[3];
+	addr->sin.sin_family = AF_INET;
+	addr->sin.sin_port = addr->sin6.sin6_port;
+	addr->sin.sin_addr.s_addr = addr->sin6.sin6_addr.s6_addr32[3];
 }
 
 /* Map v4 address to v4-mapped v6 address */
-static inline void sctp_v4_map_v6(union sctp_addr *addr)
+static inline void sctp_v4_map_v6(union inet_addr *addr)
 {
-	addr->v6.sin6_family = AF_INET6;
-	addr->v6.sin6_port = addr->v4.sin_port;
-	addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
-	addr->v6.sin6_addr.s6_addr32[0] = 0;
-	addr->v6.sin6_addr.s6_addr32[1] = 0;
-	addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
+	addr->sin6.sin6_family = AF_INET6;
+	addr->sin6.sin6_port = addr->sin.sin_port;
+	addr->sin6.sin6_addr.s6_addr32[3] = addr->sin.sin_addr.s_addr;
+	addr->sin6.sin6_addr.s6_addr32[0] = 0;
+	addr->sin6.sin6_addr.s6_addr32[1] = 0;
+	addr->sin6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff);
 }
 
 /* The cookie is always 0 since this is how it's used in the
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 2aa66dd..0040c3e 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -250,11 +250,11 @@ struct sctp_chunk *sctp_make_op_error(const struct sctp_association *,
 				 size_t reserve_tail);
 
 struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *,
-					      union sctp_addr *,
+					      union inet_addr *,
 					      struct sockaddr *,
 					      int, __be16);
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
-					     union sctp_addr *addr);
+					     union inet_addr *addr);
 int sctp_verify_asconf(const struct sctp_association *asoc,
 		       struct sctp_paramhdr *param_hdr, void *chunk_end,
 		       struct sctp_paramhdr **errp);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 75c4c16..dae7bc5 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -65,15 +65,7 @@
 #include <linux/workqueue.h>	/* We need tq_struct.	 */
 #include <linux/sctp.h>		/* We need sctp* header structs.  */
 #include <net/sctp/auth.h>	/* We need auth specific structs */
-
-/* A convenience structure for handling sockaddr structures.
- * We should wean ourselves off this.
- */
-union sctp_addr {
-	struct sockaddr_in v4;
-	struct sockaddr_in6 v6;
-	struct sockaddr sa;
-};
+#include <net/inet_addr.h>
 
 /* Forward declarations for data structures. */
 struct sctp_globals;
@@ -296,7 +288,7 @@ struct sctp_cookie {
 	__u32 initial_tsn;
 
 	/* This holds the originating address of the INIT packet.  */
-	union sctp_addr peer_addr;
+	union inet_addr peer_addr;
 
 	/* IG Section 2.35.3 
 	 * Include the source port of the INIT-ACK
@@ -372,7 +364,7 @@ union sctp_params {
  */
 typedef struct sctp_sender_hb_info {
 	struct sctp_paramhdr param_hdr;
-	union sctp_addr daddr;
+	union inet_addr daddr;
 	unsigned long sent_at;
 	__u64 hb_nonce;
 } __packed sctp_sender_hb_info_t;
@@ -453,7 +445,7 @@ struct sctp_af {
 					 char __user *optval,
 					 int __user *optlen);
 	void		(*get_dst)	(struct sctp_transport *t,
-					 union sctp_addr *saddr,
+					 union inet_addr *saddr,
 					 struct flowi *fl,
 					 struct sock *sk);
 	void		(*get_saddr)	(struct sctp_sock *sk,
@@ -461,36 +453,32 @@ struct sctp_af {
 					 struct flowi *fl);
 	void		(*copy_addrlist) (struct list_head *,
 					  struct net_device *);
-	int		(*cmp_addr)	(const union sctp_addr *addr1,
-					 const union sctp_addr *addr2);
-	void		(*addr_copy)	(union sctp_addr *dst,
-					 union sctp_addr *src);
-	void		(*from_skb)	(union sctp_addr *,
+	bool		(*cmp_addr)	(const union inet_addr *addr1,
+					 const union inet_addr *addr2);
+	void		(*addr_copy)	(union inet_addr *dst,
+					 union inet_addr *src);
+	void		(*from_skb)	(union inet_addr *,
 					 struct sk_buff *skb,
 					 int saddr);
-	void		(*from_sk)	(union sctp_addr *,
+	void		(*from_sk)	(union inet_addr *,
 					 struct sock *sk);
-	void		(*to_sk_saddr)	(union sctp_addr *,
+	void		(*to_sk_saddr)	(union inet_addr *,
 					 struct sock *sk);
-	void		(*to_sk_daddr)	(union sctp_addr *,
+	void		(*to_sk_daddr)	(union inet_addr *,
 					 struct sock *sk);
-	void		(*from_addr_param) (union sctp_addr *,
+	void		(*from_addr_param) (union inet_addr *,
 					    union sctp_addr_param *,
 					    __be16 port, int iif);
-	int		(*to_addr_param) (const union sctp_addr *,
+	int		(*to_addr_param) (const union inet_addr *,
 					  union sctp_addr_param *); 
-	int		(*addr_valid)	(union sctp_addr *,
+	int		(*addr_valid)	(union inet_addr *,
 					 struct sctp_sock *,
 					 const struct sk_buff *);
-	sctp_scope_t	(*scope) (union sctp_addr *);
-	void		(*inaddr_any)	(union sctp_addr *, __be16);
-	int		(*is_any)	(const union sctp_addr *);
-	int		(*available)	(union sctp_addr *,
+	sctp_scope_t	(*scope) (union inet_addr *);
+	int		(*available)	(union inet_addr *,
 					 struct sctp_sock *);
 	int		(*skb_iif)	(const struct sk_buff *sk);
 	int		(*is_ce)	(const struct sk_buff *sk);
-	void		(*seq_dump_addr)(struct seq_file *seq,
-					 union sctp_addr *addr);
 	void		(*ecn_capable)(struct sock *sk);
 	__u16		net_header_len;
 	int		sockaddr_len;
@@ -506,15 +494,15 @@ struct sctp_pf {
 	void (*event_msgname)(struct sctp_ulpevent *, char *, int *);
 	void (*skb_msgname)  (struct sk_buff *, char *, int *);
 	int  (*af_supported) (sa_family_t, struct sctp_sock *);
-	int  (*cmp_addr) (const union sctp_addr *,
-			  const union sctp_addr *,
+	int  (*cmp_addr) (const union inet_addr *,
+			  const union inet_addr *,
 			  struct sctp_sock *);
-	int  (*bind_verify) (struct sctp_sock *, union sctp_addr *);
-	int  (*send_verify) (struct sctp_sock *, union sctp_addr *);
+	int  (*bind_verify) (struct sctp_sock *, union inet_addr *);
+	int  (*send_verify) (struct sctp_sock *, union inet_addr *);
 	int  (*supported_addrs)(const struct sctp_sock *, __be16 *);
 	struct sock *(*create_accept_sk) (struct sock *sk,
 					  struct sctp_association *asoc);
-	void (*addr_v4map) (struct sctp_sock *, union sctp_addr *);
+	void (*addr_v4map) (struct sctp_sock *, union inet_addr *);
 	struct sctp_af *af;
 };
 
@@ -613,9 +601,9 @@ struct sctp_chunk {
 	unsigned long sent_at;
 
 	/* What is the origin IP address for this chunk?  */
-	union sctp_addr source;
+	union inet_addr source;
 	/* Destination address for this chunk. */
-	union sctp_addr dest;
+	union inet_addr dest;
 
 	/* For outbound message, track all fragments for SEND_FAILED. */
 	struct sctp_datamsg *msg;
@@ -661,9 +649,9 @@ void  *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
 				 const struct sctp_association *,
 				 struct sock *);
-void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
-		     union sctp_addr *);
-const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
+void sctp_init_addrs(struct sctp_chunk *, union inet_addr *,
+		     union inet_addr *);
+const union inet_addr *sctp_source(const struct sctp_chunk *chunk);
 
 enum {
 	SCTP_ADDR_NEW,		/* new address added to assoc/ep */
@@ -675,7 +663,7 @@ enum {
 struct sctp_sockaddr_entry {
 	struct list_head list;
 	struct rcu_head	rcu;
-	union sctp_addr a;
+	union inet_addr a;
 	__u8 state;
 	__u8 valid;
 };
@@ -734,7 +722,7 @@ static inline int sctp_packet_empty(struct sctp_packet *packet)
 }
 
 /* This represents a remote transport address.
- * For local transport addresses, we just use union sctp_addr.
+ * For local transport addresses, we just use union inet_addr.
  *
  * RFC2960 Section 1.4 Key Terms
  *
@@ -786,7 +774,7 @@ struct sctp_transport {
 	struct flowi fl;
 
 	/* This is the peer's IP address and port. */
-	union sctp_addr ipaddr;
+	union inet_addr ipaddr;
 
 	/* These are the functions we call to handle LLP stuff.	 */
 	struct sctp_af *af_specific;
@@ -835,7 +823,7 @@ struct sctp_transport {
 	/* Destination */
 	struct dst_entry *dst;
 	/* Source address. */
-	union sctp_addr saddr;
+	union inet_addr saddr;
 
 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
 	 * the destination address every heartbeat interval.
@@ -948,11 +936,11 @@ struct sctp_transport {
 	struct rcu_head rcu;
 };
 
-struct sctp_transport *sctp_transport_new(struct net *, const union sctp_addr *,
+struct sctp_transport *sctp_transport_new(struct net *, const union inet_addr *,
 					  gfp_t);
 void sctp_transport_set_owner(struct sctp_transport *,
 			      struct sctp_association *);
-void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
+void sctp_transport_route(struct sctp_transport *, union inet_addr *,
 			  struct sctp_sock *);
 void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
 void sctp_transport_free(struct sctp_transport *);
@@ -1103,17 +1091,17 @@ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest,
 int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
 			const struct sctp_bind_addr *src,
 			gfp_t gfp);
-int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
+int sctp_add_bind_addr(struct sctp_bind_addr *, union inet_addr *,
 		       __u8 addr_state, gfp_t gfp);
-int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
-int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
+int sctp_del_bind_addr(struct sctp_bind_addr *, union inet_addr *);
+int sctp_bind_addr_match(struct sctp_bind_addr *, const union inet_addr *,
 			 struct sctp_sock *);
-int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union sctp_addr *,
+int sctp_bind_addr_conflict(struct sctp_bind_addr *, const union inet_addr *,
 			 struct sctp_sock *, struct sctp_sock *);
 int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
-			 const union sctp_addr *addr);
-union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
-					const union sctp_addr	*addrs,
+			 const union inet_addr *addr);
+union inet_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
+					const union inet_addr	*addrs,
 					int			addrcnt,
 					struct sctp_sock	*opt);
 union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
@@ -1122,10 +1110,10 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
 int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
 			   __u16 port, gfp_t gfp);
 
-sctp_scope_t sctp_scope(const union sctp_addr *);
-int sctp_in_scope(struct net *net, const union sctp_addr *addr, const sctp_scope_t scope);
-int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
-int sctp_addr_is_valid(const union sctp_addr *addr);
+sctp_scope_t sctp_scope(const union inet_addr *);
+int sctp_in_scope(struct net *net, const union inet_addr *addr, const sctp_scope_t scope);
+int sctp_is_any(struct sock *sk, const union inet_addr *addr);
+int sctp_addr_is_valid(const union inet_addr *addr);
 int sctp_is_ep_boundall(struct sock *sk);
 
 
@@ -1271,20 +1259,20 @@ void sctp_endpoint_hold(struct sctp_endpoint *);
 void sctp_endpoint_add_asoc(struct sctp_endpoint *, struct sctp_association *);
 struct sctp_association *sctp_endpoint_lookup_assoc(
 	const struct sctp_endpoint *ep,
-	const union sctp_addr *paddr,
+	const union inet_addr *paddr,
 	struct sctp_transport **);
 int sctp_endpoint_is_peeled_off(struct sctp_endpoint *,
-				const union sctp_addr *);
+				const union inet_addr *);
 struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *,
-					struct net *, const union sctp_addr *);
-int sctp_has_association(struct net *net, const union sctp_addr *laddr,
-			 const union sctp_addr *paddr);
+					struct net *, const union inet_addr *);
+int sctp_has_association(struct net *net, const union inet_addr *laddr,
+			 const union inet_addr *paddr);
 
 int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
 		     sctp_cid_t, sctp_init_chunk_t *peer_init,
 		     struct sctp_chunk *chunk, struct sctp_chunk **err_chunk);
 int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
-		      const union sctp_addr *peer,
+		      const union inet_addr *peer,
 		      sctp_init_chunk_t *init, gfp_t gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
@@ -1424,7 +1412,7 @@ struct sctp_association {
 		/* Cache the primary path address here, when we
 		 * need a an address for msg_name.
 		 */
-		union sctp_addr primary_addr;
+		union inet_addr primary_addr;
 
 		/* active_path
 		 *   The path that we are currently using to
@@ -1825,7 +1813,7 @@ struct sctp_association {
 	 * after reaching 4294967295.
 	 */
 	__u32 addip_serial;
-	union sctp_addr *asconf_addr_del_pending;
+	union inet_addr *asconf_addr_del_pending;
 	int src_out_of_asoc_ok;
 	struct sctp_transport *new_transport;
 
@@ -1884,15 +1872,15 @@ struct sctp_transport *sctp_assoc_choose_alter_transport(
 	struct sctp_association *, struct sctp_transport *);
 void sctp_assoc_update_retran_path(struct sctp_association *);
 struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *,
-					  const union sctp_addr *);
+					  const union inet_addr *);
 int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
-			    const union sctp_addr *laddr);
+			    const union inet_addr *laddr);
 struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
-				     const union sctp_addr *address,
+				     const union inet_addr *address,
 				     const gfp_t gfp,
 				     const int peer_state);
 void sctp_assoc_del_peer(struct sctp_association *asoc,
-			 const union sctp_addr *addr);
+			 const union inet_addr *addr);
 void sctp_assoc_rm_peer(struct sctp_association *asoc,
 			 struct sctp_transport *peer);
 void sctp_assoc_control_transport(struct sctp_association *,
@@ -1901,8 +1889,8 @@ void sctp_assoc_control_transport(struct sctp_association *,
 struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *, __u32);
 struct sctp_transport *sctp_assoc_is_match(struct sctp_association *,
 					   struct net *,
-					   const union sctp_addr *,
-					   const union sctp_addr *);
+					   const union inet_addr *,
+					   const union inet_addr *);
 void sctp_assoc_migrate(struct sctp_association *, struct sock *);
 void sctp_assoc_update(struct sctp_association *old,
 		       struct sctp_association *new);
@@ -1928,8 +1916,8 @@ struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
 					__be32 serial);
 void sctp_asconf_queue_teardown(struct sctp_association *asoc);
 
-int sctp_cmp_addr_exact(const union sctp_addr *ss1,
-			const union sctp_addr *ss2);
+int sctp_cmp_addr_exact(const union inet_addr *ss1,
+			const union inet_addr *ss2);
 struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
 
 /* A convenience structure to parse out SCTP specific CMSGs. */
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 07aff2b..0961b9f 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -493,7 +493,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
 
 	/* Set a default msg_name for events. */
 	memcpy(&asoc->peer.primary_addr, &transport->ipaddr,
-	       sizeof(union sctp_addr));
+	       sizeof(union inet_addr));
 
 	/* If the primary path is changing, assume that the
 	 * user wants to use this new path.
@@ -623,7 +623,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
 
 /* Add a transport address to an association.  */
 struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
-					   const union sctp_addr *addr,
+					   const union inet_addr *addr,
 					   const gfp_t gfp,
 					   const int peer_state)
 {
@@ -635,7 +635,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 	sp = sctp_sk(asoc->base.sk);
 
 	/* AF_INET and AF_INET6 share common port field. */
-	port = ntohs(addr->v4.sin_port);
+	port = ntohs(addr->sin.sin_port);
 
 	pr_debug("%s: association:%p addr:%pIApc state:%d\n", __func__,
 		 asoc, &addr->sa, peer_state);
@@ -767,7 +767,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 
 /* Delete a transport address from an association.  */
 void sctp_assoc_del_peer(struct sctp_association *asoc,
-			 const union sctp_addr *addr)
+			 const union inet_addr *addr)
 {
 	struct list_head	*pos;
 	struct list_head	*temp;
@@ -786,7 +786,7 @@ void sctp_assoc_del_peer(struct sctp_association *asoc,
 /* Lookup a transport by address. */
 struct sctp_transport *sctp_assoc_lookup_paddr(
 					const struct sctp_association *asoc,
-					const union sctp_addr *address)
+					const union inet_addr *address)
 {
 	struct sctp_transport *t;
 
@@ -983,8 +983,8 @@ __u32 sctp_association_get_next_tsn(struct sctp_association *asoc)
 /* Compare two addresses to see if they match.  Wildcard addresses
  * only match themselves.
  */
-int sctp_cmp_addr_exact(const union sctp_addr *ss1,
-			const union sctp_addr *ss2)
+int sctp_cmp_addr_exact(const union inet_addr *ss1,
+			const union inet_addr *ss2)
 {
 	struct sctp_af *af;
 
@@ -1075,13 +1075,13 @@ out:
 /* Is this the association we are looking for? */
 struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
 					   struct net *net,
-					   const union sctp_addr *laddr,
-					   const union sctp_addr *paddr)
+					   const union inet_addr *laddr,
+					   const union inet_addr *paddr)
 {
 	struct sctp_transport *transport;
 
-	if ((htons(asoc->base.bind_addr.port) == laddr->v4.sin_port) &&
-	    (htons(asoc->peer.port) == paddr->v4.sin_port) &&
+	if ((htons(asoc->base.bind_addr.port) == laddr->sin.sin_port) &&
+	    (htons(asoc->peer.port) == paddr->sin.sin_port) &&
 	    net_eq(sock_net(asoc->base.sk), net)) {
 		transport = sctp_assoc_lookup_paddr(asoc, paddr);
 		if (!transport)
@@ -1557,11 +1557,11 @@ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
 
 /* Lookup laddr in the bind address list of an association. */
 int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
-			    const union sctp_addr *laddr)
+			    const union inet_addr *laddr)
 {
 	int found = 0;
 
-	if ((asoc->base.bind_addr.port == ntohs(laddr->v4.sin_port)) &&
+	if ((asoc->base.bind_addr.port == ntohs(laddr->sin.sin_port)) &&
 	    sctp_bind_addr_match(&asoc->base.bind_addr, laddr,
 				 sctp_sk(asoc->base.sk)))
 		found = 1;
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index f34ce8b..36504c8 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -53,7 +53,7 @@
 
 /* Forward declarations for internal helpers. */
 static int sctp_copy_one_addr(struct net *, struct sctp_bind_addr *,
-			      union sctp_addr *, sctp_scope_t scope, gfp_t gfp,
+			      union inet_addr *, sctp_scope_t scope, gfp_t gfp,
 			      int flags);
 static void sctp_bind_addr_clean(struct sctp_bind_addr *);
 
@@ -156,7 +156,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp)
 }
 
 /* Add an address to the bind address list in the SCTP_bind_addr structure. */
-int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
+int sctp_add_bind_addr(struct sctp_bind_addr *bp, union inet_addr *new,
 		       __u8 addr_state, gfp_t gfp)
 {
 	struct sctp_sockaddr_entry *addr;
@@ -171,8 +171,8 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 	/* Fix up the port if it has not yet been set.
 	 * Both v4 and v6 have the port at the same offset.
 	 */
-	if (!addr->a.v4.sin_port)
-		addr->a.v4.sin_port = htons(bp->port);
+	if (!addr->a.sin.sin_port)
+		addr->a.sin.sin_port = htons(bp->port);
 
 	addr->state = addr_state;
 	addr->valid = 1;
@@ -191,7 +191,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 /* Delete an address from the bind address list in the SCTP_bind_addr
  * structure.
  */
-int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
+int sctp_del_bind_addr(struct sctp_bind_addr *bp, union inet_addr *del_addr)
 {
 	struct sctp_sockaddr_entry *addr, *temp;
 	int found = 0;
@@ -259,7 +259,7 @@ union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
 	addrparms = retval;
 
 	list_for_each_entry(addr, &bp->address_list, list) {
-		af = sctp_get_af_specific(addr->a.v4.sin_family);
+		af = sctp_get_af_specific(addr->a.sin.sin_family);
 		len = af->to_addr_param(&addr->a, &rawaddr);
 		memcpy(addrparms.v, &rawaddr, len);
 		addrparms.v += len;
@@ -280,7 +280,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
 {
 	union sctp_addr_param *rawaddr;
 	struct sctp_paramhdr *param;
-	union sctp_addr addr;
+	union inet_addr addr;
 	int retval = 0;
 	int len;
 	struct sctp_af *af;
@@ -319,7 +319,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
 
 /* Does this contain a specified address?  Allow wildcarding. */
 int sctp_bind_addr_match(struct sctp_bind_addr *bp,
-			 const union sctp_addr *addr,
+			 const union inet_addr *addr,
 			 struct sctp_sock *opt)
 {
 	struct sctp_sockaddr_entry *laddr;
@@ -343,7 +343,7 @@ int sctp_bind_addr_match(struct sctp_bind_addr *bp,
  * the bp.
  */
 int sctp_bind_addr_conflict(struct sctp_bind_addr *bp,
-			    const union sctp_addr *addr,
+			    const union inet_addr *addr,
 			    struct sctp_sock *bp_sp,
 			    struct sctp_sock *addr_sp)
 {
@@ -378,7 +378,7 @@ int sctp_bind_addr_conflict(struct sctp_bind_addr *bp,
 
 /* Get the state of the entry in the bind_addr_list */
 int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
-			 const union sctp_addr *addr)
+			 const union inet_addr *addr)
 {
 	struct sctp_sockaddr_entry *laddr;
 	struct sctp_af *af;
@@ -405,13 +405,13 @@ int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
 /* Find the first address in the bind address list that is not present in
  * the addrs packed array.
  */
-union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
-					const union sctp_addr	*addrs,
+union inet_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
+					const union inet_addr	*addrs,
 					int			addrcnt,
 					struct sctp_sock	*opt)
 {
 	struct sctp_sockaddr_entry	*laddr;
-	union sctp_addr			*addr;
+	union inet_addr			*addr;
 	void 				*addr_buf;
 	struct sctp_af			*af;
 	int				i;
@@ -421,10 +421,10 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
 	 * can't change.
 	 */
 	list_for_each_entry(laddr, &bp->address_list, list) {
-		addr_buf = (union sctp_addr *)addrs;
+		addr_buf = (union inet_addr *)addrs;
 		for (i = 0; i < addrcnt; i++) {
 			addr = addr_buf;
-			af = sctp_get_af_specific(addr->v4.sin_family);
+			af = sctp_get_af_specific(addr->sin.sin_family);
 			if (!af)
 				break;
 
@@ -442,13 +442,13 @@ union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr	*bp,
 
 /* Copy out addresses from the global local address list. */
 static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest,
-			      union sctp_addr *addr,
+			      union inet_addr *addr,
 			      sctp_scope_t scope, gfp_t gfp,
 			      int flags)
 {
 	int error = 0;
 
-	if (sctp_is_any(NULL, addr)) {
+	if (inet_addr_any(addr)) {
 		error = sctp_copy_local_addr_list(net, dest, scope, gfp, flags);
 	} else if (sctp_in_scope(net, addr, scope)) {
 		/* Now that the address is in scope, check to see if
@@ -467,27 +467,8 @@ static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest,
 	return error;
 }
 
-/* Is this a wildcard address?  */
-int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
-{
-	unsigned short fam = 0;
-	struct sctp_af *af;
-
-	/* Try to get the right address family */
-	if (addr->sa.sa_family != AF_UNSPEC)
-		fam = addr->sa.sa_family;
-	else if (sk)
-		fam = sk->sk_family;
-
-	af = sctp_get_af_specific(fam);
-	if (!af)
-		return 0;
-
-	return af->is_any(addr);
-}
-
 /* Is 'addr' valid for 'scope'?  */
-int sctp_in_scope(struct net *net, const union sctp_addr *addr, sctp_scope_t scope)
+int sctp_in_scope(struct net *net, const union inet_addr *addr, sctp_scope_t scope)
 {
 	sctp_scope_t addr_scope = sctp_scope(addr);
 
@@ -536,7 +517,7 @@ int sctp_is_ep_boundall(struct sock *sk)
 	if (sctp_list_single_entry(&bp->address_list)) {
 		addr = list_entry(bp->address_list.next,
 				  struct sctp_sockaddr_entry, list);
-		if (sctp_is_any(sk, &addr->a))
+		if (inet_addr_any(&addr->a))
 			return 1;
 	}
 	return 0;
@@ -547,7 +528,7 @@ int sctp_is_ep_boundall(struct sock *sk)
  ********************************************************************/
 
 /* What is the scope of 'addr'?  */
-sctp_scope_t sctp_scope(const union sctp_addr *addr)
+sctp_scope_t sctp_scope(const union inet_addr *addr)
 {
 	struct sctp_af *af;
 
@@ -555,5 +536,5 @@ sctp_scope_t sctp_scope(const union sctp_addr *addr)
 	if (!af)
 		return SCTP_SCOPE_UNUSABLE;
 
-	return af->scope((union sctp_addr *)addr);
+	return af->scope((union inet_addr *)addr);
 }
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 825b754..880670f 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -305,11 +305,11 @@ void sctp_endpoint_put(struct sctp_endpoint *ep)
 /* Is this the endpoint we are looking for?  */
 struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
 					       struct net *net,
-					       const union sctp_addr *laddr)
+					       const union inet_addr *laddr)
 {
 	struct sctp_endpoint *retval = NULL;
 
-	if ((htons(ep->base.bind_addr.port) == laddr->v4.sin_port) &&
+	if ((htons(ep->base.bind_addr.port) == laddr->sin.sin_port) &&
 	    net_eq(sock_net(ep->base.sk), net)) {
 		if (sctp_bind_addr_match(&ep->base.bind_addr, laddr,
 					 sctp_sk(ep->base.sk)))
@@ -325,7 +325,7 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
  */
 static struct sctp_association *__sctp_endpoint_lookup_assoc(
 	const struct sctp_endpoint *ep,
-	const union sctp_addr *paddr,
+	const union inet_addr *paddr,
 	struct sctp_transport **transport)
 {
 	struct sctp_association *asoc = NULL;
@@ -344,7 +344,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
 	if (!ep->base.bind_addr.port)
 		goto out;
 
-	rport = ntohs(paddr->v4.sin_port);
+	rport = ntohs(paddr->sin.sin_port);
 
 	hash = sctp_assoc_hashfn(sock_net(ep->base.sk), ep->base.bind_addr.port,
 				 rport);
@@ -370,7 +370,7 @@ out:
 /* Lookup association on an endpoint based on a peer address.  BH-safe.  */
 struct sctp_association *sctp_endpoint_lookup_assoc(
 	const struct sctp_endpoint *ep,
-	const union sctp_addr *paddr,
+	const union inet_addr *paddr,
 	struct sctp_transport **transport)
 {
 	struct sctp_association *asoc;
@@ -386,7 +386,7 @@ struct sctp_association *sctp_endpoint_lookup_assoc(
  * given peer address.
  */
 int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
-				const union sctp_addr *paddr)
+				const union inet_addr *paddr)
 {
 	struct sctp_sockaddr_entry *addr;
 	struct sctp_bind_addr *bp;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index fa91aff..f6c9ee6 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -68,15 +68,15 @@
 static int sctp_rcv_ootb(struct sk_buff *);
 static struct sctp_association *__sctp_rcv_lookup(struct net *net,
 				      struct sk_buff *skb,
-				      const union sctp_addr *paddr,
-				      const union sctp_addr *laddr,
+				      const union inet_addr *paddr,
+				      const union inet_addr *laddr,
 				      struct sctp_transport **transportp);
 static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
-						const union sctp_addr *laddr);
+						const union inet_addr *laddr);
 static struct sctp_association *__sctp_lookup_association(
 					struct net *net,
-					const union sctp_addr *local,
-					const union sctp_addr *peer,
+					const union inet_addr *local,
+					const union inet_addr *peer,
 					struct sctp_transport **pt);
 
 static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
@@ -120,8 +120,8 @@ int sctp_rcv(struct sk_buff *skb)
 	struct sctp_transport *transport = NULL;
 	struct sctp_chunk *chunk;
 	struct sctphdr *sh;
-	union sctp_addr src;
-	union sctp_addr dest;
+	union inet_addr src;
+	union inet_addr dest;
 	int family;
 	struct sctp_af *af;
 	struct net *net = dev_net(skb->dev);
@@ -476,8 +476,8 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb,
 			     struct sctp_association **app,
 			     struct sctp_transport **tpp)
 {
-	union sctp_addr saddr;
-	union sctp_addr daddr;
+	union inet_addr saddr;
+	union inet_addr daddr;
 	struct sctp_af *af;
 	struct sock *sk = NULL;
 	struct sctp_association *asoc;
@@ -771,14 +771,14 @@ void sctp_unhash_endpoint(struct sctp_endpoint *ep)
 
 /* Look up an endpoint. */
 static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(struct net *net,
-						const union sctp_addr *laddr)
+						const union inet_addr *laddr)
 {
 	struct sctp_hashbucket *head;
 	struct sctp_ep_common *epb;
 	struct sctp_endpoint *ep;
 	int hash;
 
-	hash = sctp_ep_hashfn(net, ntohs(laddr->v4.sin_port));
+	hash = sctp_ep_hashfn(net, ntohs(laddr->sin.sin_port));
 	head = &sctp_ep_hashtable[hash];
 	read_lock(&head->lock);
 	sctp_for_each_hentry(epb, &head->chain) {
@@ -859,8 +859,8 @@ void sctp_unhash_established(struct sctp_association *asoc)
 /* Look up an association. */
 static struct sctp_association *__sctp_lookup_association(
 					struct net *net,
-					const union sctp_addr *local,
-					const union sctp_addr *peer,
+					const union inet_addr *local,
+					const union inet_addr *peer,
 					struct sctp_transport **pt)
 {
 	struct sctp_hashbucket *head;
@@ -872,8 +872,8 @@ static struct sctp_association *__sctp_lookup_association(
 	/* Optimize here for direct hit, only listening connections can
 	 * have wildcards anyways.
 	 */
-	hash = sctp_assoc_hashfn(net, ntohs(local->v4.sin_port),
-				 ntohs(peer->v4.sin_port));
+	hash = sctp_assoc_hashfn(net, ntohs(local->sin.sin_port),
+				 ntohs(peer->sin.sin_port));
 	head = &sctp_assoc_hashtable[hash];
 	read_lock(&head->lock);
 	sctp_for_each_hentry(epb, &head->chain) {
@@ -897,8 +897,8 @@ hit:
 /* Look up an association. BH-safe. */
 static
 struct sctp_association *sctp_lookup_association(struct net *net,
-						 const union sctp_addr *laddr,
-						 const union sctp_addr *paddr,
+						 const union inet_addr *laddr,
+						 const union inet_addr *paddr,
 						 struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc;
@@ -912,8 +912,8 @@ struct sctp_association *sctp_lookup_association(struct net *net,
 
 /* Is there an association matching the given local and peer addresses? */
 int sctp_has_association(struct net *net,
-			 const union sctp_addr *laddr,
-			 const union sctp_addr *paddr)
+			 const union inet_addr *laddr,
+			 const union inet_addr *paddr)
 {
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
@@ -946,11 +946,11 @@ int sctp_has_association(struct net *net,
  */
 static struct sctp_association *__sctp_rcv_init_lookup(struct net *net,
 	struct sk_buff *skb,
-	const union sctp_addr *laddr, struct sctp_transport **transportp)
+	const union inet_addr *laddr, struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc;
-	union sctp_addr addr;
-	union sctp_addr *paddr = &addr;
+	union inet_addr addr;
+	union inet_addr *paddr = &addr;
 	struct sctphdr *sh = sctp_hdr(skb);
 	union sctp_params params;
 	sctp_init_chunk_t *init;
@@ -1010,14 +1010,14 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net,
 static struct sctp_association *__sctp_rcv_asconf_lookup(
 					struct net *net,
 					sctp_chunkhdr_t *ch,
-					const union sctp_addr *laddr,
+					const union inet_addr *laddr,
 					__be16 peer_port,
 					struct sctp_transport **transportp)
 {
 	sctp_addip_chunk_t *asconf = (struct sctp_addip_chunk *)ch;
 	struct sctp_af *af;
 	union sctp_addr_param *param;
-	union sctp_addr paddr;
+	union inet_addr paddr;
 
 	/* Skip over the ADDIP header and find the Address parameter */
 	param = (union sctp_addr_param *)(asconf + 1);
@@ -1043,7 +1043,7 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
 */
 static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net,
 				      struct sk_buff *skb,
-				      const union sctp_addr *laddr,
+				      const union inet_addr *laddr,
 				      struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc = NULL;
@@ -1110,7 +1110,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net,
  */
 static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net,
 				      struct sk_buff *skb,
-				      const union sctp_addr *laddr,
+				      const union inet_addr *laddr,
 				      struct sctp_transport **transportp)
 {
 	sctp_chunkhdr_t *ch;
@@ -1144,8 +1144,8 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct net *net,
 /* Lookup an association for an inbound skb. */
 static struct sctp_association *__sctp_rcv_lookup(struct net *net,
 				      struct sk_buff *skb,
-				      const union sctp_addr *paddr,
-				      const union sctp_addr *laddr,
+				      const union inet_addr *paddr,
+				      const union inet_addr *laddr,
 				      struct sctp_transport **transportp)
 {
 	struct sctp_association *asoc;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 85d688f..4df88f208 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -80,12 +80,12 @@
 
 #include <asm/uaccess.h>
 
-static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
-					 union sctp_addr *s2);
-static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
+static inline int sctp_v6_addr_match_len(union inet_addr *s1,
+					 union inet_addr *s2);
+static void sctp_v6_to_addr(union inet_addr *addr, struct in6_addr *saddr,
 			      __be16 port);
-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
-			    const union sctp_addr *addr2);
+static bool sctp_v6_cmp_addr(const union inet_addr *addr1,
+			     const union inet_addr *addr2);
 
 /* Event handler for inet6 address addition/deletion events.
  * The sctp_local_addr_list needs to be protocted by a spin lock since
@@ -106,10 +106,10 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
 	case NETDEV_UP:
 		addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
 		if (addr) {
-			addr->a.v6.sin6_family = AF_INET6;
-			addr->a.v6.sin6_port = 0;
-			addr->a.v6.sin6_addr = ifa->addr;
-			addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
+			addr->a.sin6.sin6_family = AF_INET6;
+			addr->a.sin6.sin6_port = 0;
+			addr->a.sin6.sin6_addr = ifa->addr;
+			addr->a.sin6.sin6_scope_id = ifa->idev->dev->ifindex;
 			addr->valid = 1;
 			spin_lock_bh(&net->sctp.local_addr_lock);
 			list_add_tail_rcu(&addr->list, &net->sctp.local_addr_list);
@@ -122,7 +122,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
 		list_for_each_entry_safe(addr, temp,
 					&net->sctp.local_addr_list, list) {
 			if (addr->a.sa.sa_family == AF_INET6 &&
-					ipv6_addr_equal(&addr->a.v6.sin6_addr,
+					ipv6_addr_equal(&addr->a.sin6.sin6_addr,
 						&ifa->addr)) {
 				sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
 				found = 1;
@@ -224,13 +224,13 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
 	/* Fill in the dest address from the route entry passed with the skb
 	 * and the source address from the transport.
 	 */
-	fl6.daddr = transport->ipaddr.v6.sin6_addr;
-	fl6.saddr = transport->saddr.v6.sin6_addr;
+	fl6.daddr = transport->ipaddr.sin6.sin6_addr;
+	fl6.saddr = transport->saddr.sin6.sin6_addr;
 
 	fl6.flowlabel = np->flow_label;
 	IP6_ECN_flow_xmit(sk, fl6.flowlabel);
 	if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL)
-		fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id;
+		fl6.flowi6_oif = transport->saddr.sin6.sin6_scope_id;
 	else
 		fl6.flowi6_oif = sk->sk_bound_dev_if;
 
@@ -253,7 +253,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+static void sctp_v6_get_dst(struct sctp_transport *t, union inet_addr *saddr,
 			    struct flowi *fl, struct sock *sk)
 {
 	struct sctp_association *asoc = t->asoc;
@@ -261,19 +261,19 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 	struct flowi6 *fl6 = &fl->u.ip6;
 	struct sctp_bind_addr *bp;
 	struct sctp_sockaddr_entry *laddr;
-	union sctp_addr *baddr = NULL;
-	union sctp_addr *daddr = &t->ipaddr;
-	union sctp_addr dst_saddr;
+	union inet_addr *baddr = NULL;
+	union inet_addr *daddr = &t->ipaddr;
+	union inet_addr dst_saddr;
 	__u8 matchlen = 0;
 	__u8 bmatchlen;
 	sctp_scope_t scope;
 
 	memset(fl6, 0, sizeof(struct flowi6));
-	fl6->daddr = daddr->v6.sin6_addr;
-	fl6->fl6_dport = daddr->v6.sin6_port;
+	fl6->daddr = daddr->sin6.sin6_addr;
+	fl6->fl6_dport = daddr->sin6.sin6_port;
 	fl6->flowi6_proto = IPPROTO_SCTP;
-	if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
-		fl6->flowi6_oif = daddr->v6.sin6_scope_id;
+	if (ipv6_addr_type(&daddr->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
+		fl6->flowi6_oif = daddr->sin6.sin6_scope_id;
 
 	pr_debug("%s: dst=%pI6 ", __func__, &fl6->daddr);
 
@@ -281,8 +281,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 		fl6->fl6_sport = htons(asoc->base.bind_addr.port);
 
 	if (saddr) {
-		fl6->saddr = saddr->v6.sin6_addr;
-		fl6->fl6_sport = saddr->v6.sin6_port;
+		fl6->saddr = saddr->sin6.sin6_addr;
+		fl6->fl6_sport = saddr->sin6.sin6_port;
 
 		pr_debug("src=%pI6 - ", &fl6->saddr);
 	}
@@ -340,8 +340,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 	}
 	rcu_read_unlock();
 	if (baddr) {
-		fl6->saddr = baddr->v6.sin6_addr;
-		fl6->fl6_sport = baddr->v6.sin6_port;
+		fl6->saddr = baddr->sin6.sin6_addr;
+		fl6->fl6_sport = baddr->sin6.sin6_port;
 		dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
 	}
 
@@ -364,10 +364,10 @@ out:
 /* Returns the number of consecutive initial bits that match in the 2 ipv6
  * addresses.
  */
-static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
-					 union sctp_addr *s2)
+static inline int sctp_v6_addr_match_len(union inet_addr *s1,
+					 union inet_addr *s2)
 {
-	return ipv6_addr_diff(&s1->v6.sin6_addr, &s2->v6.sin6_addr);
+	return ipv6_addr_diff(&s1->sin6.sin6_addr, &s2->sin6.sin6_addr);
 }
 
 /* Fills in the source address(saddr) based on the destination address(daddr)
@@ -378,13 +378,13 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
 			      struct flowi *fl)
 {
 	struct flowi6 *fl6 = &fl->u.ip6;
-	union sctp_addr *saddr = &t->saddr;
+	union inet_addr *saddr = &t->saddr;
 
 	pr_debug("%s: asoc:%p dst:%p\n", __func__, t->asoc, t->dst);
 
 	if (t->dst) {
-		saddr->v6.sin6_family = AF_INET6;
-		saddr->v6.sin6_addr = fl6->saddr;
+		saddr->sin6.sin6_family = AF_INET6;
+		saddr->sin6.sin6_addr = fl6->saddr;
 	}
 }
 
@@ -407,10 +407,10 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
 		/* Add the address to the local list.  */
 		addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
 		if (addr) {
-			addr->a.v6.sin6_family = AF_INET6;
-			addr->a.v6.sin6_port = 0;
-			addr->a.v6.sin6_addr = ifp->addr;
-			addr->a.v6.sin6_scope_id = dev->ifindex;
+			addr->a.sin6.sin6_family = AF_INET6;
+			addr->a.sin6.sin6_port = 0;
+			addr->a.sin6.sin6_addr = ifp->addr;
+			addr->a.sin6.sin6_scope_id = dev->ifindex;
 			addr->valid = 1;
 			INIT_LIST_HEAD(&addr->list);
 			list_add_tail(&addr->list, addrlist);
@@ -422,155 +422,132 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
 }
 
 /* Initialize a sockaddr_storage from in incoming skb. */
-static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
+static void sctp_v6_from_skb(union inet_addr *addr,struct sk_buff *skb,
 			     int is_saddr)
 {
 	__be16 *port;
 	struct sctphdr *sh;
 
-	port = &addr->v6.sin6_port;
-	addr->v6.sin6_family = AF_INET6;
-	addr->v6.sin6_flowinfo = 0; /* FIXME */
-	addr->v6.sin6_scope_id = ((struct inet6_skb_parm *)skb->cb)->iif;
+	port = &addr->sin6.sin6_port;
+	addr->sin6.sin6_family = AF_INET6;
+	addr->sin6.sin6_flowinfo = 0; /* FIXME */
+	addr->sin6.sin6_scope_id = ((struct inet6_skb_parm *)skb->cb)->iif;
 
 	sh = sctp_hdr(skb);
 	if (is_saddr) {
 		*port  = sh->source;
-		addr->v6.sin6_addr = ipv6_hdr(skb)->saddr;
+		addr->sin6.sin6_addr = ipv6_hdr(skb)->saddr;
 	} else {
 		*port = sh->dest;
-		addr->v6.sin6_addr = ipv6_hdr(skb)->daddr;
+		addr->sin6.sin6_addr = ipv6_hdr(skb)->daddr;
 	}
 }
 
-/* Initialize an sctp_addr from a socket. */
-static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
+/* Initialize an inet_addr from a socket. */
+static void sctp_v6_from_sk(union inet_addr *addr, struct sock *sk)
 {
-	addr->v6.sin6_family = AF_INET6;
-	addr->v6.sin6_port = 0;
-	addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr;
+	addr->sin6.sin6_family = AF_INET6;
+	addr->sin6.sin6_port = 0;
+	addr->sin6.sin6_addr = inet6_sk(sk)->rcv_saddr;
 }
 
-/* Initialize sk->sk_rcv_saddr from sctp_addr. */
-static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
+/* Initialize sk->sk_rcv_saddr from inet_addr. */
+static void sctp_v6_to_sk_saddr(union inet_addr *addr, struct sock *sk)
 {
 	if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) {
 		inet6_sk(sk)->rcv_saddr.s6_addr32[0] = 0;
 		inet6_sk(sk)->rcv_saddr.s6_addr32[1] = 0;
 		inet6_sk(sk)->rcv_saddr.s6_addr32[2] = htonl(0x0000ffff);
 		inet6_sk(sk)->rcv_saddr.s6_addr32[3] =
-			addr->v4.sin_addr.s_addr;
+			addr->sin.sin_addr.s_addr;
 	} else {
-		inet6_sk(sk)->rcv_saddr = addr->v6.sin6_addr;
+		inet6_sk(sk)->rcv_saddr = addr->sin6.sin6_addr;
 	}
 }
 
-/* Initialize sk->sk_daddr from sctp_addr. */
-static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
+/* Initialize sk->sk_daddr from inet_addr. */
+static void sctp_v6_to_sk_daddr(union inet_addr *addr, struct sock *sk)
 {
 	if (addr->sa.sa_family == AF_INET && sctp_sk(sk)->v4mapped) {
 		inet6_sk(sk)->daddr.s6_addr32[0] = 0;
 		inet6_sk(sk)->daddr.s6_addr32[1] = 0;
 		inet6_sk(sk)->daddr.s6_addr32[2] = htonl(0x0000ffff);
-		inet6_sk(sk)->daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
+		inet6_sk(sk)->daddr.s6_addr32[3] = addr->sin.sin_addr.s_addr;
 	} else {
-		inet6_sk(sk)->daddr = addr->v6.sin6_addr;
+		inet6_sk(sk)->daddr = addr->sin6.sin6_addr;
 	}
 }
 
-/* Initialize a sctp_addr from an address parameter. */
-static void sctp_v6_from_addr_param(union sctp_addr *addr,
+/* Initialize a inet_addr from an address parameter. */
+static void sctp_v6_from_addr_param(union inet_addr *addr,
 				    union sctp_addr_param *param,
 				    __be16 port, int iif)
 {
-	addr->v6.sin6_family = AF_INET6;
-	addr->v6.sin6_port = port;
-	addr->v6.sin6_flowinfo = 0; /* BUG */
-	addr->v6.sin6_addr = param->v6.addr;
-	addr->v6.sin6_scope_id = iif;
+	addr->sin6.sin6_family = AF_INET6;
+	addr->sin6.sin6_port = port;
+	addr->sin6.sin6_flowinfo = 0; /* BUG */
+	addr->sin6.sin6_addr = param->v6.addr;
+	addr->sin6.sin6_scope_id = iif;
 }
 
-/* Initialize an address parameter from a sctp_addr and return the length
+/* Initialize an address parameter from a inet_addr and return the length
  * of the address parameter.
  */
-static int sctp_v6_to_addr_param(const union sctp_addr *addr,
+static int sctp_v6_to_addr_param(const union inet_addr *addr,
 				 union sctp_addr_param *param)
 {
 	int length = sizeof(sctp_ipv6addr_param_t);
 
 	param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
 	param->v6.param_hdr.length = htons(length);
-	param->v6.addr = addr->v6.sin6_addr;
+	param->v6.addr = addr->sin6.sin6_addr;
 
 	return length;
 }
 
-/* Initialize a sctp_addr from struct in6_addr. */
-static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
+/* Initialize a inet_addr from struct in6_addr. */
+static void sctp_v6_to_addr(union inet_addr *addr, struct in6_addr *saddr,
 			      __be16 port)
 {
 	addr->sa.sa_family = AF_INET6;
-	addr->v6.sin6_port = port;
-	addr->v6.sin6_addr = *saddr;
+	addr->sin6.sin6_port = port;
+	addr->sin6.sin6_addr = *saddr;
 }
 
 /* Compare addresses exactly.
  * v4-mapped-v6 is also in consideration.
  */
-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
-			    const union sctp_addr *addr2)
+static bool sctp_v6_cmp_addr(const union inet_addr *addr1,
+			     const union inet_addr *addr2)
 {
 	if (addr1->sa.sa_family != addr2->sa.sa_family) {
 		if (addr1->sa.sa_family == AF_INET &&
 		    addr2->sa.sa_family == AF_INET6 &&
-		    ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
-			if (addr2->v6.sin6_port == addr1->v4.sin_port &&
-			    addr2->v6.sin6_addr.s6_addr32[3] ==
-			    addr1->v4.sin_addr.s_addr)
+		    ipv6_addr_v4mapped(&addr2->sin6.sin6_addr)) {
+			if (addr2->sin6.sin6_port == addr1->sin.sin_port &&
+			    addr2->sin6.sin6_addr.s6_addr32[3] ==
+			    addr1->sin.sin_addr.s_addr)
 				return 1;
 		}
 		if (addr2->sa.sa_family == AF_INET &&
 		    addr1->sa.sa_family == AF_INET6 &&
-		    ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
-			if (addr1->v6.sin6_port == addr2->v4.sin_port &&
-			    addr1->v6.sin6_addr.s6_addr32[3] ==
-			    addr2->v4.sin_addr.s_addr)
+		    ipv6_addr_v4mapped(&addr1->sin6.sin6_addr)) {
+			if (addr1->sin6.sin6_port == addr2->sin.sin_port &&
+			    addr1->sin6.sin6_addr.s6_addr32[3] ==
+			    addr2->sin.sin_addr.s_addr)
 				return 1;
 		}
 		return 0;
 	}
-	if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
-		return 0;
-	/* If this is a linklocal address, compare the scope_id. */
-	if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-		if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
-		    (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
-			return 0;
-		}
-	}
-
-	return 1;
-}
 
-/* Initialize addr struct to INADDR_ANY. */
-static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
-{
-	memset(addr, 0x00, sizeof(union sctp_addr));
-	addr->v6.sin6_family = AF_INET6;
-	addr->v6.sin6_port = port;
-}
-
-/* Is this a wildcard address? */
-static int sctp_v6_is_any(const union sctp_addr *addr)
-{
-	return ipv6_addr_any(&addr->v6.sin6_addr);
+	return inet_addr_equal(addr1, addr2);
 }
 
 /* Should this be available for binding?   */
-static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
+static int sctp_v6_available(union inet_addr *addr, struct sctp_sock *sp)
 {
 	int type;
-	const struct in6_addr *in6 = (const struct in6_addr *)&addr->v6.sin6_addr;
+	const struct in6_addr *in6 = (const struct in6_addr *)&addr->sin6.sin6_addr;
 
 	type = ipv6_addr_type(in6);
 	if (IPV6_ADDR_ANY == type)
@@ -596,11 +573,11 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
  * Return 0 - If the address is a non-unicast or an illegal address.
  * Return 1 - If the address is a unicast.
  */
-static int sctp_v6_addr_valid(union sctp_addr *addr,
+static int sctp_v6_addr_valid(union inet_addr *addr,
 			      struct sctp_sock *sp,
 			      const struct sk_buff *skb)
 {
-	int ret = ipv6_addr_type(&addr->v6.sin6_addr);
+	int ret = ipv6_addr_type(&addr->sin6.sin6_addr);
 
 	/* Support v4-mapped-v6 address. */
 	if (ret == IPV6_ADDR_MAPPED) {
@@ -623,7 +600,7 @@ static int sctp_v6_addr_valid(union sctp_addr *addr,
 }
 
 /* What is the scope of 'addr'?  */
-static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
+static sctp_scope_t sctp_v6_scope(union inet_addr *addr)
 {
 	int v6scope;
 	sctp_scope_t retval;
@@ -632,7 +609,7 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
 	 * See IFA_* in <net/if_inet6.h>.  Map to a generic SCTP scope.
 	 */
 
-	v6scope = ipv6_addr_scope(&addr->v6.sin6_addr);
+	v6scope = ipv6_addr_scope(&addr->sin6.sin6_addr);
 	switch (v6scope) {
 	case IFA_HOST:
 		retval = SCTP_SCOPE_LOOPBACK;
@@ -694,7 +671,7 @@ out:
 }
 
 /* Map v4 address to mapped v6 address */
-static void sctp_v6_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
+static void sctp_v6_addr_v4map(struct sctp_sock *sp, union inet_addr *addr)
 {
 	if (sp->v4mapped && AF_INET == addr->sa.sa_family)
 		sctp_v4_map_v6(addr);
@@ -713,12 +690,6 @@ static int sctp_v6_is_ce(const struct sk_buff *skb)
 	return *((__u32 *)(ipv6_hdr(skb))) & htonl(1 << 20);
 }
 
-/* Dump the v6 addr to the seq file. */
-static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
-{
-	seq_printf(seq, "%pI6 ", &addr->v6.sin6_addr);
-}
-
 static void sctp_v6_ecn_capable(struct sock *sk)
 {
 	inet6_sk(sk)->tclass |= INET_ECN_ECT_0;
@@ -743,7 +714,7 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
 	struct sockaddr_in6 *sin6, *sin6from;
 
 	if (msgname) {
-		union sctp_addr *addr;
+		union inet_addr *addr;
 		struct sctp_association *asoc;
 
 		asoc = event->asoc;
@@ -759,13 +730,13 @@ static void sctp_inet6_event_msgname(struct sctp_ulpevent *event,
 		/* Map ipv4 address into v4-mapped-on-v6 address.  */
 		if (sctp_sk(asoc->base.sk)->v4mapped &&
 		    AF_INET == addr->sa.sa_family) {
-			sctp_v4_map_v6((union sctp_addr *)sin6);
+			sctp_v4_map_v6((union inet_addr *)sin6);
 			sin6->sin6_addr.s6_addr32[3] =
-				addr->v4.sin_addr.s_addr;
+				addr->sin.sin_addr.s_addr;
 			return;
 		}
 
-		sin6from = &asoc->peer.primary_addr.v6;
+		sin6from = &asoc->peer.primary_addr.sin6;
 		sin6->sin6_addr = sin6from->sin6_addr;
 		if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
 			sin6->sin6_scope_id = sin6from->sin6_scope_id;
@@ -788,7 +759,7 @@ static void sctp_inet6_skb_msgname(struct sk_buff *skb, char *msgname,
 		/* Map ipv4 address into v4-mapped-on-v6 address. */
 		if (sctp_sk(skb->sk)->v4mapped &&
 		    ip_hdr(skb)->version == 4) {
-			sctp_v4_map_v6((union sctp_addr *)sin6);
+			sctp_v4_map_v6((union inet_addr *)sin6);
 			sin6->sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr;
 			return;
 		}
@@ -821,8 +792,8 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_sock *sp)
  * of indirection lets us choose whether a PF_INET6 should
  * disallow any v4 addresses if we so choose.
  */
-static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
-			       const union sctp_addr *addr2,
+static int sctp_inet6_cmp_addr(const union inet_addr *addr1,
+			       const union inet_addr *addr2,
 			       struct sctp_sock *opt)
 {
 	struct sctp_af *af1, *af2;
@@ -839,7 +810,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
 		return 0;
 
 	/* Today, wildcard AF_INET/AF_INET6. */
-	if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
+	if (inet_addr_any(addr1) || inet_addr_any(addr2))
 		return 1;
 
 	if (addr1->sa.sa_family != addr2->sa.sa_family)
@@ -851,7 +822,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
 /* Verify that the provided sockaddr looks bindable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_bind_verify(struct sctp_sock *opt, union inet_addr *addr)
 {
 	struct sctp_af *af;
 
@@ -859,18 +830,18 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 	if (addr->sa.sa_family != AF_INET6)
 		af = sctp_get_af_specific(addr->sa.sa_family);
 	else {
-		int type = ipv6_addr_type(&addr->v6.sin6_addr);
+		int type = ipv6_addr_type(&addr->sin6.sin6_addr);
 		struct net_device *dev;
 
 		if (type & IPV6_ADDR_LINKLOCAL) {
 			struct net *net;
-			if (!addr->v6.sin6_scope_id)
+			if (!addr->sin6.sin6_scope_id)
 				return 0;
 			net = sock_net(&opt->inet.sk);
 			rcu_read_lock();
-			dev = dev_get_by_index_rcu(net, addr->v6.sin6_scope_id);
+			dev = dev_get_by_index_rcu(net, addr->sin6.sin6_scope_id);
 			if (!dev ||
-			    !ipv6_chk_addr(net, &addr->v6.sin6_addr, dev, 0)) {
+			    !ipv6_chk_addr(net, &addr->sin6.sin6_addr, dev, 0)) {
 				rcu_read_unlock();
 				return 0;
 			}
@@ -888,7 +859,7 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 /* Verify that the provided sockaddr looks sendable.   Common verification,
  * has already been taken care of.
  */
-static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet6_send_verify(struct sctp_sock *opt, union inet_addr *addr)
 {
 	struct sctp_af *af = NULL;
 
@@ -896,15 +867,15 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
 	if (addr->sa.sa_family != AF_INET6)
 		af = sctp_get_af_specific(addr->sa.sa_family);
 	else {
-		int type = ipv6_addr_type(&addr->v6.sin6_addr);
+		int type = ipv6_addr_type(&addr->sin6.sin6_addr);
 		struct net_device *dev;
 
 		if (type & IPV6_ADDR_LINKLOCAL) {
-			if (!addr->v6.sin6_scope_id)
+			if (!addr->sin6.sin6_scope_id)
 				return 0;
 			rcu_read_lock();
 			dev = dev_get_by_index_rcu(sock_net(&opt->inet.sk),
-						   addr->v6.sin6_scope_id);
+						   addr->sin6.sin6_scope_id);
 			rcu_read_unlock();
 			if (!dev)
 				return 0;
@@ -1001,12 +972,9 @@ static struct sctp_af sctp_af_inet6 = {
 	.cmp_addr	   = sctp_v6_cmp_addr,
 	.scope		   = sctp_v6_scope,
 	.addr_valid	   = sctp_v6_addr_valid,
-	.inaddr_any	   = sctp_v6_inaddr_any,
-	.is_any		   = sctp_v6_is_any,
 	.available	   = sctp_v6_available,
 	.skb_iif	   = sctp_v6_skb_iif,
 	.is_ce		   = sctp_v6_is_ce,
-	.seq_dump_addr	   = sctp_v6_seq_dump_addr,
 	.ecn_capable	   = sctp_v6_ecn_capable,
 	.net_header_len	   = sizeof(struct ipv6hdr),
 	.sockaddr_len	   = sizeof(struct sockaddr_in6),
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 5131323..2d6c272 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -63,7 +63,7 @@ static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
 static void sctp_check_transmitted(struct sctp_outq *q,
 				   struct list_head *transmitted_queue,
 				   struct sctp_transport *transport,
-				   union sctp_addr *saddr,
+				   union inet_addr *saddr,
 				   struct sctp_sackhdr *sack,
 				   __u32 *highest_new_tsn);
 
@@ -1321,7 +1321,7 @@ int sctp_outq_is_empty(const struct sctp_outq *q)
 static void sctp_check_transmitted(struct sctp_outq *q,
 				   struct list_head *transmitted_queue,
 				   struct sctp_transport *transport,
-				   union sctp_addr *saddr,
+				   union inet_addr *saddr,
 				   struct sctp_sackhdr *sack,
 				   __u32 *highest_new_tsn_in_sack)
 {
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index aff0cac..2778728 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -130,7 +130,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
 	struct sctp_association *asoc;
 	struct sctp_sockaddr_entry *laddr;
 	struct sctp_transport *peer;
-	union sctp_addr *addr, *primary = NULL;
+	union inet_addr *addr, *primary = NULL;
 	struct sctp_af *af;
 
 	if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
@@ -155,7 +155,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
 		if (primary && af->cmp_addr(addr, primary)) {
 			seq_printf(seq, "*");
 		}
-		af->seq_dump_addr(seq, addr);
+		seq_printf(seq, "%pIA ", &addr);
 	}
 	rcu_read_unlock();
 }
@@ -164,7 +164,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
 static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_association *assoc)
 {
 	struct sctp_transport *transport;
-	union sctp_addr *addr, *primary;
+	union inet_addr *addr, *primary;
 	struct sctp_af *af;
 
 	primary = &assoc->peer.primary_addr;
@@ -179,7 +179,7 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
 		if (af->cmp_addr(addr, primary)) {
 			seq_printf(seq, "*");
 		}
-		af->seq_dump_addr(seq, addr);
+		seq_printf(seq, "%pIA ", addr);
 	}
 	rcu_read_unlock();
 }
@@ -468,7 +468,7 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
 			/*
 			 * The remote address (ADDR)
 			 */
-			tsp->af_specific->seq_dump_addr(seq, &tsp->ipaddr);
+			seq_printf(seq, "%pIA ", &tsp->ipaddr);
 			seq_printf(seq, " ");
 
 			/*
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 1928862..599744e 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -155,9 +155,9 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
 		/* Add the address to the local list.  */
 		addr = kzalloc(sizeof(*addr), GFP_ATOMIC);
 		if (addr) {
-			addr->a.v4.sin_family = AF_INET;
-			addr->a.v4.sin_port = 0;
-			addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
+			addr->a.sa.sa_family = AF_INET;
+			addr->a.sin.sin_port = 0;
+			addr->a.sin.sin_addr.s_addr = ifa->ifa_local;
 			addr->valid = 1;
 			INIT_LIST_HEAD(&addr->list);
 			list_add_tail(&addr->list, addrlist);
@@ -233,16 +233,16 @@ end_copy:
 	return error;
 }
 
-/* Initialize a sctp_addr from in incoming skb.  */
-static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
+/* Initialize a inet_addr from in incoming skb.  */
+static void sctp_v4_from_skb(union inet_addr *addr, struct sk_buff *skb,
 			     int is_saddr)
 {
 	void *from;
 	__be16 *port;
 	struct sctphdr *sh;
 
-	port = &addr->v4.sin_port;
-	addr->v4.sin_family = AF_INET;
+	port = &addr->sin.sin_port;
+	addr->sa.sa_family = AF_INET;
 
 	sh = sctp_hdr(skb);
 	if (is_saddr) {
@@ -252,89 +252,61 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 		*port = sh->dest;
 		from = &ip_hdr(skb)->daddr;
 	}
-	memcpy(&addr->v4.sin_addr.s_addr, from, sizeof(struct in_addr));
+	memcpy(&addr->sin.sin_addr.s_addr, from, sizeof(struct in_addr));
 }
 
-/* Initialize an sctp_addr from a socket. */
-static void sctp_v4_from_sk(union sctp_addr *addr, struct sock *sk)
+/* Initialize an inet_addr from a socket. */
+static void sctp_v4_from_sk(union inet_addr *addr, struct sock *sk)
 {
-	addr->v4.sin_family = AF_INET;
-	addr->v4.sin_port = 0;
-	addr->v4.sin_addr.s_addr = inet_sk(sk)->inet_rcv_saddr;
+	addr->sa.sa_family = AF_INET;
+	addr->sin.sin_port = 0;
+	addr->sin.sin_addr.s_addr = inet_sk(sk)->inet_rcv_saddr;
 }
 
-/* Initialize sk->sk_rcv_saddr from sctp_addr. */
-static void sctp_v4_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
+/* Initialize sk->sk_rcv_saddr from inet_addr. */
+static void sctp_v4_to_sk_saddr(union inet_addr *addr, struct sock *sk)
 {
-	inet_sk(sk)->inet_rcv_saddr = addr->v4.sin_addr.s_addr;
+	inet_sk(sk)->inet_rcv_saddr = addr->sin.sin_addr.s_addr;
 }
 
-/* Initialize sk->sk_daddr from sctp_addr. */
-static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
+/* Initialize sk->sk_daddr from inet_addr. */
+static void sctp_v4_to_sk_daddr(union inet_addr *addr, struct sock *sk)
 {
-	inet_sk(sk)->inet_daddr = addr->v4.sin_addr.s_addr;
+	inet_sk(sk)->inet_daddr = addr->sin.sin_addr.s_addr;
 }
 
-/* Initialize a sctp_addr from an address parameter. */
-static void sctp_v4_from_addr_param(union sctp_addr *addr,
+/* Initialize a inet_addr from an address parameter. */
+static void sctp_v4_from_addr_param(union inet_addr *addr,
 				    union sctp_addr_param *param,
 				    __be16 port, int iif)
 {
-	addr->v4.sin_family = AF_INET;
-	addr->v4.sin_port = port;
-	addr->v4.sin_addr.s_addr = param->v4.addr.s_addr;
+	addr->sa.sa_family = AF_INET;
+	addr->sin.sin_port = port;
+	addr->sin.sin_addr.s_addr = param->v4.addr.s_addr;
 }
 
-/* Initialize an address parameter from a sctp_addr and return the length
+/* Initialize an address parameter from a inet_addr and return the length
  * of the address parameter.
  */
-static int sctp_v4_to_addr_param(const union sctp_addr *addr,
+static int sctp_v4_to_addr_param(const union inet_addr *addr,
 				 union sctp_addr_param *param)
 {
 	int length = sizeof(sctp_ipv4addr_param_t);
 
 	param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
 	param->v4.param_hdr.length = htons(length);
-	param->v4.addr.s_addr = addr->v4.sin_addr.s_addr;
+	param->v4.addr.s_addr = addr->sin.sin_addr.s_addr;
 
 	return length;
 }
 
-/* Initialize a sctp_addr from a dst_entry. */
-static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct flowi4 *fl4,
+/* Initialize a inet_addr from a dst_entry. */
+static void sctp_v4_dst_saddr(union inet_addr *saddr, struct flowi4 *fl4,
 			      __be16 port)
 {
-	saddr->v4.sin_family = AF_INET;
-	saddr->v4.sin_port = port;
-	saddr->v4.sin_addr.s_addr = fl4->saddr;
-}
-
-/* Compare two addresses exactly. */
-static int sctp_v4_cmp_addr(const union sctp_addr *addr1,
-			    const union sctp_addr *addr2)
-{
-	if (addr1->sa.sa_family != addr2->sa.sa_family)
-		return 0;
-	if (addr1->v4.sin_port != addr2->v4.sin_port)
-		return 0;
-	if (addr1->v4.sin_addr.s_addr != addr2->v4.sin_addr.s_addr)
-		return 0;
-
-	return 1;
-}
-
-/* Initialize addr struct to INADDR_ANY. */
-static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port)
-{
-	addr->v4.sin_family = AF_INET;
-	addr->v4.sin_addr.s_addr = htonl(INADDR_ANY);
-	addr->v4.sin_port = port;
-}
-
-/* Is this a wildcard address? */
-static int sctp_v4_is_any(const union sctp_addr *addr)
-{
-	return htonl(INADDR_ANY) == addr->v4.sin_addr.s_addr;
+	saddr->sin.sin_family = AF_INET;
+	saddr->sin.sin_port = port;
+	saddr->sin.sin_addr.s_addr = fl4->saddr;
 }
 
 /* This function checks if the address is a valid address to be used for
@@ -344,7 +316,7 @@ static int sctp_v4_is_any(const union sctp_addr *addr)
  * Return 0 - If the address is a non-unicast or an illegal address.
  * Return 1 - If the address is a unicast.
  */
-static int sctp_v4_addr_valid(union sctp_addr *addr,
+static int sctp_v4_addr_valid(union inet_addr *addr,
 			      struct sctp_sock *sp,
 			      const struct sk_buff *skb)
 {
@@ -353,7 +325,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
 		return 0;
 
 	/* Is this a non-unicast address or a unusable SCTP address? */
-	if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr))
+	if (IS_IPV4_UNUSABLE_ADDRESS(addr->sin.sin_addr.s_addr))
 		return 0;
 
 	/* Is this a broadcast address? */
@@ -364,13 +336,13 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
 }
 
 /* Should this be available for binding?   */
-static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
+static int sctp_v4_available(union inet_addr *addr, struct sctp_sock *sp)
 {
 	struct net *net = sock_net(&sp->inet.sk);
-	int ret = inet_addr_type(net, addr->v4.sin_addr.s_addr);
+	int ret = inet_addr_type(net, addr->sin.sin_addr.s_addr);
 
 
-	if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) &&
+	if (addr->sin.sin_addr.s_addr != htonl(INADDR_ANY) &&
 	   ret != RTN_LOCAL &&
 	   !sp->inet.freebind &&
 	   !sysctl_ip_nonlocal_bind)
@@ -399,20 +371,20 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
  * IPv4 scoping can be controlled through sysctl option
  * net.sctp.addr_scope_policy
  */
-static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
+static sctp_scope_t sctp_v4_scope(union inet_addr *addr)
 {
 	sctp_scope_t retval;
 
 	/* Check for unusable SCTP addresses. */
-	if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) {
+	if (IS_IPV4_UNUSABLE_ADDRESS(addr->sin.sin_addr.s_addr)) {
 		retval =  SCTP_SCOPE_UNUSABLE;
-	} else if (ipv4_is_loopback(addr->v4.sin_addr.s_addr)) {
+	} else if (ipv4_is_loopback(addr->sin.sin_addr.s_addr)) {
 		retval = SCTP_SCOPE_LOOPBACK;
-	} else if (ipv4_is_linklocal_169(addr->v4.sin_addr.s_addr)) {
+	} else if (ipv4_is_linklocal_169(addr->sin.sin_addr.s_addr)) {
 		retval = SCTP_SCOPE_LINK;
-	} else if (ipv4_is_private_10(addr->v4.sin_addr.s_addr) ||
-		   ipv4_is_private_172(addr->v4.sin_addr.s_addr) ||
-		   ipv4_is_private_192(addr->v4.sin_addr.s_addr)) {
+	} else if (ipv4_is_private_10(addr->sin.sin_addr.s_addr) ||
+		   ipv4_is_private_172(addr->sin.sin_addr.s_addr) ||
+		   ipv4_is_private_192(addr->sin.sin_addr.s_addr)) {
 		retval = SCTP_SCOPE_PRIVATE;
 	} else {
 		retval = SCTP_SCOPE_GLOBAL;
@@ -425,7 +397,7 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
  * addresses. If an association is passed, trys to get a dst entry with a
  * source address that matches an address in the bind address list.
  */
-static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
+static void sctp_v4_get_dst(struct sctp_transport *t, union inet_addr *saddr,
 				struct flowi *fl, struct sock *sk)
 {
 	struct sctp_association *asoc = t->asoc;
@@ -434,12 +406,12 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 	struct sctp_bind_addr *bp;
 	struct sctp_sockaddr_entry *laddr;
 	struct dst_entry *dst = NULL;
-	union sctp_addr *daddr = &t->ipaddr;
-	union sctp_addr dst_saddr;
+	union inet_addr *daddr = &t->ipaddr;
+	union inet_addr dst_saddr;
 
 	memset(fl4, 0x0, sizeof(struct flowi4));
-	fl4->daddr  = daddr->v4.sin_addr.s_addr;
-	fl4->fl4_dport = daddr->v4.sin_port;
+	fl4->daddr  = daddr->sin.sin_addr.s_addr;
+	fl4->fl4_dport = daddr->sin.sin_port;
 	fl4->flowi4_proto = IPPROTO_SCTP;
 	if (asoc) {
 		fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk);
@@ -447,8 +419,8 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 		fl4->fl4_sport = htons(asoc->base.bind_addr.port);
 	}
 	if (saddr) {
-		fl4->saddr = saddr->v4.sin_addr.s_addr;
-		fl4->fl4_sport = saddr->v4.sin_port;
+		fl4->saddr = saddr->sin.sin_addr.s_addr;
+		fl4->fl4_sport = saddr->sin.sin_port;
 	}
 
 	pr_debug("%s: dst:%pI4, src:%pI4 - ", __func__, &fl4->daddr,
@@ -477,7 +449,7 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 			    (laddr->state != SCTP_ADDR_SRC &&
 			    !asoc->src_out_of_asoc_ok))
 				continue;
-			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
+			if (inet_addr_equal_strict(&dst_saddr, &laddr->a))
 				goto out_unlock;
 		}
 		rcu_read_unlock();
@@ -498,8 +470,8 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 			continue;
 		if ((laddr->state == SCTP_ADDR_SRC) &&
 		    (AF_INET == laddr->a.sa.sa_family)) {
-			fl4->saddr = laddr->a.v4.sin_addr.s_addr;
-			fl4->fl4_sport = laddr->a.v4.sin_port;
+			fl4->saddr = laddr->a.sin.sin_addr.s_addr;
+			fl4->fl4_sport = laddr->a.sin.sin_port;
 			rt = ip_route_output_key(sock_net(sk), fl4);
 			if (!IS_ERR(rt)) {
 				dst = &rt->dst;
@@ -526,12 +498,12 @@ static void sctp_v4_get_saddr(struct sctp_sock *sk,
 			      struct sctp_transport *t,
 			      struct flowi *fl)
 {
-	union sctp_addr *saddr = &t->saddr;
+	union inet_addr *saddr = &t->saddr;
 	struct rtable *rt = (struct rtable *)t->dst;
 
 	if (rt) {
-		saddr->v4.sin_family = AF_INET;
-		saddr->v4.sin_addr.s_addr = fl->u.ip4.saddr;
+		saddr->sa.sa_family = AF_INET;
+		saddr->sin.sin_addr.s_addr = fl->u.ip4.saddr;
 	}
 }
 
@@ -565,7 +537,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
 
 	newinet = inet_sk(newsk);
 
-	newinet->inet_daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
+	newinet->inet_daddr = asoc->peer.primary_addr.sin.sin_addr.s_addr;
 
 	sk_refcnt_debug_inc(newsk);
 
@@ -579,17 +551,11 @@ out:
 }
 
 /* Map address, empty for v4 family */
-static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
+static void sctp_v4_addr_v4map(struct sctp_sock *sp, union inet_addr *addr)
 {
 	/* Empty */
 }
 
-/* Dump the v4 addr to the seq file. */
-static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
-{
-	seq_printf(seq, "%pI4 ", &addr->v4.sin_addr);
-}
-
 static void sctp_v4_ecn_capable(struct sock *sk)
 {
 	INET_ECN_xmit(sk);
@@ -614,11 +580,11 @@ static void sctp_addr_wq_timeout_handler(unsigned long arg)
 		if (addrw->a.sa.sa_family == AF_INET6) {
 			struct in6_addr *in6;
 
-			if (ipv6_addr_type(&addrw->a.v6.sin6_addr) &
+			if (ipv6_addr_type(&addrw->a.sin6.sin6_addr) &
 			    IPV6_ADDR_LINKLOCAL)
 				goto free_next;
 
-			in6 = (struct in6_addr *)&addrw->a.v6.sin6_addr;
+			in6 = (struct in6_addr *)&addrw->a.sin6.sin6_addr;
 			if (ipv6_chk_addr(net, in6, NULL, 0) == 0 &&
 			    addrw->state == SCTP_ADDR_NEW) {
 				unsigned long timeo_val;
@@ -678,17 +644,8 @@ static struct sctp_sockaddr_entry *sctp_addr_wq_lookup(struct net *net,
 	struct sctp_sockaddr_entry *addrw;
 
 	list_for_each_entry(addrw, &net->sctp.addr_waitq, list) {
-		if (addrw->a.sa.sa_family != addr->a.sa.sa_family)
-			continue;
-		if (addrw->a.sa.sa_family == AF_INET) {
-			if (addrw->a.v4.sin_addr.s_addr ==
-			    addr->a.v4.sin_addr.s_addr)
-				return addrw;
-		} else if (addrw->a.sa.sa_family == AF_INET6) {
-			if (ipv6_addr_equal(&addrw->a.v6.sin6_addr,
-			    &addr->a.v6.sin6_addr))
-				return addrw;
-		}
+		if (inet_addr_equal(&addrw->a, &addr->a))
+			return addrw;
 	}
 	return NULL;
 }
@@ -759,9 +716,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
 	case NETDEV_UP:
 		addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
 		if (addr) {
-			addr->a.v4.sin_family = AF_INET;
-			addr->a.v4.sin_port = 0;
-			addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
+			addr->a.sa.sa_family = AF_INET;
+			addr->a.sin.sin_port = 0;
+			addr->a.sin.sin_addr.s_addr = ifa->ifa_local;
 			addr->valid = 1;
 			spin_lock_bh(&net->sctp.local_addr_lock);
 			list_add_tail_rcu(&addr->list, &net->sctp.local_addr_list);
@@ -774,7 +731,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
 		list_for_each_entry_safe(addr, temp,
 					&net->sctp.local_addr_list, list) {
 			if (addr->a.sa.sa_family == AF_INET &&
-					addr->a.v4.sin_addr.s_addr ==
+					addr->a.sin.sin_addr.s_addr ==
 					ifa->ifa_local) {
 				sctp_addr_wq_mgmt(net, addr, SCTP_ADDR_DEL);
 				found = 1;
@@ -881,7 +838,7 @@ static void sctp_inet_event_msgname(struct sctp_ulpevent *event, char *msgname,
 		asoc = event->asoc;
 		sctp_inet_msgname(msgname, addr_len);
 		sin = (struct sockaddr_in *)msgname;
-		sinfrom = &asoc->peer.primary_addr.v4;
+		sinfrom = &asoc->peer.primary_addr.sin;
 		sin->sin_port = htons(asoc->peer.port);
 		sin->sin_addr.s_addr = sinfrom->sin_addr.s_addr;
 	}
@@ -908,17 +865,17 @@ static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp)
 }
 
 /* Address matching with wildcards allowed. */
-static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
-			      const union sctp_addr *addr2,
+static int sctp_inet_cmp_addr(const union inet_addr *addr1,
+			      const union inet_addr *addr2,
 			      struct sctp_sock *opt)
 {
 	/* PF_INET only supports AF_INET addresses. */
 	if (addr1->sa.sa_family != addr2->sa.sa_family)
 		return 0;
-	if (htonl(INADDR_ANY) == addr1->v4.sin_addr.s_addr ||
-	    htonl(INADDR_ANY) == addr2->v4.sin_addr.s_addr)
+	if (htonl(INADDR_ANY) == addr1->sin.sin_addr.s_addr ||
+	    htonl(INADDR_ANY) == addr2->sin.sin_addr.s_addr)
 		return 1;
-	if (addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr)
+	if (addr1->sin.sin_addr.s_addr == addr2->sin.sin_addr.s_addr)
 		return 1;
 
 	return 0;
@@ -927,7 +884,7 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1,
 /* Verify that provided sockaddr looks bindable.  Common verification has
  * already been taken care of.
  */
-static int sctp_inet_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_bind_verify(struct sctp_sock *opt, union inet_addr *addr)
 {
 	return sctp_v4_available(addr, opt);
 }
@@ -935,7 +892,7 @@ static int sctp_inet_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
 /* Verify that sockaddr looks sendable.  Common verification has already
  * been taken care of.
  */
-static int sctp_inet_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
+static int sctp_inet_send_verify(struct sctp_sock *opt, union inet_addr *addr)
 {
 	return 1;
 }
@@ -1054,15 +1011,12 @@ static struct sctp_af sctp_af_inet = {
 	.to_sk_daddr	   = sctp_v4_to_sk_daddr,
 	.from_addr_param   = sctp_v4_from_addr_param,
 	.to_addr_param	   = sctp_v4_to_addr_param,
-	.cmp_addr	   = sctp_v4_cmp_addr,
+	.cmp_addr	   = inet_addr_equal_strict,
 	.addr_valid	   = sctp_v4_addr_valid,
-	.inaddr_any	   = sctp_v4_inaddr_any,
-	.is_any		   = sctp_v4_is_any,
 	.available	   = sctp_v4_available,
 	.scope		   = sctp_v4_scope,
 	.skb_iif	   = sctp_v4_skb_iif,
 	.is_ce		   = sctp_v4_is_ce,
-	.seq_dump_addr	   = sctp_v4_seq_dump_addr,
 	.ecn_capable	   = sctp_v4_ecn_capable,
 	.net_header_len	   = sizeof(struct iphdr),
 	.sockaddr_len	   = sizeof(struct sockaddr_in),
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 780a2d4..d74d7d3 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -77,7 +77,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
 					const __u8 *raw_addrs, int addrs_len);
 static int sctp_process_param(struct sctp_association *asoc,
 			      union sctp_params param,
-			      const union sctp_addr *peer_addr,
+			      const union inet_addr *peer_addr,
 			      gfp_t gfp);
 static void *sctp_addto_param(struct sctp_chunk *chunk, int len,
 			      const void *data);
@@ -1329,15 +1329,15 @@ nodata:
 }
 
 /* Set chunk->source and dest based on the IP header in chunk->skb.  */
-void sctp_init_addrs(struct sctp_chunk *chunk, union sctp_addr *src,
-		     union sctp_addr *dest)
+void sctp_init_addrs(struct sctp_chunk *chunk, union inet_addr *src,
+		     union inet_addr *dest)
 {
-	memcpy(&chunk->source, src, sizeof(union sctp_addr));
-	memcpy(&chunk->dest, dest, sizeof(union sctp_addr));
+	memcpy(&chunk->source, src, sizeof(union inet_addr));
+	memcpy(&chunk->dest, dest, sizeof(union inet_addr));
 }
 
 /* Extract the source address from a chunk.  */
-const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
+const union inet_addr *sctp_source(const struct sctp_chunk *chunk)
 {
 	/* If we have a known transport, use that.  */
 	if (chunk->transport) {
@@ -1741,7 +1741,7 @@ no_hmac:
 		goto fail;
 	}
 
-	if (chunk->sctp_hdr->source != bear_cookie->peer_addr.v4.sin_port ||
+	if (chunk->sctp_hdr->source != bear_cookie->peer_addr.sin.sin_port ||
 	    ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
 		*error = -SCTP_IERROR_BAD_PORTS;
 		goto fail;
@@ -2269,7 +2269,7 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
  * FIXME:  This is an association method.
  */
 int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
-		      const union sctp_addr *peer_addr,
+		      const union inet_addr *peer_addr,
 		      sctp_init_chunk_t *peer_init, gfp_t gfp)
 {
 	struct net *net = sock_net(asoc->base.sk);
@@ -2277,7 +2277,7 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
 	struct sctp_transport *transport;
 	struct list_head *pos, *temp;
 	struct sctp_af *af;
-	union sctp_addr addr;
+	union inet_addr addr;
 	char *cookie;
 	int src_match = 0;
 
@@ -2466,11 +2466,11 @@ nomem:
  */
 static int sctp_process_param(struct sctp_association *asoc,
 			      union sctp_params param,
-			      const union sctp_addr *peer_addr,
+			      const union inet_addr *peer_addr,
 			      gfp_t gfp)
 {
 	struct net *net = sock_net(asoc->base.sk);
-	union sctp_addr addr;
+	union inet_addr addr;
 	int i;
 	__u16 sat;
 	int retval = 1;
@@ -2717,7 +2717,7 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *ep)
  * Address Parameter and other parameter will not be wrapped in this function
  */
 static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
-					   union sctp_addr *addr,
+					   union inet_addr *addr,
 					   int vparam_len)
 {
 	sctp_addiphdr_t asconf;
@@ -2725,7 +2725,7 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
 	int length = sizeof(asconf) + vparam_len;
 	union sctp_addr_param addrparam;
 	int addrlen;
-	struct sctp_af *af = sctp_get_af_specific(addr->v4.sin_family);
+	struct sctp_af *af = sctp_get_af_specific(addr->sin.sin_family);
 
 	addrlen = af->to_addr_param(addr, &addrparam);
 	if (!addrlen)
@@ -2772,7 +2772,7 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
  *
  */
 struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
-					      union sctp_addr	      *laddr,
+					      union inet_addr	      *laddr,
 					      struct sockaddr	      *addrs,
 					      int		      addrcnt,
 					      __be16		      flags)
@@ -2780,7 +2780,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 	sctp_addip_param_t	param;
 	struct sctp_chunk	*retval;
 	union sctp_addr_param	addr_param;
-	union sctp_addr		*addr;
+	union inet_addr		*addr;
 	void			*addr_buf;
 	struct sctp_af		*af;
 	int			paramlen = sizeof(param);
@@ -2793,7 +2793,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 	addr_buf = addrs;
 	for (i = 0; i < addrcnt; i++) {
 		addr = addr_buf;
-		af = sctp_get_af_specific(addr->v4.sin_family);
+		af = sctp_get_af_specific(addr->sin.sin_family);
 		addr_param_len = af->to_addr_param(addr, &addr_param);
 
 		totallen += paramlen;
@@ -2821,7 +2821,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 	addr_buf = addrs;
 	for (i = 0; i < addrcnt; i++) {
 		addr = addr_buf;
-		af = sctp_get_af_specific(addr->v4.sin_family);
+		af = sctp_get_af_specific(addr->sin.sin_family);
 		addr_param_len = af->to_addr_param(addr, &addr_param);
 		param.param_hdr.type = flags;
 		param.param_hdr.length = htons(paramlen + addr_param_len);
@@ -2834,7 +2834,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
 	}
 	if (flags == SCTP_PARAM_ADD_IP && del_pickup) {
 		addr = asoc->asconf_addr_del_pending;
-		af = sctp_get_af_specific(addr->v4.sin_family);
+		af = sctp_get_af_specific(addr->sin.sin_family);
 		addr_param_len = af->to_addr_param(addr, &addr_param);
 		param.param_hdr.type = SCTP_PARAM_DEL_IP;
 		param.param_hdr.length = htons(paramlen + addr_param_len);
@@ -2861,14 +2861,14 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
  * Create an ASCONF chunk with Set Primary IP address parameter.
  */
 struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc,
-					     union sctp_addr *addr)
+					     union inet_addr *addr)
 {
 	sctp_addip_param_t	param;
 	struct sctp_chunk 	*retval;
 	int 			len = sizeof(param);
 	union sctp_addr_param	addrparam;
 	int			addrlen;
-	struct sctp_af		*af = sctp_get_af_specific(addr->v4.sin_family);
+	struct sctp_af		*af = sctp_get_af_specific(addr->sin.sin_family);
 
 	addrlen = af->to_addr_param(addr, &addrparam);
 	if (!addrlen)
@@ -2977,7 +2977,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 {
 	struct sctp_transport *peer;
 	struct sctp_af *af;
-	union sctp_addr	addr;
+	union inet_addr	addr;
 	union sctp_addr_param *addr_param;
 
 	addr_param = (void *)asconf_param + sizeof(sctp_addip_param_t);
@@ -3011,7 +3011,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 	 * (note: wildcard is permitted and requires special handling so
 	 *  make sure we check for that)
 	 */
-	if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
+	if (!inet_addr_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
 		return SCTP_ERROR_DNS_FAILED;
 
 	switch (asconf_param->param_hdr.type) {
@@ -3020,7 +3020,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 		 * If the address 0.0.0.0 or ::0 is provided, the source
 		 * address of the packet MUST be added.
 		 */
-		if (af->is_any(&addr))
+		if (inet_addr_any(&addr))
 			memcpy(&addr, &asconf->source, sizeof(addr));
 
 		/* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
@@ -3063,7 +3063,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 		 * addresses of the peer except	the source address of the
 		 * packet MUST be deleted.
 		 */
-		if (af->is_any(&addr)) {
+		if (inet_addr_any(&addr)) {
 			sctp_assoc_set_primary(asoc, asconf->transport);
 			sctp_assoc_del_nonprimary_peers(asoc,
 							asconf->transport);
@@ -3076,8 +3076,8 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 		 * MAY mark the source address of the packet as its
 		 * primary.
 		 */
-		if (af->is_any(&addr))
-			memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
+		if (inet_addr_any(&addr))
+			memcpy(&addr.sin, sctp_source(asconf), sizeof(addr));
 
 		peer = sctp_assoc_lookup_paddr(asoc, &addr);
 		if (!peer)
@@ -3231,7 +3231,7 @@ static void sctp_asconf_param_success(struct sctp_association *asoc,
 				     sctp_addip_param_t *asconf_param)
 {
 	struct sctp_af *af;
-	union sctp_addr	addr;
+	union inet_addr	addr;
 	struct sctp_bind_addr *bp = &asoc->base.bind_addr;
 	union sctp_addr_param *addr_param;
 	struct sctp_transport *transport;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 93271f0..912d4b0 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -1130,7 +1130,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net,
 					sctp_cmd_seq_t *commands)
 {
 	struct sctp_chunk *chunk = arg;
-	union sctp_addr from_addr;
+	union inet_addr from_addr;
 	struct sctp_transport *link;
 	sctp_sender_hb_info_t *hbinfo;
 	unsigned long max_interval;
@@ -1156,17 +1156,8 @@ sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net,
 
 	/* This should never happen, but lets log it if so.  */
 	if (unlikely(!link)) {
-		if (from_addr.sa.sa_family == AF_INET6) {
-			net_warn_ratelimited("%s association %p could not find address %pI6\n",
-					     __func__,
-					     asoc,
-					     &from_addr.v6.sin6_addr);
-		} else {
-			net_warn_ratelimited("%s association %p could not find address %pI4\n",
-					     __func__,
-					     asoc,
-					     &from_addr.v4.sin_addr.s_addr);
-		}
+		net_warn_ratelimited("%s association %p could not find address %pIA\n",
+				     __func__, asoc, &from_addr);
 		return SCTP_DISPOSITION_DISCARD;
 	}
 
@@ -1199,7 +1190,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(struct net *net,
 /* Helper function to send out an abort for the restart
  * condition.
  */
-static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa,
+static int sctp_sf_send_restart_abort(struct net *net, union inet_addr *ssa,
 				      struct sctp_chunk *init,
 				      sctp_cmd_seq_t *commands)
 {
@@ -1209,7 +1200,7 @@ static int sctp_sf_send_restart_abort(struct net *net, union sctp_addr *ssa,
 	struct sctp_errhdr *errhdr;
 	struct sctp_endpoint *ep;
 	char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)];
-	struct sctp_af *af = sctp_get_af_specific(ssa->v4.sin_family);
+	struct sctp_af *af = sctp_get_af_specific(ssa->sin.sin_family);
 
 	/* Build the error on the stack.   We are way to malloc crazy
 	 * throughout the code today.
@@ -1249,7 +1240,7 @@ out:
 }
 
 static bool list_has_sctp_addr(const struct list_head *list,
-			       union sctp_addr *ipaddr)
+			       union inet_addr *ipaddr)
 {
 	struct sctp_transport *addr;
 
@@ -6047,7 +6038,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
 	/* Cache a route for the transport with the chunk's destination as
 	 * the source address.
 	 */
-	sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
+	sctp_transport_route(transport, (union inet_addr *)&chunk->dest,
 			     sctp_sk(net->sctp.ctl_sock));
 
 	packet = sctp_packet_init(&transport->packet, transport, sport, dport);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 851093f..0f54762 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -95,14 +95,14 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo);
 static void sctp_wait_for_close(struct sock *sk, long timeo);
 static void sctp_destruct_sock(struct sock *sk);
 static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
-					union sctp_addr *addr, int len);
+					union inet_addr *addr, int len);
 static int sctp_bindx_add(struct sock *, struct sockaddr *, int);
 static int sctp_bindx_rem(struct sock *, struct sockaddr *, int);
 static int sctp_send_asconf_add_ip(struct sock *, struct sockaddr *, int);
 static int sctp_send_asconf_del_ip(struct sock *, struct sockaddr *, int);
 static int sctp_send_asconf(struct sctp_association *asoc,
 			    struct sctp_chunk *chunk);
-static int sctp_do_bind(struct sock *, union sctp_addr *, int);
+static int sctp_do_bind(struct sock *, union inet_addr *, int);
 static int sctp_autobind(struct sock *sk);
 static void sctp_sock_migrate(struct sock *, struct sock *,
 			      struct sctp_association *, sctp_socket_type_t);
@@ -179,7 +179,7 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
 }
 
 /* Verify that this is a valid address. */
-static inline int sctp_verify_addr(struct sock *sk, union sctp_addr *addr,
+static inline int sctp_verify_addr(struct sock *sk, union inet_addr *addr,
 				   int len)
 {
 	struct sctp_af *af;
@@ -246,7 +246,7 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
 {
 	struct sctp_association *addr_asoc = NULL, *id_asoc = NULL;
 	struct sctp_transport *transport;
-	union sctp_addr *laddr = (union sctp_addr *)addr;
+	union inet_addr *laddr = (union inet_addr *)addr;
 
 	addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep,
 					       laddr,
@@ -260,7 +260,7 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
 		return NULL;
 
 	sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
-						(union sctp_addr *)addr);
+						(union inet_addr *)addr);
 
 	return transport;
 }
@@ -286,7 +286,7 @@ static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
 
 	/* Disallow binding twice. */
 	if (!sctp_sk(sk)->ep->base.bind_addr.port)
-		retval = sctp_do_bind(sk, (union sctp_addr *)addr,
+		retval = sctp_do_bind(sk, (union inet_addr *)addr,
 				      addr_len);
 	else
 		retval = -EINVAL;
@@ -296,11 +296,11 @@ static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
 	return retval;
 }
 
-static long sctp_get_port_local(struct sock *, union sctp_addr *);
+static long sctp_get_port_local(struct sock *, union inet_addr *);
 
 /* Verify this is a valid sockaddr. */
 static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
-					union sctp_addr *addr, int len)
+					union inet_addr *addr, int len)
 {
 	struct sctp_af *af;
 
@@ -310,7 +310,7 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 
 	/* V4 mapped address are really of AF_INET family */
 	if (addr->sa.sa_family == AF_INET6 &&
-	    ipv6_addr_v4mapped(&addr->v6.sin6_addr)) {
+	    ipv6_addr_v4mapped(&addr->sin6.sin6_addr)) {
 		if (!opt->pf->af_supported(AF_INET, opt))
 			return NULL;
 	} else {
@@ -329,7 +329,7 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
 }
 
 /* Bind a local address either to an endpoint or to an association.  */
-static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
+static int sctp_do_bind(struct sock *sk, union inet_addr *addr, int len)
 {
 	struct net *net = sock_net(sk);
 	struct sctp_sock *sp = sctp_sk(sk);
@@ -347,7 +347,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 		return -EINVAL;
 	}
 
-	snum = ntohs(addr->v4.sin_port);
+	snum = ntohs(addr->sin.sin_port);
 
 	pr_debug("%s: sk:%p, new addr:%pIAc, port:%d, new port:%d, len:%d\n",
 		 __func__, sk, &addr->sa, bp->port, snum, len);
@@ -384,7 +384,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
 	 * The function sctp_get_port_local() does duplicate address
 	 * detection.
 	 */
-	addr->v4.sin_port = htons(snum);
+	addr->sin.sin_port = htons(snum);
 	if ((ret = sctp_get_port_local(sk, addr))) {
 		return -EADDRINUSE;
 	}
@@ -478,7 +478,7 @@ static int sctp_bindx_add(struct sock *sk, struct sockaddr *addrs, int addrcnt)
 			goto err_bindx_add;
 		}
 
-		retval = sctp_do_bind(sk, (union sctp_addr *)sa_addr,
+		retval = sctp_do_bind(sk, (union inet_addr *)sa_addr,
 				      af->sockaddr_len);
 
 		addr_buf += af->sockaddr_len;
@@ -516,8 +516,8 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
 	struct sctp_bind_addr		*bp;
 	struct sctp_chunk		*chunk;
 	struct sctp_sockaddr_entry	*laddr;
-	union sctp_addr			*addr;
-	union sctp_addr			saveaddr;
+	union inet_addr			*addr;
+	union inet_addr			saveaddr;
 	void				*addr_buf;
 	struct sctp_af			*af;
 	struct list_head		*p;
@@ -551,7 +551,7 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
 		addr_buf = addrs;
 		for (i = 0; i < addrcnt; i++) {
 			addr = addr_buf;
-			af = sctp_get_af_specific(addr->v4.sin_family);
+			af = sctp_get_af_specific(addr->sin.sin_family);
 			if (!af) {
 				retval = -EINVAL;
 				goto out;
@@ -584,7 +584,7 @@ static int sctp_send_asconf_add_ip(struct sock		*sk,
 		addr_buf = addrs;
 		for (i = 0; i < addrcnt; i++) {
 			addr = addr_buf;
-			af = sctp_get_af_specific(addr->v4.sin_family);
+			af = sctp_get_af_specific(addr->sin.sin_family);
 			memcpy(&saveaddr, addr, af->sockaddr_len);
 			retval = sctp_add_bind_addr(bp, &saveaddr,
 						    SCTP_ADDR_NEW, GFP_ATOMIC);
@@ -637,7 +637,7 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
 	struct sctp_bind_addr *bp = &ep->base.bind_addr;
 	int retval = 0;
 	void *addr_buf;
-	union sctp_addr *sa_addr;
+	union inet_addr *sa_addr;
 	struct sctp_af *af;
 
 	pr_debug("%s: sk:%p, addrs:%p, addrcnt:%d\n",
@@ -667,14 +667,14 @@ static int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
 			goto err_bindx_rem;
 		}
 
-		if (sa_addr->v4.sin_port &&
-		    sa_addr->v4.sin_port != htons(bp->port)) {
+		if (sa_addr->sin.sin_port &&
+		    sa_addr->sin.sin_port != htons(bp->port)) {
 			retval = -EINVAL;
 			goto err_bindx_rem;
 		}
 
-		if (!sa_addr->v4.sin_port)
-			sa_addr->v4.sin_port = htons(bp->port);
+		if (!sa_addr->sin.sin_port)
+			sa_addr->sin.sin_port = htons(bp->port);
 
 		/* FIXME - There is probably a need to check if sk->sk_saddr and
 		 * sk->sk_rcv_addr are currently set to one of the addresses to
@@ -719,7 +719,7 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 	struct sctp_transport	*transport;
 	struct sctp_bind_addr	*bp;
 	struct sctp_chunk	*chunk;
-	union sctp_addr		*laddr;
+	union inet_addr		*laddr;
 	void			*addr_buf;
 	struct sctp_af		*af;
 	struct sctp_sockaddr_entry *saddr;
@@ -756,7 +756,7 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 		addr_buf = addrs;
 		for (i = 0; i < addrcnt; i++) {
 			laddr = addr_buf;
-			af = sctp_get_af_specific(laddr->v4.sin_family);
+			af = sctp_get_af_specific(laddr->sin.sin_family);
 			if (!af) {
 				retval = -EINVAL;
 				goto out;
@@ -776,31 +776,31 @@ static int sctp_send_asconf_del_ip(struct sock		*sk,
 		 * association.
 		 */
 		bp = &asoc->base.bind_addr;
-		laddr = sctp_find_unmatch_addr(bp, (union sctp_addr *)addrs,
+		laddr = sctp_find_unmatch_addr(bp, (union inet_addr *)addrs,
 					       addrcnt, sp);
 		if ((laddr == NULL) && (addrcnt == 1)) {
 			if (asoc->asconf_addr_del_pending)
 				continue;
 			asoc->asconf_addr_del_pending =
-			    kzalloc(sizeof(union sctp_addr), GFP_ATOMIC);
+			    kzalloc(sizeof(union inet_addr), GFP_ATOMIC);
 			if (asoc->asconf_addr_del_pending == NULL) {
 				retval = -ENOMEM;
 				goto out;
 			}
 			asoc->asconf_addr_del_pending->sa.sa_family =
 				    addrs->sa_family;
-			asoc->asconf_addr_del_pending->v4.sin_port =
+			asoc->asconf_addr_del_pending->sin.sin_port =
 				    htons(bp->port);
 			if (addrs->sa_family == AF_INET) {
 				struct sockaddr_in *sin;
 
 				sin = (struct sockaddr_in *)addrs;
-				asoc->asconf_addr_del_pending->v4.sin_addr.s_addr = sin->sin_addr.s_addr;
+				asoc->asconf_addr_del_pending->sin.sin_addr.s_addr = sin->sin_addr.s_addr;
 			} else if (addrs->sa_family == AF_INET6) {
 				struct sockaddr_in6 *sin6;
 
 				sin6 = (struct sockaddr_in6 *)addrs;
-				asoc->asconf_addr_del_pending->v6.sin6_addr = sin6->sin6_addr;
+				asoc->asconf_addr_del_pending->sin6.sin6_addr = sin6->sin6_addr;
 			}
 
 			pr_debug("%s: keep the last address asoc:%p %pIAc at %p\n",
@@ -830,7 +830,7 @@ skip_mkasconf:
 		addr_buf = addrs;
 		for (i = 0; i < addrcnt; i++) {
 			laddr = addr_buf;
-			af = sctp_get_af_specific(laddr->v4.sin_family);
+			af = sctp_get_af_specific(laddr->sin.sin_family);
 			list_for_each_entry(saddr, &bp->address_list, list) {
 				if (sctp_cmp_addr_exact(&saddr->a, laddr))
 					saddr->state = SCTP_ADDR_DEL;
@@ -862,12 +862,12 @@ out:
 int sctp_asconf_mgmt(struct sctp_sock *sp, struct sctp_sockaddr_entry *addrw)
 {
 	struct sock *sk = sctp_opt2sk(sp);
-	union sctp_addr *addr;
+	union inet_addr *addr;
 	struct sctp_af *af;
 
 	/* It is safe to write port space in caller. */
 	addr = &addrw->a;
-	addr->v4.sin_port = htons(sp->ep->base.bind_addr.port);
+	addr->sin.sin_port = htons(sp->ep->base.bind_addr.port);
 	af = sctp_get_af_specific(addr->sa.sa_family);
 	if (!af)
 		return -EINVAL;
@@ -1054,14 +1054,14 @@ static int __sctp_connect(struct sock* sk,
 	struct sctp_association *asoc = NULL;
 	struct sctp_association *asoc2;
 	struct sctp_transport *transport;
-	union sctp_addr to;
+	union inet_addr to;
 	struct sctp_af *af;
 	sctp_scope_t scope;
 	long timeo;
 	int err = 0;
 	int addrcnt = 0;
 	int walk_size = 0;
-	union sctp_addr *sa_addr = NULL;
+	union inet_addr *sa_addr = NULL;
 	void *addr_buf;
 	unsigned short port;
 	unsigned int f_flags = 0;
@@ -1099,7 +1099,7 @@ static int __sctp_connect(struct sock* sk,
 			goto out_free;
 		}
 
-		port = ntohs(sa_addr->v4.sin_port);
+		port = ntohs(sa_addr->sin.sin_port);
 
 		/* Save current address so we can work with it */
 		memcpy(&to, sa_addr, af->sockaddr_len);
@@ -1575,7 +1575,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 	struct sctp_association *new_asoc=NULL, *asoc=NULL;
 	struct sctp_transport *transport, *chunk_tp;
 	struct sctp_chunk *chunk;
-	union sctp_addr to;
+	union inet_addr to;
 	struct sockaddr *msg_name = NULL;
 	struct sctp_sndrcvinfo default_sinfo;
 	struct sctp_sndrcvinfo *sinfo;
@@ -1617,7 +1617,7 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 	if (!sctp_style(sk, UDP_HIGH_BANDWIDTH) && msg->msg_name) {
 		int msg_namelen = msg->msg_namelen;
 
-		err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name,
+		err = sctp_verify_addr(sk, (union inet_addr *)msg->msg_name,
 				       msg_namelen);
 		if (err)
 			return err;
@@ -2483,7 +2483,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
 	/* If an address other than INADDR_ANY is specified, and
 	 * no transport is found, then the request is invalid.
 	 */
-	if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
+	if (!inet_addr_any((union inet_addr *)&params.spp_address)) {
 		trans = sctp_addr_id2transport(sk, &params.spp_address,
 					       params.spp_assoc_id);
 		if (!trans)
@@ -3065,15 +3065,15 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
 	if (!af)
 		return -EINVAL;
 
-	if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+	if (!af->addr_valid((union inet_addr *)&prim.sspp_addr, sp, NULL))
 		return -EADDRNOTAVAIL;
 
-	if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
+	if (!sctp_assoc_lookup_laddr(asoc, (union inet_addr *)&prim.sspp_addr))
 		return -EADDRNOTAVAIL;
 
 	/* Create an ASCONF chunk with SET_PRIMARY parameter	*/
 	chunk = sctp_make_asconf_set_prim(asoc,
-					  (union sctp_addr *)&prim.sspp_addr);
+					  (union inet_addr *)&prim.sspp_addr);
 	if (!chunk)
 		return -ENOMEM;
 
@@ -3502,7 +3502,7 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
 		return -EFAULT;
 
 
-	if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
+	if (inet_addr_any((const union inet_addr *)&val.spt_address)) {
 		asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 		if (!asoc)
 			return -ENOENT;
@@ -4100,7 +4100,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
 			transport->af_specific->sockaddr_len);
 	/* Map ipv4 address into v4-mapped-on-v6 address.  */
 	sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
-		(union sctp_addr *)&status.sstat_primary.spinfo_address);
+		(union inet_addr *)&status.sstat_primary.spinfo_address);
 	status.sstat_primary.spinfo_state = transport->state;
 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
 	status.sstat_primary.spinfo_srtt = transport->srtt;
@@ -4455,7 +4455,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
 	/* If an address other than INADDR_ANY is specified, and
 	 * no transport is found, then the request is invalid.
 	 */
-	if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
+	if (!inet_addr_any((union inet_addr *)&params.spp_address)) {
 		trans = sctp_addr_id2transport(sk, &params.spp_address,
 					       params.spp_assoc_id);
 		if (!trans) {
@@ -4639,7 +4639,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
 	struct sctp_getaddrs getaddrs;
 	struct sctp_transport *from;
 	void __user *to;
-	union sctp_addr temp;
+	union inet_addr temp;
 	struct sctp_sock *sp = sctp_sk(sk);
 	int addrlen;
 	size_t space_left;
@@ -4686,7 +4686,7 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
 			    size_t space_left, int *bytes_copied)
 {
 	struct sctp_sockaddr_entry *addr;
-	union sctp_addr temp;
+	union inet_addr temp;
 	int cnt = 0;
 	int addrlen;
 	struct net *net = sock_net(sk);
@@ -4704,8 +4704,8 @@ static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to,
 		    (AF_INET == addr->a.sa.sa_family))
 			continue;
 		memcpy(&temp, &addr->a, sizeof(temp));
-		if (!temp.v4.sin_port)
-			temp.v4.sin_port = htons(port);
+		if (!temp.sin.sin_port)
+			temp.sin.sin_port = htons(port);
 
 		sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
 								&temp);
@@ -4736,7 +4736,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
 	struct sctp_getaddrs getaddrs;
 	struct sctp_sockaddr_entry *addr;
 	void __user *to;
-	union sctp_addr temp;
+	union inet_addr temp;
 	struct sctp_sock *sp = sctp_sk(sk);
 	int addrlen;
 	int err = 0;
@@ -4779,7 +4779,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
 	if (sctp_list_single_entry(&bp->address_list)) {
 		addr = list_entry(bp->address_list.next,
 				  struct sctp_sockaddr_entry, list);
-		if (sctp_is_any(sk, &addr->a)) {
+		if (inet_addr_any(&addr->a)) {
 			cnt = sctp_copy_laddrs(sk, bp->port, addrs,
 						space_left, &bytes_copied);
 			if (cnt < 0) {
@@ -4858,7 +4858,7 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
 		asoc->peer.primary_path->af_specific->sockaddr_len);
 
 	sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp,
-			(union sctp_addr *)&prim.ssp_addr);
+			(union inet_addr *)&prim.ssp_addr);
 
 	if (put_user(len, optlen))
 		return -EFAULT;
@@ -5611,7 +5611,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
 	if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len))
 		return -EFAULT;
 
-	if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
+	if (inet_addr_any((const union inet_addr *)&val.spt_address)) {
 		asoc = sctp_id2assoc(sk, val.spt_assoc_id);
 		if (!asoc)
 			return -ENOENT;
@@ -5875,14 +5875,14 @@ static void sctp_unhash(struct sock *sk)
 static struct sctp_bind_bucket *sctp_bucket_create(
 	struct sctp_bind_hashbucket *head, struct net *, unsigned short snum);
 
-static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
+static long sctp_get_port_local(struct sock *sk, union inet_addr *addr)
 {
 	struct sctp_bind_hashbucket *head; /* hash list */
 	struct sctp_bind_bucket *pp;
 	unsigned short snum;
 	int ret;
 
-	snum = ntohs(addr->v4.sin_port);
+	snum = ntohs(addr->sin.sin_port);
 
 	pr_debug("%s: begins, snum:%d\n", __func__, snum);
 
@@ -6029,12 +6029,12 @@ fail:
  */
 static int sctp_get_port(struct sock *sk, unsigned short snum)
 {
-	union sctp_addr addr;
+	union inet_addr addr;
 	struct sctp_af *af = sctp_sk(sk)->pf->af;
 
 	/* Set up a dummy address struct from the sk. */
 	af->from_sk(&addr, sk);
-	addr.v4.sin_port = htons(snum);
+	addr.sin.sin_port = htons(snum);
 
 	/* Note: sk->sk_num gets filled in if ephemeral port request. */
 	return !!sctp_get_port_local(sk, &addr);
@@ -6270,6 +6270,16 @@ void sctp_put_port(struct sock *sk)
 	sctp_local_bh_enable();
 }
 
+static void sctp_inaddr_any(union inet_addr *addr, sa_family_t family, __be16 port)
+{
+	memset(addr, 0x00, sizeof(union inet_addr));
+	addr->sa.sa_family = family;
+	if (family == AF_INET)
+		addr->sin.sin_port = port;
+	else
+		addr->sin6.sin6_port = port;
+}
+
 /*
  * The system picks an ephemeral port and choose an address set equivalent
  * to binding with a wildcard address.
@@ -6278,7 +6288,7 @@ void sctp_put_port(struct sock *sk)
  */
 static int sctp_autobind(struct sock *sk)
 {
-	union sctp_addr autoaddr;
+	union inet_addr autoaddr;
 	struct sctp_af *af;
 	__be16 port;
 
@@ -6286,7 +6296,7 @@ static int sctp_autobind(struct sock *sk)
 	af = sctp_sk(sk)->pf->af;
 
 	port = htons(inet_sk(sk)->inet_num);
-	af->inaddr_any(&autoaddr, port);
+	sctp_inaddr_any(&autoaddr, af->sa_family, port);
 
 	return sctp_do_bind(sk, &autoaddr, af->sockaddr_len);
 }
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 9602c52..f9e7baa 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -9,7 +9,7 @@
  *
  * This module provides the abstraction for an SCTP tranport representing
  * a remote transport address.  For local transport addresses, we just use
- * union sctp_addr.
+ * union inet_addr.
  *
  * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
@@ -61,13 +61,13 @@
 /* Initialize a new transport from provided memory.  */
 static struct sctp_transport *sctp_transport_init(struct net *net,
 						  struct sctp_transport *peer,
-						  const union sctp_addr *addr,
+						  const union inet_addr *addr,
 						  gfp_t gfp)
 {
 	/* Copy in the address.  */
 	peer->ipaddr = *addr;
 	peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
-	memset(&peer->saddr, 0, sizeof(union sctp_addr));
+	memset(&peer->saddr, 0, sizeof(union inet_addr));
 
 	peer->sack_generation = 0;
 
@@ -111,7 +111,7 @@ static struct sctp_transport *sctp_transport_init(struct net *net,
 
 /* Allocate and initialize a new transport.  */
 struct sctp_transport *sctp_transport_new(struct net *net,
-					  const union sctp_addr *addr,
+					  const union inet_addr *addr,
 					  gfp_t gfp)
 {
 	struct sctp_transport *transport;
@@ -273,7 +273,7 @@ void sctp_transport_update_pmtu(struct sock *sk, struct sctp_transport *t, u32 p
  * address.
  */
 void sctp_transport_route(struct sctp_transport *transport,
-			  union sctp_addr *saddr, struct sctp_sock *opt)
+			  union inet_addr *saddr, struct sctp_sock *opt)
 {
 	struct sctp_association *asoc = transport->asoc;
 	struct sctp_af *af = transport->af_specific;
@@ -281,7 +281,7 @@ void sctp_transport_route(struct sctp_transport *transport,
 	af->get_dst(transport, saddr, &transport->fl, sctp_opt2sk(opt));
 
 	if (saddr)
-		memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
+		memcpy(&transport->saddr, saddr, sizeof(union inet_addr));
 	else
 		af->get_saddr(opt, transport, &transport->fl);
 
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index c07624f..3100bec 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -350,7 +350,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
 	/* Map ipv4 address into v4-mapped-on-v6 address.  */
 	sctp_get_pf_specific(asoc->base.sk->sk_family)->addr_v4map(
 					sctp_sk(asoc->base.sk),
-					(union sctp_addr *)&spc->spc_aaddr);
+					(union inet_addr *)&spc->spc_aaddr);
 
 	return event;
 
-- 
1.7.7.6

^ permalink raw reply related

* [Patch net-next v2 4/8] bridge: use generic struct in_addr_gen
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Stephen Hemminger, Cong Wang
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

From: Cong Wang <amwang@redhat.com>

Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 net/bridge/br_mdb.c       |   53 ++++++++++++++++++------------------
 net/bridge/br_multicast.c |   65 +++++++++++++++++++-------------------------
 net/bridge/br_private.h   |    9 +-----
 3 files changed, 57 insertions(+), 70 deletions(-)

diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c
index 0daae3e..3fad730 100644
--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -13,6 +13,29 @@
 
 #include "br_private.h"
 
+static void br_ip_to_entry(struct br_mdb_entry *entry, struct br_ip *ip)
+{
+	if (ip->ip.family == AF_INET) {
+		entry->addr.proto = htons(ETH_P_IP);
+		entry->addr.u.ip4 = ip->ip.in_addr.s_addr;
+	} else {
+		entry->addr.proto = htons(ETH_P_IPV6);
+		entry->addr.u.ip6 = ip->ip.in6_addr;
+	}
+}
+
+static void br_entry_to_ip(struct br_ip *ip, struct br_mdb_entry *entry)
+{
+	__be16 proto = entry->addr.proto;
+	if (proto == htons(ETH_P_IP)) {
+		ip->ip.family = AF_INET;
+		ip->ip.in_addr.s_addr = entry->addr.u.ip4;
+	} else {
+		ip->ip.family = AF_INET6;
+		ip->ip.in6_addr = entry->addr.u.ip6;
+	}
+}
+
 static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
 			       struct net_device *dev)
 {
@@ -83,13 +106,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
 					memset(&e, 0, sizeof(e));
 					e.ifindex = port->dev->ifindex;
 					e.state = p->state;
-					if (p->addr.proto == htons(ETH_P_IP))
-						e.addr.u.ip4 = p->addr.u.ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-					if (p->addr.proto == htons(ETH_P_IPV6))
-						e.addr.u.ip6 = p->addr.u.ip6;
-#endif
-					e.addr.proto = p->addr.proto;
+					br_ip_to_entry(&e, &p->addr);
 					if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) {
 						nla_nest_cancel(skb, nest2);
 						err = -EMSGSIZE;
@@ -233,11 +250,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 
 	memset(&entry, 0, sizeof(entry));
 	entry.ifindex = port->dev->ifindex;
-	entry.addr.proto = group->proto;
-	entry.addr.u.ip4 = group->u.ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-	entry.addr.u.ip6 = group->u.ip6;
-#endif
+	br_ip_to_entry(&entry, group);
 	__br_mdb_notify(dev, &entry, type);
 }
 
@@ -368,13 +381,7 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br,
 	if (!p || p->br != br || p->state == BR_STATE_DISABLED)
 		return -EINVAL;
 
-	ip.proto = entry->addr.proto;
-	if (ip.proto == htons(ETH_P_IP))
-		ip.u.ip4 = entry->addr.u.ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-	else
-		ip.u.ip6 = entry->addr.u.ip6;
-#endif
+	br_entry_to_ip(&ip, entry);
 
 	spin_lock_bh(&br->multicast_lock);
 	ret = br_mdb_add_group(br, p, &ip, entry->state);
@@ -417,13 +424,7 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
 	if (timer_pending(&br->multicast_querier_timer))
 		return -EBUSY;
 
-	ip.proto = entry->addr.proto;
-	if (ip.proto == htons(ETH_P_IP))
-		ip.u.ip4 = entry->addr.u.ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-	else
-		ip.u.ip6 = entry->addr.u.ip6;
-#endif
+	br_entry_to_ip(&ip, entry);
 
 	spin_lock_bh(&br->multicast_lock);
 	mdb = mlock_dereference(br->mdb, br);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 69af490..2cbb135 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -38,19 +38,9 @@ unsigned int br_mdb_rehash_seq;
 
 static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
 {
-	if (a->proto != b->proto)
-		return 0;
 	if (a->vid != b->vid)
 		return 0;
-	switch (a->proto) {
-	case htons(ETH_P_IP):
-		return a->u.ip4 == b->u.ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-	case htons(ETH_P_IPV6):
-		return ipv6_addr_equal(&a->u.ip6, &b->u.ip6);
-#endif
-	}
-	return 0;
+	return in_addr_gen_equal(&a->ip, &b->ip);
 }
 
 static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip,
@@ -72,12 +62,12 @@ static inline int __br_ip6_hash(struct net_bridge_mdb_htable *mdb,
 static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb,
 			     struct br_ip *ip)
 {
-	switch (ip->proto) {
+	switch (ip->ip.family) {
 	case htons(ETH_P_IP):
-		return __br_ip4_hash(mdb, ip->u.ip4, ip->vid);
+		return __br_ip4_hash(mdb, ip->ip.in_addr.s_addr, ip->vid);
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
-		return __br_ip6_hash(mdb, &ip->u.ip6, ip->vid);
+		return __br_ip6_hash(mdb, &ip->ip.in6_addr, ip->vid);
 #endif
 	}
 	return 0;
@@ -110,8 +100,8 @@ static struct net_bridge_mdb_entry *br_mdb_ip4_get(
 {
 	struct br_ip br_dst;
 
-	br_dst.u.ip4 = dst;
-	br_dst.proto = htons(ETH_P_IP);
+	br_dst.ip.in_addr.s_addr = dst;
+	br_dst.ip.family = AF_INET;
 	br_dst.vid = vid;
 
 	return br_mdb_ip_get(mdb, &br_dst);
@@ -124,8 +114,8 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get(
 {
 	struct br_ip br_dst;
 
-	br_dst.u.ip6 = *dst;
-	br_dst.proto = htons(ETH_P_IPV6);
+	br_dst.ip.in6_addr = *dst;
+	br_dst.ip.family = AF_INET6;
 	br_dst.vid = vid;
 
 	return br_mdb_ip_get(mdb, &br_dst);
@@ -144,16 +134,17 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
 	if (BR_INPUT_SKB_CB(skb)->igmp)
 		return NULL;
 
-	ip.proto = skb->protocol;
 	ip.vid = vid;
 
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
-		ip.u.ip4 = ip_hdr(skb)->daddr;
+		ip.ip.family = AF_INET;
+		ip.ip.in_addr.s_addr = ip_hdr(skb)->daddr;
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
-		ip.u.ip6 = ipv6_hdr(skb)->daddr;
+		ip.ip.family = AF_INET6;
+		ip.ip.in6_addr = ipv6_hdr(skb)->daddr;
 		break;
 #endif
 	default:
@@ -495,12 +486,12 @@ out:
 static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br,
 						struct br_ip *addr)
 {
-	switch (addr->proto) {
-	case htons(ETH_P_IP):
-		return br_ip4_multicast_alloc_query(br, addr->u.ip4);
+	switch (addr->ip.family) {
+	case AF_INET:
+		return br_ip4_multicast_alloc_query(br, addr->ip.in_addr.s_addr);
 #if IS_ENABLED(CONFIG_IPV6)
-	case htons(ETH_P_IPV6):
-		return br_ip6_multicast_alloc_query(br, &addr->u.ip6);
+	case AF_INET6:
+		return br_ip6_multicast_alloc_query(br, &addr->ip.in6_addr);
 #endif
 	}
 	return NULL;
@@ -705,8 +696,8 @@ static int br_ip4_multicast_add_group(struct net_bridge *br,
 	if (ipv4_is_local_multicast(group))
 		return 0;
 
-	br_group.u.ip4 = group;
-	br_group.proto = htons(ETH_P_IP);
+	br_group.ip.in_addr.s_addr = group;
+	br_group.ip.family = AF_INET;
 	br_group.vid = vid;
 
 	return br_multicast_add_group(br, port, &br_group);
@@ -723,8 +714,8 @@ static int br_ip6_multicast_add_group(struct net_bridge *br,
 	if (!ipv6_is_transient_multicast(group))
 		return 0;
 
-	br_group.u.ip6 = *group;
-	br_group.proto = htons(ETH_P_IPV6);
+	br_group.ip.in6_addr = *group;
+	br_group.ip.family = AF_INET6;
 	br_group.vid = vid;
 
 	return br_multicast_add_group(br, port, &br_group);
@@ -796,13 +787,13 @@ static void br_multicast_send_query(struct net_bridge *br,
 	    timer_pending(&br->multicast_querier_timer))
 		return;
 
-	memset(&br_group.u, 0, sizeof(br_group.u));
+	memset(&br_group.ip, 0, sizeof(br_group.ip));
 
-	br_group.proto = htons(ETH_P_IP);
+	br_group.ip.family = AF_INET;
 	__br_multicast_send_query(br, port, &br_group);
 
 #if IS_ENABLED(CONFIG_IPV6)
-	br_group.proto = htons(ETH_P_IPV6);
+	br_group.ip.family = AF_INET6;
 	__br_multicast_send_query(br, port, &br_group);
 #endif
 
@@ -1326,8 +1317,8 @@ static void br_ip4_multicast_leave_group(struct net_bridge *br,
 	if (ipv4_is_local_multicast(group))
 		return;
 
-	br_group.u.ip4 = group;
-	br_group.proto = htons(ETH_P_IP);
+	br_group.ip.in_addr.s_addr = group;
+	br_group.ip.family = AF_INET;
 	br_group.vid = vid;
 
 	br_multicast_leave_group(br, port, &br_group);
@@ -1344,8 +1335,8 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
 	if (!ipv6_is_transient_multicast(group))
 		return;
 
-	br_group.u.ip6 = *group;
-	br_group.proto = htons(ETH_P_IPV6);
+	br_group.ip.in6_addr = *group;
+	br_group.ip.family = AF_INET6;
 	br_group.vid = vid;
 
 	br_multicast_leave_group(br, port, &br_group);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 43347f1..72c822a 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -19,6 +19,7 @@
 #include <linux/u64_stats_sync.h>
 #include <net/route.h>
 #include <linux/if_vlan.h>
+#include <net/inet_addr.h>
 
 #define BR_HASH_BITS 8
 #define BR_HASH_SIZE (1 << BR_HASH_BITS)
@@ -56,13 +57,7 @@ struct mac_addr
 
 struct br_ip
 {
-	union {
-		__be32	ip4;
-#if IS_ENABLED(CONFIG_IPV6)
-		struct in6_addr ip6;
-#endif
-	} u;
-	__be16		proto;
+	struct in_addr_gen ip;
 	__u16		vid;
 };
 
-- 
1.7.7.6

^ permalink raw reply related

* [Patch net-next v2 3/8] inetpeer: use generic struct in_addr_gen
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Eric Dumazet, Cong Wang
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

From: Cong Wang <amwang@redhat.com>

Similar definition of struct inetpeer_addr is used by bridge multciast
code too, therefore it makes sense to introduce a generic struct
in_addr_gen, so that code can be shared.

There is no more overhead for inet_peer structs now.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 include/net/inet_addr.h |   22 ++++++++++++++
 include/net/inetpeer.h  |   25 ++++-----------
 net/ipv4/inetpeer.c     |   33 +++++++++++++-------
 net/ipv4/tcp_metrics.c  |   74 ++++++++++++++++++----------------------------
 4 files changed, 79 insertions(+), 75 deletions(-)

diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
index 7289aed..ee80df4 100644
--- a/include/net/inet_addr.h
+++ b/include/net/inet_addr.h
@@ -13,6 +13,28 @@ union inet_addr {
 	struct sockaddr sa;
 };
 
+/* a simpler definition of generic inet addr, without additional
+ * information for IPv6 address.
+ */
+struct in_addr_gen {
+	union {
+		struct in_addr	in_addr;
+		struct in6_addr	in6_addr;
+	};
+	unsigned short int	family;
+};
+
+static inline
+bool in_addr_gen_equal(const struct in_addr_gen *a, const struct in_addr_gen *b)
+{
+	if (a->family != b->family)
+		return false;
+	if (a->family == AF_INET6)
+		return ipv6_addr_equal(&a->in6_addr, &b->in6_addr);
+	else
+		return a->in_addr.s_addr == b->in_addr.s_addr;
+}
+
 #if IS_ENABLED(CONFIG_IPV6)
 static inline
 bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 53f464d..9574843 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -13,24 +13,13 @@
 #include <linux/spinlock.h>
 #include <linux/rtnetlink.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 #include <linux/atomic.h>
 
-struct inetpeer_addr_base {
-	union {
-		__be32			a4;
-		__be32			a6[4];
-	};
-};
-
-struct inetpeer_addr {
-	struct inetpeer_addr_base	addr;
-	__u16				family;
-};
-
 struct inet_peer {
 	/* group together avl_left,avl_right,v4daddr to speedup lookups */
 	struct inet_peer __rcu	*avl_left, *avl_right;
-	struct inetpeer_addr	daddr;
+	struct in_addr_gen	daddr;
 	__u32			avl_height;
 
 	u32			metrics[RTAX_MAX];
@@ -133,16 +122,16 @@ static inline bool inet_metrics_new(const struct inet_peer *p)
 
 /* can be called with or without local BH being disabled */
 struct inet_peer *inet_getpeer(struct inet_peer_base *base,
-			       const struct inetpeer_addr *daddr,
+			       const struct in_addr_gen *daddr,
 			       int create);
 
 static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
 						__be32 v4daddr,
 						int create)
 {
-	struct inetpeer_addr daddr;
+	struct in_addr_gen daddr;
 
-	daddr.addr.a4 = v4daddr;
+	daddr.in_addr.s_addr = v4daddr;
 	daddr.family = AF_INET;
 	return inet_getpeer(base, &daddr, create);
 }
@@ -151,9 +140,9 @@ static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
 						const struct in6_addr *v6daddr,
 						int create)
 {
-	struct inetpeer_addr daddr;
+	struct in_addr_gen daddr;
 
-	*(struct in6_addr *)daddr.addr.a6 = *v6daddr;
+	daddr.in6_addr = *v6daddr;
 	daddr.family = AF_INET6;
 	return inet_getpeer(base, &daddr, create);
 }
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 000e3d2..70ffc9e 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -197,17 +197,26 @@ void __init inet_initpeers(void)
 	INIT_DEFERRABLE_WORK(&gc_work, inetpeer_gc_worker);
 }
 
-static int addr_compare(const struct inetpeer_addr *a,
-			const struct inetpeer_addr *b)
+static int addr_compare(const struct in_addr_gen *a,
+			const struct in_addr_gen *b)
 {
-	int i, n = (a->family == AF_INET ? 1 : 4);
+	int i;
 
-	for (i = 0; i < n; i++) {
-		if (a->addr.a6[i] == b->addr.a6[i])
-			continue;
-		if ((__force u32)a->addr.a6[i] < (__force u32)b->addr.a6[i])
+	if (a->family == AF_INET) {
+		if (a->in_addr.s_addr == b->in_addr.s_addr)
+			return 0;
+		if ((__force u32)a->in_addr.s_addr <
+		    (__force u32)b->in_addr.s_addr)
 			return -1;
-		return 1;
+	} else {
+		for (i = 0; i < 4; i++) {
+			if (a->in6_addr.s6_addr32[i] == b->in6_addr.s6_addr32[i])
+				continue;
+			if ((__force u32)a->in6_addr.s6_addr32[i] <
+			    (__force u32)b->in6_addr.s6_addr32[i])
+				return -1;
+			return 1;
+		}
 	}
 
 	return 0;
@@ -248,7 +257,7 @@ static int addr_compare(const struct inetpeer_addr *a,
  * But every pointer we follow is guaranteed to be valid thanks to RCU.
  * We exit from this function if number of links exceeds PEER_MAXDEPTH
  */
-static struct inet_peer *lookup_rcu(const struct inetpeer_addr *daddr,
+static struct inet_peer *lookup_rcu(const struct in_addr_gen *daddr,
 				    struct inet_peer_base *base)
 {
 	struct inet_peer *u = rcu_dereference(base->root);
@@ -457,7 +466,7 @@ static int inet_peer_gc(struct inet_peer_base *base,
 }
 
 struct inet_peer *inet_getpeer(struct inet_peer_base *base,
-			       const struct inetpeer_addr *daddr,
+			       const struct in_addr_gen *daddr,
 			       int create)
 {
 	struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr;
@@ -506,8 +515,8 @@ relookup:
 		atomic_set(&p->rid, 0);
 		atomic_set(&p->ip_id_count,
 				(daddr->family == AF_INET) ?
-					secure_ip_id(daddr->addr.a4) :
-					secure_ipv6_id(daddr->addr.a6));
+					secure_ip_id(daddr->in_addr.s_addr) :
+					secure_ipv6_id(daddr->in6_addr.s6_addr32));
 		p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
 		p->rate_tokens = 0;
 		/* 60*HZ is arbitrary, but chosen enough high so that the first
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index f6a005c..3bb3789 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -31,7 +31,7 @@ struct tcp_fastopen_metrics {
 
 struct tcp_metrics_block {
 	struct tcp_metrics_block __rcu	*tcpm_next;
-	struct inetpeer_addr		tcpm_addr;
+	struct in_addr_gen		tcpm_addr;
 	unsigned long			tcpm_stamp;
 	u32				tcpm_ts;
 	u32				tcpm_ts_stamp;
@@ -74,22 +74,6 @@ static void tcp_metric_set_msecs(struct tcp_metrics_block *tm,
 	tm->tcpm_vals[idx] = jiffies_to_msecs(val);
 }
 
-static bool addr_same(const struct inetpeer_addr *a,
-		      const struct inetpeer_addr *b)
-{
-	const struct in6_addr *a6, *b6;
-
-	if (a->family != b->family)
-		return false;
-	if (a->family == AF_INET)
-		return a->addr.a4 == b->addr.a4;
-
-	a6 = (const struct in6_addr *) &a->addr.a6[0];
-	b6 = (const struct in6_addr *) &b->addr.a6[0];
-
-	return ipv6_addr_equal(a6, b6);
-}
-
 struct tcpm_hash_bucket {
 	struct tcp_metrics_block __rcu	*chain;
 };
@@ -131,7 +115,7 @@ static void tcpm_suck_dst(struct tcp_metrics_block *tm, struct dst_entry *dst,
 }
 
 static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst,
-					  struct inetpeer_addr *addr,
+					  struct in_addr_gen *addr,
 					  unsigned int hash,
 					  bool reclaim)
 {
@@ -189,7 +173,7 @@ static struct tcp_metrics_block *tcp_get_encode(struct tcp_metrics_block *tm, in
 	return NULL;
 }
 
-static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *addr,
+static struct tcp_metrics_block *__tcp_get_metrics(const struct in_addr_gen *addr,
 						   struct net *net, unsigned int hash)
 {
 	struct tcp_metrics_block *tm;
@@ -197,7 +181,7 @@ static struct tcp_metrics_block *__tcp_get_metrics(const struct inetpeer_addr *a
 
 	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
 	     tm = rcu_dereference(tm->tcpm_next)) {
-		if (addr_same(&tm->tcpm_addr, addr))
+		if (in_addr_gen_equal(&tm->tcpm_addr, addr))
 			break;
 		depth++;
 	}
@@ -208,18 +192,18 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
 						       struct dst_entry *dst)
 {
 	struct tcp_metrics_block *tm;
-	struct inetpeer_addr addr;
+	struct in_addr_gen addr;
 	unsigned int hash;
 	struct net *net;
 
 	addr.family = req->rsk_ops->family;
 	switch (addr.family) {
 	case AF_INET:
-		addr.addr.a4 = inet_rsk(req)->rmt_addr;
-		hash = (__force unsigned int) addr.addr.a4;
+		addr.in_addr.s_addr = inet_rsk(req)->rmt_addr;
+		hash = (__force unsigned int) addr.in_addr.s_addr;
 		break;
 	case AF_INET6:
-		*(struct in6_addr *)addr.addr.a6 = inet6_rsk(req)->rmt_addr;
+		addr.in6_addr = inet6_rsk(req)->rmt_addr;
 		hash = ipv6_addr_hash(&inet6_rsk(req)->rmt_addr);
 		break;
 	default:
@@ -231,7 +215,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_req(struct request_sock *req,
 
 	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
 	     tm = rcu_dereference(tm->tcpm_next)) {
-		if (addr_same(&tm->tcpm_addr, &addr))
+		if (in_addr_gen_equal(&tm->tcpm_addr, &addr))
 			break;
 	}
 	tcpm_check_stamp(tm, dst);
@@ -242,19 +226,19 @@ static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock
 {
 	struct inet6_timewait_sock *tw6;
 	struct tcp_metrics_block *tm;
-	struct inetpeer_addr addr;
+	struct in_addr_gen addr;
 	unsigned int hash;
 	struct net *net;
 
 	addr.family = tw->tw_family;
 	switch (addr.family) {
 	case AF_INET:
-		addr.addr.a4 = tw->tw_daddr;
-		hash = (__force unsigned int) addr.addr.a4;
+		addr.in_addr.s_addr = tw->tw_daddr;
+		hash = (__force unsigned int) addr.in_addr.s_addr;
 		break;
 	case AF_INET6:
 		tw6 = inet6_twsk((struct sock *)tw);
-		*(struct in6_addr *)addr.addr.a6 = tw6->tw_v6_daddr;
+		addr.in6_addr = tw6->tw_v6_daddr;
 		hash = ipv6_addr_hash(&tw6->tw_v6_daddr);
 		break;
 	default:
@@ -266,7 +250,7 @@ static struct tcp_metrics_block *__tcp_get_metrics_tw(struct inet_timewait_sock
 
 	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
 	     tm = rcu_dereference(tm->tcpm_next)) {
-		if (addr_same(&tm->tcpm_addr, &addr))
+		if (in_addr_gen_equal(&tm->tcpm_addr, &addr))
 			break;
 	}
 	return tm;
@@ -277,7 +261,7 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk,
 						 bool create)
 {
 	struct tcp_metrics_block *tm;
-	struct inetpeer_addr addr;
+	struct in_addr_gen addr;
 	unsigned int hash;
 	struct net *net;
 	bool reclaim;
@@ -285,11 +269,11 @@ static struct tcp_metrics_block *tcp_get_metrics(struct sock *sk,
 	addr.family = sk->sk_family;
 	switch (addr.family) {
 	case AF_INET:
-		addr.addr.a4 = inet_sk(sk)->inet_daddr;
-		hash = (__force unsigned int) addr.addr.a4;
+		addr.in_addr.s_addr = inet_sk(sk)->inet_daddr;
+		hash = (__force unsigned int) addr.in_addr.s_addr;
 		break;
 	case AF_INET6:
-		*(struct in6_addr *)addr.addr.a6 = inet6_sk(sk)->daddr;
+		addr.in6_addr = inet6_sk(sk)->daddr;
 		hash = ipv6_addr_hash(&inet6_sk(sk)->daddr);
 		break;
 	default:
@@ -725,12 +709,12 @@ static int tcp_metrics_fill_info(struct sk_buff *msg,
 	switch (tm->tcpm_addr.family) {
 	case AF_INET:
 		if (nla_put_be32(msg, TCP_METRICS_ATTR_ADDR_IPV4,
-				tm->tcpm_addr.addr.a4) < 0)
+				tm->tcpm_addr.in_addr.s_addr) < 0)
 			goto nla_put_failure;
 		break;
 	case AF_INET6:
 		if (nla_put(msg, TCP_METRICS_ATTR_ADDR_IPV6, 16,
-			    tm->tcpm_addr.addr.a6) < 0)
+			    tm->tcpm_addr.in6_addr.s6_addr32) < 0)
 			goto nla_put_failure;
 		break;
 	default:
@@ -853,7 +837,7 @@ done:
 	return skb->len;
 }
 
-static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
+static int parse_nl_addr(struct genl_info *info, struct in_addr_gen *addr,
 			 unsigned int *hash, int optional)
 {
 	struct nlattr *a;
@@ -861,8 +845,8 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
 	a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV4];
 	if (a) {
 		addr->family = AF_INET;
-		addr->addr.a4 = nla_get_be32(a);
-		*hash = (__force unsigned int) addr->addr.a4;
+		addr->in_addr.s_addr = nla_get_be32(a);
+		*hash = (__force unsigned int) addr->in_addr.s_addr;
 		return 0;
 	}
 	a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6];
@@ -870,8 +854,8 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
 		if (nla_len(a) != sizeof(struct in6_addr))
 			return -EINVAL;
 		addr->family = AF_INET6;
-		memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6));
-		*hash = ipv6_addr_hash((struct in6_addr *) addr->addr.a6);
+		memcpy(&addr->in6_addr, nla_data(a), sizeof(addr->in6_addr));
+		*hash = ipv6_addr_hash(&addr->in6_addr);
 		return 0;
 	}
 	return optional ? 1 : -EAFNOSUPPORT;
@@ -880,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
 static int tcp_metrics_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
 {
 	struct tcp_metrics_block *tm;
-	struct inetpeer_addr addr;
+	struct in_addr_gen addr;
 	unsigned int hash;
 	struct sk_buff *msg;
 	struct net *net = genl_info_net(info);
@@ -905,7 +889,7 @@ static int tcp_metrics_nl_cmd_get(struct sk_buff *skb, struct genl_info *info)
 	rcu_read_lock();
 	for (tm = rcu_dereference(net->ipv4.tcp_metrics_hash[hash].chain); tm;
 	     tm = rcu_dereference(tm->tcpm_next)) {
-		if (addr_same(&tm->tcpm_addr, &addr)) {
+		if (in_addr_gen_equal(&tm->tcpm_addr, &addr)) {
 			ret = tcp_metrics_fill_info(msg, tm);
 			break;
 		}
@@ -960,7 +944,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	struct tcpm_hash_bucket *hb;
 	struct tcp_metrics_block *tm;
 	struct tcp_metrics_block __rcu **pp;
-	struct inetpeer_addr addr;
+	struct in_addr_gen addr;
 	unsigned int hash;
 	struct net *net = genl_info_net(info);
 	int ret;
@@ -977,7 +961,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	spin_lock_bh(&tcp_metrics_lock);
 	for (tm = deref_locked_genl(*pp); tm;
 	     pp = &tm->tcpm_next, tm = deref_locked_genl(*pp)) {
-		if (addr_same(&tm->tcpm_addr, &addr)) {
+		if (in_addr_gen_equal(&tm->tcpm_addr, &addr)) {
 			*pp = tm->tcpm_next;
 			break;
 		}
-- 
1.7.7.6

^ permalink raw reply related

* [Patch net-next v2 2/8] net: introduce generic simple_inet_pton()
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Ben Hutchings, Stephen Hemminger, Cong Wang
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

From: Cong Wang <amwang@redhat.com>

simple_inet_pton() is a simple implementation of inet_pton()
in kernel, the original code is already in netpoll, so just move
it to global.

Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
 include/net/inet_addr.h |    3 +++
 net/core/netpoll.c      |   36 ++++++++----------------------------
 net/core/utils.c        |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
index 66a16fe..7289aed 100644
--- a/include/net/inet_addr.h
+++ b/include/net/inet_addr.h
@@ -4,6 +4,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/socket.h>
+#include <linux/inet.h>
 #include <net/addrconf.h>
 
 union inet_addr {
@@ -59,4 +60,6 @@ static inline bool inet_addr_multicast(const union inet_addr *ipa)
 }
 #endif
 
+int simple_inet_pton(const char *str, union inet_addr *addr);
+
 #endif
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index e7d4388..67174c4 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -908,30 +908,10 @@ void netpoll_print_options(struct netpoll *np)
 }
 EXPORT_SYMBOL(netpoll_print_options);
 
-static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr)
-{
-	const char *end;
-
-	if (!strchr(str, ':') &&
-	    in4_pton(str, -1, (void *)addr, -1, &end) > 0) {
-		if (!*end)
-			return 0;
-	}
-	if (in6_pton(str, -1, addr->sin6.sin6_addr.s6_addr, -1, &end) > 0) {
-#if IS_ENABLED(CONFIG_IPV6)
-		if (!*end)
-			return 1;
-#else
-		return -1;
-#endif
-	}
-	return -1;
-}
-
 int netpoll_parse_options(struct netpoll *np, char *opt)
 {
 	char *cur=opt, *delim;
-	int ipv6;
+	int ret;
 
 	if (*cur != '@') {
 		if ((delim = strchr(cur, '@')) == NULL)
@@ -947,11 +927,11 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 		if ((delim = strchr(cur, '/')) == NULL)
 			goto parse_failed;
 		*delim = 0;
-		ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip);
-		if (ipv6 < 0)
+		ret = simple_inet_pton(cur, &np->local_ip);
+		if (ret < 0)
 			goto parse_failed;
 		else
-			np->ipv6 = (bool)ipv6;
+			np->ipv6 = np->local_ip.sa.sa_family == AF_INET6;
 		cur = delim;
 	}
 	cur++;
@@ -983,13 +963,13 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 	if ((delim = strchr(cur, '/')) == NULL)
 		goto parse_failed;
 	*delim = 0;
-	ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip);
-	if (ipv6 < 0)
+	ret = simple_inet_pton(cur, &np->remote_ip);
+	if (ret < 0)
 		goto parse_failed;
-	else if (np->ipv6 != (bool)ipv6)
+	else if (np->ipv6 != (np->local_ip.sa.sa_family == AF_INET6))
 		goto parse_failed;
 	else
-		np->ipv6 = (bool)ipv6;
+		np->ipv6 = np->local_ip.sa.sa_family == AF_INET6;
 	cur = delim + 1;
 
 	if (*cur != 0) {
diff --git a/net/core/utils.c b/net/core/utils.c
index aa88e23..22dd621 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -29,6 +29,7 @@
 
 #include <net/sock.h>
 #include <net/net_ratelimit.h>
+#include <net/inet_addr.h>
 
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
@@ -338,3 +339,38 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
 				  csum_unfold(*sum)));
 }
 EXPORT_SYMBOL(inet_proto_csum_replace16);
+
+/**
+ * simple_inet_pton - a simple implementation of inet_pton()
+ * @str: the start of the IPv4 or IPv6 address string
+ * @addr: a pointer to union inet_addr
+ *
+ * Return zero on success, callers should check addr->sa.sa_family
+ * to know if the address is IPv4 or IPv6; return negative when
+ * any error occurs.
+ *
+ */
+int simple_inet_pton(const char *str, union inet_addr *addr)
+{
+	const char *end;
+
+	if (!strchr(str, ':') &&
+	    in4_pton(str, -1, (void *)addr, -1, &end) > 0) {
+		if (!*end) {
+			addr->sa.sa_family = AF_INET;
+			return 0;
+		}
+	}
+	if (in6_pton(str, -1, addr->sin6.sin6_addr.s6_addr, -1, &end) > 0) {
+#if IS_ENABLED(CONFIG_IPV6)
+		if (!*end) {
+			addr->sa.sa_family = AF_INET6;
+			return 0;
+		}
+#else
+		return -EAFNOSUPPORT;
+#endif
+	}
+	return -EINVAL;
+}
+EXPORT_SYMBOL(simple_inet_pton);
-- 
1.7.7.6

^ permalink raw reply related

* [Patch net-next v2 0/8] net: introduce generic type and helpers for IP address
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller, Cong Wang

From: Cong Wang <amwang@redhat.com>

As IPv6 becomes popular, more and more subsystems begin to support IPv6,
therefore we need a generic IP address type, in case of duplicates.
Also we will also need some helpers to compare, print, check the generic
IP address.

This patchset introduce a new type union inet_addr as a union of IPv4
and IPv6 address, and struct in_addr_gen for inetpeer and bridge mdb,
plus some helper functions that will be used by existing code and
in the future VXLAN module.

However, due to ABI limit, we still can't convert union nf_inet_addr
to union inet_addr.

Signed-off-by: Cong Wang <amwang@redhat.com>

v1 -> v2:
* introduce another generic IP address type, struct in_addr_gen
* convert bridge multicast code too
* complete the smack part

RFC -> v1:
* rebase these patches on top of Daniel's
* rename inet_pton() to simple_inet_pton()
* fix the simple_inet_pton() API
* make inet_addr_equal() non-inline
* add two more patches

Cong Wang (8):
  net: introduce generic union inet_addr
  net: introduce generic simple_inet_pton()
  inetpeer: use generic struct in_addr_gen
  bridge: use generic struct in_addr_gen
  sunrpc: use generic union inet_addr
  fs: use generic union inet_addr and help functions
  sctp: use generic union inet_addr
  selinux: use generic union inet_addr

 Documentation/printk-formats.txt   |   20 ++--
 drivers/net/netconsole.c           |   22 ++--
 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/linux/lsm_audit.h          |   19 +---
 include/linux/netpoll.h            |    9 +--
 include/linux/sunrpc/addr.h        |  118 +-----------------
 include/net/inet_addr.h            |  128 +++++++++++++++++++
 include/net/inetpeer.h             |   25 +---
 include/net/sctp/sctp.h            |   22 ++--
 include/net/sctp/sm.h              |    4 +-
 include/net/sctp/structs.h         |  132 +++++++++-----------
 lib/vsprintf.c                     |   29 ++---
 net/bridge/br_mdb.c                |   53 ++++----
 net/bridge/br_multicast.c          |   65 ++++------
 net/bridge/br_private.h            |    9 +-
 net/core/netpoll.c                 |   86 +++++--------
 net/core/utils.c                   |   84 +++++++++++++
 net/ipv4/inetpeer.c                |   33 +++--
 net/ipv4/tcp_metrics.c             |   74 +++++-------
 net/sctp/associola.c               |   32 +++---
 net/sctp/bind_addr.c               |   61 +++------
 net/sctp/endpointola.c             |   12 +-
 net/sctp/input.c                   |   56 ++++----
 net/sctp/ipv6.c                    |  240 ++++++++++++++++--------------------
 net/sctp/outqueue.c                |    4 +-
 net/sctp/proc.c                    |   10 +-
 net/sctp/protocol.c                |  204 ++++++++++++-------------------
 net/sctp/sm_make_chunk.c           |   54 ++++----
 net/sctp/sm_sideeffect.c           |    2 +-
 net/sctp/sm_statefuns.c            |   23 +---
 net/sctp/socket.c                  |  130 +++++++++++---------
 net/sctp/transport.c               |   12 +-
 net/sctp/ulpevent.c                |    2 +-
 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 ++--
 43 files changed, 1008 insertions(+), 1311 deletions(-)
 create mode 100644 include/net/inet_addr.h

-- 
1.7.7.6

^ permalink raw reply

* [Patch net-next v2 8/8] selinux: use generic union inet_addr
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
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

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

* [Patch net-next v2 6/8] fs: use generic union inet_addr and helper functions
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
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

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

* [Patch net-next v2 5/8] sunrpc: use generic union inet_addr
From: Cong Wang @ 2013-08-02  7:14 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: David S. Miller, Trond Myklebust, J. Bruce Fields,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA, Cong Wang
In-Reply-To: <1375427674-21735-1-git-send-email-amwang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

From: Cong Wang <amwang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

sunrpc defines some helper functions for sockaddr, actually they
can re-use the generic functions for union inet_addr too.

Cc: Trond Myklebust <Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
Cc: "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Cong Wang <amwang-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/sunrpc/addr.h |  118 +++----------------------------------------
 include/net/inet_addr.h     |   74 +++++++++++++++++++++------
 net/core/utils.c            |   25 +++++++++
 3 files changed, 89 insertions(+), 128 deletions(-)

diff --git a/include/linux/sunrpc/addr.h b/include/linux/sunrpc/addr.h
index 07d8e53..10d07f6 100644
--- a/include/linux/sunrpc/addr.h
+++ b/include/linux/sunrpc/addr.h
@@ -11,6 +11,7 @@
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <net/ipv6.h>
+#include <net/inet_addr.h>
 
 size_t		rpc_ntop(const struct sockaddr *, char *, const size_t);
 size_t		rpc_pton(struct net *, const char *, const size_t,
@@ -21,135 +22,30 @@ size_t		rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
 
 static inline unsigned short rpc_get_port(const struct sockaddr *sap)
 {
-	switch (sap->sa_family) {
-	case AF_INET:
-		return ntohs(((struct sockaddr_in *)sap)->sin_port);
-	case AF_INET6:
-		return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
-	}
-	return 0;
+	return inet_addr_get_port((const union inet_addr *)sap);
 }
 
 static inline void rpc_set_port(struct sockaddr *sap,
 				const unsigned short port)
 {
-	switch (sap->sa_family) {
-	case AF_INET:
-		((struct sockaddr_in *)sap)->sin_port = htons(port);
-		break;
-	case AF_INET6:
-		((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
-		break;
-	}
+	inet_addr_set_port((union inet_addr *)sap, port);
 }
 
 #define IPV6_SCOPE_DELIMITER		'%'
 #define IPV6_SCOPE_ID_LEN		sizeof("%nnnnnnnnnn")
 
-static inline bool __rpc_cmp_addr4(const struct sockaddr *sap1,
-				   const struct sockaddr *sap2)
-{
-	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
-	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;
-
-	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
-}
-
-static inline bool __rpc_copy_addr4(struct sockaddr *dst,
-				    const struct sockaddr *src)
-{
-	const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
-	struct sockaddr_in *dsin = (struct sockaddr_in *) dst;
-
-	dsin->sin_family = ssin->sin_family;
-	dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
-	return true;
-}
-
-#if IS_ENABLED(CONFIG_IPV6)
-static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
-				   const struct sockaddr *sap2)
-{
-	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
-	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
-
-	if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
-		return false;
-	else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-		return sin1->sin6_scope_id == sin2->sin6_scope_id;
-
-	return true;
-}
-
-static inline bool __rpc_copy_addr6(struct sockaddr *dst,
-				    const struct sockaddr *src)
-{
-	const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
-	struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;
-
-	dsin6->sin6_family = ssin6->sin6_family;
-	dsin6->sin6_addr = ssin6->sin6_addr;
-	dsin6->sin6_scope_id = ssin6->sin6_scope_id;
-	return true;
-}
-#else	/* !(IS_ENABLED(CONFIG_IPV6) */
-static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
-				   const struct sockaddr *sap2)
-{
-	return false;
-}
-
-static inline bool __rpc_copy_addr6(struct sockaddr *dst,
-				    const struct sockaddr *src)
-{
-	return false;
-}
-#endif	/* !(IS_ENABLED(CONFIG_IPV6) */
-
-/**
- * rpc_cmp_addr - compare the address portion of two sockaddrs.
- * @sap1: first sockaddr
- * @sap2: second sockaddr
- *
- * Just compares the family and address portion. Ignores port, but
- * compares the scope if it's a link-local address.
- *
- * Returns true if the addrs are equal, false if they aren't.
- */
 static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
 				const struct sockaddr *sap2)
 {
-	if (sap1->sa_family == sap2->sa_family) {
-		switch (sap1->sa_family) {
-		case AF_INET:
-			return __rpc_cmp_addr4(sap1, sap2);
-		case AF_INET6:
-			return __rpc_cmp_addr6(sap1, sap2);
-		}
-	}
-	return false;
+	return inet_addr_equal((const union inet_addr *)sap1,
+			       (const union inet_addr *)sap2);
 }
 
-/**
- * rpc_copy_addr - copy the address portion of one sockaddr to another
- * @dst: destination sockaddr
- * @src: source sockaddr
- *
- * Just copies the address portion and family. Ignores port, scope, etc.
- * Caller is responsible for making certain that dst is large enough to hold
- * the address in src. Returns true if address family is supported. Returns
- * false otherwise.
- */
 static inline bool rpc_copy_addr(struct sockaddr *dst,
 				 const struct sockaddr *src)
 {
-	switch (src->sa_family) {
-	case AF_INET:
-		return __rpc_copy_addr4(dst, src);
-	case AF_INET6:
-		return __rpc_copy_addr6(dst, src);
-	}
-	return false;
+	return inet_addr_copy((union inet_addr *)dst,
+			      (const union inet_addr *)src);
 }
 
 /**
diff --git a/include/net/inet_addr.h b/include/net/inet_addr.h
index ee80df4..e846050 100644
--- a/include/net/inet_addr.h
+++ b/include/net/inet_addr.h
@@ -36,17 +36,6 @@ bool in_addr_gen_equal(const struct in_addr_gen *a, const struct in_addr_gen *b)
 }
 
 #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)
@@ -65,12 +54,6 @@ static inline bool inet_addr_multicast(const union inet_addr *ipa)
 
 #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);
@@ -82,6 +65,63 @@ static inline bool inet_addr_multicast(const union inet_addr *ipa)
 }
 #endif
 
+/**
+ * inet_addr_copy - copy the address portion of one inet_addr to another
+ * @dst: destination sockaddr
+ * @src: source sockaddr
+ *
+ * Just copies the address portion and family. Ignores port, scope, etc.
+ * Caller is responsible for making certain that dst is large enough to hold
+ * the address in src. Returns true if address family is supported. Returns
+ * false otherwise.
+ */
+static inline bool inet_addr_copy(union inet_addr *dst,
+				  const union inet_addr *src)
+{
+	dst->sa.sa_family = src->sa.sa_family;
+
+	switch (src->sa.sa_family) {
+	case AF_INET:
+		dst->sin.sin_addr.s_addr = src->sin.sin_addr.s_addr;
+		return true;
+#if IS_ENABLED(CONFIG_IPV6)
+	case AF_INET6:
+		dst->sin6.sin6_addr = src->sin6.sin6_addr;
+		dst->sin6.sin6_scope_id = src->sin6.sin6_scope_id;
+		return true;
+#endif
+	}
+
+	return false;
+}
+
+static inline
+unsigned short inet_addr_get_port(const union inet_addr *sap)
+{
+	switch (sap->sa.sa_family) {
+	case AF_INET:
+		return ntohs(sap->sin.sin_port);
+	case AF_INET6:
+		return ntohs(sap->sin6.sin6_port);
+	}
+	return 0;
+}
+
+static inline
+void inet_addr_set_port(union inet_addr *sap,
+			const unsigned short port)
+{
+	switch (sap->sa.sa_family) {
+	case AF_INET:
+		sap->sin.sin_port = htons(port);
+		break;
+	case AF_INET6:
+		sap->sin6.sin6_port = htons(port);
+		break;
+	}
+}
+
+bool inet_addr_equal(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 22dd621..837bb18 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -374,3 +374,28 @@ int simple_inet_pton(const char *str, union inet_addr *addr)
 	return -EINVAL;
 }
 EXPORT_SYMBOL(simple_inet_pton);
+
+#if IS_ENABLED(CONFIG_IPV6)
+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;
+	else if (a->sa.sa_family == AF_INET6) {
+		if (!ipv6_addr_equal(&a->sin6.sin6_addr, &b->sin6.sin6_addr))
+			return false;
+		else if (__ipv6_addr_needs_scope_id(__ipv6_addr_type(&a->sin6.sin6_addr)))
+			return a->sin6.sin6_scope_id == b->sin6.sin6_scope_id;
+		else
+			return true;
+	} else
+		return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
+}
+#else
+bool inet_addr_equal(const union inet_addr *a, const union inet_addr *b)
+{
+	if (a->sa.sa_family == AF_UNSPEC)
+		return a->sa.sa_family == b->sa.sa_family;
+	return a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr;
+}
+#endif
+EXPORT_SYMBOL(inet_addr_equal);
-- 
1.7.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [Patch net-next v2 1/8] net: introduce generic union inet_addr
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
In-Reply-To: <1375427674-21735-1-git-send-email-amwang@redhat.com>

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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox