Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 02/19] ndisc: Move ndisc_opt_addr_space() to include/net/ndisc.h.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:47 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

This also makes ndisc_opt_addr_data() and ndisc_fill_addr_option()
use ndisc_opt_addr_space().

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 include/net/ndisc.h |    8 +++++++-
 net/ipv6/ndisc.c    |    7 +------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index ec48f42..745bf74 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -127,13 +127,19 @@ static int ndisc_addr_option_pad(unsigned short type)
 	}
 }
 
+static inline int ndisc_opt_addr_space(struct net_device *dev)
+{
+	return NDISC_OPT_SPACE(dev->addr_len +
+			       ndisc_addr_option_pad(dev->type));
+}
+
 static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
 				      struct net_device *dev)
 {
 	u8 *lladdr = (u8 *)(p + 1);
 	int lladdrlen = p->nd_opt_len << 3;
 	int prepad = ndisc_addr_option_pad(dev->type);
-	if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad))
+	if (lladdrlen != ndisc_opt_addr_space(dev))
 		return NULL;
 	return lladdr + prepad;
 }
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 49dfc2a..82ccf0a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -143,17 +143,12 @@ struct neigh_table nd_tbl = {
 	.gc_thresh3 =	1024,
 };
 
-static inline int ndisc_opt_addr_space(struct net_device *dev)
-{
-	return NDISC_OPT_SPACE(dev->addr_len + ndisc_addr_option_pad(dev->type));
-}
-
 static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
 				  struct net_device *dev)
 {
 	int pad   = ndisc_addr_option_pad(dev->type);
 	int data_len = dev->addr_len;
-	int space = NDISC_OPT_SPACE(data_len + pad);
+	int space = ndisc_opt_addr_space(dev);
 
 	opt[0] = type;
 	opt[1] = space>>3;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 03/19] ndisc: Use skb_linearize() instead of pskb_may_pull(skb, skb->len).
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Suggested by Eric Dumazet <edumazet@google.com>.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 82ccf0a..539b2ec 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1509,7 +1509,7 @@ int ndisc_rcv(struct sk_buff *skb)
 {
 	struct nd_msg *msg;
 
-	if (!pskb_may_pull(skb, skb->len))
+	if (skb_linearize(skb))
 		return 0;
 
 	msg = (struct nd_msg *)skb_transport_header(skb);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 04/19] ndisc: Introduce ndisc_fill_redirect_hdr_option().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 539b2ec..53a545f 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1341,6 +1341,19 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 	icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
 }
 
+static u8 *ndisc_fill_redirect_hdr_option(u8 *opt, struct sk_buff *orig_skb,
+					  int rd_len)
+{
+	memset(opt, 0, 8);
+	*(opt++) = ND_OPT_REDIRECT_HDR;
+	*(opt++) = (rd_len >> 3);
+	opt += 6;
+
+	memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
+
+	return opt + rd_len - 8;
+}
+
 void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 {
 	struct net_device *dev = skb->dev;
@@ -1470,12 +1483,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	 *	build redirect option and copy skb over to the new packet.
 	 */
 
-	memset(opt, 0, 8);
-	*(opt++) = ND_OPT_REDIRECT_HDR;
-	*(opt++) = (rd_len >> 3);
-	opt += 6;
-
-	memcpy(opt, ipv6_hdr(skb), rd_len - 8);
+	if (rd_len)
+		opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len);
 
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
 						 len, IPPROTO_ICMPV6,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 05/19] ndisc: Introduce ndisc_alloc_skb() helper.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   52 +++++++++++++++++++++++++++-------------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 53a545f..1776a0d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -366,6 +366,29 @@ static void pndisc_destructor(struct pneigh_entry *n)
 	ipv6_dev_mc_dec(dev, &maddr);
 }
 
+static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
+				       int len)
+{
+	int hlen = LL_RESERVED_SPACE(dev);
+	int tlen = dev->needed_tailroom;
+	struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
+	struct sk_buff *skb;
+	int err;
+
+	skb = sock_alloc_send_skb(sk,
+				  hlen + sizeof(struct ipv6hdr) + len + tlen,
+				  1, &err);
+	if (!skb) {
+		ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, err=%d\n",
+			  __func__, err);
+		return NULL;
+	}
+
+	skb_reserve(skb, hlen);
+
+	return skb;
+}
+
 static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 				       const struct in6_addr *daddr,
 				       const struct in6_addr *saddr,
@@ -377,10 +400,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	struct sock *sk = net->ipv6.ndisc_sk;
 	struct sk_buff *skb;
 	struct icmp6hdr *hdr;
-	int hlen = LL_RESERVED_SPACE(dev);
-	int tlen = dev->needed_tailroom;
 	int len;
-	int err;
 	u8 *opt;
 
 	if (!dev->addr_len)
@@ -390,17 +410,10 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (llinfo)
 		len += ndisc_opt_addr_space(dev);
 
-	skb = sock_alloc_send_skb(sk,
-				  (sizeof(struct ipv6hdr) +
-				   len + hlen + tlen),
-				  1, &err);
-	if (!skb) {
-		ND_PRINTK(0, err, "ND: %s failed to allocate an skb, err=%d\n",
-			  __func__, err);
+	skb = ndisc_alloc_skb(dev, len);
+	if (!skb)
 		return NULL;
-	}
 
-	skb_reserve(skb, hlen);
 	ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
 
 	skb->transport_header = skb->tail;
@@ -1369,7 +1382,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	struct inet6_dev *idev;
 	struct flowi6 fl6;
 	u8 *opt;
-	int hlen, tlen;
 	int rd_len;
 	int err;
 	u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
@@ -1439,20 +1451,10 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	rd_len &= ~0x7;
 	len += rd_len;
 
-	hlen = LL_RESERVED_SPACE(dev);
-	tlen = dev->needed_tailroom;
-	buff = sock_alloc_send_skb(sk,
-				   (sizeof(struct ipv6hdr) +
-				    len + hlen + tlen),
-				   1, &err);
-	if (buff == NULL) {
-		ND_PRINTK(0, err,
-			  "Redirect: %s failed to allocate an skb, err=%d\n",
-			  __func__, err);
+	buff = ndisc_alloc_skb(dev, len);
+	if (!buff)
 		goto release;
-	}
 
-	skb_reserve(buff, hlen);
 	ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
 		   IPPROTO_ICMPV6, len);
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 06/19] ipv6: Unshare ip6_nd_hdr() and change return type to void.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

- move ip6_nd_hdr() to its users' source files.
  In net/ipv6/mcast.c, it will be called ip6_mc_hdr().
