Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 214546
b: refs/heads/master
c: 4e3d16c
h: refs/heads/master
v: v3
  • Loading branch information
Rémi Denis-Courmont authored and David S. Miller committed Sep 16, 2010
1 parent c3c84fa commit 9be23cd
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6482f554e2b9cbe733d63124765104f29cf0c9ad
refs/heads/master: 4e3d16ce5e82648d7f4dfd28b6cf8fe2e9a9efc3
5 changes: 5 additions & 0 deletions trunk/include/net/phonet/phonet.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ void pn_sock_hash(struct sock *sk);
void pn_sock_unhash(struct sock *sk);
int pn_sock_get_port(struct sock *sk, unsigned short sport);

struct sock *pn_find_sock_by_res(struct net *net, u8 res);
int pn_sock_bind_res(struct sock *sock, u8 res);
int pn_sock_unbind_res(struct sock *sk, u8 res);
void pn_sock_unbind_all_res(struct sock *sk);

int pn_skb_send(struct sock *sk, struct sk_buff *skb,
const struct sockaddr_pn *target);

Expand Down
88 changes: 88 additions & 0 deletions trunk/net/phonet/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,3 +565,91 @@ const struct file_operations pn_sock_seq_fops = {
.release = seq_release_net,
};
#endif

static struct {
struct sock *sk[256];
} pnres;

/*
* Find and hold socket based on resource.
*/
struct sock *pn_find_sock_by_res(struct net *net, u8 res)
{
struct sock *sk;

if (!net_eq(net, &init_net))
return NULL;

rcu_read_lock();
sk = rcu_dereference(pnres.sk[res]);
if (sk)
sock_hold(sk);
rcu_read_unlock();
return sk;
}

static DEFINE_MUTEX(resource_mutex);

int pn_sock_bind_res(struct sock *sk, u8 res)
{
int ret = -EADDRINUSE;

if (!net_eq(sock_net(sk), &init_net))
return -ENOIOCTLCMD;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (pn_socket_autobind(sk->sk_socket))
return -EAGAIN;

mutex_lock(&resource_mutex);
if (pnres.sk[res] == NULL) {
sock_hold(sk);
rcu_assign_pointer(pnres.sk[res], sk);
ret = 0;
}
mutex_unlock(&resource_mutex);
return ret;
}

int pn_sock_unbind_res(struct sock *sk, u8 res)
{
int ret = -ENOENT;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;

mutex_lock(&resource_mutex);
if (pnres.sk[res] == sk) {
rcu_assign_pointer(pnres.sk[res], NULL);
ret = 0;
}
mutex_unlock(&resource_mutex);

if (ret == 0) {
synchronize_rcu();
sock_put(sk);
}
return ret;
}

void pn_sock_unbind_all_res(struct sock *sk)
{
unsigned res, match = 0;

mutex_lock(&resource_mutex);
for (res = 0; res < 256; res++) {
if (pnres.sk[res] == sk) {
rcu_assign_pointer(pnres.sk[res], NULL);
match++;
}
}
mutex_unlock(&resource_mutex);

if (match == 0)
return;
synchronize_rcu();
while (match > 0) {
sock_put(sk);
match--;
}
}

0 comments on commit 9be23cd

Please sign in to comment.