diff options
Diffstat (limited to 'net/ipv4/ip_sockglue.c')
-rw-r--r-- | net/ipv4/ip_sockglue.c | 31 |
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 | ||
113 | static 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 | ||
113 | void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) | 127 | void 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 | ||
143 | int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc) | 162 | int 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; |