* Re: [GIT PULL net-next] NDISC Updates (sender-side clean-up)
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
@ 2012-12-17 22:31 ` David Miller
2012-12-18 10:52 ` [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers YOSHIFUJI Hideaki
` (16 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: David Miller @ 2012-12-17 22:31 UTC (permalink / raw)
To: yoshfuji; +Cc: netdev
Sorry, you cannot just send a pull request without posting
the patches as well for people to review.
I'm not pulling from your tree without any posting of the
patches for review.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
2012-12-17 22:31 ` David Miller
@ 2012-12-18 10:52 ` YOSHIFUJI Hideaki
2012-12-19 0:23 ` David Miller
2012-12-18 10:52 ` [GIT PULL net-next 02/17] ipv6: Introduce __ip6_hdr() for setting IPv6 header YOSHIFUJI Hideaki
` (15 subsequent siblings)
17 siblings, 1 reply; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:52 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
We used to allocate MAX_HEADER bytes more than needed but
reserved hlen only (not MAX_HEADER + hlen) and the MAX_HEADER
was left behind.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f2a007b..a1d2a45 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -395,8 +395,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
len += ndisc_opt_addr_space(dev);
skb = sock_alloc_send_skb(sk,
- (MAX_HEADER + sizeof(struct ipv6hdr) +
- len + hlen + tlen),
+ hlen + sizeof(struct ipv6hdr) + len + tlen,
1, &err);
if (!skb) {
ND_PRINTK(0, err, "ND: %s failed to allocate an skb, err=%d\n",
@@ -1422,8 +1421,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom;
buff = sock_alloc_send_skb(sk,
- (MAX_HEADER + sizeof(struct ipv6hdr) +
- len + hlen + tlen),
+ hlen + sizeof(struct ipv6hdr) + len + tlen,
1, &err);
if (buff == NULL) {
ND_PRINTK(0, err,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers.
2012-12-18 10:52 ` [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers YOSHIFUJI Hideaki
@ 2012-12-19 0:23 ` David Miller
2012-12-19 0:24 ` David Miller
2012-12-19 3:08 ` YOSHIFUJI Hideaki
0 siblings, 2 replies; 27+ messages in thread
From: David Miller @ 2012-12-19 0:23 UTC (permalink / raw)
To: yoshfuji; +Cc: netdev
From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Date: Tue, 18 Dec 2012 19:52:04 +0900
> We used to allocate MAX_HEADER bytes more than needed but
> reserved hlen only (not MAX_HEADER + hlen) and the MAX_HEADER
> was left behind.
>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
This change is wrong.
The MAX_HEADER is being used in order to accomodate any
possible encapsulation that may occur.
I'm really disappointed that the very first patch in this series is
buggy, and you didn't even bother to repost the absolutely required
"00/17" email for this series which is where you're supposed to give a
top-level overview of your changes as well as any GIT pull request.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers.
2012-12-19 0:23 ` David Miller
@ 2012-12-19 0:24 ` David Miller
2012-12-19 3:00 ` YOSHIFUJI Hideaki
2012-12-19 3:08 ` YOSHIFUJI Hideaki
1 sibling, 1 reply; 27+ messages in thread
From: David Miller @ 2012-12-19 0:24 UTC (permalink / raw)
To: yoshfuji; +Cc: netdev
From: David Miller <davem@davemloft.net>
Date: Tue, 18 Dec 2012 16:23:38 -0800 (PST)
> I'm really disappointed that the very first patch in this series is
> buggy, and you didn't even bother to repost the absolutely required
> "00/17" email for this series which is where you're supposed to give a
> top-level overview of your changes as well as any GIT pull request.
Also, right now the net-next tree is not open, so these changes
aren't even appropriate to be submitting right now.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers.
2012-12-19 0:24 ` David Miller
@ 2012-12-19 3:00 ` YOSHIFUJI Hideaki
0 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-19 3:00 UTC (permalink / raw)
To: David Miller; +Cc: netdev
David Miller wrote:
> From: David Miller <davem@davemloft.net>
> Date: Tue, 18 Dec 2012 16:23:38 -0800 (PST)
>
>> I'm really disappointed that the very first patch in this series is
>> buggy, and you didn't even bother to repost the absolutely required
>> "00/17" email for this series which is where you're supposed to give a
>> top-level overview of your changes as well as any GIT pull request.
>
> Also, right now the net-next tree is not open, so these changes
> aren't even appropriate to be submitting right now.
Sorry about this, and I'll repost later.
--yoshfuji
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers.
2012-12-19 0:23 ` David Miller
2012-12-19 0:24 ` David Miller
@ 2012-12-19 3:08 ` YOSHIFUJI Hideaki
1 sibling, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-19 3:08 UTC (permalink / raw)
To: David Miller; +Cc: netdev, YOSHIFUJI Hideaki
David Miller wrote:
> From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> Date: Tue, 18 Dec 2012 19:52:04 +0900
>
>> We used to allocate MAX_HEADER bytes more than needed but
>> reserved hlen only (not MAX_HEADER + hlen) and the MAX_HEADER
>> was left behind.
>>
>> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
>
> This change is wrong.
>
> The MAX_HEADER is being used in order to accomodate any
> possible encapsulation that may occur.
As I tried to explain in the commit message, ndisc_build_skb() does tI would say his:
| int hlen = LL_RESERVED_SPACE(dev);
:
| skb = sock_alloc_send_skb(sk,
| (MAX_HEADER + 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);
| return NULL;
| }
|
| skb_reserve(skb, hlen);
This means, MAX_HEADER has been placed at the TAIL of
the buffer, instead of the HEAD of the buffer, like this.
head data tail end
+--------------------------------------------------------------+
+ | | | |
+--------------------------------------------------------------+
|<- hlen ->|<---ipv6 packet------>|<--tlen-->|<--MAX_HEADER-->|
| = LL_
RESERVED_
SPACE(dev)
MAX_HEADER will not be used at all and I would say it is waste of
memory.
Or do you expect something like this?
+--------------------------------------------------------------+
+ | | | |
+--------------------------------------------------------------+
|<--MAX_HEADER-->|<---hlen-->|<---ipv6 packet------>|<--tlen-->|
head data tail end
or like this:
+--------------------------------------------------+
+ | | |
+--------------------------------------------------+
|<--MAX_HEADER-->|<---ipv6 packet------>|<--tlen-->|
head data tail end
If so, we should (re)visit almost all users of
sock_alloc_send_skb() and friends, anyway, I think.
--yoshfuji
^ permalink raw reply [flat|nested] 27+ messages in thread
* [GIT PULL net-next 02/17] ipv6: Introduce __ip6_hdr() for setting IPv6 header.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
2012-12-17 22:31 ` David Miller
2012-12-18 10:52 ` [GIT PULL net-next 01/17] ndisc: Fix size calculation for headers YOSHIFUJI Hideaki
@ 2012-12-18 10:52 ` YOSHIFUJI Hideaki
2012-12-18 10:53 ` [GIT PULL net-next 03/17] ndisc: Introduce struct red_msg for redirect message YOSHIFUJI Hideaki
` (14 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:52 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
include/net/ipv6.h | 15 +++++++++++++++
net/ipv6/ip6_gre.c | 18 ++++++------------
net/ipv6/ip6_output.c | 26 +++++---------------------
net/ipv6/ip6_tunnel.c | 12 +++++-------
4 files changed, 31 insertions(+), 40 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 5af66b2..710bf2b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -622,6 +622,21 @@ extern int ip6_mc_input(struct sk_buff *skb);
extern int __ip6_local_out(struct sk_buff *skb);
extern int ip6_local_out(struct sk_buff *skb);
+static inline void __ip6_hdr(struct ipv6hdr *hdr,
+ unsigned int tclass,
+ __be32 flowlabel,
+ unsigned int proto,
+ unsigned int hoplimit,
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr)
+{
+ *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
+ hdr->nexthdr = proto;
+ hdr->hop_limit = hoplimit;
+ hdr->saddr = *saddr;
+ hdr->daddr = *daddr;
+}
+
/*
* Extension header (options) processing
*/
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 867466c..d91deaa 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -773,13 +773,10 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
* Push down and install the IP header.
*/
ipv6h = ipv6_hdr(skb);
- *(__be32 *)ipv6h = fl6->flowlabel | htonl(0x60000000);
- dsfield = INET_ECN_encapsulate(0, dsfield);
- ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
- ipv6h->hop_limit = tunnel->parms.hop_limit;
- ipv6h->nexthdr = proto;
- ipv6h->saddr = fl6->saddr;
- ipv6h->daddr = fl6->daddr;
+
+ __ip6_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield),
+ fl6->flowlabel, proto, tunnel->parms.hop_limit,
+ &fl6->saddr, &fl6->daddr);
((__be16 *)(ipv6h + 1))[0] = tunnel->parms.o_flags;
((__be16 *)(ipv6h + 1))[1] = (dev->type == ARPHRD_ETHER) ?
@@ -1241,11 +1238,8 @@ static int ip6gre_header(struct sk_buff *skb, struct net_device *dev,
struct ipv6hdr *ipv6h = (struct ipv6hdr *)skb_push(skb, t->hlen);
__be16 *p = (__be16 *)(ipv6h+1);
- *(__be32 *)ipv6h = t->fl.u.ip6.flowlabel | htonl(0x60000000);
- ipv6h->hop_limit = t->parms.hop_limit;
- ipv6h->nexthdr = NEXTHDR_GRE;
- ipv6h->saddr = t->parms.laddr;
- ipv6h->daddr = t->parms.raddr;
+ __ip6_hdr(ipv6h, 0, t->fl.u.ip6.flowlabel, NEXTHDR_GRE,
+ t->parms.hop_limit, &t->parms.laddr, &t->parms.raddr);
p[0] = t->parms.o_flags;
p[1] = htons(type);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 5552d13..8c597b3 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -216,14 +216,9 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
if (hlimit < 0)
hlimit = ip6_dst_hoplimit(dst);
- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
-
+ __ip6_hdr(hdr, tclass, fl6->flowlabel, proto, hlimit,
+ &fl6->saddr, first_hop);
hdr->payload_len = htons(seg_len);
- hdr->nexthdr = proto;
- hdr->hop_limit = hlimit;
-
- hdr->saddr = fl6->saddr;
- hdr->daddr = *first_hop;
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
@@ -267,14 +262,8 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
skb_put(skb, sizeof(struct ipv6hdr));
hdr = ipv6_hdr(skb);
- *(__be32*)hdr = htonl(0x60000000);
-
+ __ip6_hdr(hdr, 0, 0, proto, np->hop_limit, saddr, daddr);
hdr->payload_len = htons(len);
- hdr->nexthdr = proto;
- hdr->hop_limit = np->hop_limit;
-
- hdr->saddr = *saddr;
- hdr->daddr = *daddr;
return 0;
}
@@ -1548,13 +1537,8 @@ int ip6_push_pending_frames(struct sock *sk)
skb_reset_network_header(skb);
hdr = ipv6_hdr(skb);
- *(__be32*)hdr = fl6->flowlabel |
- htonl(0x60000000 | ((int)np->cork.tclass << 20));
-
- hdr->hop_limit = np->cork.hop_limit;
- hdr->nexthdr = proto;
- hdr->saddr = fl6->saddr;
- hdr->daddr = *final_dst;
+ __ip6_hdr(hdr, np->cork.tclass, fl6->flowlabel, proto,
+ np->cork.hop_limit, &fl6->saddr, final_dst);
skb->priority = sk->sk_priority;
skb->mark = sk->sk_mark;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index a14f28b..28e4bf0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1030,13 +1030,11 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ipv6h = ipv6_hdr(skb);
- *(__be32*)ipv6h = fl6->flowlabel | htonl(0x60000000);
- dsfield = INET_ECN_encapsulate(0, dsfield);
- ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
- ipv6h->hop_limit = t->parms.hop_limit;
- ipv6h->nexthdr = proto;
- ipv6h->saddr = fl6->saddr;
- ipv6h->daddr = fl6->daddr;
+
+ __ip6_hdr(ipv6h, INET_ECN_encapsulate(0, dsfield),
+ fl6->flowlabel, proto, t->parms.hop_limit,
+ &fl6->saddr, &fl6->daddr);
+
nf_reset(skb);
pkt_len = skb->len;
err = ip6_local_out(skb);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 03/17] ndisc: Introduce struct red_msg for redirect message.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (2 preceding siblings ...)
2012-12-18 10:52 ` [GIT PULL net-next 02/17] ipv6: Introduce __ip6_hdr() for setting IPv6 header YOSHIFUJI Hideaki
@ 2012-12-18 10:53 ` YOSHIFUJI Hideaki
2012-12-18 10:54 ` [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option() YOSHIFUJI Hideaki
` (13 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:53 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
include/net/ndisc.h | 7 +++++++
net/ipv6/ndisc.c | 25 +++++++++++--------------
net/ipv6/route.c | 24 ++++++++++--------------
3 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 7af1ea8..a7df01d 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -78,6 +78,13 @@ struct ra_msg {
__be32 retrans_timer;
};
+struct red_msg {
+ struct icmp6hdr icmph;
+ struct in6_addr target;
+ struct in6_addr dest;
+ __u8 opt[0];
+};
+
struct nd_opt_hdr {
__u8 nd_opt_type;
__u8 nd_opt_len;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a1d2a45..a181113 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1337,12 +1337,11 @@ 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 icmp6hdr) + 2 * sizeof(struct in6_addr);
+ int len = sizeof(struct red_msg);
struct inet_peer *peer;
struct sk_buff *buff;
- struct icmp6hdr *icmph;
+ struct red_msg *msg;
struct in6_addr saddr_buf;
- struct in6_addr *addrp;
struct rt6_info *rt;
struct dst_entry *dst;
struct inet6_dev *idev;
@@ -1436,21 +1435,19 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data);
skb_put(buff, len);
- icmph = icmp6_hdr(buff);
+ msg = (struct red_msg *)icmp6_hdr(buff);
- memset(icmph, 0, sizeof(struct icmp6hdr));
- icmph->icmp6_type = NDISC_REDIRECT;
+ memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
+ msg->icmph.icmp6_type = NDISC_REDIRECT;
/*
* copy target and destination addresses
*/
- addrp = (struct in6_addr *)(icmph + 1);
- *addrp = *target;
- addrp++;
- *addrp = ipv6_hdr(skb)->daddr;
+ msg->target = *target;
+ msg->dest = ipv6_hdr(skb)->daddr;
- opt = (u8*) (addrp + 1);
+ opt = msg->opt;
/*
* include target_address option
@@ -1471,9 +1468,9 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
memcpy(opt, ipv6_hdr(skb), rd_len - 8);
- icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
- len, IPPROTO_ICMPV6,
- csum_partial(icmph, len, 0));
+ msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr,
+ len, IPPROTO_ICMPV6,
+ csum_partial(msg, len, 0));
skb_dst_set(buff, dst);
rcu_read_lock();
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index e229a3b..ec31862 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1705,37 +1705,33 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
struct net *net = dev_net(skb->dev);
struct netevent_redirect netevent;
struct rt6_info *rt, *nrt = NULL;
- const struct in6_addr *target;
struct ndisc_options ndopts;
- const struct in6_addr *dest;
struct neighbour *old_neigh;
struct inet6_dev *in6_dev;
struct neighbour *neigh;
- struct icmp6hdr *icmph;
+ struct red_msg *msg;
int optlen, on_link;
u8 *lladdr;
optlen = skb->tail - skb->transport_header;
- optlen -= sizeof(struct icmp6hdr) + 2 * sizeof(struct in6_addr);
+ optlen -= sizeof(*msg);
if (optlen < 0) {
net_dbg_ratelimited("rt6_do_redirect: packet too short\n");
return;
}
- icmph = icmp6_hdr(skb);
- target = (const struct in6_addr *) (icmph + 1);
- dest = target + 1;
+ msg = (struct red_msg *)icmp6_hdr(skb);
- if (ipv6_addr_is_multicast(dest)) {
+ if (ipv6_addr_is_multicast(&msg->dest)) {
net_dbg_ratelimited("rt6_do_redirect: destination address is multicast\n");
return;
}
on_link = 0;
- if (ipv6_addr_equal(dest, target)) {
+ if (ipv6_addr_equal(&msg->dest, &msg->target)) {
on_link = 1;
- } else if (ipv6_addr_type(target) !=
+ } else if (ipv6_addr_type(&msg->target) !=
(IPV6_ADDR_UNICAST|IPV6_ADDR_LINKLOCAL)) {
net_dbg_ratelimited("rt6_do_redirect: target address is not link-local unicast\n");
return;
@@ -1752,7 +1748,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
* first-hop router for the specified ICMP Destination Address.
*/
- if (!ndisc_parse_options((u8*)(dest + 1), optlen, &ndopts)) {
+ if (!ndisc_parse_options(msg->opt, optlen, &ndopts)) {
net_dbg_ratelimited("rt6_redirect: invalid ND options\n");
return;
}
@@ -1779,7 +1775,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
*/
dst_confirm(&rt->dst);
- neigh = __neigh_lookup(&nd_tbl, target, skb->dev, 1);
+ neigh = __neigh_lookup(&nd_tbl, &msg->target, skb->dev, 1);
if (!neigh)
return;
@@ -1799,7 +1795,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
NEIGH_UPDATE_F_ISROUTER))
);
- nrt = ip6_rt_copy(rt, dest);
+ nrt = ip6_rt_copy(rt, &msg->dest);
if (!nrt)
goto out;
@@ -1817,7 +1813,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
netevent.old_neigh = old_neigh;
netevent.new = &nrt->dst;
netevent.new_neigh = neigh;
- netevent.daddr = dest;
+ netevent.daddr = &msg->dest;
call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
if (rt->rt6i_flags & RTF_CACHE) {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (3 preceding siblings ...)
2012-12-18 10:53 ` [GIT PULL net-next 03/17] ndisc: Introduce struct red_msg for redirect message YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-19 3:08 ` YOSHIFUJI Hideaki
2012-12-19 11:47 ` Bjørn Mork
2012-12-18 10:54 ` [GIT PULL net-next 05/17] ndisc: Rename and break up __ndisc_send() YOSHIFUJI Hideaki
` (12 subsequent siblings)
17 siblings, 2 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 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 a181113..0a4f3a9 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1332,6 +1332,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;
+}
+
void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
{
struct net_device *dev = skb->dev;
@@ -1461,12 +1474,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 [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option().
2012-12-18 10:54 ` [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option() YOSHIFUJI Hideaki
@ 2012-12-19 3:08 ` YOSHIFUJI Hideaki
2012-12-19 11:47 ` Bjørn Mork
1 sibling, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-19 3:08 UTC (permalink / raw)
To: 'netdev@vger.kernel.org', David Miller; +Cc: YOSHIFUJI Hideaki
YOSHIFUJI Hideaki wrote:
> 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 a181113..0a4f3a9 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -1332,6 +1332,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;
> +}
> +
> void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
> {
> struct net_device *dev = skb->dev;
By the way, is it really safe to use memcpy here?
Should we use skb_copy_bits() instead?
--yoshfuji
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option().
2012-12-18 10:54 ` [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option() YOSHIFUJI Hideaki
2012-12-19 3:08 ` YOSHIFUJI Hideaki
@ 2012-12-19 11:47 ` Bjørn Mork
2012-12-19 16:25 ` YOSHIFUJI Hideaki
1 sibling, 1 reply; 27+ messages in thread
From: Bjørn Mork @ 2012-12-19 11:47 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: davem, netdev
YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> writes:
> 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 a181113..0a4f3a9 100644
> --- a/net/ipv6/ndisc.c
> +++ b/net/ipv6/ndisc.c
> @@ -1332,6 +1332,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;
> +}
> +
I realize that it doesn't currently matter, but the above modification
of "opt" looks like a bug-waiting-to-happen to me.
> void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
> {
> struct net_device *dev = skb->dev;
> @@ -1461,12 +1474,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);
I understand that opt isn't currently used after this, but if it ever is
then it is going to come as big a surprise that this implies opt += 8;
This was previously quite clear when the code was inline, but it becomes
problematic when it is factored out.
Bjørn
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option().
2012-12-19 11:47 ` Bjørn Mork
@ 2012-12-19 16:25 ` YOSHIFUJI Hideaki
2012-12-19 17:27 ` YOSHIFUJI Hideaki
0 siblings, 1 reply; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-19 16:25 UTC (permalink / raw)
To: Bjørn Mork; +Cc: davem, netdev, YOSHIFUJI Hideaki
Bjørn Mork wrote:
> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> writes:
>
>> 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 a181113..0a4f3a9 100644
>> --- a/net/ipv6/ndisc.c
>> +++ b/net/ipv6/ndisc.c
>> @@ -1332,6 +1332,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;
>> +}
>> +
>
> I realize that it doesn't currently matter, but the above modification
> of "opt" looks like a bug-waiting-to-happen to me.
>
>> void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
>> {
>> struct net_device *dev = skb->dev;
>> @@ -1461,12 +1474,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);
>
>
> I understand that opt isn't currently used after this, but if it ever is
> then it is going to come as big a surprise that this implies opt += 8;
>
> This was previously quite clear when the code was inline, but it becomes
> problematic when it is factored out.
I understand your concern. opt will be disappeared by following
changeset (12 of 17).
--yoshfuji
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option().
2012-12-19 16:25 ` YOSHIFUJI Hideaki
@ 2012-12-19 17:27 ` YOSHIFUJI Hideaki
0 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-19 17:27 UTC (permalink / raw)
To: Bjørn Mork; +Cc: YOSHIFUJI Hideaki, davem, netdev
(2012年12月20日 01:25), YOSHIFUJI Hideaki wrote:
> Bjørn Mork wrote:
>> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> writes:
>>> +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;
>>> +}
:
>> I understand that opt isn't currently used after this, but if it ever is
>> then it is going to come as big a surprise that this implies opt += 8;
>>
>> This was previously quite clear when the code was inline, but it becomes
>> problematic when it is factored out.
>
> I understand your concern. opt will be disappeared by following
> changeset (12 of 17).
Argh, I now notice return value was not quite right; it should
return opt + rd_len - 8.
Fixed in my local tree. Thanks.
--yoshfuji
^ permalink raw reply [flat|nested] 27+ messages in thread
* [GIT PULL net-next 05/17] ndisc: Rename and break up __ndisc_send().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (4 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 04/17] ndisc: Introduce ndisc_fill_redirect_hdr_option() YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-18 10:54 ` [GIT PULL net-next 06/17] ndisc: Introduce ndisc_send_skb_alloc() for sk_buff allocation YOSHIFUJI Hideaki
` (11 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Rename (old) __ndisc_send() to ndisc_send() and create new
__ndisc_send() for more trivial work without dst_entry allocation.
Use new __ndisc_send() for redirect.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 81 ++++++++++++++++++++++--------------------------------
1 file changed, 33 insertions(+), 48 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0a4f3a9..a293676 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -430,28 +430,13 @@ 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,
- struct neighbour *neigh,
- const struct in6_addr *daddr,
- const struct in6_addr *saddr,
- struct icmp6hdr *icmp6h)
+static void __ndisc_send(struct sk_buff *skb, struct dst_entry *dst)
{
- struct flowi6 fl6;
- struct dst_entry *dst;
- struct net *net = dev_net(dev);
- struct sock *sk = net->ipv6.ndisc_sk;
+ struct net *net = dev_net(dst->dev);
struct inet6_dev *idev;
+ struct icmp6hdr *icmp6h = icmp6_hdr(skb);
+ u8 type = icmp6h->icmp6_type;
int err;
- u8 type;
-
- type = icmp6h->icmp6_type;
-
- icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
- dst = icmp6_dst_alloc(dev, neigh, &fl6);
- if (IS_ERR(dst)) {
- kfree_skb(skb);
- return;
- }
skb_dst_set(skb, dst);
@@ -472,20 +457,32 @@ static void ndisc_send_skb(struct sk_buff *skb, struct net_device *dev,
/*
* Send a Neighbour Discover packet
*/
-static void __ndisc_send(struct net_device *dev,
- struct neighbour *neigh,
- const struct in6_addr *daddr,
- const struct in6_addr *saddr,
- struct icmp6hdr *icmp6h, const struct in6_addr *target,
- int llinfo)
+static void ndisc_send(struct net_device *dev,
+ struct neighbour *neigh,
+ const struct in6_addr *daddr,
+ const struct in6_addr *saddr,
+ struct icmp6hdr *icmp6h, const struct in6_addr *target,
+ int llinfo)
{
+ struct flowi6 fl6;
+ struct dst_entry *dst;
+ struct net *net = dev_net(dev);
+ struct sock *sk = net->ipv6.ndisc_sk;
struct sk_buff *skb;
+ u8 type = icmp6h->icmp6_type;
skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo);
if (!skb)
return;
- ndisc_send_skb(skb, dev, neigh, daddr, saddr, icmp6h);
+ icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
+ dst = icmp6_dst_alloc(dev, neigh, &fl6);
+ if (IS_ERR(dst)) {
+ kfree_skb(skb);
+ return;
+ }
+
+ __ndisc_send(skb, dst);
}
static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
@@ -520,9 +517,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
icmp6h.icmp6_solicited = solicited;
icmp6h.icmp6_override = override;
- __ndisc_send(dev, neigh, daddr, src_addr,
- &icmp6h, solicited_addr,
- inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
+ ndisc_send(dev, neigh, daddr, src_addr,
+ &icmp6h, solicited_addr,
+ inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
}
static void ndisc_send_unsol_na(struct net_device *dev)
@@ -562,9 +559,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
saddr = &addr_buf;
}
- __ndisc_send(dev, neigh, daddr, saddr,
- &icmp6h, solicit,
- !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
+ ndisc_send(dev, neigh, daddr, saddr,
+ &icmp6h, solicit,
+ !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
}
void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
@@ -597,9 +594,9 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
}
}
#endif
- __ndisc_send(dev, NULL, daddr, saddr,
- &icmp6h, NULL,
- send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
+ ndisc_send(dev, NULL, daddr, saddr,
+ &icmp6h, NULL,
+ send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
}
@@ -1357,7 +1354,6 @@ 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;
u8 *opt;
int hlen, tlen;
@@ -1481,18 +1477,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
len, IPPROTO_ICMPV6,
csum_partial(msg, len, 0));
- 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(buff, dst);
return;
release:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 06/17] ndisc: Introduce ndisc_send_skb_alloc() for sk_buff allocation.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (5 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 05/17] ndisc: Rename and break up __ndisc_send() YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-18 10:54 ` [GIT PULL net-next 07/17] ipv6: Move ip6_nd_hdr() to its users' source files YOSHIFUJI Hideaki
` (10 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 50 ++++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index a293676..45ce72c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -370,6 +370,28 @@ 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,
@@ -381,10 +403,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)
@@ -394,16 +413,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,
- hlen + sizeof(struct ipv6hdr) + len + 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;
@@ -1356,9 +1369,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
struct dst_entry *dst;
struct flowi6 fl6;
u8 *opt;
- int hlen, tlen;
int rd_len;
- int err;
u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
bool ret;
@@ -1426,19 +1437,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,
- hlen + sizeof(struct ipv6hdr) + len + 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 [flat|nested] 27+ messages in thread
* [GIT PULL net-next 07/17] ipv6: Move ip6_nd_hdr() to its users' source files.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (6 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 06/17] ndisc: Introduce ndisc_send_skb_alloc() for sk_buff allocation YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-18 10:54 ` [GIT PULL net-next 08/17] ndisc: Set skb->dev and skb->protocol inside ndisc_alloc_skb() YOSHIFUJI Hideaki
` (9 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
This also makes return type to void since this function
never fails, and uses hoplimit argument instead of pointer
to struct sock. For ND, it also removes protocol argument.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
include/net/ipv6.h | 7 -------
net/ipv6/ip6_output.c | 27 ---------------------------
net/ipv6/mcast.c | 24 ++++++++++++++++++++++--
net/ipv6/ndisc.c | 24 +++++++++++++++++++++---
4 files changed, 43 insertions(+), 39 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 710bf2b..dcc4b45 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -570,13 +570,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 8c597b3..bb0c4cc 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -241,33 +241,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_hdr(hdr, 0, 0, proto, np->hop_limit, saddr, daddr);
- hdr->payload_len = htons(len);
-
- 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 28dfa5f..7c42776 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1340,6 +1340,24 @@ mld_scount(struct ifmcaddr6 *pmc, int type, int gdeleted, int sdeleted)
return scount;
}
+static void ip6_mc_hdr(struct sk_buff *skb, struct net_device *dev,
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr,
+ int proto, int hoplimit, 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_hdr(hdr, 0, 0, proto, hoplimit, saddr, daddr);
+ hdr->payload_len = htons(len);
+}
+
static struct sk_buff *mld_newpack(struct net_device *dev, int size)
{
struct net *net = dev_net(dev);
@@ -1375,7 +1393,8 @@ 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(skb, dev, saddr, &mld2_all_mcr,
+ NEXTHDR_HOP, inet6_sk(sk)->hop_limit, 0);
memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
@@ -1767,7 +1786,8 @@ 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(skb, dev, saddr, snd_addr, NEXTHDR_HOP,
+ inet6_sk(sk)->hop_limit, payload_len);
memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 45ce72c..f2942f3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -392,6 +392,24 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev,
return skb;
}
+static void ip6_nd_hdr(struct sk_buff *skb, struct net_device *dev,
+ const struct in6_addr *saddr,
+ const struct in6_addr *daddr,
+ int hoplimit, 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_hdr(hdr, 0, 0, IPPROTO_ICMPV6, hoplimit, saddr, daddr);
+ hdr->payload_len = htons(len);
+}
+
static struct sk_buff *ndisc_build_skb(struct net_device *dev,
const struct in6_addr *daddr,
const struct in6_addr *saddr,
@@ -417,7 +435,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);
@@ -1441,8 +1459,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 [flat|nested] 27+ messages in thread
* [GIT PULL net-next 08/17] ndisc: Set skb->dev and skb->protocol inside ndisc_alloc_skb().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (7 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 07/17] ipv6: Move ip6_nd_hdr() to its users' source files YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-18 10:54 ` [GIT PULL net-next 09/17] ndisc: Defer building IPv6 header YOSHIFUJI Hideaki
` (8 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f2942f3..b32f079 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -388,20 +388,18 @@ 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,
- const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- int hoplimit, int len)
+static void ip6_nd_hdr(struct sk_buff *skb, const struct in6_addr *saddr,
+ const struct in6_addr *daddr, int hoplimit, 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);
@@ -435,7 +433,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);
@@ -1459,7 +1457,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 [flat|nested] 27+ messages in thread
* [GIT PULL net-next 09/17] ndisc: Defer building IPv6 header.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (8 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 08/17] ndisc: Set skb->dev and skb->protocol inside ndisc_alloc_skb() YOSHIFUJI Hideaki
@ 2012-12-18 10:54 ` YOSHIFUJI Hideaki
2012-12-18 10:55 ` [GIT PULL net-next 10/17] ndisc: Reset skb->transport_header inside ndisc_alloc_send_skb() YOSHIFUJI Hideaki
` (7 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:54 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Fill out IPv6 header just before sending ND message.
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 b32f079..2ebb2fb 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -391,7 +391,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;
}
@@ -400,8 +400,8 @@ static void ip6_nd_hdr(struct sk_buff *skb, const struct in6_addr *saddr,
{
struct ipv6hdr *hdr;
+ __skb_push(skb, sizeof(*hdr));
skb_reset_network_header(skb);
- skb_put(skb, sizeof(struct ipv6hdr));
hdr = ipv6_hdr(skb);
__ip6_hdr(hdr, 0, 0, IPPROTO_ICMPV6, hoplimit, saddr, daddr);
@@ -433,8 +433,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);
@@ -451,10 +449,12 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
ndisc_fill_addr_option(opt, llinfo, dev->dev_addr,
dev->addr_len, dev->type);
- 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;
}
@@ -1457,9 +1457,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 red_msg *)icmp6_hdr(buff);
@@ -1492,8 +1489,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);
__ndisc_send(buff, dst);
return;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 10/17] ndisc: Reset skb->transport_header inside ndisc_alloc_send_skb().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (9 preceding siblings ...)
2012-12-18 10:54 ` [GIT PULL net-next 09/17] ndisc: Defer building IPv6 header YOSHIFUJI Hideaki
@ 2012-12-18 10:55 ` YOSHIFUJI Hideaki
2012-12-18 10:55 ` [GIT PULL net-next 11/17] ndisc: Calculate message body length and option length separately YOSHIFUJI Hideaki
` (6 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:55 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2ebb2fb..073e52a 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -392,6 +392,8 @@ 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;
}
@@ -433,7 +435,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);
@@ -1457,7 +1458,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 red_msg *)icmp6_hdr(buff);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 11/17] ndisc: Calculate message body length and option length separately.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (10 preceding siblings ...)
2012-12-18 10:55 ` [GIT PULL net-next 10/17] ndisc: Reset skb->transport_header inside ndisc_alloc_send_skb() YOSHIFUJI Hideaki
@ 2012-12-18 10:55 ` YOSHIFUJI Hideaki
2012-12-18 10:55 ` [GIT PULL net-next 12/17] ndisc: Make ndisc_fill_xxx_option() for sk_buff YOSHIFUJI Hideaki
` (5 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:55 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 073e52a..1100559 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -422,6 +422,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)
@@ -429,13 +430,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));
@@ -1377,7 +1378,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 red_msg);
+ int optlen = 0;
struct inet_peer *peer;
struct sk_buff *buff;
struct red_msg *msg;
@@ -1442,7 +1443,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);
@@ -1450,15 +1451,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(struct red_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(struct red_msg) + optlen);
if (!buff)
goto release;
- skb_put(buff, len);
+ skb_put(buff, sizeof(struct red_msg) + optlen);
msg = (struct red_msg *)icmp6_hdr(buff);
memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 12/17] ndisc: Make ndisc_fill_xxx_option() for sk_buff.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (11 preceding siblings ...)
2012-12-18 10:55 ` [GIT PULL net-next 11/17] ndisc: Calculate message body length and option length separately YOSHIFUJI Hideaki
@ 2012-12-18 10:55 ` YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 13/17] ndisc: Calculate checksum and build IPv6 header in __ndisc_send() YOSHIFUJI Hideaki
` (4 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:55 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 1100559..5458aed 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -148,11 +148,12 @@ 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, int data_len,
- unsigned short addr_type)
+static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data)
{
- int pad = ndisc_addr_option_pad(addr_type);
+ int data_len = skb->dev->addr_len;
+ int pad = ndisc_addr_option_pad(skb->dev->type);
int space = NDISC_OPT_SPACE(data_len + pad);
+ u8 *opt = __skb_put(skb, space);
opt[0] = type;
opt[1] = space>>3;
@@ -166,7 +167,6 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
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,
@@ -436,7 +436,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));
@@ -448,8 +448,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev,
}
if (llinfo)
- ndisc_fill_addr_option(opt, llinfo, dev->dev_addr,
- dev->addr_len, dev->type);
+ ndisc_fill_addr_option(skb, llinfo, dev->dev_addr);
hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len,
IPPROTO_ICMPV6,
@@ -1360,17 +1359,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;
}
void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
@@ -1386,7 +1386,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
struct rt6_info *rt;
struct dst_entry *dst;
struct flowi6 fl6;
- u8 *opt;
int rd_len;
u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
bool ret;
@@ -1460,7 +1459,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
if (!buff)
goto release;
- skb_put(buff, sizeof(struct red_msg) + optlen);
+ skb_put(buff, sizeof(struct red_msg));
msg = (struct red_msg *)icmp6_hdr(buff);
memset(&msg->icmph, 0, sizeof(struct icmp6hdr));
@@ -1473,22 +1472,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->addr_len, dev->type);
+ 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 [flat|nested] 27+ messages in thread
* [GIT PULL net-next 13/17] ndisc: Calculate checksum and build IPv6 header in __ndisc_send().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (12 preceding siblings ...)
2012-12-18 10:55 ` [GIT PULL net-next 12/17] ndisc: Make ndisc_fill_xxx_option() for sk_buff YOSHIFUJI Hideaki
@ 2012-12-18 10:56 ` YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 14/17] ndisc: Concentrate ndisc_send() on sending message YOSHIFUJI Hideaki
` (3 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:56 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 5458aed..c0937d3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -417,8 +417,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;
@@ -450,19 +448,15 @@ 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;
}
-static void __ndisc_send(struct sk_buff *skb, struct dst_entry *dst)
+static void __ndisc_send(struct sk_buff *skb, struct dst_entry *dst,
+ const struct in6_addr *daddr,
+ const struct in6_addr *saddr)
{
struct net *net = dev_net(dst->dev);
+ struct sock *sk = net->ipv6.ndisc_sk;
struct inet6_dev *idev;
struct icmp6hdr *icmp6h = icmp6_hdr(skb);
u8 type = icmp6h->icmp6_type;
@@ -470,6 +464,13 @@ static void __ndisc_send(struct sk_buff *skb, struct dst_entry *dst)
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);
@@ -512,7 +513,7 @@ static void ndisc_send(struct net_device *dev,
return;
}
- __ndisc_send(skb, dst);
+ __ndisc_send(skb, dst, daddr, saddr);
}
static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
@@ -1486,14 +1487,7 @@ 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);
-
- __ndisc_send(buff, dst);
+ __ndisc_send(buff, dst, &ipv6_hdr(skb)->saddr, &saddr_buf);
return;
release:
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 14/17] ndisc: Concentrate ndisc_send() on sending message.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (13 preceding siblings ...)
2012-12-18 10:56 ` [GIT PULL net-next 13/17] ndisc: Calculate checksum and build IPv6 header in __ndisc_send() YOSHIFUJI Hideaki
@ 2012-12-18 10:56 ` YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 15/17] ndisc: Break down ndisc_build_skb() YOSHIFUJI Hideaki
` (2 subsequent siblings)
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:56 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Build NDISC message outside ndisc_send() and concentrate the
function sending sk_buff with given destination/source.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 51 ++++++++++++++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 21 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c0937d3..c974d9d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -488,26 +488,20 @@ static void __ndisc_send(struct sk_buff *skb, struct dst_entry *dst,
/*
* Send a Neighbour Discover packet
*/
-static void ndisc_send(struct net_device *dev,
+static void ndisc_send(struct sk_buff *skb,
struct neighbour *neigh,
const struct in6_addr *daddr,
- const struct in6_addr *saddr,
- struct icmp6hdr *icmp6h, const struct in6_addr *target,
- int llinfo)
+ const struct in6_addr *saddr)
{
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 sk_buff *skb;
+ struct icmp6hdr *icmp6h = icmp6_hdr(skb);
u8 type = icmp6h->icmp6_type;
- skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo);
- if (!skb)
- return;
-
- icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
- dst = icmp6_dst_alloc(dev, neigh, &fl6);
+ icmpv6_flow_init(sk, &fl6, type, saddr, daddr, skb->dev->ifindex);
+ dst = icmp6_dst_alloc(skb->dev, neigh, &fl6);
if (IS_ERR(dst)) {
kfree_skb(skb);
return;
@@ -527,6 +521,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
struct icmp6hdr icmp6h = {
.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
};
+ struct sk_buff *skb;
/* for anycast or proxy, solicited_addr != src_addr */
ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
@@ -548,9 +543,13 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
icmp6h.icmp6_solicited = solicited;
icmp6h.icmp6_override = override;
- ndisc_send(dev, neigh, 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, neigh, daddr, src_addr);
}
static void ndisc_send_unsol_na(struct net_device *dev)
@@ -582,6 +581,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
struct icmp6hdr icmp6h = {
.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
};
+ struct sk_buff *skb;
if (saddr == NULL) {
if (ipv6_get_lladdr(dev, &addr_buf,
@@ -590,9 +590,13 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
saddr = &addr_buf;
}
- ndisc_send(dev, neigh, 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, neigh, daddr, saddr);
}
void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
@@ -602,6 +606,7 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
.icmp6_type = NDISC_ROUTER_SOLICITATION,
};
int send_sllao = dev->addr_len;
+ struct sk_buff *skb;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
/*
@@ -625,9 +630,13 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
}
}
#endif
- ndisc_send(dev, NULL, 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, NULL, daddr, saddr);
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 15/17] ndisc: Break down ndisc_build_skb().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (14 preceding siblings ...)
2012-12-18 10:56 ` [GIT PULL net-next 14/17] ndisc: Concentrate ndisc_send() on sending message YOSHIFUJI Hideaki
@ 2012-12-18 10:56 ` YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 16/17] ndisc: Fill in ND message on skb directly YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 17/17] ndisc: Use return value of __skb_put(), instead of icmp6_hdr() YOSHIFUJI Hideaki
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:56 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Split up ndisc_build_skb() into pieces; sk_buff allocation
by ndisc_allocl_skb(), filling out the core message and
options.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 98 ++++++++++++++++++++++++++----------------------------
1 file changed, 48 insertions(+), 50 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index c974d9d..580a2f0 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -410,47 +410,6 @@ static void ip6_nd_hdr(struct sk_buff *skb, const struct in6_addr *saddr,
hdr->payload_len = htons(len);
}
-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(struct sk_buff *skb, struct dst_entry *dst,
const struct in6_addr *daddr,
const struct in6_addr *saddr)
@@ -521,6 +480,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
struct icmp6hdr icmp6h = {
.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
};
+ struct nd_msg *msg;
+ int optlen = 0;
struct sk_buff *skb;
/* for anycast or proxy, solicited_addr != src_addr */
@@ -539,16 +500,27 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
src_addr = &tmpaddr;
}
+ if (!dev->addr_len)
+ inc_opt = 0;
+ if (inc_opt)
+ optlen += ndisc_opt_addr_space(dev);
+
icmp6h.icmp6_router = router;
icmp6h.icmp6_solicited = solicited;
icmp6h.icmp6_override = override;
- 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(struct nd_msg) + optlen);
if (!skb)
return;
+ msg = (struct nd_msg *)__skb_put(skb, sizeof(struct nd_msg));
+ memcpy(msg, &icmp6h, sizeof(icmp6h));
+ msg->target = *solicited_addr;
+
+ if (inc_opt)
+ ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
+ dev->dev_addr);
+
ndisc_send(skb, neigh, daddr, src_addr);
}
@@ -581,6 +553,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
struct icmp6hdr icmp6h = {
.icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
};
+ struct nd_msg *msg;
+ int inc_opt = dev->addr_len;
+ int optlen = 0;
struct sk_buff *skb;
if (saddr == NULL) {
@@ -590,12 +565,23 @@ 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(struct nd_msg) + optlen);
if (!skb)
return;
+ msg = (struct nd_msg *)__skb_put(skb, sizeof(struct nd_msg));
+ memcpy(&msg->icmph, &icmp6h, sizeof(msg->icmph));
+ msg->target = *solicit;
+
+ if (inc_opt)
+ ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
+ dev->dev_addr);
+
ndisc_send(skb, neigh, daddr, saddr);
}
@@ -605,7 +591,9 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
struct icmp6hdr icmp6h = {
.icmp6_type = NDISC_ROUTER_SOLICITATION,
};
+ struct rs_msg *msg;
int send_sllao = dev->addr_len;
+ int optlen = 0;
struct sk_buff *skb;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
@@ -630,12 +618,22 @@ 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(struct rs_msg) + optlen);
if (!skb)
return;
+ msg = (struct rs_msg *)__skb_put(skb, sizeof(struct rs_msg));
+ memcpy(&msg->icmph, &icmp6h, sizeof(msg->icmph));
+
+ if (send_sllao)
+ ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
+ dev->dev_addr);
+
ndisc_send(skb, NULL, daddr, saddr);
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [GIT PULL net-next 16/17] ndisc: Fill in ND message on skb directly.
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (15 preceding siblings ...)
2012-12-18 10:56 ` [GIT PULL net-next 15/17] ndisc: Break down ndisc_build_skb() YOSHIFUJI Hideaki
@ 2012-12-18 10:56 ` YOSHIFUJI Hideaki
2012-12-18 10:56 ` [GIT PULL net-next 17/17] ndisc: Use return value of __skb_put(), instead of icmp6_hdr() YOSHIFUJI Hideaki
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:56 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
Use compound literals to fill out ND message on skb.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
net/ipv6/ndisc.c | 55 +++++++++++++++++++++++++++---------------------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 580a2f0..e614388 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -477,9 +477,6 @@ 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;
struct sk_buff *skb;
@@ -505,17 +502,20 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
if (inc_opt)
optlen += ndisc_opt_addr_space(dev);
- icmp6h.icmp6_router = router;
- icmp6h.icmp6_solicited = solicited;
- icmp6h.icmp6_override = override;
-
skb = ndisc_alloc_skb(dev, sizeof(struct nd_msg) + optlen);
if (!skb)
return;
msg = (struct nd_msg *)__skb_put(skb, sizeof(struct nd_msg));
- memcpy(msg, &icmp6h, sizeof(icmp6h));
- msg->target = *solicited_addr;
+ *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,
@@ -550,9 +550,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
const struct in6_addr *daddr, const struct in6_addr *saddr)
{
struct in6_addr addr_buf;
- struct icmp6hdr icmp6h = {
- .icmp6_type = NDISC_NEIGHBOUR_SOLICITATION,
- };
struct nd_msg *msg;
int inc_opt = dev->addr_len;
int optlen = 0;
@@ -575,8 +572,12 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
return;
msg = (struct nd_msg *)__skb_put(skb, sizeof(struct nd_msg));
- memcpy(&msg->icmph, &icmp6h, sizeof(msg->icmph));
- msg->target = *solicit;
+ *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,
@@ -588,9 +589,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
const struct in6_addr *daddr)
{
- struct icmp6hdr icmp6h = {
- .icmp6_type = NDISC_ROUTER_SOLICITATION,
- };
struct rs_msg *msg;
int send_sllao = dev->addr_len;
int optlen = 0;
@@ -628,7 +626,11 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
return;
msg = (struct rs_msg *)__skb_put(skb, sizeof(struct rs_msg));
- memcpy(&msg->icmph, &icmp6h, sizeof(msg->icmph));
+ *msg = (struct rs_msg) {
+ .icmph = {
+ .icmp6_type = NDISC_ROUTER_SOLICITATION,
+ },
+ };
if (send_sllao)
ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
@@ -1469,16 +1471,13 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
skb_put(buff, sizeof(struct red_msg));
msg = (struct red_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 red_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 [flat|nested] 27+ messages in thread
* [GIT PULL net-next 17/17] ndisc: Use return value of __skb_put(), instead of icmp6_hdr().
2012-12-17 20:46 [GIT PULL net-next] NDISC Updates (sender-side clean-up) YOSHIFUJI Hideaki
` (16 preceding siblings ...)
2012-12-18 10:56 ` [GIT PULL net-next 16/17] ndisc: Fill in ND message on skb directly YOSHIFUJI Hideaki
@ 2012-12-18 10:56 ` YOSHIFUJI Hideaki
17 siblings, 0 replies; 27+ messages in thread
From: YOSHIFUJI Hideaki @ 2012-12-18 10:56 UTC (permalink / raw)
To: davem, netdev; +Cc: yoshfuji
It is safe to use __skb_put() here and it returns buffer for
ICMPv6 header. Let's use it.
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 e614388..232daea 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1469,8 +1469,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
if (!buff)
goto release;
- skb_put(buff, sizeof(struct red_msg));
- msg = (struct red_msg *)icmp6_hdr(buff);
+ msg = (struct red_msg *)__skb_put(buff, sizeof(struct red_msg));
*msg = (struct red_msg) {
.icmph = {
.icmp6_type = NDISC_REDIRECT,
--
1.7.9.5
^ permalink raw reply related [flat|nested] 27+ messages in thread