X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv6%2Fipv6_sockglue.c;h=286c86735aed7772f6851228026d0a633a1d45bd;hb=132a69c6cc3dfa7fa354a88128acee7e6ee7082b;hp=de6b91981b30611b0cd63ea8d14a304b34387c27;hpb=97d41e90fe61399b99d74820cb7f2d6e0fbac91d;p=linux-2.6-omap-h63xx.git diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index de6b91981b3..286c86735ae 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -1,9 +1,9 @@ /* * IPv6 BSD socket options interface - * Linux INET6 implementation + * Linux INET6 implementation * * Authors: - * Pedro Roque + * Pedro Roque * * Based on linux/net/ipv4/ip_sockglue.c * @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +50,7 @@ #include #include #include +#include #include #include @@ -163,7 +163,7 @@ out: } static struct packet_type ipv6_packet_type = { - .type = __constant_htons(ETH_P_IPV6), + .type = __constant_htons(ETH_P_IPV6), .func = ipv6_rcv, .gso_send_check = ipv6_gso_send_check, .gso_segment = ipv6_gso_segment, @@ -239,6 +239,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, struct sk_buff *pktopt; if (sk->sk_protocol != IPPROTO_UDP && + sk->sk_protocol != IPPROTO_UDPLITE && sk->sk_protocol != IPPROTO_TCP) break; @@ -276,11 +277,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sk->sk_family = PF_INET; tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); } else { + struct proto *prot = &udp_prot; + + if (sk->sk_protocol == IPPROTO_UDPLITE) + prot = &udplite_prot; local_bh_disable(); sock_prot_dec_use(sk->sk_prot); - sock_prot_inc_use(&udp_prot); + sock_prot_inc_use(prot); local_bh_enable(); - sk->sk_prot = &udp_prot; + sk->sk_prot = prot; sk->sk_socket->ops = &inet_dgram_ops; sk->sk_family = PF_INET; } @@ -314,7 +319,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, np->rxopt.bits.rxinfo = valbool; retv = 0; break; - + case IPV6_2292PKTINFO: np->rxopt.bits.rxoinfo = valbool; retv = 0; @@ -370,7 +375,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, np->tclass = val; retv = 0; break; - + case IPV6_RECVTCLASS: np->rxopt.bits.rxtclass = valbool; retv = 0; @@ -813,6 +818,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, switch (optname) { case IPV6_ADDRFORM: if (sk->sk_protocol != IPPROTO_UDP && + sk->sk_protocol != IPPROTO_UDPLITE && sk->sk_protocol != IPPROTO_TCP) return -EINVAL; if (sk->sk_state != TCP_ESTABLISHED) @@ -886,7 +892,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, case IPV6_MTU: { struct dst_entry *dst; - val = 0; + val = 0; lock_sock(sk); dst = sk_dst_get(sk); if (dst) { @@ -971,12 +977,27 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; case IPV6_UNICAST_HOPS: - val = np->hop_limit; - break; - case IPV6_MULTICAST_HOPS: - val = np->mcast_hops; + { + struct dst_entry *dst; + + if (optname == IPV6_UNICAST_HOPS) + val = np->hop_limit; + else + val = np->mcast_hops; + + dst = sk_dst_get(sk); + if (dst) { + if (val < 0) + val = dst_metric(dst, RTAX_HOPLIMIT); + if (val < 0) + val = ipv6_get_hoplimit(dst->dev); + dst_release(dst); + } + if (val < 0) + val = ipv6_devconf.hop_limit; break; + } case IPV6_MULTICAST_LOOP: val = np->mc_loop;