/* Description: Check the setsockopt() call and if the user is trying to replace the IP options on a socket and a NetLabel is in place for the socket deny the access; otherwise allow the access. Returns zero when the access is allowed, -EACCES when denied, and other negative values on error.  */
int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname)
/* Description: Check the setsockopt() call and if the user is trying to replace the IP options on a socket and a NetLabel is in place for the socket deny the access; otherwise allow the access. Returns zero when the access is allowed, -EACCES when denied, and other negative values on error.  */
int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname)
{
	int rc = 0;
	struct sock *sk = sock->sk;
	struct sk_security_struct *sksec = sk->sk_security;
	struct netlbl_lsm_secattr secattr;
	if (level == IPPROTO_IP && optname == IP_OPTIONS &&
	    (sksec->nlbl_state == NLBL_LABELED ||
	     sksec->nlbl_state == NLBL_CONNLABELED)) {
		netlbl_secattr_init(&secattr);
		lock_sock(sk);
		rc = netlbl_sock_getattr(sk, &secattr);
		release_sock(sk);
		if (rc == 0)
			rc = -EACCES;
		else if (rc == -ENOMSG)
			rc = 0;
		netlbl_secattr_destroy(&secattr);
	}
	return rc;
}