- make return type to void since this function never fails.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 include/net/ipv6.h    |    7 -------
 net/ipv6/ip6_output.c |   33 ---------------------------------
 net/ipv6/mcast.c      |   29 +++++++++++++++++++++++++++--
 net/ipv6/ndisc.c      |   25 +++++++++++++++++++++++++
 4 files changed, 52 insertions(+), 42 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 464c6f7..c1878f7 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -661,13 +661,6 @@ extern int			ip6_xmit(struct sock *sk,
 					 struct ipv6_txoptions *opt,
 					 int tclass);
 
-extern int			ip6_nd_hdr(struct sock *sk,
-					   struct sk_buff *skb,
-					   struct net_device *dev,
-					   const struct in6_addr *saddr,
-					   const struct in6_addr *daddr,
-					   int proto, int len);
-
 extern int			ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
 
 extern int			ip6_append_data(struct sock *sk,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index b0895f5..7eee94c 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -254,39 +254,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
 
 EXPORT_SYMBOL(ip6_xmit);
 
-/*
- *	To avoid extra problems ND packets are send through this
- *	routine. It's code duplication but I really want to avoid
- *	extra checks since ipv6_build_header is used by TCP (which
- *	is for us performance critical)
- */
-
-int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
-	       const struct in6_addr *saddr, const struct in6_addr *daddr,
-	       int proto, int len)
-{
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct ipv6hdr *hdr;
-
-	skb->protocol = htons(ETH_P_IPV6);
-	skb->dev = dev;
-
-	skb_reset_network_header(skb);
-	skb_put(skb, sizeof(struct ipv6hdr));
-	hdr = ipv6_hdr(skb);
-
-	ip6_flow_hdr(hdr, 0, 0);
-
-	hdr->payload_len = htons(len);
-	hdr->nexthdr = proto;
-	hdr->hop_limit = np->hop_limit;
-
-	hdr->saddr = *saddr;
-	hdr->daddr = *daddr;
-
-	return 0;
-}
-
 static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
 {
 	struct ip6_ra_chain *ra;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 587a845..f25002a 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1313,6 +1313,31 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted)
 	return scount;
 }
 
+static void ip6_mc_hdr(struct sock *sk, struct sk_buff *skb,
+		       struct net_device *dev,
+		       const struct in6_addr *saddr,
+		       const struct in6_addr *daddr,
+		       int proto, int len)
+{
+	struct ipv6hdr *hdr;
+
+	skb->protocol = htons(ETH_P_IPV6);
+	skb->dev = dev;
+
+	skb_reset_network_header(skb);
+	skb_put(skb, sizeof(struct ipv6hdr));
+	hdr = ipv6_hdr(skb);
+
+	ip6_flow_hdr(hdr, 0, 0);
+
+	hdr->payload_len = htons(len);
+	hdr->nexthdr = proto;
+	hdr->hop_limit = inet6_sk(sk)->hop_limit;
+
+	hdr->saddr = *saddr;
+	hdr->daddr = *daddr;
+}
+
 static struct sk_buff *mld_newpack(struct net_device *dev, int size)
 {
 	struct net *net = dev_net(dev);
@@ -1348,7 +1373,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
 	} else
 		saddr = &addr_buf;
 
-	ip6_nd_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
+	ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
 
 	memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
 
@@ -1740,7 +1765,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 	} else
 		saddr = &addr_buf;
 
-	ip6_nd_hdr(sk, skb, dev, saddr, snd_addr, NEXTHDR_HOP, payload_len);
+	ip6_mc_hdr(sk, skb, dev, saddr, snd_addr, NEXTHDR_HOP, payload_len);
 
 	memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 1776a0d..7ce266f 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -389,6 +389,31 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	return skb;
 }
 
+static void ip6_nd_hdr(struct sock *sk,
+		       struct sk_buff *skb, struct net_device *dev,
+		       const struct in6_addr *saddr,
+		       const struct in6_addr *daddr,
+		       int proto, int len)
+{
+	struct ipv6hdr *hdr;
+
+	skb->protocol = htons(ETH_P_IPV6);
+	skb->dev = dev;
+
+	skb_reset_network_header(skb);
+	skb_put(skb, sizeof(struct ipv6hdr));
+	hdr = ipv6_hdr(skb);
+
+	ip6_flow_hdr(hdr, 0, 0);
+
+	hdr->payload_len = htons(len);
+	hdr->nexthdr = proto;
+	hdr->hop_limit = inet6_sk(sk)->hop_limit;
+
+	hdr->saddr = *saddr;
+	hdr->daddr = *daddr;
+}
+
 static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 				       const struct in6_addr *daddr,
 				       const struct in6_addr *saddr,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 07/19] ndisc: Simplify arguments for ip6_nd_hdr().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 7ce266f..05c6996 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -389,11 +389,10 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	return skb;
 }
 
-static void ip6_nd_hdr(struct sock *sk,
-		       struct sk_buff *skb, struct net_device *dev,
+static void ip6_nd_hdr(struct sk_buff *skb, struct net_device *dev,
 		       const struct in6_addr *saddr,
 		       const struct in6_addr *daddr,
-		       int proto, int len)
+		       int hop_limit, int len)
 {
 	struct ipv6hdr *hdr;
 
@@ -407,8 +406,8 @@ static void ip6_nd_hdr(struct sock *sk,
 	ip6_flow_hdr(hdr, 0, 0);
 
 	hdr->payload_len = htons(len);
-	hdr->nexthdr = proto;
-	hdr->hop_limit = inet6_sk(sk)->hop_limit;
+	hdr->nexthdr = IPPROTO_ICMPV6;
+	hdr->hop_limit = hop_limit;
 
 	hdr->saddr = *saddr;
 	hdr->daddr = *daddr;
@@ -439,7 +438,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (!skb)
 		return NULL;
 
-	ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
+	ip6_nd_hdr(skb, dev, saddr, daddr, inet6_sk(sk)->hop_limit, len);
 
 	skb->transport_header = skb->tail;
 	skb_put(skb, len);
@@ -1480,8 +1479,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
-		   IPPROTO_ICMPV6, len);
+	ip6_nd_hdr(buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
+		   inet6_sk(sk)->hop_limit, len);
 
 	skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
 	skb_put(buff, len);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 08/19] ndisc: Set skb->dev and skb->protocol inside ndisc_alloc_skb().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 05c6996..ed3ba8e 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -384,21 +384,21 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 		return NULL;
 	}
 
+	skb->protocol = htons(ETH_P_IPV6);
+	skb->dev = dev;
+
 	skb_reserve(skb, hlen);
 
 	return skb;
 }
 
