summaryrefslogtreecommitdiff
path: root/pfinet/linux-src/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorStefan Siegl <stesie@brokenpipe.de>2007-10-13 01:43:00 +0000
committerStefan Siegl <stesie@brokenpipe.de>2007-10-13 01:43:00 +0000
commit92f5a6111a2ae5fe7569c65afe1834382ff9147a (patch)
tree371d6357e98489b0f66311180133ddc874342379 /pfinet/linux-src/net/ipv6/tcp_ipv6.c
parent1793f42c8f1c00dcc0163ee61e8f1a48fbf1b039 (diff)
2007-10-13 Stefan Siegl <stesie@brokenpipe.de>
* linux-src/net/ipv6/af_inet6.c (inet6_getname): Initialize sin6_scope_id. * linux-src/net/ipv6/datagram_ipv6.c (ipv6_recv_error): Likewise. * linux-src/net/ipv6/tcp_ipv6.c (v6_addr2sockaddr): Likewise. * linux-src/net/ipv6/udp_ipv6.c (udpv6_recvmsg): Likewise. * linux-src/net/ipv6/raw_ipv6.c (rawv6_recvmsg): Likewise. * linux-src/net/ipv6/af_inet6.c (inet6_bind): For link-local IPv6 addresses copy sin6_scope_id to bound_dev_if and error out unless bound. * linux-src/net/ipv6/tcp_ipv6.c (tcp_v6_connect): Likewise. * linux-src/net/ipv6/udp_ipv6.c (udpv6_connect): Likewise. * linux-src/net/ipv6/raw_ipv6.c (rawv6_bind): Likewise. * linux-src/net/ipv6/raw_ipv6.c (rawv6_sendmsg): For link-local IPv6 addresses bind packet to interface specified by sin6_scope_id. * linux-src/net/ipv6/udp_ipv6.c (udpv6_sendmsg): Likewise.
Diffstat (limited to 'pfinet/linux-src/net/ipv6/tcp_ipv6.c')
-rw-r--r--pfinet/linux-src/net/ipv6/tcp_ipv6.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/pfinet/linux-src/net/ipv6/tcp_ipv6.c b/pfinet/linux-src/net/ipv6/tcp_ipv6.c
index 85a5ab27..c761e76c 100644
--- a/pfinet/linux-src/net/ipv6/tcp_ipv6.c
+++ b/pfinet/linux-src/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.2 2007/10/08 21:59:10 stesie Exp $
+ * $Id: tcp_ipv6.c,v 1.3 2007/10/13 01:43:00 stesie Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
@@ -421,6 +421,24 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
if(addr_type & IPV6_ADDR_MULTICAST)
return -ENETUNREACH;
+ if (addr_type&IPV6_ADDR_LINKLOCAL) {
+ if (addr_len >= sizeof(struct sockaddr_in6) &&
+ usin->sin6_scope_id) {
+ /* If interface is set while binding, indices
+ * must coincide.
+ */
+ if (sk->bound_dev_if &&
+ sk->bound_dev_if != usin->sin6_scope_id)
+ return -EINVAL;
+
+ sk->bound_dev_if = usin->sin6_scope_id;
+ }
+
+ /* Connect to link-local address requires an interface */
+ if (!sk->bound_dev_if)
+ return -EINVAL;
+ }
+
/*
* connect to self not allowed
*/
@@ -1587,6 +1605,10 @@ static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
sin6->sin6_port = sk->dport;
/* We do not store received flowlabel for TCP */
sin6->sin6_flowinfo = 0;
+ sin6->sin6_scope_id = 0;
+ if (sk->bound_dev_if &&
+ ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+ sin6->sin6_scope_id = sk->bound_dev_if;
}
static struct tcp_func ipv6_specific = {