@@ -229,8 +229,9 @@ struct ipv6_pinfo {
rxflow:1,
rxtclass:1,
rxpmtu:1,
- rxorigdstaddr:1;
- /* 2 bits hole */
+ rxorigdstaddr:1,
+ recvfragsize:1;
+ /* 1 bits hole */
} bits;
__u16 all;
} rxopt;
@@ -283,6 +283,7 @@ struct in6_flowlabel_req {
#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
#define IPV6_TRANSPARENT 75
#define IPV6_UNICAST_IF 76
+#define IPV6_RECVFRAGSIZE 77
/*
* Multicast Routing:
@@ -715,6 +715,11 @@ void ip6_datagram_recv_specific_ctl(struct sock *sk, struct msghdr *msg,
put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6);
}
}
+ if (np->rxopt.bits.recvfragsize && opt->frag_max_size) {
+ int val = opt->frag_max_size;
+
+ put_cmsg(msg, SOL_IPV6, IPV6_RECVFRAGSIZE, sizeof(val), &val);
+ }
}
void ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
@@ -868,6 +868,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
np->autoflowlabel = valbool;
retv = 0;
break;
+ case IPV6_RECVFRAGSIZE:
+ np->rxopt.bits.recvfragsize = valbool;
+ retv = 0;
+ break;
}
release_sock(sk);
@@ -1310,6 +1314,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = np->autoflowlabel;
break;
+ case IPV6_RECVFRAGSIZE:
+ val = np->rxopt.bits.recvfragsize;
+ break;
+
default:
return -ENOPROTOOPT;
}