-static void ip6_nd_hdr(struct sk_buff *skb, struct net_device *dev,
+static void ip6_nd_hdr(struct sk_buff *skb,
 		       const struct in6_addr *saddr,
 		       const struct in6_addr *daddr,
 		       int hop_limit, int len)
 {
 	struct ipv6hdr *hdr;
 
-	skb->protocol = htons(ETH_P_IPV6);
-	skb->dev = dev;
-
 	skb_reset_network_header(skb);
 	skb_put(skb, sizeof(struct ipv6hdr));
 	hdr = ipv6_hdr(skb);
@@ -438,7 +438,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (!skb)
 		return NULL;
 
-	ip6_nd_hdr(skb, dev, saddr, daddr, inet6_sk(sk)->hop_limit, len);
+	ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, len);
 
 	skb->transport_header = skb->tail;
 	skb_put(skb, len);
@@ -1479,7 +1479,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	ip6_nd_hdr(buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
+	ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr,
 		   inet6_sk(sk)->hop_limit, len);
 
 	skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 09/19] ndisc: Remove dev argument for ndisc_send_skb().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Since we have skb->dev, use it.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ed3ba8e..200b2b2 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -463,14 +463,14 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	return skb;
 }
 
-static void ndisc_send_skb(struct sk_buff *skb, struct net_device *dev,
+static void ndisc_send_skb(struct sk_buff *skb,
 			   const struct in6_addr *daddr,
 			   const struct in6_addr *saddr,
 			   struct icmp6hdr *icmp6h)
 {
 	struct flowi6 fl6;
 	struct dst_entry *dst;
-	struct net *net = dev_net(dev);
+	struct net *net = dev_net(skb->dev);
 	struct sock *sk = net->ipv6.ndisc_sk;
 	struct inet6_dev *idev;
 	int err;
@@ -478,8 +478,8 @@ static void ndisc_send_skb(struct sk_buff *skb, struct net_device *dev,
 
 	type = icmp6h->icmp6_type;
 
-	icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
-	dst = icmp6_dst_alloc(dev, &fl6);
+	icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
+	dst = icmp6_dst_alloc(skb->dev, &fl6);
 	if (IS_ERR(dst)) {
 		kfree_skb(skb);
 		return;
@@ -516,7 +516,7 @@ static void __ndisc_send(struct net_device *dev,
 	if (!skb)
 		return;
 
-	ndisc_send_skb(skb, dev, daddr, saddr, icmp6h);
+	ndisc_send_skb(skb, daddr, saddr, icmp6h);
 }
 
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 10/19] ndisc: Defer building IPv6 header.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Build ICMPv6 message first and make buffer management easier;
we can use skb->len when filling checksum in ICMPv6 header,
and then build IP header with length field.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 200b2b2..09171fd 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -387,7 +387,7 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	skb->protocol = htons(ETH_P_IPV6);
 	skb->dev = dev;
 
-	skb_reserve(skb, hlen);
+	skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
 
 	return skb;
 }
@@ -399,8 +399,8 @@ static void ip6_nd_hdr(struct sk_buff *skb,
 {
 	struct ipv6hdr *hdr;
 
+	skb_push(skb, sizeof(*hdr));
 	skb_reset_network_header(skb);
-	skb_put(skb, sizeof(struct ipv6hdr));
 	hdr = ipv6_hdr(skb);
 
 	ip6_flow_hdr(hdr, 0, 0);
@@ -438,8 +438,6 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (!skb)
 		return NULL;
 
-	ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, len);
-
 	skb->transport_header = skb->tail;
 	skb_put(skb, len);
 
@@ -455,10 +453,12 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (llinfo)
 		ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev);
 
-	hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len,
+	hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
 					   IPPROTO_ICMPV6,
 					   csum_partial(hdr,
-							len, 0));
+							skb->len, 0));
+
+	ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
 
 	return skb;
 }
@@ -1479,9 +1479,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr,
-		   inet6_sk(sk)->hop_limit, len);
-
 	skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
 	skb_put(buff, len);
 	msg = (struct rd_msg *)icmp6_hdr(buff);
@@ -1513,8 +1510,11 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 		opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len);
 
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
-						 len, IPPROTO_ICMPV6,
-						 csum_partial(msg, len, 0));
+						 buff->len, IPPROTO_ICMPV6,
+						 csum_partial(msg, buff->len, 0));
+
+	ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr,
+		   inet6_sk(sk)->hop_limit, buff->len);
 
 	skb_dst_set(buff, dst);
 	rcu_read_lock();
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 11/19] ndisc: Reset skb->trasport_headner inside ndisc_alloc_send_skb().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 09171fd..62b1415 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -388,6 +388,7 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
 	skb->dev = dev;
 
 	skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
+	skb_reset_transport_header(skb);
 
 	return skb;
 }
@@ -438,7 +439,6 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (!skb)
 		return NULL;
 
-	skb->transport_header = skb->tail;
 	skb_put(skb, len);
 
 	hdr = (struct icmp6hdr *)skb_transport_header(skb);
@@ -1479,7 +1479,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
 	skb_put(buff, len);
 	msg = (struct rd_msg *)icmp6_hdr(buff);
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 12/19] ndisc: Calculate message body length and option length separately.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 62b1415..c2b16ff 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -426,6 +426,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	struct sk_buff *skb;
 	struct icmp6hdr *hdr;
 	int len;
+	int optlen = 0;
 	u8 *opt;
 
 	if (!dev->addr_len)
@@ -433,13 +434,13 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 
 	len = sizeof(struct icmp6hdr) + (target ? sizeof(*target) : 0);
 	if (llinfo)
-		len += ndisc_opt_addr_space(dev);
+		optlen += ndisc_opt_addr_space(dev);
 
-	skb = ndisc_alloc_skb(dev, len);
+	skb = ndisc_alloc_skb(dev, len + optlen);
 	if (!skb)
 		return NULL;
 
-	skb_put(skb, len);
+	skb_put(skb, len + optlen);
 
 	hdr = (struct icmp6hdr *)skb_transport_header(skb);
 	memcpy(hdr, icmp6h, sizeof(*hdr));
@@ -1396,7 +1397,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	struct net_device *dev = skb->dev;
 	struct net *net = dev_net(dev);
 	struct sock *sk = net->ipv6.ndisc_sk;
-	int len = sizeof(struct rd_msg);
+	int optlen = 0;
 	struct inet_peer *peer;
 	struct sk_buff *buff;
 	struct rd_msg *msg;
