Skip to content

Commit

Permalink
IPv6: data structure changes for new socket options
Browse files Browse the repository at this point in the history
Add underlying data structure changes and basic setsockopt()
and getsockopt() support for IPV6_RECVPATHMTU, IPV6_PATHMTU,
and IPV6_DONTFRAG.  IPV6_PATHMTU is actually fully functional
at this point.

Signed-off-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Brian Haley authored and David S. Miller committed Apr 24, 2010
1 parent 3a73702 commit 793b147
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/linux/in6.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,10 @@ struct in6_flowlabel_req {
#define IPV6_RTHDR 57
#define IPV6_RECVDSTOPTS 58
#define IPV6_DSTOPTS 59
#if 0 /* not yet */
#define IPV6_RECVPATHMTU 60
#define IPV6_PATHMTU 61
#define IPV6_DONTFRAG 62
#if 0 /* not yet */
#define IPV6_USE_MIN_MTU 63
#endif

Expand Down
13 changes: 10 additions & 3 deletions include/linux/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ struct in6_pktinfo {
int ipi6_ifindex;
};

struct ip6_mtuinfo {
struct sockaddr_in6 ip6m_addr;
__u32 ip6m_mtu;
};

struct in6_ifreq {
struct in6_addr ifr6_addr;
Expand Down Expand Up @@ -334,22 +338,25 @@ struct ipv6_pinfo {
dstopts:1,
odstopts:1,
rxflow:1,
rxtclass:1;
rxtclass:1,
rxpmtu:1;
} bits;
__u16 all;
} rxopt;

/* sockopt flags */
__u8 recverr:1,
__u16 recverr:1,
sndflow:1,
pmtudisc:2,
ipv6only:1,
srcprefs:3; /* 001: prefer temporary address
srcprefs:3, /* 001: prefer temporary address
* 010: prefer public address
* 100: prefer care-of address
*/
dontfrag:1;
__u8 min_hopcount;
__u8 tclass;
__u8 padding;

__u32 dst_cookie;

Expand Down
46 changes: 46 additions & 0 deletions net/ipv6/ipv6_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0;
break;

case IPV6_RECVPATHMTU:
if (optlen < sizeof(int))
goto e_inval;
np->rxopt.bits.rxpmtu = valbool;
retv = 0;
break;

case IPV6_HOPOPTS:
case IPV6_RTHDRDSTOPTS:
case IPV6_RTHDR:
Expand Down Expand Up @@ -773,6 +780,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
if (val < 0 || val > 255)
goto e_inval;
np->min_hopcount = val;
break;
case IPV6_DONTFRAG:
np->dontfrag = valbool;
retv = 0;
break;
}
Expand Down Expand Up @@ -1063,6 +1073,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = np->rxopt.bits.rxflow;
break;

case IPV6_RECVPATHMTU:
val = np->rxopt.bits.rxpmtu;
break;

case IPV6_PATHMTU:
{
struct dst_entry *dst;
struct ip6_mtuinfo mtuinfo;

if (len < sizeof(mtuinfo))
return -EINVAL;

len = sizeof(mtuinfo);
memset(&mtuinfo, 0, sizeof(mtuinfo));

rcu_read_lock();
dst = __sk_dst_get(sk);
if (dst)
mtuinfo.ip6m_mtu = dst_mtu(dst);
rcu_read_unlock();
if (!mtuinfo.ip6m_mtu)
return -ENOTCONN;

if (put_user(len, optlen))
return -EFAULT;
if (copy_to_user(optval, &mtuinfo, len))
return -EFAULT;

return 0;
break;
}

case IPV6_UNICAST_HOPS:
case IPV6_MULTICAST_HOPS:
{
Expand Down Expand Up @@ -1128,6 +1170,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = np->min_hopcount;
break;

case IPV6_DONTFRAG:
val = np->dontfrag;
break;

default:
return -ENOPROTOOPT;
}
Expand Down

0 comments on commit 793b147

Please sign in to comment.