Skip to contentSkip to conversation

netpoll: add IPv6 support

PATCH In review Cong Wang 2 participants 6 messages Jan 8, 2013 – Jan 9, 2013

Subsystems (6)
lore
Share & tools
lore

Cong Wang

author
#0 lore raw

v5 cover netpoll: add IPv6 support

v5: move some ipv6 checksum functions into net/ipv6/ip6_checksum.c

v4: remove ndisc_parse_options(), ignore ICMP options there
make udp6_csum_init() inline so that we don't rely on IPV6=y fix a conflict with Jiri's patchset

v3: fix CONFIG_IPV6=m case

v2: use bool for ipv6 flag
fix !CONFIG_IPV6 case

This patchset implements netpoll over IPv6.

Cong Wang (4):
netpoll: prepare for ipv6
ipv6: move csum_ipv6_magic() and udp6_csum_init() into static library
netpoll: add IPv6 support
netconsole: add IPv6 example in doc

 Documentation/networking/netconsole.txt |    7 +-
 drivers/net/netconsole.c                |   44 ++-
 include/linux/netpoll.h                 |   13 +-
 include/net/ip6_checksum.h              |   62 +---
 net/core/netpoll.c                      |  622 ++++++++++++++++++++++---------
 net/ipv6/Makefile                       |    2 +-
 net/ipv6/ip6_checksum.c                 |   97 +++++
 net/ipv6/udp.c                          |   34 --
 8 files changed, 607 insertions(+), 274 deletions(-)
Signature · 1 line
1.7.7.6
author
#1 lore raw

PATCH v5 1/4 netpoll: prepare for ipv6

From: Cong Wang <[email protected]>

This patch adjusts some struct and functions, to prepare for supporting IPv6.

Cc David S. Miller <[email protected]>
---
 drivers/net/netconsole.c |   12 +-
 include/linux/netpoll.h  |   13 ++-
 net/core/netpoll.c       |  402 ++++++++++++++++++++++++++--------------------
 3 files changed, 243 insertions(+), 184 deletions(-)
drivers/net/netconsole.c +8 -4
index 6989ebe..998fa02 100644
@@ -269,12 +269,14 @@ static ssize_t show_remote_port(struct netconsole_target *nt, char *buf)
 
 static ssize_t show_local_ip(struct netconsole_target *nt, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
+	if (!nt->np.ipv6)
+		return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
 }
 
 static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
+	if (!nt->np.ipv6)
+		return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
 }
 
 static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
@@ -410,7 +412,8 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
 		return -EINVAL;
 	}
 
-	nt->np.local_ip = in_aton(buf);
+	if (!strnchr(buf, count, ':'))
+		nt->np.local_ip.ip = in_aton(buf);
 
 	return strnlen(buf, count);
 }
@@ -426,7 +429,8 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
 		return -EINVAL;
 	}
 
-	nt->np.remote_ip = in_aton(buf);
+	if (!strnchr(buf, count, ':'))
+		nt->np.remote_ip.ip = in_aton(buf);
 
 	return strnlen(buf, count);
 }
include/linux/netpoll.h +11 -2
index 66d5379..f54c3bb 100644
@@ -12,13 +12,22 @@
 #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;
