aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_sockglue.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_sockglue.c')
-rw-r--r--net/ipv4/ip_sockglue.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 2bf8d782f678..b5c4f61518e8 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -50,6 +50,7 @@
50#define IP_CMSG_TOS 4 50#define IP_CMSG_TOS 4
51#define IP_CMSG_RECVOPTS 8 51#define IP_CMSG_RECVOPTS 8
52#define IP_CMSG_RETOPTS 16 52#define IP_CMSG_RETOPTS 16
53#define IP_CMSG_PASSSEC 32
53 54
54/* 55/*
55 * SOL_IP control messages. 56 * SOL_IP control messages.
@@ -109,6 +110,19 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
109 put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data); 110 put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
110} 111}
111 112
113static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
114{
115 char *secdata;
116 u32 seclen;
117 int err;
118
119 err = security_socket_getpeersec_dgram(skb, &secdata, &seclen);
120 if (err)
121 return;
122
123 put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
124}
125
112 126
113void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) 127void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
114{ 128{
@@ -138,6 +152,11 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
138 152
139 if (flags & 1) 153 if (flags & 1)
140 ip_cmsg_recv_retopts(msg, skb); 154 ip_cmsg_recv_retopts(msg, skb);
155 if ((flags>>=1) == 0)
156 return;
157
158 if (flags & 1)
159 ip_cmsg_recv_security(msg, skb);
141} 160}
142 161
143int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc) 162int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc)
@@ -393,7 +412,8 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
393 (1<<IP_RETOPTS) | (1<<IP_TOS) | 412 (1<<IP_RETOPTS) | (1<<IP_TOS) |
394 (1<<IP_TTL) | (1<<IP_HDRINCL) | 413 (1<<IP_TTL) | (1<<IP_HDRINCL) |
395 (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | 414 (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
396 (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND))) || 415 (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
416 (1<<IP_PASSSEC))) ||
397 optname == IP_MULTICAST_TTL || 417 optname == IP_MULTICAST_TTL ||
398 optname == IP_MULTICAST_LOOP) { 418 optname == IP_MULTICAST_LOOP) {
399 if (optlen >= sizeof(int)) { 419 if (optlen >= sizeof(int)) {
@@ -478,6 +498,12 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
478 else 498 else
479 inet->cmsg_flags &= ~IP_CMSG_RETOPTS; 499 inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
480 break; 500 break;
501 case IP_PASSSEC:
502 if (val)
503 inet->cmsg_flags |= IP_CMSG_PASSSEC;
504 else
505 inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
506 break;
481 case IP_TOS: /* This sets both TOS and Precedence */ 507 case IP_TOS: /* This sets both TOS and Precedence */
482 if (sk->sk_type == SOCK_STREAM) { 508 if (sk->sk_type == SOCK_STREAM) {
483 val &= ~3; 509 val &= ~3;
@@ -932,6 +958,9 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval,
932 case IP_RETOPTS: 958 case IP_RETOPTS:
933 val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0; 959 val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
934 break; 960 break;
961 case IP_PASSSEC:
962 val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
963 break;
935 case IP_TOS: 964 case IP_TOS:
936 val = inet->tos; 965 val = inet->tos;
937 break; 966 break;