diff options
| author | Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 2003-07-18 09:44:04 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2003-07-18 09:44:04 -0700 |
| commit | 0cc526e0e801dd0a372641bfbefb20f74e881cb9 (patch) | |
| tree | 007758e65478dd65b6ca8bd4943243f320fd6c2b /net | |
| parent | 2135f3fb6233831584d450f6bdb792fa04f0d79f (diff) | |
[IPV6]: Fix anycast usage.
- Recognition of reserved anycasts is removed from ipv6_addr_type()
Flag IPV6_ADDR_ANYCAST is removed as well.
- Some meaningless noop code checking for anycast which are not
going to happen is removed from ndisc.c
- ipv6_unicast_destination() replaces suboptimal ipv6_chk_acast_addr()
in data paths
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv6/addrconf.c | 13 | ||||
| -rw-r--r-- | net/ipv6/anycast.c | 25 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 3 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 6 | ||||
| -rw-r--r-- | net/ipv6/route.c | 4 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 5 |
6 files changed, 25 insertions, 31 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b0c186efccd3..649df9f76068 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -209,15 +209,8 @@ int ipv6_addr_type(const struct in6_addr *addr) }; return type; } - /* check for reserved anycast addresses */ - - if ((st & htonl(0xE0000000)) && - ((addr->s6_addr32[2] == htonl(0xFDFFFFFF) && - (addr->s6_addr32[3] | htonl(0x7F)) == (u32)~0) || - (addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0))) - type = IPV6_ADDR_ANYCAST; - else - type = IPV6_ADDR_UNICAST; + + type = IPV6_ADDR_UNICAST; /* Consider all addresses with the first three bits different of 000 and 111 as finished. @@ -2552,7 +2545,7 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) switch (event) { case RTM_NEWADDR: - ip6_rt_addr_add(&ifp->addr, ifp->idev->dev); + ip6_rt_addr_add(&ifp->addr, ifp->idev->dev, 0); break; case RTM_DELADDR: addrconf_leave_solict(ifp->idev->dev, &ifp->addr); diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 1dc5b9da2e2b..f36fee99a37c 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -96,7 +96,6 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev) return onlink; } - /* * socket join an anycast group */ @@ -110,8 +109,12 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) int ishost = !ipv6_devconf.forwarding; int err = 0; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; if (ipv6_addr_type(addr) & IPV6_ADDR_MULTICAST) return -EINVAL; + if (ipv6_chk_addr(addr, NULL)) + return -EINVAL; pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); if (pac == NULL) @@ -161,21 +164,12 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) * For hosts, allow link-local or matching prefix anycasts. * This obviates the need for propagating anycast routes while * still allowing some non-router anycast participation. - * - * allow anyone to join anycasts that don't require a special route - * and can't be spoofs of unicast addresses (reserved anycast only) */ if (!ip6_onlink(addr, dev)) { if (ishost) err = -EADDRNOTAVAIL; - else if (!capable(CAP_NET_ADMIN)) - err = -EPERM; if (err) goto out_dev_put; - } else if (!(ipv6_addr_type(addr) & IPV6_ADDR_ANYCAST) && - !capable(CAP_NET_ADMIN)) { - err = -EPERM; - goto out_dev_put; } err = ipv6_dev_ac_inc(dev, addr); @@ -266,6 +260,13 @@ void ipv6_sock_ac_close(struct sock *sk) dev_put(dev); } +#if 0 +/* The function is not used, which is funny. Apparently, author + * supposed to use it to filter out datagrams inside udp/raw but forgot. + * + * It is OK, anycasts are not special comparing to delivery to unicasts. + */ + int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex) { struct ipv6_ac_socklist *pac; @@ -286,6 +287,8 @@ int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex) return found; } +#endif + static void aca_put(struct ifacaddr6 *ac) { if (atomic_dec_and_test(&ac->aca_refcnt)) { @@ -347,7 +350,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) idev->ac_list = aca; write_unlock_bh(&idev->lock); - ip6_rt_addr_add(&aca->aca_addr, dev); + ip6_rt_addr_add(&aca->aca_addr, dev, 1); addrconf_join_solict(dev, &aca->aca_addr); diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 5cfc70535e35..727b681325aa 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -415,8 +415,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) saddr = &skb->nh.ipv6h->daddr; - if (ipv6_addr_type(saddr) & IPV6_ADDR_MULTICAST || - ipv6_chk_acast_addr(0, saddr)) + if (!ipv6_unicast_destination(skb)) saddr = NULL; memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr)); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 75a9eeaa05d0..95772c3e915a 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -785,8 +785,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) ipv6_addr_all_nodes(&maddr); ndisc_send_na(dev, NULL, &maddr, &ifp->addr, ifp->idev->cnf.forwarding, 0, - ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, - 1); + 1, 1); in6_ifa_put(ifp); return; } @@ -809,8 +808,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) if (neigh || !dev->hard_header) { ndisc_send_na(dev, neigh, saddr, &ifp->addr, ifp->idev->cnf.forwarding, 1, - ipv6_addr_type(&ifp->addr)&IPV6_ADDR_ANYCAST ? 0 : 1, - 1); + 1, 1); if (neigh) neigh_release(neigh); } diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ac76e702faa2..69d7791712f8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1261,7 +1261,7 @@ int ip6_pkt_discard(struct sk_buff *skb) * Add address */ -int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev) +int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev, int anycast) { struct rt6_info *rt = ip6_dst_alloc(); @@ -1280,6 +1280,8 @@ int ip6_rt_addr_add(struct in6_addr *addr, struct net_device *dev) rt->u.dst.obsolete = -1; rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; + if (!anycast) + rt->rt6i_flags |= RTF_LOCAL; rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); if (rt->rt6i_nexthop == NULL) { dst_free((struct dst_entry *) rt); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 21b165ec5339..e5cd4c372577 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -971,7 +971,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) if (th->rst) return; - if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) + if (!ipv6_unicast_destination(skb)) return; /* @@ -1175,8 +1175,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); - /* FIXME: do the same check for anycast */ - if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) + if (!ipv6_unicast_destination(skb)) goto drop; /* |
