aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>2013-01-21 01:48:53 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-21 13:33:16 -0500
commit5f5a0115635bf678d267cbc72169a718e8724d03 (patch)
tree47c31f8e6df98e55ef45351433ad577e992c82b9
parent2ce13576144ade3e9340efce9620a6dd338aedc7 (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.c33
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
146static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, 146static 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
168static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, 167static 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
1382static u8 *ndisc_fill_redirect_hdr_option(u8 *opt, struct sk_buff *orig_skb, 1381static 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
1395void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) 1395void 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,