@@ -1463,7 +1464,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 			memcpy(ha_buf, neigh->ha, dev->addr_len);
 			read_unlock_bh(&neigh->lock);
 			ha = ha_buf;
-			len += ndisc_opt_addr_space(dev);
+			optlen += ndisc_opt_addr_space(dev);
 		} else
 			read_unlock_bh(&neigh->lock);
 
@@ -1471,15 +1472,16 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	}
 
 	rd_len = min_t(unsigned int,
-		     IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
+		       IPV6_MIN_MTU - sizeof(struct ipv6hdr) - sizeof(*msg) - optlen,
+		       skb->len + 8);
 	rd_len &= ~0x7;
-	len += rd_len;
+	optlen += rd_len;
 
-	buff = ndisc_alloc_skb(dev, len);
+	buff = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
 	if (!buff)
 		goto release;
 
-	skb_put(buff, len);
+	skb_put(buff, sizeof(*msg) + optlen);
 	msg = (struct rd_msg *)icmp6_hdr(buff);
 
 	memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 13/19] ndisc: Make ndisc_fill_xxx_option() for sk_buff.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c2b16ff..ed78644 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -143,12 +143,12 @@ struct neigh_table nd_tbl = {
 	.gc_thresh3 =	1024,
 };
 
-static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
-				  struct net_device *dev)
+static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data)
 {
-	int pad   = ndisc_addr_option_pad(dev->type);
-	int data_len = dev->addr_len;
-	int space = ndisc_opt_addr_space(dev);
+	int pad   = ndisc_addr_option_pad(skb->dev->type);
+	int data_len = skb->dev->addr_len;
+	int space = ndisc_opt_addr_space(skb->dev);
+	u8 *opt = skb_put(skb, space);
 
 	opt[0] = type;
 	opt[1] = space>>3;
@@ -162,7 +162,6 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data,
 	opt += data_len;
 	if ((space -= data_len) > 0)
 		memset(opt, 0, space);
-	return opt + space;
 }
 
 static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur,
@@ -440,7 +439,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (!skb)
 		return NULL;
 
-	skb_put(skb, len + optlen);
+	skb_put(skb, len);
 
 	hdr = (struct icmp6hdr *)skb_transport_header(skb);
 	memcpy(hdr, icmp6h, sizeof(*hdr));
@@ -452,7 +451,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	}
 
 	if (llinfo)
-		ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev);
+		ndisc_fill_addr_option(skb, llinfo, dev->dev_addr);
 
 	hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
 					   IPPROTO_ICMPV6,
@@ -1379,17 +1378,18 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 	icmpv6_notify(skb, NDISC_REDIRECT, 0, 0);
 }
 
-static u8 *ndisc_fill_redirect_hdr_option(u8 *opt, struct sk_buff *orig_skb,
-					  int rd_len)
+static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb,
+					   struct sk_buff *orig_skb,
+					   int rd_len)
 {
+	u8 *opt = skb_put(skb, rd_len);
+
 	memset(opt, 0, 8);
 	*(opt++) = ND_OPT_REDIRECT_HDR;
 	*(opt++) = (rd_len >> 3);
 	opt += 6;
 
 	memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8);
-
-	return opt + rd_len - 8;
 }
 
 void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
@@ -1406,7 +1406,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	struct dst_entry *dst;
 	struct inet6_dev *idev;
 	struct flowi6 fl6;
-	u8 *opt;
 	int rd_len;
 	int err;
 	u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
@@ -1481,7 +1480,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	skb_put(buff, sizeof(*msg) + optlen);
+	skb_put(buff, sizeof(*msg));
 	msg = (struct rd_msg *)icmp6_hdr(buff);
 
 	memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
@@ -1494,21 +1493,19 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	msg->target = *target;
 	msg->dest = ipv6_hdr(skb)->daddr;
 
-	opt = msg->opt;
-
 	/*
 	 *	include target_address option
 	 */
 
 	if (ha)
-		opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha, dev);
+		ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR, ha);
 
 	/*
 	 *	build redirect option and copy skb over to the new packet.
 	 */
 
 	if (rd_len)
-		opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len);
+		ndisc_fill_redirect_hdr_option(buff, skb, rd_len);
 
 	msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
 						 buff->len, IPPROTO_ICMPV6,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 14/19] ndisc: Remove icmp6h argument from ndisc_send_skb().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:48 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

skb_transport_header() (thus icmp6_hdr()) is available here,
use it.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ed78644..f0c436b 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -465,8 +465,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 
 static void ndisc_send_skb(struct sk_buff *skb,
 			   const struct in6_addr *daddr,
-			   const struct in6_addr *saddr,
-			   struct icmp6hdr *icmp6h)
+			   const struct in6_addr *saddr)
 {
 	struct flowi6 fl6;
 	struct dst_entry *dst;
@@ -474,6 +473,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
 	struct sock *sk = net->ipv6.ndisc_sk;
 	struct inet6_dev *idev;
 	int err;
+	struct icmp6hdr *icmp6h = icmp6_hdr(skb);
 	u8 type;
 
 	type = icmp6h->icmp6_type;
@@ -516,7 +516,7 @@ static void __ndisc_send(struct net_device *dev,
 	if (!skb)
 		return;
 
-	ndisc_send_skb(skb, daddr, saddr, icmp6h);
+	ndisc_send_skb(skb, daddr, saddr);
 }
 
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 15/19] ndisc: Use ndisc_send_skb() for redirect.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:49 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Reuse dst if one is attached with skb.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   37 ++++++++++++++-----------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f0c436b..437781c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -467,10 +467,8 @@ static void ndisc_send_skb(struct sk_buff *skb,
 			   const struct in6_addr *daddr,
 			   const struct in6_addr *saddr)
 {
-	struct flowi6 fl6;
-	struct dst_entry *dst;
+	struct dst_entry *dst = skb_dst(skb);
 	struct net *net = dev_net(skb->dev);
-	struct sock *sk = net->ipv6.ndisc_sk;
 	struct inet6_dev *idev;
 	int err;
 	struct icmp6hdr *icmp6h = icmp6_hdr(skb);
@@ -478,14 +476,19 @@ static void ndisc_send_skb(struct sk_buff *skb,
 
 	type = icmp6h->icmp6_type;
 
-	icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
-	dst = icmp6_dst_alloc(skb->dev, &fl6);
-	if (IS_ERR(dst)) {
-		kfree_skb(skb);
-		return;
-	}
+	if (!dst) {
+		struct sock *sk = net->ipv6.ndisc_sk;
+		struct flowi6 fl6;
 
-	skb_dst_set(skb, dst);
+		icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
+		dst = icmp6_dst_alloc(skb->dev, &fl6);
+		if (IS_ERR(dst)) {
+			kfree_skb(skb);
+			return;
+		}
+
+		skb_dst_set(skb, dst);
+	}
 
 	rcu_read_lock();
 	idev = __in6_dev_get(dst->dev);
@@ -1404,10 +1407,8 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	struct in6_addr saddr_buf;
 	struct rt6_info *rt;
 	struct dst_entry *dst;
-	struct inet6_dev *idev;
 	struct flowi6 fl6;
 	int rd_len;
-	int err;
 	u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
 	bool ret;
 
@@ -1515,17 +1516,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 		   inet6_sk(sk)->hop_limit, buff->len);
 
 	skb_dst_set(buff, dst);
-	rcu_read_lock();
-	idev = __in6_dev_get(dst->dev);
-	IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
-	err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
-		      dst_output);
-	if (!err) {
-		ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);
-		ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-	}
-
-	rcu_read_unlock();
+	ndisc_send_skb(buff, &ipv6_hdr(skb)->saddr, &saddr_buf);
 	return;
 
 release:
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 16/19] ndisc: Fill in ICMPv6 checksum and IPv6 header in ndisc_send_skb().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:49 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 437781c..dda4add 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -420,8 +420,6 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 				       const struct in6_addr *target,
 				       int llinfo)
 {
-	struct net *net = dev_net(dev);
-	struct sock *sk = net->ipv6.ndisc_sk;
 	struct sk_buff *skb;
 	struct icmp6hdr *hdr;
 	int len;
@@ -453,13 +451,6 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
 	if (llinfo)
 		ndisc_fill_addr_option(skb, llinfo, dev->dev_addr);
 
-	hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
-					   IPPROTO_ICMPV6,
-					   csum_partial(hdr,
-							skb->len, 0));
-
-	ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
-
 	return skb;
 }
 
