#ifndef _NX_VS_NETWORK_H
#define _NX_VS_NETWORK_H
-
-// #define NX_DEBUG
-
-#include <linux/kernel.h>
-#include <linux/rcupdate.h>
-#include <linux/sched.h>
-
+#include "vserver/context.h"
#include "vserver/network.h"
-
-#if defined(NX_DEBUG)
-#define nxdprintk(x...) printk("nxd: " x)
-#else
-#define nxdprintk(x...)
-#endif
-
-
-extern int proc_pid_nx_info(struct task_struct *, char *);
+#include "vserver/base.h"
+#include "vserver/debug.h"
#define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__)
{
if (!nxi)
return NULL;
- nxdprintk("get_nx_info(%p[#%d.%d])\t%s:%d\n",
+
+ vxlprintk(VXD_CBIT(nid, 2), "get_nx_info(%p[#%d.%d])",
nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
_file, _line);
+
atomic_inc(&nxi->nx_usecnt);
return nxi;
}
-#define free_nx_info(nxi) \
- call_rcu(&nxi->nx_rcu, rcu_free_nx_info);
+extern void free_nx_info(struct nx_info *);
#define put_nx_info(i) __put_nx_info(i,__FILE__,__LINE__)
{
if (!nxi)
return;
- nxdprintk("put_nx_info(%p[#%d.%d])\t%s:%d\n",
+
+ vxlprintk(VXD_CBIT(nid, 2), "put_nx_info(%p[#%d.%d])",
nxi, nxi?nxi->nx_id:0, nxi?atomic_read(&nxi->nx_usecnt):0,
_file, _line);
+
if (atomic_dec_and_test(&nxi->nx_usecnt))
free_nx_info(nxi);
}
+#define init_nx_info(p,i) __init_nx_info(p,i,__FILE__,__LINE__)
+
+static inline void __init_nx_info(struct nx_info **nxp, struct nx_info *nxi,
+ const char *_file, int _line)
+{
+ if (nxi) {
+ vxlprintk(VXD_CBIT(nid, 3),
+ "init_nx_info(%p[#%d.%d])",
+ nxi, nxi?nxi->nx_id:0,
+ nxi?atomic_read(&nxi->nx_usecnt):0,
+ _file, _line);
+
+ atomic_inc(&nxi->nx_usecnt);
+ }
+ *nxp = nxi;
+}
+
+
#define set_nx_info(p,i) __set_nx_info(p,i,__FILE__,__LINE__)
static inline void __set_nx_info(struct nx_info **nxp, struct nx_info *nxi,
const char *_file, int _line)
{
- BUG_ON(*nxp);
+ struct nx_info *nxo;
+
if (!nxi)
return;
- nxdprintk("set_nx_info(%p[#%d.%d.%d])\t%s:%d\n",
+
+ vxlprintk(VXD_CBIT(nid, 3), "set_nx_info(%p[#%d.%d])",
nxi, nxi?nxi->nx_id:0,
nxi?atomic_read(&nxi->nx_usecnt):0,
- nxi?atomic_read(&nxi->nx_refcnt):0,
_file, _line);
- atomic_inc(&nxi->nx_refcnt);
- *nxp = __get_nx_info(nxi, _file, _line);
+
+ atomic_inc(&nxi->nx_usecnt);
+ nxo = xchg(nxp, nxi);
+ BUG_ON(nxo);
}
-#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__)
+#define clr_nx_info(p) __clr_nx_info(p,__FILE__,__LINE__)
static inline void __clr_nx_info(struct nx_info **nxp,
const char *_file, int _line)
{
- struct nx_info *nxo = *nxp;
+ struct nx_info *nxo;
+ nxo = xchg(nxp, NULL);
if (!nxo)
return;
- nxdprintk("clr_nx_info(%p[#%d.%d.%d])\t%s:%d\n",
+
+ vxlprintk(VXD_CBIT(nid, 3), "clr_nx_info(%p[#%d.%d])",
nxo, nxo?nxo->nx_id:0,
nxo?atomic_read(&nxo->nx_usecnt):0,
- nxo?atomic_read(&nxo->nx_refcnt):0,
_file, _line);
- *nxp = NULL;
- wmb();
- if (nxo && atomic_dec_and_test(&nxo->nx_refcnt))
- unhash_nx_info(nxo);
- __put_nx_info(nxo, _file, _line);
+
+ if (atomic_dec_and_test(&nxo->nx_usecnt))
+ free_nx_info(nxo);
}
-#define task_get_nx_info(i) __task_get_nx_info(i,__FILE__,__LINE__)
+#define claim_nx_info(v,p) __claim_nx_info(v,p,__FILE__,__LINE__)
-static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
- const char *_file, int _line)
+static inline void __claim_nx_info(struct nx_info *nxi,
+ struct task_struct *task, const char *_file, int _line)
{
- struct nx_info *nxi;
-
- task_lock(p);
- nxi = __get_nx_info(p->nx_info, _file, _line);
- task_unlock(p);
- return nxi;
-}
-
-#define nx_verify_info(p,i) \
- __nx_verify_info((p)->nx_info,i,__FILE__,__LINE__)
+ vxlprintk(VXD_CBIT(nid, 3), "claim_nx_info(%p[#%d.%d.%d]) %p",
+ nxi, nxi?nxi->nx_id:0,
+ nxi?atomic_read(&nxi->nx_usecnt):0,
+ nxi?atomic_read(&nxi->nx_tasks):0,
+ task, _file, _line);
-static __inline__ void __nx_verify_info(
- struct nx_info *ipa, struct nx_info *ipb,
- const char *_file, int _line)
-{
- if (ipa == ipb)
- return;
- printk(KERN_ERR "ip bad assumption (%p==%p) at %s:%d\n",
- ipa, ipb, _file, _line);
+ atomic_inc(&nxi->nx_tasks);
}
-#define nx_task_nid(t) ((t)->nid)
+extern void unhash_nx_info(struct nx_info *);
-#define nx_current_nid() nx_task_nid(current)
+#define release_nx_info(v,p) __release_nx_info(v,p,__FILE__,__LINE__)
-#define nx_check(c,m) __nx_check(nx_current_nid(),c,m)
+static inline void __release_nx_info(struct nx_info *nxi,
+ struct task_struct *task, const char *_file, int _line)
+{
+ vxlprintk(VXD_CBIT(nid, 3), "release_nx_info(%p[#%d.%d.%d]) %p",
+ nxi, nxi?nxi->nx_id:0,
+ nxi?atomic_read(&nxi->nx_usecnt):0,
+ nxi?atomic_read(&nxi->nx_tasks):0,
+ task, _file, _line);
-#define nx_weak_check(c,m) ((m) ? nx_check(c,m) : 1)
+ might_sleep();
-#undef nxdprintk
-#define nxdprintk(x...)
+ if (atomic_dec_and_test(&nxi->nx_tasks))
+ unhash_nx_info(nxi);
+}
-#define __nx_flags(v,m,f) (((v) & (m)) ^ (f))
+#define task_get_nx_info(i) __task_get_nx_info(i,__FILE__,__LINE__)
-#define __nx_task_flags(t,m,f) \
- (((t) && ((t)->nx_info)) ? \
- __nx_flags((t)->nx_info->nx_flags,(m),(f)) : 0)
+static __inline__ struct nx_info *__task_get_nx_info(struct task_struct *p,
+ const char *_file, int _line)
+{
+ struct nx_info *nxi;
+
+ task_lock(p);
+ vxlprintk(VXD_CBIT(nid, 5), "task_get_nx_info(%p)",
+ p, _file, _line);
+ nxi = __get_nx_info(p->nx_info, _file, _line);
+ task_unlock(p);
+ return nxi;
+}
-#define nx_current_flags() \
- ((current->nx_info) ? current->nx_info->nx_flags : 0)
-#define nx_flags(m,f) __nx_flags(nx_current_flags(),(m),(f))
-#define nx_current_ncaps() \
- ((current->nx_info) ? current->nx_info->nx_ncaps : 0)
+static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr)
+{
+ int n,i;
-#define nx_ncaps(c) (nx_current_ncaps() & (c))
+ if (!nxi)
+ return 1;
+
+ n = nxi->nbipv4;
+ if (n && (nxi->ipv4[0] == 0))
+ return 1;
+ for (i=0; i<n; i++) {
+ if (nxi->ipv4[i] == addr)
+ return 1;
+ }
+ return 0;
+}
+static inline void exit_nx_info(struct task_struct *p)
+{
+ if (p->nx_info)
+ release_nx_info(p->nx_info, p);
+}
#else