Hi David,
David Stevens wrote:
OK, I see what you're trying to fix now.
I think the scope_id checks are not quite right-- they
should be something like this:
if (addr_type&IPV6_ADDR_LINKLOCAL) {
if (addr_len >= sizeof(struct sockaddr_in6)) {
if (sk->sk_bound_dev_if && usin->sin6_scope_id &&
sk->sk_bound_dev_if != usin->sin6_scope_id) {
err = -EINVAL;
goto out;
}
if (usin->sin6_scope_id)
sk->sk_bound_dev_if = usin->sin6_scope_id;
if (!sk->sk_bound_dev_if &&
(addr_type & IPV6_ADDR_MULTICAST))
fl.oif = np->mcast_oif;
This assignment will not get us past the next check...
/* connect to the link-local addres requires an interface */
if (!sk->sk_bound_dev_if) {
err = -EINVAL;
goto out;
}
... and even if it did, fl.oif is over-written by sk_bound_dev_if just a
few lines down.
If I did an SO_BINDTODEVICE and specified sin6_scope_id,
then they better agree.
If I specified sin6_scope_id without SO_BINDTODEVICE, set
the device to that.
If I get this far without a device and it's multicast, use
mcast_oif
If I get all through that and don't have a device, EINVAL.
You also need to check if mcast_oif matches sk_bind_dev_if here - it's
actually done in the setsockopt() code already when we set it,
duplicating it here isn't that big a deal.
How about the following patch? It does not set sk_bound_dev_if to
mcast_oif, but does allow the connect() to succeed.
-Brian
Signed-off-by: Brian Haley <[EMAIL PROTECTED]>
---
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 2ed689a..3226970 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -114,6 +114,8 @@ ipv4_connected:
goto out;
}
+ fl.oif = sk->sk_bound_dev_if;
+
if (addr_type&IPV6_ADDR_LINKLOCAL) {
if (addr_len >= sizeof(struct sockaddr_in6) &&
usin->sin6_scope_id) {
@@ -122,14 +124,14 @@ ipv4_connected:
err = -EINVAL;
goto out;
}
- sk->sk_bound_dev_if = usin->sin6_scope_id;
- if (!sk->sk_bound_dev_if &&
- (addr_type & IPV6_ADDR_MULTICAST))
- fl.oif = np->mcast_oif;
+ fl.oif = sk->sk_bound_dev_if = usin->sin6_scope_id;
}
+ if (!fl.oif && (addr_type & IPV6_ADDR_MULTICAST))
+ fl.oif = np->mcast_oif;
+
/* Connect to link-local address requires an interface */
- if (!sk->sk_bound_dev_if) {
+ if (!fl.oif) {
err = -EINVAL;
goto out;
}
@@ -148,7 +150,6 @@ ipv4_connected:
fl.proto = sk->sk_protocol;
ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
- fl.oif = sk->sk_bound_dev_if;
fl.fl_ip_dport = inet->dport;
fl.fl_ip_sport = inet->sport;