else
clear_bit(SOCK_PASSSEC, &sock->flags);
break;
+ case SO_MARK:
+ if (!capable(CAP_NET_ADMIN))
+ ret = -EPERM;
+ else {
+ sk->sk_mark = val;
+ }
+ break;
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
case SO_PEERSEC:
return security_socket_getpeersec_stream(sock, optval, optlen, len);
+ case SO_MARK:
+ v.val = sk->sk_mark;
+ break;
+
default:
return -ENOPROTOOPT;
}
if (atomic_read(&sk->sk_omem_alloc))
printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n",
- __FUNCTION__, atomic_read(&sk->sk_omem_alloc));
+ __func__, atomic_read(&sk->sk_omem_alloc));
put_net(sk->sk_net);
sk_prot_free(sk->sk_prot_creator, sk);
}
+/*
+ * Last sock_put should drop referrence to sk->sk_net. It has already
+ * been dropped in sk_change_net. Taking referrence to stopping namespace
+ * is not an option.
+ * Take referrence to a socket to remove it from hash _alive_ and after that
+ * destroy it in the context of init_net.
+ */
+void sk_release_kernel(struct sock *sk)
+{
+ if (sk == NULL || sk->sk_socket == NULL)
+ return;
+
+ sock_hold(sk);
+ sock_release(sk->sk_socket);
+ sk->sk_net = get_net(&init_net);
+ sock_put(sk);
+}
+EXPORT_SYMBOL(sk_release_kernel);
+
struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
{
struct sock *newsk;
atomic_set(&sk->sk_drops, 0);
}
-void fastcall lock_sock_nested(struct sock *sk, int subclass)
+void lock_sock_nested(struct sock *sk, int subclass)
{
might_sleep();
spin_lock_bh(&sk->sk_lock.slock);
EXPORT_SYMBOL(lock_sock_nested);
-void fastcall release_sock(struct sock *sk)
+void release_sock(struct sock *sk)
{
/*
* The sk_lock has mutex_unlock() semantics:
char *request_sock_slab_name = NULL;
char *timewait_sock_slab_name;
- if (pcounter_alloc(&prot->inuse) != 0) {
+ if (sock_prot_inuse_init(prot) != 0) {
printk(KERN_CRIT "%s: Can't alloc inuse counters!\n", prot->name);
goto out;
}
kmem_cache_destroy(prot->slab);
prot->slab = NULL;
out_free_inuse:
- pcounter_free(&prot->inuse);
+ sock_prot_inuse_free(prot);
out:
return -ENOBUFS;
}
list_del(&prot->node);
write_unlock(&proto_list_lock);
- pcounter_free(&prot->inuse);
+ sock_prot_inuse_free(prot);
if (prot->slab != NULL) {
kmem_cache_destroy(prot->slab);
#ifdef CONFIG_PROC_FS
static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(proto_list_lock)
{
read_lock(&proto_list_lock);
return seq_list_start_head(&proto_list, *pos);
}
static void proto_seq_stop(struct seq_file *seq, void *v)
+ __releases(proto_list_lock)
{
read_unlock(&proto_list_lock);
}