X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=linux-2.6-710-xidmask.patch;h=8d56b6d0d0eb80782fa37a0ba54c87f3c815d479;hb=refs%2Fheads%2Frhel6-mlab;hp=5e1897ed16d35b2901edaa7a5eff2f08e7759e6d;hpb=dec39e401234eed5dcc48da5e16a79e4a1d71fc1;p=linux-2.6.git diff --git a/linux-2.6-710-xidmask.patch b/linux-2.6-710-xidmask.patch index 5e1897ed1..8d56b6d0d 100644 --- a/linux-2.6-710-xidmask.patch +++ b/linux-2.6-710-xidmask.patch @@ -1,19 +1,71 @@ +diff -Ndur linux-2.6.32-700/fs/proc/web100.c linux-2.6.32-700-xidmask/fs/proc/web100.c +--- linux-2.6.32-700/fs/proc/web100.c 2013-01-10 14:18:50.429337747 -0500 ++++ linux-2.6.32-700-xidmask/fs/proc/web100.c 2013-02-06 17:36:52.308961450 -0500 +@@ -427,10 +427,10 @@ + local_port = vars->LocalPort; + remote_port = vars->RemPort; + +- len += v6addr_str(tmpbuf + len, (short *)&vars->LocalAddress.v6addr.addr); +- len += sprintf(tmpbuf + len, ".%d ", local_port); +- len += v6addr_str(tmpbuf + len, (short *)&vars->RemAddress.v6addr.addr); +- len += sprintf(tmpbuf + len, ".%d\n", remote_port); ++ len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%pI6", &vars->LocalAddress.v6addr.addr); ++ len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, ".%d ", local_port); ++ len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%pI6", &vars->RemAddress.v6addr.addr); ++ len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, ".%d\n", remote_port); + } else { + printk(KERN_ERR "connection_spec_ascii_read: LocalAddressType invalid\n"); + return 0; +@@ -655,7 +655,8 @@ + + stats = web100stats_first; + while (stats && n < max) { +- if (!stats->wc_dead) { ++ // only return readable stats ++ if ( 1 == vx_can_read_stats(stats) ) { + if (pos <= 0) + cids[n++] = stats->wc_cid; + else +diff -Ndur linux-2.6.32-700/include/linux/vserver/context.h linux-2.6.32-700-xidmask/include/linux/vserver/context.h +--- linux-2.6.32-700/include/linux/vserver/context.h 2013-01-10 14:18:49.949337361 -0500 ++++ linux-2.6.32-700-xidmask/include/linux/vserver/context.h 2013-01-19 23:27:42.280655065 -0500 +@@ -79,6 +79,7 @@ + #define VXC_KTHREAD 0x01000000 + #define VXC_NAMESPACE 0x02000000 + ++#define VXC_ENABLE_WEB100 0x10000000 + + #ifdef __KERNEL__ + diff -Ndur linux-2.6.32-700/include/net/tcp.h linux-2.6.32-700-xidmask/include/net/tcp.h --- linux-2.6.32-700/include/net/tcp.h 2013-01-10 14:18:49.880337393 -0500 -+++ linux-2.6.32-700-xidmask/include/net/tcp.h 2013-01-10 14:21:16.366337329 -0500 -@@ -251,6 +251,8 @@ ++++ linux-2.6.32-700-xidmask/include/net/tcp.h 2013-01-19 15:41:28.218337671 -0500 +@@ -251,6 +251,7 @@ #ifdef CONFIG_WEB100_STATS extern int sysctl_web100_fperms; extern int sysctl_web100_gid; +extern int sysctl_web100_sidestream_xid; -+extern int sysctl_web100_mask_xid; #endif extern atomic_t tcp_memory_allocated; +diff -Ndur linux-2.6.32-700/include/net/web100.h linux-2.6.32-700-xidmask/include/net/web100.h +--- linux-2.6.32-700/include/net/web100.h 2013-01-10 14:18:49.874218972 -0500 ++++ linux-2.6.32-700-xidmask/include/net/web100.h 2013-01-19 23:44:09.561660368 -0500 +@@ -46,7 +46,9 @@ + extern rwlock_t web100_linkage_lock; + + /* For /proc/web100 */ +-extern struct web100stats *web100stats_lookup(int cid); ++extern int vx_can_read_stats(struct web100stats *stats); ++extern struct web100stats *vx_web100stats_lookup(int cid, int vx_filter); ++#define web100stats_lookup(cid) vx_web100stats_lookup(cid, 1) + + /* For the TCP code */ + extern int web100_stats_create(struct sock *sk); diff -Ndur linux-2.6.32-700/net/ipv4/sysctl_net_ipv4.c linux-2.6.32-700-xidmask/net/ipv4/sysctl_net_ipv4.c --- linux-2.6.32-700/net/ipv4/sysctl_net_ipv4.c 2013-01-10 14:18:50.233320698 -0500 -+++ linux-2.6.32-700-xidmask/net/ipv4/sysctl_net_ipv4.c 2013-01-10 14:30:18.997403751 -0500 -@@ -754,6 +754,22 @@ ++++ linux-2.6.32-700-xidmask/net/ipv4/sysctl_net_ipv4.c 2013-01-19 15:41:52.767269242 -0500 +@@ -754,6 +754,14 @@ .mode = 0644, .proc_handler = &web100_proc_dointvec_update, }, @@ -24,31 +76,22 @@ diff -Ndur linux-2.6.32-700/net/ipv4/sysctl_net_ipv4.c linux-2.6.32-700-xidmask/ + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &web100_proc_dointvec_update, -+ }, -+ { -+ .ctl_name = CTL_UNNUMBERED, -+ .procname = "web100_mask_xid", -+ .data = &sysctl_web100_mask_xid, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &web100_proc_dointvec_update, + }, #endif { .ctl_name = CTL_UNNUMBERED, diff -Ndur linux-2.6.32-700/net/ipv4/tcp.c linux-2.6.32-700-xidmask/net/ipv4/tcp.c --- linux-2.6.32-700/net/ipv4/tcp.c 2013-01-10 14:18:50.234322447 -0500 -+++ linux-2.6.32-700-xidmask/net/ipv4/tcp.c 2013-01-10 14:21:16.368337586 -0500 -@@ -297,6 +297,8 @@ ++++ linux-2.6.32-700-xidmask/net/ipv4/tcp.c 2013-01-19 15:42:50.975214376 -0500 +@@ -297,6 +297,7 @@ #ifdef CONFIG_WEB100_STATS int sysctl_web100_fperms = CONFIG_WEB100_FPERMS; int sysctl_web100_gid = CONFIG_WEB100_GID; -+int sysctl_web100_sidestream_xid = 0; -+int sysctl_web100_mask_xid = -1; ++int sysctl_web100_sidestream_xid = -1; #endif atomic_t tcp_memory_allocated; /* Current allocated memory. */ -@@ -848,7 +850,7 @@ +@@ -848,7 +849,7 @@ if (copied) { tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); #ifdef CONFIG_WEB100_STATS @@ -57,7 +100,7 @@ diff -Ndur linux-2.6.32-700/net/ipv4/tcp.c linux-2.6.32-700-xidmask/net/ipv4/tcp #endif } -@@ -1101,7 +1103,7 @@ +@@ -1101,7 +1102,7 @@ if (copied) { tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); #ifdef CONFIG_WEB100_STATS @@ -66,7 +109,7 @@ diff -Ndur linux-2.6.32-700/net/ipv4/tcp.c linux-2.6.32-700-xidmask/net/ipv4/tcp #endif } -@@ -1471,7 +1473,7 @@ +@@ -1471,7 +1472,7 @@ tp->rcv_nxt, flags); } #ifdef CONFIG_WEB100_STATS @@ -141,31 +184,150 @@ diff -Ndur linux-2.6.32-700/net/ipv4/tcp_ipv4.c linux-2.6.32-700-xidmask/net/ipv diff -Ndur linux-2.6.32-700/net/ipv4/web100_stats.c linux-2.6.32-700-xidmask/net/ipv4/web100_stats.c --- linux-2.6.32-700/net/ipv4/web100_stats.c 2013-01-10 14:18:50.231318735 -0500 -+++ linux-2.6.32-700-xidmask/net/ipv4/web100_stats.c 2013-01-10 14:21:16.373337472 -0500 -@@ -252,6 +252,16 @@ ++++ linux-2.6.32-700-xidmask/net/ipv4/web100_stats.c 2013-02-06 22:25:11.711402213 -0500 +@@ -72,7 +72,99 @@ + return cid % web100stats_htsize; + } + +-struct web100stats *web100stats_lookup(int cid) ++/* ++ * Determine if the given socket should have web100 stats structure. ++ * ++ * Args: ++ * sk -- socket pointer ++ * Returns: ++ * 0 -- false, do not create the web100 stats struct ++ * 1 -- true, create the web100 stats structure ++ */ ++int vx_can_create_stats(struct sock *sk) { ++ struct vx_info *vxi=NULL; ++ ++ if ( NULL == sk ) { ++ return 0; ++ } ++ ++ if ( 0 != sk->sk_xid ) { ++ vxi = lookup_vx_info(sk->sk_xid); ++ if ( NULL != vxi && !vx_info_ccaps(vxi, VXC_ENABLE_WEB100) ) { ++ /* do not create stats struct */ ++ return 0; ++ } ++ } ++ /* create stats struct */ ++ return 1; ++} ++ ++/* ++ * Determine if the current task has permission to read given stats struct. The ++ * reader's identity is taken as the current task. If the current task ++ * has permission, then the function returns TRUE. Otherwise, FALSE. ++ * ++ * At least one condition must be satisfied for the function to return TRUE: ++ * xid == 0 -- reader is the root context of the system. ++ * xid == stats->wc_sk->sk_xid -- reader created the stats object ++ * xid == web100_sidestream_xid -- reader can see all stats ++ * ++ * Args: ++ * stats - the web100 stats structure to read. ++ * ++ * Returns: ++ * 0 - FALSE, read permission should be denied. ++ * 1 - TRUE, current task has read permission ++ */ ++int vx_can_read_stats(struct web100stats *stats) { ++ struct vx_info *vxi=NULL; ++ struct sock *sk = NULL; ++ ++ if ( NULL == stats || stats->wc_dead ) { ++ return 0; ++ } ++ ++ if ( 0 == vx_current_xid() ) { ++ // always ok for xid=0 (root context) ++ return 1; ++ } ++ ++ vxi = current_vx_info(); ++ if ( NULL == vxi ) { ++ /* non-root context is missing vx_info; cannot check access flags */ ++ return 0; ++ } ++ ++ if ( vx_current_xid() == sysctl_web100_sidestream_xid ) { ++ /* the sidestream xid can view all stats. */ ++ return 1; ++ } ++ ++ sk = stats->wc_sk; ++ if ( vx_current_xid() == sk->sk_xid ) { ++ /* the xid is the socket owner so can see it's own connections */ ++ return 1; ++ } ++ ++ /* all checks have failed, so deny read permission. */ ++ return 0; ++} ++ ++/* ++ * Based on the connection ID, return the web100stats structure. ++ * Optionally, when vx_filter=1, filter the result by the ++ * read-permission of the current task. When vx_filter=0, do not perform ++ * filtering. ++ * ++ * Args: ++ * cid -- connection id ++ * vx_filter -- 1 or 0, filter the returned stats or not ++ * ++ * Returns: ++ * If the cid is found, a pointer to a web100stats struct; ++ * If the cid is not found or filtered, NULL is returned. ++ */ ++struct web100stats *vx_web100stats_lookup(int cid, int vx_filter) + { + struct web100stats *stats; + +@@ -83,7 +175,10 @@ + stats = web100stats_ht[web100stats_hash(cid)]; + while (stats && stats->wc_cid != cid) + stats = stats->wc_hash_next; +- return stats; ++ if ( 0 == vx_filter || 1 == vx_can_read_stats(stats) ) { ++ return stats; ++ } ++ return NULL; + } + + /* This will get really slow as the cid space fills. This can be done +@@ -99,7 +194,8 @@ + + i = web100stats_next_cid; + do { +- if (web100stats_lookup(i) == NULL) ++ /* use vx sensitive version *without* filtering */ ++ if (vx_web100stats_lookup(i,0) == NULL) + break; + i = (i + 1) % WEB100_MAX_CONNS; + } while (i != web100stats_next_cid); +@@ -252,6 +348,12 @@ struct web100directs *vars; struct tcp_sock *tp = tcp_sk(sk); struct timeval tv; + -+ printk("Web100: stats_create(): checking xid(%d) mask(%d)\n", -+ sk->sk_xid, sysctl_web100_mask_xid); -+ if ( sk->sk_xid == sysctl_web100_mask_xid ) { -+ /* this xid is masked, so do not allocate or update tcp_stats */ -+ printk("Web100: skipping stats_create() for xid(%d) mask(%d)\n", -+ sk->sk_xid, sysctl_web100_mask_xid); ++ if ( 0 == vx_can_create_stats(sk) ) { ++ /* do not create web100 stats for this socket */ + tp->tcp_stats = NULL; + return 0; + } if ((stats = kmalloc(sizeof (struct web100stats), gfp_any())) == NULL) return -ENOMEM; -@@ -294,6 +304,9 @@ +@@ -294,6 +396,9 @@ void web100_stats_destroy(struct web100stats *stats) { -+ if ( stats == NULL ) { -+ return; -+ } ++ if ( NULL == stats ) { ++ return; ++ } /* Attribute final sndlim time. */ web100_update_sndlim(tcp_sk(stats->wc_sk), stats->wc_limstate);