aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-11-20 01:38:33 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:54:32 -0500
commit42a73808ed4f30b739eb52bcbb33a02fe62ceef5 (patch)
tree3bd75f0afd1277d9340aa416ff79eec0be040392
parentab70768ec78c6784958bab3b58fbe3f4150006df (diff)
[RAW]: Consolidate proc interface.
Both ipv6/raw.c and ipv4/raw.c use the seq files to walk through the raw sockets hash and show them. The "walking" code is rather huge, but is identical in both cases. The difference is the hash table to walk over and the protocol family to check (this was not in the first virsion of the patch, which was noticed by YOSHIFUJI) Make the ->open store the needed hash table and the family on the allocated raw_iter_state and make the start/next/stop callbacks work with it. This removes most of the code. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/raw.h14
-rw-r--r--net/ipv4/raw.c52
-rw-r--r--net/ipv6/raw.c82
3 files changed, 53 insertions, 95 deletions
diff --git a/include/net/raw.h b/include/net/raw.h
index 81a1773b58ba..4d1aba032bf5 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -37,6 +37,20 @@ struct raw_hashinfo {
37#ifdef CONFIG_PROC_FS 37#ifdef CONFIG_PROC_FS
38extern int raw_proc_init(void); 38extern int raw_proc_init(void);
39extern void raw_proc_exit(void); 39extern void raw_proc_exit(void);
40
41struct raw_iter_state {
42 int bucket;
43 unsigned short family;
44 struct raw_hashinfo *h;
45};
46
47#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
48void *raw_seq_start(struct seq_file *seq, loff_t *pos);
49void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
50void raw_seq_stop(struct seq_file *seq, void *v);
51int raw_seq_open(struct file *file, struct raw_hashinfo *h,
52 unsigned short family);
53
40#endif 54#endif
41 55
42void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h); 56void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h);
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index d24501a342a4..2ff8214a530b 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -845,12 +845,6 @@ struct proto raw_prot = {
845}; 845};
846 846
847#ifdef CONFIG_PROC_FS 847#ifdef CONFIG_PROC_FS
848struct raw_iter_state {
849 int bucket;
850};
851
852#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
853
854static struct sock *raw_get_first(struct seq_file *seq) 848static struct sock *raw_get_first(struct seq_file *seq)
855{ 849{
856 struct sock *sk; 850 struct sock *sk;
@@ -860,8 +854,8 @@ static struct sock *raw_get_first(struct seq_file *seq)
860 ++state->bucket) { 854 ++state->bucket) {
861 struct hlist_node *node; 855 struct hlist_node *node;
862 856
863 sk_for_each(sk, node, &raw_v4_hashinfo.ht[state->bucket]) 857 sk_for_each(sk, node, &state->h->ht[state->bucket])
864 if (sk->sk_family == PF_INET) 858 if (sk->sk_family == state->family)
865 goto found; 859 goto found;
866 } 860 }
867 sk = NULL; 861 sk = NULL;
@@ -877,10 +871,10 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
877 sk = sk_next(sk); 871 sk = sk_next(sk);
878try_again: 872try_again:
879 ; 873 ;
880 } while (sk && sk->sk_family != PF_INET); 874 } while (sk && sk->sk_family != state->family);
881 875
882 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) { 876 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
883 sk = sk_head(&raw_v4_hashinfo.ht[state->bucket]); 877 sk = sk_head(&state->h->ht[state->bucket]);
884 goto try_again; 878 goto try_again;
885 } 879 }
886 return sk; 880 return sk;
@@ -896,13 +890,16 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
896 return pos ? NULL : sk; 890 return pos ? NULL : sk;
897} 891}
898 892
899static void *raw_seq_start(struct seq_file *seq, loff_t *pos) 893void *raw_seq_start(struct seq_file *seq, loff_t *pos)
900{ 894{
901 read_lock(&raw_v4_hashinfo.lock); 895 struct raw_iter_state *state = raw_seq_private(seq);
896
897 read_lock(&state->h->lock);
902 return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; 898 return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
903} 899}
900EXPORT_SYMBOL_GPL(raw_seq_start);
904 901
905static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos) 902void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
906{ 903{
907 struct sock *sk; 904 struct sock *sk;
908 905
@@ -913,11 +910,15 @@ static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
913 ++*pos; 910 ++*pos;
914 return sk; 911 return sk;
915} 912}
913EXPORT_SYMBOL_GPL(raw_seq_next);
916 914
917static void raw_seq_stop(struct seq_file *seq, void *v) 915void raw_seq_stop(struct seq_file *seq, void *v)
918{ 916{
919 read_unlock(&raw_v4_hashinfo.lock); 917 struct raw_iter_state *state = raw_seq_private(seq);
918
919 read_unlock(&state->h->lock);
920} 920}
921EXPORT_SYMBOL_GPL(raw_seq_stop);
921 922
922static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i) 923static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
923{ 924{
@@ -964,15 +965,30 @@ static const struct seq_operations raw_seq_ops = {
964 .show = raw_seq_show, 965 .show = raw_seq_show,
965}; 966};
966 967
967static int raw_seq_open(struct inode *inode, struct file *file) 968int raw_seq_open(struct file *file, struct raw_hashinfo *h,
969 unsigned short family)
968{ 970{
969 return seq_open_private(file, &raw_seq_ops, 971 struct raw_iter_state *i;
972
973 i = __seq_open_private(file, &raw_seq_ops,
970 sizeof(struct raw_iter_state)); 974 sizeof(struct raw_iter_state));
975 if (i == NULL)
976 return -ENOMEM;
977
978 i->h = h;
979 i->family = family;
980 return 0;
981}
982EXPORT_SYMBOL_GPL(raw_seq_open);
983
984static int raw_v4_seq_open(struct inode *inode, struct file *file)
985{
986 return raw_seq_open(file, &raw_v4_hashinfo, PF_INET);
971} 987}
972 988
973static const struct file_operations raw_seq_fops = { 989static const struct file_operations raw_seq_fops = {
974 .owner = THIS_MODULE, 990 .owner = THIS_MODULE,
975 .open = raw_seq_open, 991 .open = raw_v4_seq_open,
976 .read = seq_read, 992 .read = seq_read,
977 .llseek = seq_lseek, 993 .llseek = seq_lseek,
978 .release = seq_release_private, 994 .release = seq_release_private,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 422d27cfbe16..b34631e1b015 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1200,77 +1200,6 @@ struct proto rawv6_prot = {
1200}; 1200};
1201 1201
1202#ifdef CONFIG_PROC_FS 1202#ifdef CONFIG_PROC_FS
1203struct raw6_iter_state {
1204 int bucket;
1205};
1206
1207#define raw6_seq_private(seq) ((struct raw6_iter_state *)(seq)->private)
1208
1209static struct sock *raw6_get_first(struct seq_file *seq)
1210{
1211 struct sock *sk;
1212 struct hlist_node *node;
1213 struct raw6_iter_state* state = raw6_seq_private(seq);
1214
1215 for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
1216 ++state->bucket)
1217 sk_for_each(sk, node, &raw_v6_hashinfo.ht[state->bucket])
1218 if (sk->sk_family == PF_INET6)
1219 goto out;
1220 sk = NULL;
1221out:
1222 return sk;
1223}
1224
1225static struct sock *raw6_get_next(struct seq_file *seq, struct sock *sk)
1226{
1227 struct raw6_iter_state* state = raw6_seq_private(seq);
1228
1229 do {
1230 sk = sk_next(sk);
1231try_again:
1232 ;
1233 } while (sk && sk->sk_family != PF_INET6);
1234
1235 if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
1236 sk = sk_head(&raw_v6_hashinfo.ht[state->bucket]);
1237 goto try_again;
1238 }
1239 return sk;
1240}
1241
1242static struct sock *raw6_get_idx(struct seq_file *seq, loff_t pos)
1243{
1244 struct sock *sk = raw6_get_first(seq);
1245 if (sk)
1246 while (pos && (sk = raw6_get_next(seq, sk)) != NULL)
1247 --pos;
1248 return pos ? NULL : sk;
1249}
1250
1251static void *raw6_seq_start(struct seq_file *seq, loff_t *pos)
1252{
1253 read_lock(&raw_v6_hashinfo.lock);
1254 return *pos ? raw6_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
1255}
1256
1257static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1258{
1259 struct sock *sk;
1260
1261 if (v == SEQ_START_TOKEN)
1262 sk = raw6_get_first(seq);
1263 else
1264 sk = raw6_get_next(seq, v);
1265 ++*pos;
1266 return sk;
1267}
1268
1269static void raw6_seq_stop(struct seq_file *seq, void *v)
1270{
1271 read_unlock(&raw_v6_hashinfo.lock);
1272}
1273
1274static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) 1203static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
1275{ 1204{
1276 struct ipv6_pinfo *np = inet6_sk(sp); 1205 struct ipv6_pinfo *np = inet6_sk(sp);
@@ -1308,21 +1237,20 @@ static int raw6_seq_show(struct seq_file *seq, void *v)
1308 "st tx_queue rx_queue tr tm->when retrnsmt" 1237 "st tx_queue rx_queue tr tm->when retrnsmt"
1309 " uid timeout inode drops\n"); 1238 " uid timeout inode drops\n");
1310 else 1239 else
1311 raw6_sock_seq_show(seq, v, raw6_seq_private(seq)->bucket); 1240 raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
1312 return 0; 1241 return 0;
1313} 1242}
1314 1243
1315static const struct seq_operations raw6_seq_ops = { 1244static const struct seq_operations raw6_seq_ops = {
1316 .start = raw6_seq_start, 1245 .start = raw_seq_start,
1317 .next = raw6_seq_next, 1246 .next = raw_seq_next,
1318 .stop = raw6_seq_stop, 1247 .stop = raw_seq_stop,
1319 .show = raw6_seq_show, 1248 .show = raw6_seq_show,
1320}; 1249};
1321 1250
1322static int raw6_seq_open(struct inode *inode, struct file *file) 1251static int raw6_seq_open(struct inode *inode, struct file *file)
1323{ 1252{
1324 return seq_open_private(file, &raw6_seq_ops, 1253 return raw_seq_open(file, &raw_v6_hashinfo, PF_INET6);
1325 sizeof(struct raw6_iter_state));
1326} 1254}
1327 1255
1328static const struct file_operations raw6_seq_fops = { 1256static const struct file_operations raw6_seq_fops = {