|
@@ -97,6 +97,17 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
|
|
|
put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
|
|
|
}
|
|
|
|
|
|
+static void ip_cmsg_recv_fragsize(struct msghdr *msg, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ int val;
|
|
|
+
|
|
|
+ if (IPCB(skb)->frag_max_size == 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ val = IPCB(skb)->frag_max_size;
|
|
|
+ put_cmsg(msg, SOL_IP, IP_RECVFRAGSIZE, sizeof(val), &val);
|
|
|
+}
|
|
|
+
|
|
|
static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
|
|
|
int tlen, int offset)
|
|
|
{
|
|
@@ -218,6 +229,9 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb,
|
|
|
|
|
|
if (flags & IP_CMSG_CHECKSUM)
|
|
|
ip_cmsg_recv_checksum(msg, skb, tlen, offset);
|
|
|
+
|
|
|
+ if (flags & IP_CMSG_RECVFRAGSIZE)
|
|
|
+ ip_cmsg_recv_fragsize(msg, skb);
|
|
|
}
|
|
|
EXPORT_SYMBOL(ip_cmsg_recv_offset);
|
|
|
|
|
@@ -614,6 +628,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
|
|
|
case IP_MULTICAST_LOOP:
|
|
|
case IP_RECVORIGDSTADDR:
|
|
|
case IP_CHECKSUM:
|
|
|
+ case IP_RECVFRAGSIZE:
|
|
|
if (optlen >= sizeof(int)) {
|
|
|
if (get_user(val, (int __user *) optval))
|
|
|
return -EFAULT;
|
|
@@ -726,6 +741,14 @@ static int do_ip_setsockopt(struct sock *sk, int level,
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
+ case IP_RECVFRAGSIZE:
|
|
|
+ if (sk->sk_type != SOCK_RAW && sk->sk_type != SOCK_DGRAM)
|
|
|
+ goto e_inval;
|
|
|
+ if (val)
|
|
|
+ inet->cmsg_flags |= IP_CMSG_RECVFRAGSIZE;
|
|
|
+ else
|
|
|
+ inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
|
|
|
+ break;
|
|
|
case IP_TOS: /* This sets both TOS and Precedence */
|
|
|
if (sk->sk_type == SOCK_STREAM) {
|
|
|
val &= ~INET_ECN_MASK;
|
|
@@ -1357,6 +1380,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
|
|
case IP_CHECKSUM:
|
|
|
val = (inet->cmsg_flags & IP_CMSG_CHECKSUM) != 0;
|
|
|
break;
|
|
|
+ case IP_RECVFRAGSIZE:
|
|
|
+ val = (inet->cmsg_flags & IP_CMSG_RECVFRAGSIZE) != 0;
|
|
|
+ break;
|
|
|
case IP_TOS:
|
|
|
val = inet->tos;
|
|
|
break;
|