diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-01-11 01:44:09 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:01:45 -0500 |
commit | 1cab3da6be6c7659f62d0d297b389cc0e48b2178 (patch) | |
tree | f5a3e8a21136322625cb61dcf94d3edfac5ab7d1 | |
parent | 06bfe655e7db7719c0eb51eb420fb9c2a6aa1e00 (diff) |
[NETNS][IPV6]: inet6_addr - ipv6_get_ifaddr namespace aware
The inet6_addr_lst is browsed taking into account the network
namespace specified as parameter. If an address does not belong
to the specified namespace, it is ignored.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/addrconf.h | 8 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 9 |
4 files changed, 19 insertions, 12 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index d1697b587a1a..77f630f12806 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h | |||
@@ -67,9 +67,11 @@ extern int ipv6_chk_addr(struct net *net, | |||
67 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 67 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
68 | extern int ipv6_chk_home_addr(struct in6_addr *addr); | 68 | extern int ipv6_chk_home_addr(struct in6_addr *addr); |
69 | #endif | 69 | #endif |
70 | extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, | 70 | extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, |
71 | struct net_device *dev, | 71 | struct in6_addr *addr, |
72 | int strict); | 72 | struct net_device *dev, |
73 | int strict); | ||
74 | |||
73 | extern int ipv6_get_saddr(struct dst_entry *dst, | 75 | extern int ipv6_get_saddr(struct dst_entry *dst, |
74 | struct in6_addr *daddr, | 76 | struct in6_addr *daddr, |
75 | struct in6_addr *saddr); | 77 | struct in6_addr *saddr); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 41cc31ee297e..c4df6cdff650 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1247,13 +1247,16 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | |||
1247 | return ifp != NULL; | 1247 | return ifp != NULL; |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict) | 1250 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, |
1251 | struct net_device *dev, int strict) | ||
1251 | { | 1252 | { |
1252 | struct inet6_ifaddr * ifp; | 1253 | struct inet6_ifaddr * ifp; |
1253 | u8 hash = ipv6_addr_hash(addr); | 1254 | u8 hash = ipv6_addr_hash(addr); |
1254 | 1255 | ||
1255 | read_lock_bh(&addrconf_hash_lock); | 1256 | read_lock_bh(&addrconf_hash_lock); |
1256 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1257 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { |
1258 | if (ifp->idev->dev->nd_net != net) | ||
1259 | continue; | ||
1257 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1260 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1258 | if (dev == NULL || ifp->idev->dev == dev || | 1261 | if (dev == NULL || ifp->idev->dev == dev || |
1259 | !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) { | 1262 | !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) { |
@@ -1739,7 +1742,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1739 | 1742 | ||
1740 | ok: | 1743 | ok: |
1741 | 1744 | ||
1742 | ifp = ipv6_get_ifaddr(&addr, dev, 1); | 1745 | ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1); |
1743 | 1746 | ||
1744 | if (ifp == NULL && valid_lft) { | 1747 | if (ifp == NULL && valid_lft) { |
1745 | int max_addresses = in6_dev->cnf.max_addresses; | 1748 | int max_addresses = in6_dev->cnf.max_addresses; |
@@ -3135,7 +3138,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
3135 | /* We ignore other flags so far. */ | 3138 | /* We ignore other flags so far. */ |
3136 | ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); | 3139 | ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); |
3137 | 3140 | ||
3138 | ifa = ipv6_get_ifaddr(pfx, dev, 1); | 3141 | ifa = ipv6_get_ifaddr(net, pfx, dev, 1); |
3139 | if (ifa == NULL) { | 3142 | if (ifa == NULL) { |
3140 | /* | 3143 | /* |
3141 | * It would be best to check for !NLM_F_CREATE here but | 3144 | * It would be best to check for !NLM_F_CREATE here but |
@@ -3442,7 +3445,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3442 | if (ifm->ifa_index) | 3445 | if (ifm->ifa_index) |
3443 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); | 3446 | dev = __dev_get_by_index(&init_net, ifm->ifa_index); |
3444 | 3447 | ||
3445 | if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) { | 3448 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { |
3446 | err = -EADDRNOTAVAIL; | 3449 | err = -EADDRNOTAVAIL; |
3447 | goto errout; | 3450 | goto errout; |
3448 | } | 3451 | } |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index ba7c8aaf2782..15c4f6cee3e6 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -936,7 +936,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
936 | struct flowi fl_gw; | 936 | struct flowi fl_gw; |
937 | int redirect; | 937 | int redirect; |
938 | 938 | ||
939 | ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); | 939 | ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src, |
940 | (*dst)->dev, 1); | ||
940 | 941 | ||
941 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); | 942 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); |
942 | if (ifp) | 943 | if (ifp) |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index e217d3ff00f3..bdfc4ea61941 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -556,7 +556,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
556 | }; | 556 | }; |
557 | 557 | ||
558 | /* for anycast or proxy, solicited_addr != src_addr */ | 558 | /* for anycast or proxy, solicited_addr != src_addr */ |
559 | ifp = ipv6_get_ifaddr(solicited_addr, dev, 1); | 559 | ifp = ipv6_get_ifaddr(&init_net, solicited_addr, dev, 1); |
560 | if (ifp) { | 560 | if (ifp) { |
561 | src_addr = solicited_addr; | 561 | src_addr = solicited_addr; |
562 | if (ifp->flags & IFA_F_OPTIMISTIC) | 562 | if (ifp->flags & IFA_F_OPTIMISTIC) |
@@ -616,7 +616,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, | |||
616 | * suppress the inclusion of the sllao. | 616 | * suppress the inclusion of the sllao. |
617 | */ | 617 | */ |
618 | if (send_sllao) { | 618 | if (send_sllao) { |
619 | struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); | 619 | struct inet6_ifaddr *ifp = ipv6_get_ifaddr(&init_net, saddr, |
620 | dev, 1); | ||
620 | if (ifp) { | 621 | if (ifp) { |
621 | if (ifp->flags & IFA_F_OPTIMISTIC) { | 622 | if (ifp->flags & IFA_F_OPTIMISTIC) { |
622 | send_sllao = 0; | 623 | send_sllao = 0; |
@@ -741,7 +742,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
741 | 742 | ||
742 | inc = ipv6_addr_is_multicast(daddr); | 743 | inc = ipv6_addr_is_multicast(daddr); |
743 | 744 | ||
744 | if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) { | 745 | if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1)) != NULL) { |
745 | 746 | ||
746 | if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { | 747 | if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { |
747 | if (dad) { | 748 | if (dad) { |
@@ -899,7 +900,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
899 | return; | 900 | return; |
900 | } | 901 | } |
901 | } | 902 | } |
902 | if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) { | 903 | if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1))) { |
903 | if (ifp->flags & IFA_F_TENTATIVE) { | 904 | if (ifp->flags & IFA_F_TENTATIVE) { |
904 | addrconf_dad_failure(ifp); | 905 | addrconf_dad_failure(ifp); |
905 | return; | 906 | return; |