diff options
author | YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> | 2013-01-21 01:48:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-21 13:33:16 -0500 |
commit | 5f5a0115635bf678d267cbc72169a718e8724d03 (patch) | |
tree | 47c31f8e6df98e55ef45351433ad577e992c82b9 | |
parent | 2ce13576144ade3e9340efce9620a6dd338aedc7 (diff) |
ndisc: Make ndisc_fill_xxx_option() for sk_buff.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/ndisc.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index c2b16ffeb1a8..ed786441bc51 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -143,12 +143,12 @@ struct neigh_table nd_tbl = { | |||
143 | .gc_thresh3 = 1024, | 143 | .gc_thresh3 = 1024, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, | 146 | static void ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data) |
147 | struct net_device *dev) | ||
148 | { | 147 | { |
149 | int pad = ndisc_addr_option_pad(dev->type); | 148 | int pad = ndisc_addr_option_pad(skb->dev->type); |
150 | int data_len = dev->addr_len; | 149 | int data_len = skb->dev->addr_len; |
151 | int space = ndisc_opt_addr_space(dev); | 150 | int space = ndisc_opt_addr_space(skb->dev); |
151 | u8 *opt = skb_put(skb, space); | ||
152 | 152 | ||
153 | opt[0] = type; | 153 | opt[0] = type; |
154 | opt[1] = space>>3; | 154 | opt[1] = space>>3; |
@@ -162,7 +162,6 @@ static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, | |||
162 | opt += data_len; | 162 | opt += data_len; |
163 | if ((space -= data_len) > 0) | 163 | if ((space -= data_len) > 0) |
164 | memset(opt, 0, space); | 164 | memset(opt, 0, space); |
165 | return opt + space; | ||
166 | } | 165 | } |
167 | 166 | ||
168 | static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, | 167 | 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, | |||
440 | if (!skb) | 439 | if (!skb) |
441 | return NULL; | 440 | return NULL; |
442 | 441 | ||
443 | skb_put(skb, len + optlen); | 442 | skb_put(skb, len); |
444 | 443 | ||
445 | hdr = (struct icmp6hdr *)skb_transport_header(skb); | 444 | hdr = (struct icmp6hdr *)skb_transport_header(skb); |
446 | memcpy(hdr, icmp6h, sizeof(*hdr)); | 445 | memcpy(hdr, icmp6h, sizeof(*hdr)); |
@@ -452,7 +451,7 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
452 | } | 451 | } |
453 | 452 | ||
454 | if (llinfo) | 453 | if (llinfo) |
455 | ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev); | 454 | ndisc_fill_addr_option(skb, llinfo, dev->dev_addr); |
456 | 455 | ||
457 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len, | 456 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len, |
458 | IPPROTO_ICMPV6, | 457 | IPPROTO_ICMPV6, |
@@ -1379,17 +1378,18 @@ static void ndisc_redirect_rcv(struct sk_buff *skb) | |||
1379 | icmpv6_notify(skb, NDISC_REDIRECT, 0, 0); | 1378 | icmpv6_notify(skb, NDISC_REDIRECT, 0, 0); |
1380 | } | 1379 | } |
1381 | 1380 | ||
1382 | static u8 *ndisc_fill_redirect_hdr_option(u8 *opt, struct sk_buff *orig_skb, | 1381 | static void ndisc_fill_redirect_hdr_option(struct sk_buff *skb, |
1383 | int rd_len) | 1382 | struct sk_buff *orig_skb, |
1383 | int rd_len) | ||
1384 | { | 1384 | { |
1385 | u8 *opt = skb_put(skb, rd_len); | ||
1386 | |||
1385 | memset(opt, 0, 8); | 1387 | memset(opt, 0, 8); |
1386 | *(opt++) = ND_OPT_REDIRECT_HDR; | 1388 | *(opt++) = ND_OPT_REDIRECT_HDR; |
1387 | *(opt++) = (rd_len >> 3); | 1389 | *(opt++) = (rd_len >> 3); |
1388 | opt += 6; | 1390 | opt += 6; |
1389 | 1391 | ||
1390 | memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); | 1392 | memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); |
1391 | |||
1392 | return opt + rd_len - 8; | ||
1393 | } | 1393 | } |
1394 | 1394 | ||
1395 | void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | 1395 | 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) | |||
1406 | struct dst_entry *dst; | 1406 | struct dst_entry *dst; |
1407 | struct inet6_dev *idev; | 1407 | struct inet6_dev *idev; |
1408 | struct flowi6 fl6; | 1408 | struct flowi6 fl6; |
1409 | u8 *opt; | ||
1410 | int rd_len; | 1409 | int rd_len; |
1411 | int err; | 1410 | int err; |
1412 | u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; | 1411 | 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) | |||
1481 | if (!buff) | 1480 | if (!buff) |
1482 | goto release; | 1481 | goto release; |
1483 | 1482 | ||
1484 | skb_put(buff, sizeof(*msg) + optlen); | 1483 | skb_put(buff, sizeof(*msg)); |
1485 | msg = (struct rd_msg *)icmp6_hdr(buff); | 1484 | msg = (struct rd_msg *)icmp6_hdr(buff); |
1486 | 1485 | ||
1487 | memset(&msg->icmph, 0, sizeof(struct icmp6hdr)); | 1486 | memset(&msg->icmph, 0, sizeof(struct icmp6hdr)); |
@@ -1494,21 +1493,19 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
1494 | msg->target = *target; | 1493 | msg->target = *target; |
1495 | msg->dest = ipv6_hdr(skb)->daddr; | 1494 | msg->dest = ipv6_hdr(skb)->daddr; |
1496 | 1495 | ||
1497 | opt = msg->opt; | ||
1498 | |||
1499 | /* | 1496 | /* |
1500 | * include target_address option | 1497 | * include target_address option |
1501 | */ | 1498 | */ |
1502 | 1499 | ||
1503 | if (ha) | 1500 | if (ha) |
1504 | opt = ndisc_fill_addr_option(opt, ND_OPT_TARGET_LL_ADDR, ha, dev); | 1501 | ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR, ha); |
1505 | 1502 | ||
1506 | /* | 1503 | /* |
1507 | * build redirect option and copy skb over to the new packet. | 1504 | * build redirect option and copy skb over to the new packet. |
1508 | */ | 1505 | */ |
1509 | 1506 | ||
1510 | if (rd_len) | 1507 | if (rd_len) |
1511 | opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len); | 1508 | ndisc_fill_redirect_hdr_option(buff, skb, rd_len); |
1512 | 1509 | ||
1513 | msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, | 1510 | msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, |
1514 | buff->len, IPPROTO_ICMPV6, | 1511 | buff->len, IPPROTO_ICMPV6, |