# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1514 -> 1.1515 # net/ipv6/anycast.c 1.9 -> 1.10 # net/ipv6/ip6_tunnel.c 1.15 -> 1.16 # net/ipv6/datagram.c 1.12 -> 1.13 # net/ipv6/icmp.c 1.45 -> 1.46 # net/ipv6/raw.c 1.46 -> 1.47 # net/ipv6/af_inet6.c 1.58 -> 1.59 # net/ipv6/ndisc.c 1.60 -> 1.61 # net/sctp/ipv6.c 1.49 -> 1.50 # include/net/addrconf.h 1.11 -> 1.12 # net/ipv6/addrconf.c 1.79 -> 1.80 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/01/13 vnuorval@xxxxxxxxxxxxxxxxxxxxxxx 1.1515 # Do strict (interface specific) address checks in ipv6_chk_addr() and ipv6_get_ifaddr() when # doing Neighbor Discovery. This is required by the specification when selecting a source # address for ND messages, and seems logical when doing DAD (for example on a multihomed node). # -------------------------------------------- # diff -Nru a/include/net/addrconf.h b/include/net/addrconf.h --- a/include/net/addrconf.h Tue Jan 13 21:02:08 2004 +++ b/include/net/addrconf.h Tue Jan 13 21:02:08 2004 @@ -59,9 +59,11 @@ extern int addrconf_set_dstaddr(void *arg); extern int ipv6_chk_addr(struct in6_addr *addr, - struct net_device *dev); + struct net_device *dev, + int strict); extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, - struct net_device *dev); + struct net_device *dev, + int strict); extern int ipv6_get_saddr(struct dst_entry *dst, struct in6_addr *daddr, struct in6_addr *saddr); diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/addrconf.c Tue Jan 13 21:02:08 2004 @@ -904,7 +904,7 @@ return cnt; } -int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev) +int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict) { struct inet6_ifaddr * ifp; u8 hash = ipv6_addr_hash(addr); @@ -914,7 +914,7 @@ if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && !(ifp->flags&IFA_F_TENTATIVE)) { if (dev == NULL || ifp->idev->dev == dev || - !(ifp->scope&(IFA_LINK|IFA_HOST))) + !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) break; } } @@ -939,7 +939,7 @@ return ifp != NULL; } -struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev) +struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict) { struct inet6_ifaddr * ifp; u8 hash = ipv6_addr_hash(addr); @@ -948,7 +948,7 @@ for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { if (ipv6_addr_cmp(&ifp->addr, addr) == 0) { if (dev == NULL || ifp->idev->dev == dev || - !(ifp->scope&(IFA_LINK|IFA_HOST))) { + !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) { in6_ifa_hold(ifp); break; } @@ -1387,7 +1387,7 @@ ok: - ifp = ipv6_get_ifaddr(&addr, dev); + ifp = ipv6_get_ifaddr(&addr, dev, 1); if (ifp == NULL && valid_lft) { /* Do not allow to create too much of autoconfigured @@ -2830,7 +2830,7 @@ if (!ipv6_addr_any(&addr)) ipv6_dev_ac_dec(ifp->idev->dev, &addr); } - if (!ipv6_chk_addr(&ifp->addr, NULL)) + if (!ipv6_chk_addr(&ifp->addr, ifp->idev->dev, 1)) ip6_rt_addr_del(&ifp->addr, ifp->idev->dev); break; } diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c --- a/net/ipv6/af_inet6.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/af_inet6.c Tue Jan 13 21:02:08 2004 @@ -355,7 +355,7 @@ */ v4addr = LOOPBACK4_IPV6; if (!(addr_type & IPV6_ADDR_MULTICAST)) { - if (!ipv6_chk_addr(&addr->sin6_addr, dev)) { + if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) { if (dev) dev_put(dev); err = -EADDRNOTAVAIL; diff -Nru a/net/ipv6/anycast.c b/net/ipv6/anycast.c --- a/net/ipv6/anycast.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/anycast.c Tue Jan 13 21:02:08 2004 @@ -113,7 +113,7 @@ return -EPERM; if (ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST) return -EINVAL; - if (ipv6_chk_addr(addr, NULL)) + if (ipv6_chk_addr(addr, NULL, 0)) return -EINVAL; pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); diff -Nru a/net/ipv6/datagram.c b/net/ipv6/datagram.c --- a/net/ipv6/datagram.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/datagram.c Tue Jan 13 21:02:08 2004 @@ -307,7 +307,7 @@ return -ENODEV; } } - if (!ipv6_chk_addr(&src_info->ipi6_addr, dev)) { + if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) { if (dev) dev_put(dev); err = -EINVAL; diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/icmp.c Tue Jan 13 21:02:08 2004 @@ -298,7 +298,7 @@ */ addr_type = ipv6_addr_type(&hdr->daddr); - if (ipv6_chk_addr(&hdr->daddr, skb->dev)) + if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0)) saddr = &hdr->daddr; /* diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c --- a/net/ipv6/ip6_tunnel.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/ip6_tunnel.c Tue Jan 13 21:02:08 2004 @@ -777,10 +777,10 @@ if (p->link) ldev = dev_get_by_index(p->link); - if ((ltype&IPV6_ADDR_UNICAST) && !ipv6_chk_addr(laddr, ldev)) + if (ltype&IPV6_ADDR_UNICAST && !ipv6_chk_addr(laddr, ldev, 0)) l_ok = 0; - if ((rtype&IPV6_ADDR_UNICAST) && ipv6_chk_addr(raddr, NULL)) + if (rtype&IPV6_ADDR_UNICAST && ipv6_chk_addr(raddr, NULL, 0)) r_ok = 0; if (l_ok && r_ok) { diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c --- a/net/ipv6/ndisc.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/ndisc.c Tue Jan 13 21:02:08 2004 @@ -434,7 +434,7 @@ len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); /* for anycast or proxy, solicited_addr != src_addr */ - ifp = ipv6_get_ifaddr(solicited_addr, dev); + ifp = ipv6_get_ifaddr(solicited_addr, dev, 1); if (ifp) { src_addr = solicited_addr; in6_ifa_put(ifp); @@ -680,7 +680,7 @@ struct in6_addr *target = (struct in6_addr *)&neigh->primary_key; int probes = atomic_read(&neigh->probes); - if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev)) + if (skb && ipv6_chk_addr(&skb->nh.ipv6h->saddr, dev, 1)) saddr = &skb->nh.ipv6h->saddr; if ((probes -= neigh->parms->ucast_probes) < 0) { @@ -758,7 +758,7 @@ } } - if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) { + if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) { if (ifp->flags & IFA_F_TENTATIVE) { /* Address is tentative. If the source is unspecified address, it is someone @@ -955,7 +955,7 @@ return; } } - if ((ifp = ipv6_get_ifaddr(&msg->target, dev))) { + if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) { if (ifp->flags & IFA_F_TENTATIVE) { addrconf_dad_failure(ifp); return; diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c --- a/net/ipv6/raw.c Tue Jan 13 21:02:08 2004 +++ b/net/ipv6/raw.c Tue Jan 13 21:02:08 2004 @@ -227,7 +227,7 @@ v4addr = LOOPBACK4_IPV6; if (!(addr_type & IPV6_ADDR_MULTICAST)) { err = -EADDRNOTAVAIL; - if (!ipv6_chk_addr(&addr->sin6_addr, dev)) { + if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) { if (dev) dev_put(dev); goto out; diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c --- a/net/sctp/ipv6.c Tue Jan 13 21:02:08 2004 +++ b/net/sctp/ipv6.c Tue Jan 13 21:02:08 2004 @@ -510,7 +510,7 @@ if (!(type & IPV6_ADDR_UNICAST)) return 0; - return ipv6_chk_addr(in6, NULL); + return ipv6_chk_addr(in6, NULL, 0); } /* This function checks if the address is a valid address to be used for