@@ -469,6 +460,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
 {
 	struct dst_entry *dst = skb_dst(skb);
 	struct net *net = dev_net(skb->dev);
+	struct sock *sk = net->ipv6.ndisc_sk;
 	struct inet6_dev *idev;
 	int err;
 	struct icmp6hdr *icmp6h = icmp6_hdr(skb);
@@ -490,6 +482,13 @@ static void ndisc_send_skb(struct sk_buff *skb,
 		skb_dst_set(skb, dst);
 	}
 
+	icmp6h->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
+					      IPPROTO_ICMPV6,
+					      csum_partial(icmp6h,
+							   skb->len, 0));
+
+	ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len);
+
 	rcu_read_lock();
 	idev = __in6_dev_get(dst->dev);
 	IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
@@ -1508,13 +1507,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (rd_len)
 		ndisc_fill_redirect_hdr_option(buff, skb, rd_len);
 
-	msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
-						 buff->len, IPPROTO_ICMPV6,
-						 csum_partial(msg, buff->len, 0));
-
-	ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr,
-		   inet6_sk(sk)->hop_limit, buff->len);
-
 	skb_dst_set(buff, dst);
 	ndisc_send_skb(buff, &ipv6_hdr(skb)->saddr, &saddr_buf);
 	return;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 17/19] ndisc: Break down __ndisc_send().
From: YOSHIFUJI Hideaki @ 2013-01-21 16:49 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   45 +++++++++++++++++++++------------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index dda4add..79a56a7 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -503,29 +503,12 @@ static void ndisc_send_skb(struct sk_buff *skb,
 	rcu_read_unlock();
 }
 
-/*
- *	Send a Neighbour Discover packet
- */
-static void __ndisc_send(struct net_device *dev,
-			 const struct in6_addr *daddr,
-			 const struct in6_addr *saddr,
-			 struct icmp6hdr *icmp6h, const struct in6_addr *target,
-			 int llinfo)
-{
-	struct sk_buff *skb;
-
-	skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo);
-	if (!skb)
-		return;
-
-	ndisc_send_skb(skb, daddr, saddr);
-}
-
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 			  const struct in6_addr *daddr,
 			  const struct in6_addr *solicited_addr,
 			  bool router, bool solicited, bool override, bool inc_opt)
 {
+	struct sk_buff *skb;
 	struct in6_addr tmpaddr;
 	struct inet6_ifaddr *ifp;
 	const struct in6_addr *src_addr;
@@ -553,8 +536,12 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 	icmp6h.icmp6_solicited = solicited;
 	icmp6h.icmp6_override = override;
 
-	__ndisc_send(dev, daddr, src_addr, &icmp6h, solicited_addr,
-		     inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
+	skb = ndisc_build_skb(dev, daddr, src_addr, &icmp6h, solicited_addr,
+			      inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
+	if (!skb)
+		return;
+
+	ndisc_send_skb(skb, daddr, src_addr);
 }
 
 static void ndisc_send_unsol_na(struct net_device *dev)
@@ -582,6 +569,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		   const struct in6_addr *solicit,
 		   const struct in6_addr *daddr, const struct in6_addr *saddr)
 {
+	struct sk_buff *skb;
 	struct in6_addr addr_buf;
 	struct icmp6hdr icmp6h = {
 		.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
@@ -594,13 +582,18 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		saddr = &addr_buf;
 	}
 
-	__ndisc_send(dev, daddr, saddr, &icmp6h, solicit,
-		     !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
+	skb = ndisc_build_skb(dev, daddr, saddr, &icmp6h, solicit,
+			      !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
+	if (!skb)
+		return;
+
+	ndisc_send_skb(skb, daddr, saddr);
 }
 
 void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
 		   const struct in6_addr *daddr)
 {
+	struct sk_buff *skb;
 	struct icmp6hdr icmp6h = {
 		.icmp6_type = NDISC_ROUTER_SOLICITATION,
 	};
@@ -628,8 +621,12 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
 		}
 	}
 #endif
-	__ndisc_send(dev, daddr, saddr, &icmp6h, NULL,
-		     send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
+	skb = ndisc_build_skb(dev, daddr, saddr, &icmp6h, NULL,
+			      send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
+	if (!skb)
+		return;
+
+	ndisc_send_skb(skb, daddr, saddr);
 }
 
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 18/19] ndisc: Break down ndisc_build_skb() and build message directly.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:49 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Construct NS/NA/RS message directly using C99 compound literals.

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |  122 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 63 insertions(+), 59 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 79a56a7..1c01566 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -413,47 +413,6 @@ static void ip6_nd_hdr(struct sk_buff *skb,
 	hdr->daddr = *daddr;
 }
 
-static struct sk_buff *ndisc_build_skb(struct net_device *dev,
-				       const struct in6_addr *daddr,
-				       const struct in6_addr *saddr,
-				       struct icmp6hdr *icmp6h,
-				       const struct in6_addr *target,
-				       int llinfo)
-{
-	struct sk_buff *skb;
-	struct icmp6hdr *hdr;
-	int len;
-	int optlen = 0;
-	u8 *opt;
-
-	if (!dev->addr_len)
-		llinfo = 0;
-
-	len = sizeof(struct icmp6hdr) + (target ? sizeof(*target) : 0);
-	if (llinfo)
-		optlen += ndisc_opt_addr_space(dev);
-
-	skb = ndisc_alloc_skb(dev, len + optlen);
-	if (!skb)
-		return NULL;
-
-	skb_put(skb, len);
-
-	hdr = (struct icmp6hdr *)skb_transport_header(skb);
-	memcpy(hdr, icmp6h, sizeof(*hdr));
-
-	opt = skb_transport_header(skb) + sizeof(struct icmp6hdr);
-	if (target) {
-		*(struct in6_addr *)opt = *target;
-		opt += sizeof(*target);
-	}
-
-	if (llinfo)
-		ndisc_fill_addr_option(skb, llinfo, dev->dev_addr);
-
-	return skb;
-}
-
 static void ndisc_send_skb(struct sk_buff *skb,
 			   const struct in6_addr *daddr,
 			   const struct in6_addr *saddr)
@@ -512,9 +471,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 	struct in6_addr tmpaddr;
 	struct inet6_ifaddr *ifp;
 	const struct in6_addr *src_addr;
-	struct icmp6hdr icmp6h = {
-		.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
-	};
+	struct nd_msg *msg;
+	int optlen = 0;
 
 	/* for anycast or proxy, solicited_addr != src_addr */
 	ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
@@ -532,15 +490,31 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
 		src_addr = &tmpaddr;
 	}
 
