diff options
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1160400e9dbd..bd43f0152c21 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -337,6 +337,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
337 | retv = 0; | 337 | retv = 0; |
338 | break; | 338 | break; |
339 | 339 | ||
340 | case IPV6_RECVPATHMTU: | ||
341 | if (optlen < sizeof(int)) | ||
342 | goto e_inval; | ||
343 | np->rxopt.bits.rxpmtu = valbool; | ||
344 | retv = 0; | ||
345 | break; | ||
346 | |||
340 | case IPV6_HOPOPTS: | 347 | case IPV6_HOPOPTS: |
341 | case IPV6_RTHDRDSTOPTS: | 348 | case IPV6_RTHDRDSTOPTS: |
342 | case IPV6_RTHDR: | 349 | case IPV6_RTHDR: |
@@ -451,7 +458,8 @@ sticky_done: | |||
451 | msg.msg_controllen = optlen; | 458 | msg.msg_controllen = optlen; |
452 | msg.msg_control = (void*)(opt+1); | 459 | msg.msg_control = (void*)(opt+1); |
453 | 460 | ||
454 | retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk); | 461 | retv = datagram_send_ctl(net, &msg, &fl, opt, &junk, &junk, |
462 | &junk); | ||
455 | if (retv) | 463 | if (retv) |
456 | goto done; | 464 | goto done; |
457 | update: | 465 | update: |
@@ -767,6 +775,17 @@ pref_skip_coa: | |||
767 | 775 | ||
768 | break; | 776 | break; |
769 | } | 777 | } |
778 | case IPV6_MINHOPCOUNT: | ||
779 | if (optlen < sizeof(int)) | ||
780 | goto e_inval; | ||
781 | if (val < 0 || val > 255) | ||
782 | goto e_inval; | ||
783 | np->min_hopcount = val; | ||
784 | break; | ||
785 | case IPV6_DONTFRAG: | ||
786 | np->dontfrag = valbool; | ||
787 | retv = 0; | ||
788 | break; | ||
770 | } | 789 | } |
771 | 790 | ||
772 | release_sock(sk); | 791 | release_sock(sk); |
@@ -1055,6 +1074,38 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1055 | val = np->rxopt.bits.rxflow; | 1074 | val = np->rxopt.bits.rxflow; |
1056 | break; | 1075 | break; |
1057 | 1076 | ||
1077 | case IPV6_RECVPATHMTU: | ||
1078 | val = np->rxopt.bits.rxpmtu; | ||
1079 | break; | ||
1080 | |||
1081 | case IPV6_PATHMTU: | ||
1082 | { | ||
1083 | struct dst_entry *dst; | ||
1084 | struct ip6_mtuinfo mtuinfo; | ||
1085 | |||
1086 | if (len < sizeof(mtuinfo)) | ||
1087 | return -EINVAL; | ||
1088 | |||
1089 | len = sizeof(mtuinfo); | ||
1090 | memset(&mtuinfo, 0, sizeof(mtuinfo)); | ||
1091 | |||
1092 | rcu_read_lock(); | ||
1093 | dst = __sk_dst_get(sk); | ||
1094 | if (dst) | ||
1095 | mtuinfo.ip6m_mtu = dst_mtu(dst); | ||
1096 | rcu_read_unlock(); | ||
1097 | if (!mtuinfo.ip6m_mtu) | ||
1098 | return -ENOTCONN; | ||
1099 | |||
1100 | if (put_user(len, optlen)) | ||
1101 | return -EFAULT; | ||
1102 | if (copy_to_user(optval, &mtuinfo, len)) | ||
1103 | return -EFAULT; | ||
1104 | |||
1105 | return 0; | ||
1106 | break; | ||
1107 | } | ||
1108 | |||
1058 | case IPV6_UNICAST_HOPS: | 1109 | case IPV6_UNICAST_HOPS: |
1059 | case IPV6_MULTICAST_HOPS: | 1110 | case IPV6_MULTICAST_HOPS: |
1060 | { | 1111 | { |
@@ -1116,6 +1167,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1116 | val |= IPV6_PREFER_SRC_HOME; | 1167 | val |= IPV6_PREFER_SRC_HOME; |
1117 | break; | 1168 | break; |
1118 | 1169 | ||
1170 | case IPV6_MINHOPCOUNT: | ||
1171 | val = np->min_hopcount; | ||
1172 | break; | ||
1173 | |||
1174 | case IPV6_DONTFRAG: | ||
1175 | val = np->dontfrag; | ||
1176 | break; | ||
1177 | |||
1119 | default: | 1178 | default: |
1120 | return -ENOPROTOOPT; | 1179 | return -ENOPROTOOPT; |
1121 | } | 1180 | } |