diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:49:40 -0500 |
commit | 0191b625ca5a46206d2fb862bb08f36f2fcb3b31 (patch) | |
tree | 454d1842b1833d976da62abcbd5c47521ebe9bd7 /net/ipv6/ndisc.c | |
parent | 54a696bd07c14d3b1192d03ce7269bc59b45209a (diff) | |
parent | eb56092fc168bf5af199d47af50c0d84a96db898 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1429 commits)
net: Allow dependancies of FDDI & Tokenring to be modular.
igb: Fix build warning when DCA is disabled.
net: Fix warning fallout from recent NAPI interface changes.
gro: Fix potential use after free
sfc: If AN is enabled, always read speed/duplex from the AN advertising bits
sfc: When disabling the NIC, close the device rather than unregistering it
sfc: SFT9001: Add cable diagnostics
sfc: Add support for multiple PHY self-tests
sfc: Merge top-level functions for self-tests
sfc: Clean up PHY mode management in loopback self-test
sfc: Fix unreliable link detection in some loopback modes
sfc: Generate unique names for per-NIC workqueues
802.3ad: use standard ethhdr instead of ad_header
802.3ad: generalize out mac address initializer
802.3ad: initialize ports LACPDU from const initializer
802.3ad: remove typedef around ad_system
802.3ad: turn ports is_individual into a bool
802.3ad: turn ports is_enabled into a bool
802.3ad: make ntt bool
ixgbe: Fix set_ringparam in ixgbe to use the same memory pools.
...
Fixed trivial IPv4/6 address printing conflicts in fs/cifs/connect.c due
to the conversion to %pI (in this networking merge) and the addition of
doing IPv6 addresses (from the earlier merge of CIFS).
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r-- | net/ipv6/ndisc.c | 105 |
1 files changed, 70 insertions, 35 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d0f54d18e19b..3e2970841bd8 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -437,38 +437,20 @@ static void pndisc_destructor(struct pneigh_entry *n) | |||
437 | ipv6_dev_mc_dec(dev, &maddr); | 437 | ipv6_dev_mc_dec(dev, &maddr); |
438 | } | 438 | } |
439 | 439 | ||
440 | /* | 440 | struct sk_buff *ndisc_build_skb(struct net_device *dev, |
441 | * Send a Neighbour Advertisement | 441 | const struct in6_addr *daddr, |
442 | */ | 442 | const struct in6_addr *saddr, |
443 | static void __ndisc_send(struct net_device *dev, | 443 | struct icmp6hdr *icmp6h, |
444 | struct neighbour *neigh, | 444 | const struct in6_addr *target, |
445 | const struct in6_addr *daddr, | 445 | int llinfo) |
446 | const struct in6_addr *saddr, | ||
447 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
448 | int llinfo) | ||
449 | { | 446 | { |
450 | struct flowi fl; | ||
451 | struct dst_entry *dst; | ||
452 | struct net *net = dev_net(dev); | 447 | struct net *net = dev_net(dev); |
453 | struct sock *sk = net->ipv6.ndisc_sk; | 448 | struct sock *sk = net->ipv6.ndisc_sk; |
454 | struct sk_buff *skb; | 449 | struct sk_buff *skb; |
455 | struct icmp6hdr *hdr; | 450 | struct icmp6hdr *hdr; |
456 | struct inet6_dev *idev; | ||
457 | int len; | 451 | int len; |
458 | int err; | 452 | int err; |
459 | u8 *opt, type; | 453 | u8 *opt; |
460 | |||
461 | type = icmp6h->icmp6_type; | ||
462 | |||
463 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
464 | |||
465 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
466 | if (!dst) | ||
467 | return; | ||
468 | |||
469 | err = xfrm_lookup(&dst, &fl, NULL, 0); | ||
470 | if (err < 0) | ||
471 | return; | ||
472 | 454 | ||
473 | if (!dev->addr_len) | 455 | if (!dev->addr_len) |
474 | llinfo = 0; | 456 | llinfo = 0; |
@@ -485,8 +467,7 @@ static void __ndisc_send(struct net_device *dev, | |||
485 | ND_PRINTK0(KERN_ERR | 467 | ND_PRINTK0(KERN_ERR |
486 | "ICMPv6 ND: %s() failed to allocate an skb.\n", | 468 | "ICMPv6 ND: %s() failed to allocate an skb.\n", |
487 | __func__); | 469 | __func__); |
488 | dst_release(dst); | 470 | return NULL; |
489 | return; | ||
490 | } | 471 | } |
491 | 472 | ||
492 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 473 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
@@ -510,9 +491,45 @@ static void __ndisc_send(struct net_device *dev, | |||
510 | 491 | ||
511 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, | 492 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, |
512 | IPPROTO_ICMPV6, | 493 | IPPROTO_ICMPV6, |
513 | csum_partial((__u8 *) hdr, | 494 | csum_partial(hdr, |
514 | len, 0)); | 495 | len, 0)); |
515 | 496 | ||
497 | return skb; | ||
498 | } | ||
499 | |||
500 | EXPORT_SYMBOL(ndisc_build_skb); | ||
501 | |||
502 | void ndisc_send_skb(struct sk_buff *skb, | ||
503 | struct net_device *dev, | ||
504 | struct neighbour *neigh, | ||
505 | const struct in6_addr *daddr, | ||
506 | const struct in6_addr *saddr, | ||
507 | struct icmp6hdr *icmp6h) | ||
508 | { | ||
509 | struct flowi fl; | ||
510 | struct dst_entry *dst; | ||
511 | struct net *net = dev_net(dev); | ||
512 | struct sock *sk = net->ipv6.ndisc_sk; | ||
513 | struct inet6_dev *idev; | ||
514 | int err; | ||
515 | u8 type; | ||
516 | |||
517 | type = icmp6h->icmp6_type; | ||
518 | |||
519 | icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); | ||
520 | |||
521 | dst = icmp6_dst_alloc(dev, neigh, daddr); | ||
522 | if (!dst) { | ||
523 | kfree_skb(skb); | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); | ||
528 | if (err < 0) { | ||
529 | kfree_skb(skb); | ||
530 | return; | ||
531 | } | ||
532 | |||
516 | skb->dst = dst; | 533 | skb->dst = dst; |
517 | 534 | ||
518 | idev = in6_dev_get(dst->dev); | 535 | idev = in6_dev_get(dst->dev); |
@@ -529,6 +546,27 @@ static void __ndisc_send(struct net_device *dev, | |||
529 | in6_dev_put(idev); | 546 | in6_dev_put(idev); |
530 | } | 547 | } |
531 | 548 | ||
549 | EXPORT_SYMBOL(ndisc_send_skb); | ||
550 | |||
551 | /* | ||
552 | * Send a Neighbour Discover packet | ||
553 | */ | ||
554 | static void __ndisc_send(struct net_device *dev, | ||
555 | struct neighbour *neigh, | ||
556 | const struct in6_addr *daddr, | ||
557 | const struct in6_addr *saddr, | ||
558 | struct icmp6hdr *icmp6h, const struct in6_addr *target, | ||
559 | int llinfo) | ||
560 | { | ||
561 | struct sk_buff *skb; | ||
562 | |||
563 | skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo); | ||
564 | if (!skb) | ||
565 | return; | ||
566 | |||
567 | ndisc_send_skb(skb, dev, neigh, daddr, saddr, icmp6h); | ||
568 | } | ||
569 | |||
532 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | 570 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, |
533 | const struct in6_addr *daddr, | 571 | const struct in6_addr *daddr, |
534 | const struct in6_addr *solicited_addr, | 572 | const struct in6_addr *solicited_addr, |
@@ -647,11 +685,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
647 | 685 | ||
648 | if ((probes -= neigh->parms->ucast_probes) < 0) { | 686 | if ((probes -= neigh->parms->ucast_probes) < 0) { |
649 | if (!(neigh->nud_state & NUD_VALID)) { | 687 | if (!(neigh->nud_state & NUD_VALID)) { |
650 | ND_PRINTK1(KERN_DEBUG | 688 | ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: %pI6\n", |
651 | "%s(): trying to ucast probe in NUD_INVALID: " | 689 | __func__, target); |
652 | NIP6_FMT "\n", | ||
653 | __func__, | ||
654 | NIP6(*target)); | ||
655 | } | 690 | } |
656 | ndisc_send_ns(dev, neigh, target, target, saddr); | 691 | ndisc_send_ns(dev, neigh, target, target, saddr); |
657 | } else if ((probes -= neigh->parms->app_probes) < 0) { | 692 | } else if ((probes -= neigh->parms->app_probes) < 0) { |
@@ -1494,7 +1529,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1494 | if (dst == NULL) | 1529 | if (dst == NULL) |
1495 | return; | 1530 | return; |
1496 | 1531 | ||
1497 | err = xfrm_lookup(&dst, &fl, NULL, 0); | 1532 | err = xfrm_lookup(net, &dst, &fl, NULL, 0); |
1498 | if (err) | 1533 | if (err) |
1499 | return; | 1534 | return; |
1500 | 1535 | ||
@@ -1582,7 +1617,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
1582 | 1617 | ||
1583 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, | 1618 | icmph->icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, |
1584 | len, IPPROTO_ICMPV6, | 1619 | len, IPPROTO_ICMPV6, |
1585 | csum_partial((u8 *) icmph, len, 0)); | 1620 | csum_partial(icmph, len, 0)); |
1586 | 1621 | ||
1587 | buff->dst = dst; | 1622 | buff->dst = dst; |
1588 | idev = in6_dev_get(dst->dev); | 1623 | idev = in6_dev_get(dst->dev); |