Hi Yoshifuji-san

Some more comments below...

YOSHIFUJI Hideaki / 吉藤英明 wrote:
> 
> Thank you.  Here's take 2.
> 
> diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
> index b1fe7ac..119363a 100644
> --- a/net/ipv6/datagram.c
> +++ b/net/ipv6/datagram.c
> @@ -496,7 +496,58 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr 
> *msg, struct sk_buff *skb)
>       return 0;
>  }
>  
> -int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
> +int ip6_datagram_set_pktinfo(struct sock *sk,
> +                          struct in6_pktinfo *src_info,
> +                          struct flowi *fl)
> +{
> +     struct net_device *dev = NULL;
> +     int addr_type;
> +     int err = 0;
> +     struct in6_addr *saddr = sk ? &inet6_sk(sk)->saddr : NULL;
> +
> +     if (src_info->ipi6_ifindex) {
> +             dev = dev_get_by_index(src_info->ipi6_ifindex);
> +             if (!dev)
> +                     return -ENODEV;
> +     }
> +
> +     fl->oif = src_info->ipi6_ifindex;
> +
> +     addr_type = ipv6_addr_type(&src_info->ipi6_addr);
> +     if (addr_type == IPV6_ADDR_ANY)
> +             goto out;
> +
> +     err = -EINVAL;
> +
> +     if (sk && inet_sk(sk)->is_icsk)
> +             goto out;
> +

> +     if (saddr) {
> +             if (!ipv6_addr_any(saddr))
> +                     goto out;
> +             if (!ipv6_addr_equal(&src_info->ipi6_addr, saddr))
> +                     goto out;
> +     }

shouldn't the block above go away?  IPV6_PKTINFO can override the
source address that was bound or specified via other options.

 diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
> index aa3d07c..3ebcef8 100644
> --- a/net/ipv6/ipv6_sockglue.c
> +++ b/net/ipv6/ipv6_sockglue.c
> @@ -456,6 +456,28 @@ sticky_done:
>               break;
>       }
>  
> +     case IPV6_PKTINFO:
> +     {
> +             struct in6_pktinfo pktinfo;
> +             struct flowi fl;
> +             int err;
> +
> +             if (optlen < sizeof(pktinfo))
> +                     return -EINVAL;
> +             if (copy_from_user(&pktinfo, optval, sizeof(pktinfo)))
> +                     return -EFAULT;
> +
> +             fl.fl6_flowlabel = 0;
> +             fl.oif = sk->sk_bound_dev_if;
> +
> +             lock_sock(sk);
> +             err = ip6_datagram_set_pktinfo(sk, &pktinfo, &fl);
> +             if (!err)
> +                     sk->sk_bound_dev_if = fl.oif;
> +             release_sock(sk);
> +             break;
> +     }
> +

Shouldn't this stash the source address out of the fl into something?
Otherwise we lose the source address information.

It seems like adding to ip6_txoptions might be an option.
We seem to have the same issue for IPV6_2292PKTOPTIONS case too.

>       case IPV6_2292PKTOPTIONS:
>       {
>               struct ipv6_txoptions *opt = NULL;
> @@ -490,7 +512,7 @@ sticky_done:
>               msg.msg_controllen = optlen;
>               msg.msg_control = (void*)(opt+1);
>  
> -             retv = datagram_send_ctl(&msg, &fl, opt, &junk, &junk);
> +             retv = datagram_send_ctl(sk, &msg, &fl, opt, &junk, &junk);
>               if (retv)
>                       goto done;
>  update:
> @@ -933,6 +955,29 @@ static int do_ipv6_getsockopt(struct sock *sk, int 
> level, int optname,
>               val = np->ipv6only;
>               break;
>  
> +     case IPV6_PKTINFO:
> +     {
> +             struct in6_pktinfo pktinfo;
> +
> +             lock_sock(sk);
> +             val = sk->sk_bound_dev_if;
> +             release_sock(sk);
> +
> +             /*
> +              * XXX: we may need to clear pktinfo to avoid
> +              * disclosing stack here.
> +              */
> +             pktinfo.ipi6_addr = inet6_sk(sk)->saddr;
> +             pktinfo.ipi6_ifindex = val;
> +
> +             len = min_t(unsigned int, sizeof(pktinfo), len);
> +             if (put_user(len, optlen))
> +                     return -EFAULT;
> +             if (copy_to_user(optval, &pktinfo, len))
> +                     return -EFAULT;
> +             return 0;
> +     }
> +

This returns the bound address, not the address specified in the setsockopt.

Thanks
-vlad
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to