aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ipv6_sockglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ipv6_sockglue.c')
-rw-r--r--net/ipv6/ipv6_sockglue.c61
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;
457update: 465update:
@@ -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 }