+};
+
 struct netpoll {
 	struct net_device *dev;
 	char dev_name[IFNAMSIZ];
 	const char *name;
 	void (*rx_hook)(struct netpoll *, int, char *, int);
 
-	__be32 local_ip, remote_ip;
+	union inet_addr local_ip, remote_ip;
+	bool ipv6;
 	u16 local_port, remote_port;
 	u8 remote_mac[ETH_ALEN];
 
@@ -33,7 +42,7 @@ struct netpoll_info {
 	spinlock_t rx_lock;
 	struct list_head rx_np; /* netpolls that registered an rx_hook */
 
-	struct sk_buff_head arp_tx; /* list of arp requests to reply to */
+	struct sk_buff_head neigh_tx; /* list of neigh requests to reply to */
 	struct sk_buff_head txq;
 
 	struct delayed_work tx_work;
net/core/netpoll.c +224 -178

540 lines not on this page · raw message

Signature · 1 line
1.7.7.6
author
#2 lore raw

PATCH v5 2/4 ipv6: move csum_ipv6_magic() and udp6_csum_init() into static library

In reply to Cong Wang

From: Cong Wang <[email protected]>

As suggested by David, udp6_csum_init() is too big to be inlined, move it to ipv6 static library, net/ipv6/ip6_checksum.c.

And the generic csum_ipv6_magic() too.

Cc David S. Miller <[email protected]>
---
 include/net/ip6_checksum.h |   62 ++--------------------------
 net/ipv6/Makefile          |    2 +-
 net/ipv6/ip6_checksum.c    |   97 ++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/udp.c             |   34 ---------------
 4 files changed, 103 insertions(+), 92 deletions(-)
 create mode 100644 net/ipv6/ip6_checksum.c
include/net/ip6_checksum.h +5 -57
index 652d3d3..7686e3f 100644
@@ -35,63 +35,10 @@
 #include <linux/ipv6.h>
 
 #ifndef _HAVE_ARCH_IPV6_CSUM
-
-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
-					  const struct in6_addr *daddr,
-					  __u32 len, unsigned short proto,
-					  __wsum csum)
-{
-
-	int carry;
-	__u32 ulen;
-	__u32 uproto;
-	__u32 sum = (__force u32)csum;
-
-	sum += (__force u32)saddr->s6_addr32[0];
-	carry = (sum < (__force u32)saddr->s6_addr32[0]);
-	sum += carry;
-
-	sum += (__force u32)saddr->s6_addr32[1];
-	carry = (sum < (__force u32)saddr->s6_addr32[1]);
-	sum += carry;
-
-	sum += (__force u32)saddr->s6_addr32[2];
-	carry = (sum < (__force u32)saddr->s6_addr32[2]);
-	sum += carry;
-
-	sum += (__force u32)saddr->s6_addr32[3];
-	carry = (sum < (__force u32)saddr->s6_addr32[3]);
-	sum += carry;
-
-	sum += (__force u32)daddr->s6_addr32[0];
-	carry = (sum < (__force u32)daddr->s6_addr32[0]);
-	sum += carry;
-
-	sum += (__force u32)daddr->s6_addr32[1];
-	carry = (sum < (__force u32)daddr->s6_addr32[1]);
-	sum += carry;
-
-	sum += (__force u32)daddr->s6_addr32[2];
-	carry = (sum < (__force u32)daddr->s6_addr32[2]);
-	sum += carry;
-
-	sum += (__force u32)daddr->s6_addr32[3];
-	carry = (sum < (__force u32)daddr->s6_addr32[3]);
-	sum += carry;
-
-	ulen = (__force u32)htonl((__u32) len);
-	sum += ulen;
-	carry = (sum < ulen);
-	sum += carry;
-
-	uproto = (__force u32)htonl(proto);
-	sum += uproto;
-	carry = (sum < uproto);
-	sum += carry;
-
-	return csum_fold((__force __wsum)sum);
-}
-
+__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+			const struct in6_addr *daddr,
+			__u32 len, unsigned short proto,
+			__wsum csum);
 #endif
 
 static __inline__ __sum16 tcp_v6_check(int len,
@@ -126,4 +73,5 @@ static inline void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
 	__tcp_v6_send_check(skb, &np->saddr, &np->daddr);
 }
 
+int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto);
 #endif
net/ipv6/Makefile +1 -1
index 4ea2448..309af19 100644
@@ -40,7 +40,7 @@ obj-$(CONFIG_IPV6_SIT) += sit.o
 obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
 obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
 
-obj-y += addrconf_core.o exthdrs_core.o
+obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o
 obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
 
 obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
net/ipv6/ip6_checksum.c new file +97 -0

97 lines not on this page · raw message

net/ipv6/udp.c +0 -34
index dfaa29b..1afb635 100644
@@ -752,40 +752,6 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
 	return 0;
 }
 
-static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
-				 int proto)
-{
-	int err;
-
-	UDP_SKB_CB(skb)->partial_cov = 0;
-	UDP_SKB_CB(skb)->cscov = skb->len;
-
-	if (proto == IPPROTO_UDPLITE) {
-		err = udplite_checksum_init(skb, uh);
-		if (err)
-			return err;
-	}
-
-	if (uh->check == 0) {
-		/* RFC 2460 section 8.1 says that we SHOULD log
-		   this error. Well, it is reasonable.
-		 */
-		LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
-		return 1;
-	}
-	if (skb->ip_summed == CHECKSUM_COMPLETE &&
-	    !csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
-			     skb->len, proto, skb->csum))
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-
-	if (!skb_csum_unnecessary(skb))
-		skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-							 &ipv6_hdr(skb)->daddr,
-							 skb->len, proto, 0));
-
-	return 0;
-}
-
 int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