-	icmp6h.icmp6_router = router;
-	icmp6h.icmp6_solicited = solicited;
-	icmp6h.icmp6_override = override;
+	if (!dev->addr_len)
+		inc_opt = 0;
+	if (inc_opt)
+		optlen += ndisc_opt_addr_space(dev);
 
-	skb = ndisc_build_skb(dev, daddr, src_addr, &icmp6h, solicited_addr,
-			      inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
+	skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
 	if (!skb)
 		return;
 
+	msg = (struct nd_msg *)skb_put(skb, sizeof(*msg));
+	*msg = (struct nd_msg) {
+		.icmph = {
+			.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
+			.icmp6_router = router,
+			.icmp6_solicited = solicited,
+			.icmp6_override = override,
+		},
+		.target = *solicited_addr,
+	};
+
+	if (inc_opt)
+		ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
+				       dev->dev_addr);
+
+
 	ndisc_send_skb(skb, daddr, src_addr);
 }
 
@@ -571,9 +545,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 {
 	struct sk_buff *skb;
 	struct in6_addr addr_buf;
-	struct icmp6hdr icmp6h = {
-		.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
-	};
+	int inc_opt = dev->addr_len;
+	int optlen = 0;
+	struct nd_msg *msg;
 
 	if (saddr == NULL) {
 		if (ipv6_get_lladdr(dev, &addr_buf,
@@ -582,11 +556,27 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
 		saddr = &addr_buf;
 	}
 
-	skb = ndisc_build_skb(dev, daddr, saddr, &icmp6h, solicit,
-			      !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
+	if (ipv6_addr_any(saddr))
+		inc_opt = 0;
+	if (inc_opt)
+		optlen += ndisc_opt_addr_space(dev);
+
+	skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
 	if (!skb)
 		return;
 
+	msg = (struct nd_msg *)skb_put(skb, sizeof(*msg));
+	*msg = (struct nd_msg) {
+		.icmph = {
+			.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
+		},
+		.target = *solicit,
+	};
+
+	if (inc_opt)
+		ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
+				       dev->dev_addr);
+
 	ndisc_send_skb(skb, daddr, saddr);
 }
 
@@ -594,10 +584,9 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
 		   const struct in6_addr *daddr)
 {
 	struct sk_buff *skb;
-	struct icmp6hdr icmp6h = {
-		.icmp6_type = NDISC_ROUTER_SOLICITATION,
-	};
+	struct rs_msg *msg;
 	int send_sllao = dev->addr_len;
+	int optlen = 0;
 
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
 	/*
@@ -621,11 +610,26 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
 		}
 	}
 #endif
-	skb = ndisc_build_skb(dev, daddr, saddr, &icmp6h, NULL,
-			      send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
+	if (!dev->addr_len)
+		send_sllao = 0;
+	if (send_sllao)
+		optlen += ndisc_opt_addr_space(dev);
+
+	skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
 	if (!skb)
 		return;
 
+	msg = (struct rs_msg *)skb_put(skb, sizeof(*msg));
+	*msg = (struct rs_msg) {
+		.icmph = {
+			.icmp6_type = NDISC_ROUTER_SOLICITATION,
+		},
+	};
+
+	if (send_sllao)
+		ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
+				       dev->dev_addr);
+
 	ndisc_send_skb(skb, daddr, saddr);
 }
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 19/19] ndisc: Use compound literals to build redirect message.
From: YOSHIFUJI Hideaki @ 2013-01-21 16:49 UTC (permalink / raw)
  To: davem, netdev; +Cc: yoshfuji

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
 net/ipv6/ndisc.c |   20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 1c01566..76ef435 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1481,18 +1481,14 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 	if (!buff)
 		goto release;
 
-	skb_put(buff, sizeof(*msg));
-	msg = (struct rd_msg *)icmp6_hdr(buff);
-
-	memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
-	msg->icmph.icmp6_type = NDISC_REDIRECT;
-
-	/*
-	 *	copy target and destination addresses
-	 */
-
-	msg->target = *target;
-	msg->dest = ipv6_hdr(skb)->daddr;
+	msg = (struct rd_msg *)skb_put(buff, sizeof(*msg));
+	*msg = (struct rd_msg) {
+		.icmph = {
+			.icmp6_type = NDISC_REDIRECT,
+		},
+		.target = *target,
+		.dest = ipv6_hdr(skb)->daddr,
+	};
 
 	/*
 	 *	include target_address option
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH net 2/3] net: cdc_mbim: send ZLP after max sized NTBs
From: Yauheni Kaliuta @ 2013-01-21 16:56 UTC (permalink / raw)
  To: Bjørn Mork
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	Greg Suarez, Alexey Orishko, Oliver Neukum
In-Reply-To: <1358783440-11459-3-git-send-email-bjorn-yOkvZcmFvRU@public.gmane.org>


Hi, Bjørn!

>>>>> "BM" == Bjørn Mork writes:

 > We normally avoid sending ZLPs by padding NTBs with a zero byte
 > if the NTB is shorter than dwNtbOutMaxSize, resulting in a short
 > USB packet instead of a ZLP.  But in the case where the NTB length
 > is exactly dwNtbOutMaxSize and this is an exact multiplum of
 > wMaxPacketSize, then we must send a ZLP.

The idea of NCM was to avoid extra ZLPs. If your transfer is exactly
dwNtbOutMaxSize, it's known, you can submit such request on the receiver
side and you do not need any EOT indicatation, so the frametime can be
used for useful data.

I didn't check MBIM specs, but I guess, it wasn't changed. But better get
Alexey's answer for sure.

 > This fixes an issue seen on a Sierra Wireless MC7710 device
 > where the transmission would fail whenever we ended up padding
 > the NTBs to max size.

Is it buggy?

 > Signed-off-by: Bjørn Mork <bjorn-yOkvZcmFvRU@public.gmane.org>
 > ---
 >  drivers/net/usb/cdc_mbim.c |    2 +-
 >  1 file changed, 1 insertion(+), 1 deletion(-)

 > diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
 > index 42f51c7..3a5673a 100644
 > --- a/drivers/net/usb/cdc_mbim.c
 > +++ b/drivers/net/usb/cdc_mbim.c
 > @@ -366,7 +366,7 @@ err:
 >  
 >  static const struct driver_info cdc_mbim_info = {
 >          .description = "CDC MBIM",
 > -        .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN,
 > +        .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET | FLAG_WWAN | FLAG_SEND_ZLP,
 >          .bind = cdc_mbim_bind,
 >          .unbind = cdc_mbim_unbind,
 >          .manage_power = cdc_mbim_manage_power,
 > -- 
 > 1.7.10.4



-- 
WBR, Yauheni Kaliuta
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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]  Gianfar : Enable promiscous mode after queue time out
From: Cedric VONCKEN @ 2013-01-21 16:24 UTC (permalink / raw)
  To: Claudiu Manoil, netdev

	Hi all, 

	When the Netdev tx queue timeout occurred, the function
gfar_timeout(..) is called. This function calls indirectly the
gfar_init_mac(..) function.

 	In this function, the rctrl register is set to a default value.

 	If the Promiscuous is enable on the net dev ( flag IFF_PROMISC
is  set), the gfar_init_function does not reactivate it.

 	The Promiscuous mode is used for example when the netdev is
bridged.
 	
 	I apply this patch on the kernel 3.8-rc4 to fix it.

	Signed-off-by : Voncken C Acksys <cedric.voncken@acksys.fr>

--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -349,6 +349,11 @@ static void gfar_init_mac(struct net_dev
 	/* Configure the coalescing support */
 	gfar_configure_coalescing(priv, 0xFF, 0xFF);
 
+	if (ndev->flags & IFF_PROMISC) {
+		/* Set RCTRL to PROM */
+		rctrl |= RCTRL_PROM;
+	}
+
 	if (priv->rx_filer_enable) {
 		rctrl |= RCTRL_FILREN;
 		/* Program the RIR0 reg with the required distribution
*/

^ permalink raw reply

* [PATCH] Add support for netconsole driver used on bridge device with VIF attached
From: Yuval Shaia @ 2013-01-21 17:17 UTC (permalink / raw)
  To: xen-devel, netdev, ian.campbell

When starting a VM which has virtual interface attached to the same bridge (i.e vif = [type=netfront,bridge=xenbr0'] in vm.cfg) which is used for netconsole the
following message appears (after about 60 seconds) and VM creation operation fails.
     Error: Device 0 (vif) could not be connected. Hotplug scripts not working.

Note:
When trying to do the opposite, i.e. first create VM and then run
netconsole we got the error #524 - vif2.0 doesn't support polling,
aborting.

As i see it, netconsole driver requires ndo_poll_controller from the device's controlling driver (function __netpoll_setup in net/core/netpoll.c), a thing that is not supported currently in xen_netback driver which is the driver that runs on dom0 and serve VM's virtual interface.

The following patch (to latest kernel) fix this bug by adding implementation to ndo_poll_controller.

0001-Add-support-for-netconsole-driver-used-on-bridge-dev.patch
0 2001
From: Yuval <yuval.shaia@oracle.com>
Date: Tue, 8 Jan 2013 10:08:45 +0200
Subject: [PATCH] Add support for netconsole driver used on bridge device with
 VIF attached

Signed-off-by: Yuval <yuval.shaia@oracle.com>
---
 drivers/net/xen-netback/interface.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 601ae2a..10751f5 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -179,6 +179,13 @@ static u32 xenvif_fix_features(struct net_device *dev, u32 features)
 	return features;
 }
 
+static void xenvif_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	xenvif_interrupt(dev->irq, dev);
+	enable_irq(dev->irq);
+}
+
 static const struct xenvif_stat {
 	char name[ETH_GSTRING_LEN];
 	u16 offset;
@@ -237,6 +244,7 @@ static const struct net_device_ops xenvif_netdev_ops = {
 	.ndo_stop	= xenvif_close,
 	.ndo_change_mtu	= xenvif_change_mtu,
 	.ndo_fix_features = xenvif_fix_features,
+	.ndo_poll_controller = xenvif_poll_controller,
 };
 
 struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
-- 
1.7.9.5

^ permalink raw reply related

* Re: [BUG] Bug in netprio_cgroup and netcls_cgroup ?
From: John Fastabend @ 2013-01-21 17:18 UTC (permalink / raw)
  To: Li Zefan
  Cc: Daniel Wagner, John Fastabend, Neil Horman, Daniel Wagner, LKML,
	netdev, Cgroups
In-Reply-To: <50FD1113.6010402@huawei.com>

On 01/21/2013 01:57 AM, Li Zefan wrote:
> On 2013/1/21 17:27, Daniel Wagner wrote:
>> On 21.01.2013 10:01, Li Zefan wrote:
>>> On 2013/1/21 16:50, Daniel Wagner wrote:
>>>> Hi Li,
>>>>
>>>> On 21.01.2013 07:08, Li Zefan wrote:
>>>>> I'm not a network developer, so correct me if I'm wrong.
>>>>>
>>>>> Since commit 7955490f732c2b8
>>>>> ("net: netprio_cgroup: rework update socket logic"), sock->sk->sk_cgrp_prioidx
>>>>> is set when the socket is created, and won't be updated unless the task is
>>>>> moved to another cgroup.
>>>>>
>>>>> Now the problem is, a socket can be _shared_ by multiple processes (fork, SCM_RIGHT).
>>>>> If we place those processes in different cgroups, and each cgroup has
>>>>> different configs, but all of the processes will send data via this socket
>>>>> with the same network priority.
>>>>
>>>> Wouldn't that be addressed by 48a87cc26c13b68f6cce4e9d769fcb17a6b3e4b8
>>>>
>>>>      net: netprio: fd passed in SCM_RIGHTS datagram not set correctly
>>>>
>>>>       A socket fd passed in a SCM_RIGHTS datagram was not getting
>>>>       updated with the new tasks cgrp prioidx. This leaves IO on
>>>>       the socket tagged with the old tasks priority.
>>>>
>>>>       To fix this add a check in the scm recvmsg path to update the
>>>>       sock cgrp prioidx with the new tasks value.
>>>>
>>>> As I read this this should work for net_prio.
>>>>
>>>
>>> But after process A passed the socket fd to B, both A and B can use the
>>> same socket to send data, right? Then if A and B were placed in different
>>> cgroups with differnt configs, A's config won't take effect anymore.
>>>
>>> Am I missing something?
>>
>> I don't know. I guess at one point the socket resources are shared and then
>> one configuration is taking preference. As you can see I am far away of
>> being
>> an expert in this field. Hopefully someone who understands this bits
>> can chip in.
>>
>> BTW, isn't this a similar to what should happen with the block io cgroup?
>> What is the behavior with a fd writing to a file in the scenario you
>> describe above?
>>
> 
> It forbids task moving in this case:
> 
> /*
>   * We cannot support shared io contexts, as we have no mean to support
>   * two tasks with the same ioc in two different groups without major rework
>   * of the main cic data structures.  For now we allow a task to change
>   * its cgroup only if it's the only owner of its ioc.
>   */
> static int blkcg_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
> 

OK, I guess we should do something similar in the netprio, netcls
cgroups and
yes document it as you noted in your last comment.

Thanks,
John

-- 
John Fastabend         Intel Corporation

^ permalink raw reply

* Re: [PATCH] Add support for netconsole driver used on bridge device with VIF attached
From: Ian Campbell @ 2013-01-21 17:28 UTC (permalink / raw)
  To: Yuval Shaia; +Cc: xen-devel@lists.xensource.com, netdev@vger.kernel.org
In-Reply-To: <5757e54b-902b-4338-8ac9-43857cd1906c@default>

On Mon, 2013-01-21 at 17:17 +0000, Yuval Shaia wrote:

> When starting a VM which has virtual interface attached to the same 
> bridge (i.e vif = [type=netfront,bridge=xenbr0'] in vm.cfg) which is 
> used for netconsole the
> following message appears (after about 60 seconds) and VM creation 
> operation fails.
>       Error: Device 0 (vif) could not be connected. Hotplug scripts not 
> working.

I'm not sure how this can relate netconsole since this happens before
the guest even runs, doesn't it?

> As i see it, netconsole driver requires ndo_poll_controller from the
> device's controlling driver (function __netpoll_setup in
> net/core/netpoll.c), a thing that is not supported currently in
> xen_netback driver which is the driver that runs on dom0 and serve
> VM's virtual interface.

Which domain is using netconsole? Is it dom0 or domU? What parameters do
you give it?

I assume it is the domU but if that's the case I don't see why a netback
rather than netfront patch would be required.

Or is dom0 doing netconsole where the log receiver is a domU?

Ian.

^ permalink raw reply

* Re: [PATCH 01/21] NTB: correct missing readq/writeq errors
From: Jon Mason @ 2013-01-21 17:38 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, netdev, Dave Jiang, Nicholas Bellinger
In-Reply-To: <20130120234005.GA14196@kroah.com>

On Sun, Jan 20, 2013 at 03:40:05PM -0800, Greg KH wrote:
> On Sat, Jan 19, 2013 at 02:02:15AM -0700, Jon Mason wrote:
> > Atomic readq and writeq do not exist by default on some 32bit
> > architectures, thus causing compile errors due to non-existent symbols.
> > In those cases, use the definitions of those symbols from
> > include/asm-generic/io-64-nonatomic-hi-lo.h
> > 
> > Signed-off-by: Jon Mason <jon.mason@intel.com>
> > ---
> >  drivers/ntb/ntb_hw.c |    1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c
> > index 4c71b17..0b46fef 100644
> > --- a/drivers/ntb/ntb_hw.c
> > +++ b/drivers/ntb/ntb_hw.c
> > @@ -45,6 +45,7 @@
> >   * Contact Information:
> >   * Jon Mason <jon.mason@intel.com>
> >   */
> > +#include <asm-generic/io-64-nonatomic-hi-lo.h>
> 
> Really?  This seems really odd.  Usually we just don't build the code
> for any platform that doesn't have readq/writeq.  Otherwise, shouldn't
> those arches just include this file themselves to keep everything
> working?  Individual drivers shouldn't have to do this.

There is no readq/writeq for 32bit x86.  I was using this header file
to get around that.  I freely admit that I have done 0 testing on
32bit, but it should work.  If you prefer I modify the Kconfig to only
enable this for x86_64 until such time as I test on x86_32, I will
happily submit that patch.

Thanks,
Jon

> 
> So, I'm not going to take this one just yet, sorry.
> 
> greg k-h

^ permalink raw reply

* Re: [PATCH 1/2] net: fec: refactor dt probing
From: Baruch Siach @ 2013-01-21 17:48 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: netdev, shawn.guo, davem, linux-arm-kernel
In-Reply-To: <1358757475-21035-2-git-send-email-s.hauer@pengutronix.de>

Hi Sascha,

On Mon, Jan 21, 2013 at 09:37:54AM +0100, Sascha Hauer wrote:
> For devicetree parsing only the fec_get_phy_mode_dt() is
> available. Rename it to fec_probe_dt() to be able to add more devicetree
> parsing to it.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---

[...]

> -static int fec_get_phy_mode_dt(struct platform_device *pdev)
> +static int fec_probe_dt(struct fec_enet_private *fep)
>  {
> -	struct device_node *np = pdev->dev.of_node;
> +	struct device_node *np = fep->pdev->dev.of_node;
>  
> -	if (np)
> -		return of_get_phy_mode(np);
> +	if (!np)
> +		return -ENODEV;
> +
> +	fep->phy_interface = of_get_phy_mode(np);
>  
>  	return -ENODEV;

Maybe return fep->phy_interface?

baruch

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -

^ permalink raw reply


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