diff options
-rw-r--r-- | include/net/raw.h | 14 | ||||
-rw-r--r-- | net/ipv4/raw.c | 52 | ||||
-rw-r--r-- | net/ipv6/raw.c | 82 |
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 |
38 | extern int raw_proc_init(void); | 38 | extern int raw_proc_init(void); |
39 | extern void raw_proc_exit(void); | 39 | extern void raw_proc_exit(void); |
40 | |||
41 | struct 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) | ||
48 | void *raw_seq_start(struct seq_file *seq, loff_t *pos); | ||
49 | void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos); | ||
50 | void raw_seq_stop(struct seq_file *seq, void *v); | ||
51 | int raw_seq_open(struct file *file, struct raw_hashinfo *h, | ||
52 | unsigned short family); | ||
53 | |||
40 | #endif | 54 | #endif |
41 | 55 | ||
42 | void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h); | 56 | void 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 |
848 | struct raw_iter_state { | ||
849 | int bucket; | ||
850 | }; | ||
851 | |||
852 | #define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private) | ||
853 | |||
854 | static struct sock *raw_get_first(struct seq_file *seq) | 848 | static 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); |
878 | try_again: | 872 | try_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 | ||
899 | static void *raw_seq_start(struct seq_file *seq, loff_t *pos) | 893 | void *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 | } |
900 | EXPORT_SYMBOL_GPL(raw_seq_start); | ||
904 | 901 | ||
905 | static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 902 | void *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 | } |
913 | EXPORT_SYMBOL_GPL(raw_seq_next); | ||
916 | 914 | ||
917 | static void raw_seq_stop(struct seq_file *seq, void *v) | 915 | void 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 | } |
921 | EXPORT_SYMBOL_GPL(raw_seq_stop); | ||
921 | 922 | ||
922 | static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i) | 923 | static __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 | ||
967 | static int raw_seq_open(struct inode *inode, struct file *file) | 968 | int 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 | } | ||
982 | EXPORT_SYMBOL_GPL(raw_seq_open); | ||
983 | |||
984 | static 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 | ||
973 | static const struct file_operations raw_seq_fops = { | 989 | static 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 |
1203 | struct raw6_iter_state { | ||
1204 | int bucket; | ||
1205 | }; | ||
1206 | |||
1207 | #define raw6_seq_private(seq) ((struct raw6_iter_state *)(seq)->private) | ||
1208 | |||
1209 | static 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; | ||
1221 | out: | ||
1222 | return sk; | ||
1223 | } | ||
1224 | |||
1225 | static 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); | ||
1231 | try_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 | |||
1242 | static 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 | |||
1251 | static 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 | |||
1257 | static 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 | |||
1269 | static void raw6_seq_stop(struct seq_file *seq, void *v) | ||
1270 | { | ||
1271 | read_unlock(&raw_v6_hashinfo.lock); | ||
1272 | } | ||
1273 | |||
1274 | static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | 1203 | static 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 | ||
1315 | static const struct seq_operations raw6_seq_ops = { | 1244 | static 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 | ||
1322 | static int raw6_seq_open(struct inode *inode, struct file *file) | 1251 | static 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 | ||
1328 | static const struct file_operations raw6_seq_fops = { | 1256 | static const struct file_operations raw6_seq_fops = { |