diff options
author | Stefan Siegl <stesie@brokenpipe.de> | 2007-10-13 01:43:00 +0000 |
---|---|---|
committer | Stefan Siegl <stesie@brokenpipe.de> | 2007-10-13 01:43:00 +0000 |
commit | 92f5a6111a2ae5fe7569c65afe1834382ff9147a (patch) | |
tree | 371d6357e98489b0f66311180133ddc874342379 /pfinet/linux-src/net/ipv6/udp_ipv6.c | |
parent | 1793f42c8f1c00dcc0163ee61e8f1a48fbf1b039 (diff) | |
download | hurd-92f5a6111a2ae5fe7569c65afe1834382ff9147a.tar.gz hurd-92f5a6111a2ae5fe7569c65afe1834382ff9147a.tar.bz2 hurd-92f5a6111a2ae5fe7569c65afe1834382ff9147a.zip |
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/udp_ipv6.c')
-rw-r--r-- | pfinet/linux-src/net/ipv6/udp_ipv6.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/pfinet/linux-src/net/ipv6/udp_ipv6.c b/pfinet/linux-src/net/ipv6/udp_ipv6.c index 57b5db1a..4511c024 100644 --- a/pfinet/linux-src/net/ipv6/udp_ipv6.c +++ b/pfinet/linux-src/net/ipv6/udp_ipv6.c @@ -7,7 +7,7 @@ * * Based on linux/ipv4/udp.c * - * $Id: udp_ipv6.c,v 1.2 2007/10/08 21:59:10 stesie Exp $ + * $Id: udp_ipv6.c,v 1.3 2007/10/13 01:43:00 stesie Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -272,6 +272,24 @@ ipv4_connected: return 0; } + if (addr_type&IPV6_ADDR_LINKLOCAL) { + if (addr_len >= sizeof(struct sockaddr_in6) && + usin->sin6_scope_id) { + if (sk->bound_dev_if && + sk->bound_dev_if != usin->sin6_scope_id) + return(-EINVAL); + + sk->bound_dev_if = usin->sin6_scope_id; + if (!sk->bound_dev_if && + (addr_type & IPV6_ADDR_MULTICAST)) + fl.oif = np->mcast_oif; + } + + /* Connect to link-local address requires an interface */ + if (!sk->bound_dev_if) + return(-EINVAL); + } + ipv6_addr_copy(&np->daddr, daddr); np->flow_label = fl.fl6_flowlabel; @@ -416,6 +434,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len, sin6->sin6_family = AF_INET6; sin6->sin6_port = skb->h.uh->source; sin6->sin6_flowinfo = 0; + sin6->sin6_scope_id = 0; if (skb->protocol == __constant_htons(ETH_P_IP)) { ipv6_addr_set(&sin6->sin6_addr, 0, 0, @@ -425,6 +444,9 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len, } else { memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr, sizeof(struct in6_addr)); + if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin6->sin6_scope_id = + ((struct inet6_skb_parm *) skb->cb)->iif; if (sk->net_pinfo.af_inet6.rxopt.all) datagram_recv_ctl(sk, msg, skb); @@ -805,6 +827,11 @@ static int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, int ulen) if (sk->state == TCP_ESTABLISHED && !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr)) daddr = &sk->net_pinfo.af_inet6.daddr; + + if (addr_len >= sizeof(struct sockaddr_in6) && + sin6->sin6_scope_id && + ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) + fl.oif = sin6->sin6_scope_id; } else { if (sk->state != TCP_ESTABLISHED) return(-ENOTCONN); |