|
@@ -1852,6 +1852,32 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(sock_alloc_send_skb);
|
|
EXPORT_SYMBOL(sock_alloc_send_skb);
|
|
|
|
|
|
|
|
+int sock_cmsg_send(struct sock *sk, struct msghdr *msg,
|
|
|
|
+ struct sockcm_cookie *sockc)
|
|
|
|
+{
|
|
|
|
+ struct cmsghdr *cmsg;
|
|
|
|
+
|
|
|
|
+ for_each_cmsghdr(cmsg, msg) {
|
|
|
|
+ if (!CMSG_OK(msg, cmsg))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ if (cmsg->cmsg_level != SOL_SOCKET)
|
|
|
|
+ continue;
|
|
|
|
+ switch (cmsg->cmsg_type) {
|
|
|
|
+ case SO_MARK:
|
|
|
|
+ if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
|
|
|
|
+ return -EPERM;
|
|
|
|
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(u32)))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ sockc->mark = *(u32 *)CMSG_DATA(cmsg);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(sock_cmsg_send);
|
|
|
|
+
|
|
/* On 32bit arches, an skb frag is limited to 2^15 */
|
|
/* On 32bit arches, an skb frag is limited to 2^15 */
|
|
#define SKB_FRAG_PAGE_ORDER get_order(32768)
|
|
#define SKB_FRAG_PAGE_ORDER get_order(32768)
|
|
|
|
|