Signature · 1 line
1.7.7.6
author
#3 lore raw

PATCH v5 3/4 netpoll: add IPv6 support

In reply to Cong Wang

From: Cong Wang <[email protected]>

Currently, netpoll only supports IPv4. This patch adds IPv6 support to netpoll so that we can run netconsole over IPv6 network.

Cc David S. Miller <[email protected]>
---
 drivers/net/netconsole.c |   44 +++++++-
 net/core/netpoll.c       |  246 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 274 insertions(+), 16 deletions(-)
drivers/net/netconsole.c +38 -6
index 998fa02..37add21 100644
@@ -269,13 +269,17 @@ 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)
+	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);
 }
 
 static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 {
-	if (!nt->np.ipv6)
+	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);
 }
 
@@ -412,8 +416,22 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
 		return -EINVAL;
 	}
 
-	if (!strnchr(buf, count, ':'))
-		nt->np.local_ip.ip = in_aton(buf);
+	if (strnchr(buf, count, ':')) {
+		const char *end;
+		if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
+			if (*end && *end != '\n') {
+				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end);
+				return -EINVAL;
+			}
+			nt->np.ipv6 = true;
+		} else
+			return -EINVAL;
+	} else {
+		if (!nt->np.ipv6) {
+			nt->np.local_ip.ip = in_aton(buf);
+		} else
+			return -EINVAL;
+	}
 
 	return strnlen(buf, count);
 }
@@ -429,8 +447,22 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
 		return -EINVAL;
 	}
 
-	if (!strnchr(buf, count, ':'))
-		nt->np.remote_ip.ip = in_aton(buf);
+	if (strnchr(buf, count, ':')) {
+		const char *end;
+		if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
+			if (*end && *end != '\n') {
+				printk(KERN_ERR "netconsole: invalid IPv6 address at: <%c>\n", *end);
+				return -EINVAL;
+			}
+			nt->np.ipv6 = true;
+		} else
+			return -EINVAL;
+	} else {
+		if (!nt->np.ipv6) {
+			nt->np.remote_ip.ip = in_aton(buf);
+		} else
+			return -EINVAL;
+	}
 
 	return strnlen(buf, count);
 }
net/core/netpoll.c +236 -10

320 lines not on this page · raw message

Signature · 1 line
1.7.7.6
author
#4 lore raw

PATCH v5 4/4 netconsole: add IPv6 example in doc

In reply to Cong Wang

From: Cong Wang <[email protected]>

Update the netconsole document as well.

Cc David S. Miller <[email protected]>
---
 Documentation/networking/netconsole.txt |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
Documentation/networking/netconsole.txt +6 -1
index 2e9e0ae2..a5d574a 100644
@@ -1,9 +1,10 @@
 
 started by Ingo Molnar <[email protected]>, 2001.09.17
 2.6 port and netpoll api by Matt Mackall <[email protected]>, Sep 9 2003
+IPv6 support by Cong Wang <[email protected]>, Jan 1 2013
 
 Please send bug reports to Matt Mackall <[email protected]>
-and Satyam Sharma <[email protected]>
+Satyam Sharma <[email protected]>, and Cong Wang <[email protected]>
 
 Introduction:
 =============
@@ -41,6 +42,10 @@ Examples:
 
  insmod netconsole netconsole=@/,@10.0.0.2/
 
+  or using IPv6
+
+ insmod netconsole netconsole=@/,@fd00:1:2:3::1/
+
 It also supports logging to multiple remote agents by specifying
 parameters for the multiple agents separated by semicolons and the
 complete string enclosed in "quotes", thusly:
Signature · 1 line
1.7.7.6
maintainer
#5 lore raw
In reply to Cong Wang

From: Cong Wang <[email protected]>
Date: Tue, 8 Jan 2013 14:52:38 +0800

Quoted 6 lines

v5: move some ipv6 checksum functions into net/ipv6/ip6_checksum.c

v4: remove ndisc_parse_options(), ignore ICMP options there
make udp6_csum_init() inline so that we don't rely on IPV6=y fix a conflict with Jiri's patchset

Quoted 6 lines

v3: fix CONFIG_IPV6=m case

v2: use bool for ipv6 flag
fix !CONFIG_IPV6 case

This patchset implements netpoll over IPv6.

Series applied, thanks.