From 92f5a6111a2ae5fe7569c65afe1834382ff9147a Mon Sep 17 00:00:00 2001 From: Stefan Siegl Date: Sat, 13 Oct 2007 01:43:00 +0000 Subject: 2007-10-13 Stefan Siegl * 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. --- pfinet/linux-src/net/ipv6/tcp_ipv6.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'pfinet/linux-src/net/ipv6/tcp_ipv6.c') 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 * - * $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 = { -- cgit v1.2.3