summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorEdward Jee <edjee@google.com>2015-10-08 21:56:48 (GMT)
committerDavid S. Miller <davem@davemloft.net>2015-10-13 02:25:21 (GMT)
commitf28ea365cdefc3b4fd0373e70b0106a0cd9b4c23 (patch)
tree136f458e3435a79f3b5048b62dcd3c884ff644f2 /net/core
parentc1bf5fe03184f782f2a6827cf314ae58834865da (diff)
downloadlinux-f28ea365cdefc3b4fd0373e70b0106a0cd9b4c23.tar.xz
sock: support per-packet fwmark
It's useful to allow users to set fwmark for an individual packet, without changing the socket state. The function this patch adds in sock layer can be used by the protocols that need such a feature. Signed-off-by: Edward Hyunkoo Jee <edjee@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/sock.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/net/core/sock.c b/net/core/sock.c
index 7dd1263..3395777 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1852,6 +1852,32 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
}
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 */
#define SKB_FRAG_PAGE_ORDER get_order(32768)