* Re: [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6.
[not found] <ko3rsc@ger.gmane.org>
@ 2013-05-29 5:47 ` Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 5:47 UTC (permalink / raw)
To: netdev; +Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov
Ok, here's a new complete patchset.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show.
2013-05-29 5:47 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
@ 2013-05-29 5:47 ` Lorenzo Colitti
2013-06-01 0:01 ` David Miller
2013-05-29 5:47 ` [PATCH v3 2/3] net: ipv4: make the ping /proc code AF-independent Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 5:47 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
udp6_sock_seq_show and raw6_sock_seq_show are identical, except
the UDP version displays ports and the raw version displays the
protocol. Refactor most of the code in these two functions into
a new common ip6_dgram_sock_seq_show function, in preparation
for using it to display ICMPv6 sockets as well.
Also reduce the indentation in parts of include/net/transp_v6.h
to improve readability.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/transp_v6.h | 73 +++++++++++++++++++++++++++++--------------------
net/ipv6/datagram.c | 27 ++++++++++++++++++
net/ipv6/raw.c | 45 ++++++------------------------
net/ipv6/udp.c | 49 ++++++---------------------------
4 files changed, 87 insertions(+), 107 deletions(-)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index eb40e71..841c33e 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -16,38 +16,51 @@ extern struct proto pingv6_prot;
struct flowi6;
/* extension headers */
-extern int ipv6_exthdrs_init(void);
-extern void ipv6_exthdrs_exit(void);
-extern int ipv6_frag_init(void);
-extern void ipv6_frag_exit(void);
+extern int ipv6_exthdrs_init(void);
+extern void ipv6_exthdrs_exit(void);
+extern int ipv6_frag_init(void);
+extern void ipv6_frag_exit(void);
/* transport protocols */
-extern int pingv6_init(void);
-extern void pingv6_exit(void);
-extern int rawv6_init(void);
-extern void rawv6_exit(void);
-extern int udpv6_init(void);
-extern void udpv6_exit(void);
-extern int udplitev6_init(void);
-extern void udplitev6_exit(void);
-extern int tcpv6_init(void);
-extern void tcpv6_exit(void);
-
-extern int udpv6_connect(struct sock *sk,
- struct sockaddr *uaddr,
- int addr_len);
-
-extern int ip6_datagram_recv_ctl(struct sock *sk,
- struct msghdr *msg,
- struct sk_buff *skb);
-
-extern int ip6_datagram_send_ctl(struct net *net,
- struct sock *sk,
- struct msghdr *msg,
- struct flowi6 *fl6,
- struct ipv6_txoptions *opt,
- int *hlimit, int *tclass,
- int *dontfrag);
+extern int pingv6_init(void);
+extern void pingv6_exit(void);
+extern int rawv6_init(void);
+extern void rawv6_exit(void);
+extern int udpv6_init(void);
+extern void udpv6_exit(void);
+extern int udplitev6_init(void);
+extern void udplitev6_exit(void);
+extern int tcpv6_init(void);
+extern void tcpv6_exit(void);
+
+extern int udpv6_connect(struct sock *sk,
+ struct sockaddr *uaddr,
+ int addr_len);
+
+extern int ip6_datagram_recv_ctl(struct sock *sk,
+ struct msghdr *msg,
+ struct sk_buff *skb);
+
+extern int ip6_datagram_send_ctl(struct net *net,
+ struct sock *sk,
+ struct msghdr *msg,
+ struct flowi6 *fl6,
+ struct ipv6_txoptions *opt,
+ int *hlimit, int *tclass,
+ int *dontfrag);
+
+#define IPV6_SEQ_DGRAM_HEADER \
+ " sl " \
+ "local_address " \
+ "remote_address " \
+ "st tx_queue rx_queue tr tm->when retrnsmt" \
+ " uid timeout inode ref pointer drops\n"
+
+extern void ip6_dgram_sock_seq_show(struct seq_file *seq,
+ struct sock *sp,
+ __u16 srcp,
+ __u16 destp,
+ int bucket);
#define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 4b56cbb..197e6f4 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -879,3 +879,30 @@ exit_f:
return err;
}
EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);
+
+void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
+ __u16 srcp, __u16 destp, int bucket)
+{
+ struct ipv6_pinfo *np = inet6_sk(sp);
+ const struct in6_addr *dest, *src;
+
+ dest = &np->daddr;
+ src = &np->rcv_saddr;
+ seq_printf(seq,
+ "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
+ "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
+ bucket,
+ src->s6_addr32[0], src->s6_addr32[1],
+ src->s6_addr32[2], src->s6_addr32[3], srcp,
+ dest->s6_addr32[0], dest->s6_addr32[1],
+ dest->s6_addr32[2], dest->s6_addr32[3], destp,
+ sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0,
+ from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
+ 0,
+ sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops));
+}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index eedff8c..83bef86 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1226,45 +1226,16 @@ struct proto rawv6_prot = {
};
#ifdef CONFIG_PROC_FS
-static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
-{
- struct ipv6_pinfo *np = inet6_sk(sp);
- const struct in6_addr *dest, *src;
- __u16 destp, srcp;
-
- dest = &np->daddr;
- src = &np->rcv_saddr;
- destp = 0;
- srcp = inet_sk(sp)->inet_num;
- seq_printf(seq,
- "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
- i,
- src->s6_addr32[0], src->s6_addr32[1],
- src->s6_addr32[2], src->s6_addr32[3], srcp,
- dest->s6_addr32[0], dest->s6_addr32[1],
- dest->s6_addr32[2], dest->s6_addr32[3], destp,
- sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
- 0,
- sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
-}
-
static int raw6_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
- seq_printf(seq,
- " sl "
- "local_address "
- "remote_address "
- "st tx_queue rx_queue tr tm->when retrnsmt"
- " uid timeout inode ref pointer drops\n");
- else
- raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ struct sock *sp = v;
+ __u16 srcp = inet_sk(sp)->inet_num;
+ ip6_dgram_sock_seq_show(seq, v, srcp, 0,
+ raw_seq_private(seq)->bucket);
+ }
return 0;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 42923b1..b580853 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1359,48 +1359,17 @@ static const struct inet6_protocol udpv6_protocol = {
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
-
-static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket)
-{
- struct inet_sock *inet = inet_sk(sp);
- struct ipv6_pinfo *np = inet6_sk(sp);
- const struct in6_addr *dest, *src;
- __u16 destp, srcp;
-
- dest = &np->daddr;
- src = &np->rcv_saddr;
- destp = ntohs(inet->inet_dport);
- srcp = ntohs(inet->inet_sport);
- seq_printf(seq,
- "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
- bucket,
- src->s6_addr32[0], src->s6_addr32[1],
- src->s6_addr32[2], src->s6_addr32[3], srcp,
- dest->s6_addr32[0], dest->s6_addr32[1],
- dest->s6_addr32[2], dest->s6_addr32[3], destp,
- sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
- 0,
- sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
- atomic_read(&sp->sk_drops));
-}
-
int udp6_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
- seq_printf(seq,
- " sl "
- "local_address "
- "remote_address "
- "st tx_queue rx_queue tr tm->when retrnsmt"
- " uid timeout inode ref pointer drops\n");
- else
- udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket);
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ int bucket = ((struct udp_iter_state *)seq->private)->bucket;
+ struct inet_sock *inet = inet_sk(v);
+ __u16 srcp = ntohs(inet->inet_sport);
+ __u16 destp = ntohs(inet->inet_dport);
+ ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket);
+ }
return 0;
}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show.
2013-05-29 5:47 ` [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
@ 2013-06-01 0:01 ` David Miller
2013-06-01 1:00 ` Lorenzo Colitti
0 siblings, 1 reply; 10+ messages in thread
From: David Miller @ 2013-06-01 0:01 UTC (permalink / raw)
To: lorenzo; +Cc: netdev, edumazet, yoshfuji, segoon
From: Lorenzo Colitti <lorenzo@google.com>
Date: Wed, 29 May 2013 14:47:37 +0900
> udp6_sock_seq_show and raw6_sock_seq_show are identical, except
> the UDP version displays ports and the raw version displays the
> protocol. Refactor most of the code in these two functions into
> a new common ip6_dgram_sock_seq_show function, in preparation
> for using it to display ICMPv6 sockets as well.
>
> Also reduce the indentation in parts of include/net/transp_v6.h
> to improve readability.
>
> Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
>
> Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Do not mix functional changes with unrelated whitespace and other cleanups.
Split this patch series up properly and resubmit this entire series.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/3] net: ipv4: make the ping /proc code AF-independent
2013-05-29 5:47 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
@ 2013-05-29 5:47 ` Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 5:47 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
Introduce a ping_seq_afinfo structure (similar to its UDP
equivalent) and use it to make some of the ping /proc functions
address-family independent. Rename the remaining ping /proc
functions from ping_* to ping_v4_*.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/ping.h | 8 ++++++
net/ipv4/ping.c | 73 +++++++++++++++++++++++++++++++++++-------------------
2 files changed, 55 insertions(+), 26 deletions(-)
diff --git a/include/net/ping.h b/include/net/ping.h
index 9242fa0..b9282f0 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -49,6 +49,7 @@ struct ping_table {
struct ping_iter_state {
struct seq_net_private p;
int bucket;
+ sa_family_t family;
};
extern struct proto ping_prot;
@@ -87,6 +88,13 @@ int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
void ping_rcv(struct sk_buff *skb);
#ifdef CONFIG_PROC_FS
+struct ping_seq_afinfo {
+ char *name;
+ sa_family_t family;
+ const struct file_operations *seq_fops;
+ const struct seq_operations seq_ops;
+};
+
extern int __init ping_proc_init(void);
extern void ping_proc_exit(void);
#endif
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 71f6ad0..8c2da9b 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1001,7 +1001,8 @@ static struct sock *ping_get_first(struct seq_file *seq, int start)
continue;
sk_nulls_for_each(sk, node, hslot) {
- if (net_eq(sock_net(sk), net))
+ if (net_eq(sock_net(sk), net) &&
+ sk->sk_family == state->family)
goto found;
}
}
@@ -1034,16 +1035,23 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
return pos ? NULL : sk;
}
-static void *ping_seq_start(struct seq_file *seq, loff_t *pos)
+static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
+ sa_family_t family)
{
struct ping_iter_state *state = seq->private;
state->bucket = 0;
+ state->family = family;
read_lock_bh(&ping_table.lock);
return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
}
+static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return ping_seq_start(seq, pos, AF_INET);
+}
+
static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *sk;
@@ -1062,7 +1070,7 @@ static void ping_seq_stop(struct seq_file *seq, void *v)
read_unlock_bh(&ping_table.lock);
}
-static void ping_format_sock(struct sock *sp, struct seq_file *f,
+static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
int bucket, int *len)
{
struct inet_sock *inet = inet_sk(sp);
@@ -1083,7 +1091,7 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f,
atomic_read(&sp->sk_drops), len);
}
-static int ping_seq_show(struct seq_file *seq, void *v)
+static int ping_v4_seq_show(struct seq_file *seq, void *v)
{
if (v == SEQ_START_TOKEN)
seq_printf(seq, "%-127s\n",
@@ -1094,22 +1102,23 @@ static int ping_seq_show(struct seq_file *seq, void *v)
struct ping_iter_state *state = seq->private;
int len;
- ping_format_sock(v, seq, state->bucket, &len);
+ ping_v4_format_sock(v, seq, state->bucket, &len);
seq_printf(seq, "%*s\n", 127 - len, "");
}
return 0;
}
-static const struct seq_operations ping_seq_ops = {
- .show = ping_seq_show,
- .start = ping_seq_start,
+static const struct seq_operations ping_v4_seq_ops = {
+ .show = ping_v4_seq_show,
+ .start = ping_v4_seq_start,
.next = ping_seq_next,
.stop = ping_seq_stop,
};
static int ping_seq_open(struct inode *inode, struct file *file)
{
- return seq_open_net(inode, file, &ping_seq_ops,
+ struct ping_seq_afinfo *afinfo = PDE_DATA(inode);
+ return seq_open_net(inode, file, &afinfo->seq_ops,
sizeof(struct ping_iter_state));
}
@@ -1120,46 +1129,58 @@ static const struct file_operations ping_seq_fops = {
.release = seq_release_net,
};
-static int ping_proc_register(struct net *net)
+static struct ping_seq_afinfo ping_v4_seq_afinfo = {
+ .name = "icmp",
+ .family = AF_INET,
+ .seq_fops = &ping_seq_fops,
+ .seq_ops = {
+ .start = ping_v4_seq_start,
+ .show = ping_v4_seq_show,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+ },
+};
+
+static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
{
struct proc_dir_entry *p;
- int rc = 0;
-
- p = proc_create("icmp", S_IRUGO, net->proc_net, &ping_seq_fops);
+ p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
+ afinfo->seq_fops, afinfo);
if (!p)
- rc = -ENOMEM;
- return rc;
+ return -ENOMEM;
+ return 0;
}
-static void ping_proc_unregister(struct net *net)
+static void ping_proc_unregister(struct net *net,
+ struct ping_seq_afinfo *afinfo)
{
- remove_proc_entry("icmp", net->proc_net);
+ remove_proc_entry(afinfo->name, net->proc_net);
}
-static int __net_init ping_proc_init_net(struct net *net)
+static int __net_init ping_v4_proc_init_net(struct net *net)
{
- return ping_proc_register(net);
+ return ping_proc_register(net, &ping_v4_seq_afinfo);
}
-static void __net_exit ping_proc_exit_net(struct net *net)
+static void __net_exit ping_v4_proc_exit_net(struct net *net)
{
- ping_proc_unregister(net);
+ ping_proc_unregister(net, &ping_v4_seq_afinfo);
}
-static struct pernet_operations ping_net_ops = {
- .init = ping_proc_init_net,
- .exit = ping_proc_exit_net,
+static struct pernet_operations ping_v4_net_ops = {
+ .init = ping_v4_proc_init_net,
+ .exit = ping_v4_proc_exit_net,
};
int __init ping_proc_init(void)
{
- return register_pernet_subsys(&ping_net_ops);
+ return register_pernet_subsys(&ping_v4_net_ops);
}
void ping_proc_exit(void)
{
- unregister_pernet_subsys(&ping_net_ops);
+ unregister_pernet_subsys(&ping_v4_net_ops);
}
#endif
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v3 3/3] net: ipv6: Implement /proc/net/icmp6.
2013-05-29 5:47 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 2/3] net: ipv4: make the ping /proc code AF-independent Lorenzo Colitti
@ 2013-05-29 5:47 ` Lorenzo Colitti
2 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 5:47 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
The format is based on /proc/net/icmp and /proc/net/{udp,raw}6.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Couldn't figure out how to test without CONFIG_PROC_FS enabled.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/ping.h | 8 +++++
net/ipv4/ping.c | 21 ++++++-----
net/ipv6/ping.c | 102 +++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 99 insertions(+), 32 deletions(-)
diff --git a/include/net/ping.h b/include/net/ping.h
index b9282f0..db04802 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -95,6 +95,14 @@ struct ping_seq_afinfo {
const struct seq_operations seq_ops;
};
+extern const struct file_operations ping_seq_fops;
+
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family);
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void ping_seq_stop(struct seq_file *seq, void *v);
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo);
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo);
+
extern int __init ping_proc_init(void);
extern void ping_proc_exit(void);
#endif
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8c2da9b..3552a45 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1035,8 +1035,7 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
return pos ? NULL : sk;
}
-static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
- sa_family_t family)
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family)
{
struct ping_iter_state *state = seq->private;
state->bucket = 0;
@@ -1046,13 +1045,14 @@ static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
}
+EXPORT_SYMBOL_GPL(ping_seq_start);
static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos)
{
return ping_seq_start(seq, pos, AF_INET);
}
-static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *sk;
@@ -1064,11 +1064,13 @@ static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos;
return sk;
}
+EXPORT_SYMBOL_GPL(ping_seq_next);
-static void ping_seq_stop(struct seq_file *seq, void *v)
+void ping_seq_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&ping_table.lock);
}
+EXPORT_SYMBOL_GPL(ping_seq_stop);
static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
int bucket, int *len)
@@ -1122,12 +1124,13 @@ static int ping_seq_open(struct inode *inode, struct file *file)
sizeof(struct ping_iter_state));
}
-static const struct file_operations ping_seq_fops = {
+const struct file_operations ping_seq_fops = {
.open = ping_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
+EXPORT_SYMBOL_GPL(ping_seq_fops);
static struct ping_seq_afinfo ping_v4_seq_afinfo = {
.name = "icmp",
@@ -1141,7 +1144,7 @@ static struct ping_seq_afinfo ping_v4_seq_afinfo = {
},
};
-static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
{
struct proc_dir_entry *p;
p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
@@ -1150,13 +1153,13 @@ static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
return -ENOMEM;
return 0;
}
+EXPORT_SYMBOL_GPL(ping_proc_register);
-static void ping_proc_unregister(struct net *net,
- struct ping_seq_afinfo *afinfo)
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo)
{
remove_proc_entry(afinfo->name, net->proc_net);
}
-
+EXPORT_SYMBOL_GPL(ping_proc_unregister);
static int __net_init ping_v4_proc_init_net(struct net *net)
{
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index a6462d6..62ac5f2 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -78,29 +78,6 @@ int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
return 0;
}
-int __init pingv6_init(void)
-{
- pingv6_ops.ipv6_recv_error = ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
- return inet6_register_protosw(&pingv6_protosw);
-}
-
-/* This never gets called because it's not possible to unload the ipv6 module,
- * but just in case.
- */
-void pingv6_exit(void)
-{
- pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
- inet6_unregister_protosw(&pingv6_protosw);
-}
-
int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len)
{
@@ -214,3 +191,82 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return err;
}
+
+#ifdef CONFIG_PROC_FS
+static void *ping_v6_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return ping_seq_start(seq, pos, AF_INET6);
+}
+
+int ping_v6_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ int bucket = ((struct ping_iter_state *) seq->private)->bucket;
+ struct inet_sock *inet = inet_sk(v);
+ __u16 srcp = ntohs(inet->inet_sport);
+ __u16 destp = ntohs(inet->inet_dport);
+ ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket);
+ }
+ return 0;
+}
+
+static struct ping_seq_afinfo ping_v6_seq_afinfo = {
+ .name = "icmp6",
+ .family = AF_INET6,
+ .seq_fops = &ping_seq_fops,
+ .seq_ops = {
+ .start = ping_v6_seq_start,
+ .show = ping_v6_seq_show,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+ },
+};
+
+static int __net_init ping_v6_proc_init_net(struct net *net)
+{
+ return ping_proc_register(net, &ping_v6_seq_afinfo);
+}
+
+static void __net_init ping_v6_proc_exit_net(struct net *net)
+{
+ return ping_proc_unregister(net, &ping_v6_seq_afinfo);
+}
+
+static struct pernet_operations ping_v6_net_ops = {
+ .init = ping_v6_proc_init_net,
+ .exit = ping_v6_proc_exit_net,
+};
+#endif
+
+int __init pingv6_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ int ret = register_pernet_subsys(&ping_v6_net_ops);
+ if (ret)
+ return ret;
+#endif
+ pingv6_ops.ipv6_recv_error = ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
+ return inet6_register_protosw(&pingv6_protosw);
+}
+
+/* This never gets called because it's not possible to unload the ipv6 module,
+ * but just in case.
+ */
+void pingv6_exit(void)
+{
+ pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
+#ifdef CONFIG_PROC_FS
+ unregister_pernet_subsys(&ping_v6_net_ops);
+#endif
+ inet6_unregister_protosw(&pingv6_protosw);
+}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6.
@ 2013-05-29 2:36 Lorenzo Colitti
0 siblings, 0 replies; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 2:36 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
The format is based on /proc/net/icmp and /proc/net/{udp,raw}6.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Couldn't figure out how to test without CONFIG_PROC_FS enabled.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/ping.h | 8 +++++
net/ipv4/ping.c | 21 ++++++-----
net/ipv6/ping.c | 102 +++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 99 insertions(+), 32 deletions(-)
diff --git a/include/net/ping.h b/include/net/ping.h
index b9282f0..db04802 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -95,6 +95,14 @@ struct ping_seq_afinfo {
const struct seq_operations seq_ops;
};
+extern const struct file_operations ping_seq_fops;
+
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family);
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void ping_seq_stop(struct seq_file *seq, void *v);
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo);
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo);
+
extern int __init ping_proc_init(void);
extern void ping_proc_exit(void);
#endif
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8c2da9b..3552a45 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1035,8 +1035,7 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
return pos ? NULL : sk;
}
-static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
- sa_family_t family)
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family)
{
struct ping_iter_state *state = seq->private;
state->bucket = 0;
@@ -1046,13 +1045,14 @@ static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
}
+EXPORT_SYMBOL_GPL(ping_seq_start);
static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos)
{
return ping_seq_start(seq, pos, AF_INET);
}
-static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *sk;
@@ -1064,11 +1064,13 @@ static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos;
return sk;
}
+EXPORT_SYMBOL_GPL(ping_seq_next);
-static void ping_seq_stop(struct seq_file *seq, void *v)
+void ping_seq_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&ping_table.lock);
}
+EXPORT_SYMBOL_GPL(ping_seq_stop);
static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
int bucket, int *len)
@@ -1122,12 +1124,13 @@ static int ping_seq_open(struct inode *inode, struct file *file)
sizeof(struct ping_iter_state));
}
-static const struct file_operations ping_seq_fops = {
+const struct file_operations ping_seq_fops = {
.open = ping_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
+EXPORT_SYMBOL_GPL(ping_seq_fops);
static struct ping_seq_afinfo ping_v4_seq_afinfo = {
.name = "icmp",
@@ -1141,7 +1144,7 @@ static struct ping_seq_afinfo ping_v4_seq_afinfo = {
},
};
-static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
{
struct proc_dir_entry *p;
p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
@@ -1150,13 +1153,13 @@ static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
return -ENOMEM;
return 0;
}
+EXPORT_SYMBOL_GPL(ping_proc_register);
-static void ping_proc_unregister(struct net *net,
- struct ping_seq_afinfo *afinfo)
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo)
{
remove_proc_entry(afinfo->name, net->proc_net);
}
-
+EXPORT_SYMBOL_GPL(ping_proc_unregister);
static int __net_init ping_v4_proc_init_net(struct net *net)
{
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index a6462d6..62ac5f2 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -78,29 +78,6 @@ int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
return 0;
}
-int __init pingv6_init(void)
-{
- pingv6_ops.ipv6_recv_error = ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
- return inet6_register_protosw(&pingv6_protosw);
-}
-
-/* This never gets called because it's not possible to unload the ipv6 module,
- * but just in case.
- */
-void pingv6_exit(void)
-{
- pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
- inet6_unregister_protosw(&pingv6_protosw);
-}
-
int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len)
{
@@ -214,3 +191,82 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return err;
}
+
+#ifdef CONFIG_PROC_FS
+static void *ping_v6_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return ping_seq_start(seq, pos, AF_INET6);
+}
+
+int ping_v6_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ int bucket = ((struct ping_iter_state *) seq->private)->bucket;
+ struct inet_sock *inet = inet_sk(v);
+ __u16 srcp = ntohs(inet->inet_sport);
+ __u16 destp = ntohs(inet->inet_dport);
+ ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket);
+ }
+ return 0;
+}
+
+static struct ping_seq_afinfo ping_v6_seq_afinfo = {
+ .name = "icmp6",
+ .family = AF_INET6,
+ .seq_fops = &ping_seq_fops,
+ .seq_ops = {
+ .start = ping_v6_seq_start,
+ .show = ping_v6_seq_show,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+ },
+};
+
+static int __net_init ping_v6_proc_init_net(struct net *net)
+{
+ return ping_proc_register(net, &ping_v6_seq_afinfo);
+}
+
+static void __net_init ping_v6_proc_exit_net(struct net *net)
+{
+ return ping_proc_unregister(net, &ping_v6_seq_afinfo);
+}
+
+static struct pernet_operations ping_v6_net_ops = {
+ .init = ping_v6_proc_init_net,
+ .exit = ping_v6_proc_exit_net,
+};
+#endif
+
+int __init pingv6_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ int ret = register_pernet_subsys(&ping_v6_net_ops);
+ if (ret)
+ return ret;
+#endif
+ pingv6_ops.ipv6_recv_error = ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
+ return inet6_register_protosw(&pingv6_protosw);
+}
+
+/* This never gets called because it's not possible to unload the ipv6 module,
+ * but just in case.
+ */
+void pingv6_exit(void)
+{
+ pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
+#ifdef CONFIG_PROC_FS
+ unregister_pernet_subsys(&ping_v6_net_ops);
+#endif
+ inet6_unregister_protosw(&pingv6_protosw);
+}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show.
@ 2013-05-28 14:45 Lorenzo Colitti
2013-05-28 14:45 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
0 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-28 14:45 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
udp6_sock_seq_show and raw6_sock_seq_show are identical, except
the UDP version displays ports and the raw version displays the
protocol. Refactor most of the code in these two functions into
a new common ip6_dgram_sock_seq_show function, in preparation
for using it to display ICMPv6 sockets as well.
Also reduce the indentation in parts of include/net/transp_v6.h
to improve readability.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/transp_v6.h | 73 +++++++++++++++++++++++++++++--------------------
net/ipv6/datagram.c | 27 ++++++++++++++++++
net/ipv6/raw.c | 45 ++++++------------------------
net/ipv6/udp.c | 49 ++++++---------------------------
4 files changed, 87 insertions(+), 107 deletions(-)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index eb40e71..841c33e 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -16,38 +16,51 @@ extern struct proto pingv6_prot;
struct flowi6;
/* extension headers */
-extern int ipv6_exthdrs_init(void);
-extern void ipv6_exthdrs_exit(void);
-extern int ipv6_frag_init(void);
-extern void ipv6_frag_exit(void);
+extern int ipv6_exthdrs_init(void);
+extern void ipv6_exthdrs_exit(void);
+extern int ipv6_frag_init(void);
+extern void ipv6_frag_exit(void);
/* transport protocols */
-extern int pingv6_init(void);
-extern void pingv6_exit(void);
-extern int rawv6_init(void);
-extern void rawv6_exit(void);
-extern int udpv6_init(void);
-extern void udpv6_exit(void);
-extern int udplitev6_init(void);
-extern void udplitev6_exit(void);
-extern int tcpv6_init(void);
-extern void tcpv6_exit(void);
-
-extern int udpv6_connect(struct sock *sk,
- struct sockaddr *uaddr,
- int addr_len);
-
-extern int ip6_datagram_recv_ctl(struct sock *sk,
- struct msghdr *msg,
- struct sk_buff *skb);
-
-extern int ip6_datagram_send_ctl(struct net *net,
- struct sock *sk,
- struct msghdr *msg,
- struct flowi6 *fl6,
- struct ipv6_txoptions *opt,
- int *hlimit, int *tclass,
- int *dontfrag);
+extern int pingv6_init(void);
+extern void pingv6_exit(void);
+extern int rawv6_init(void);
+extern void rawv6_exit(void);
+extern int udpv6_init(void);
+extern void udpv6_exit(void);
+extern int udplitev6_init(void);
+extern void udplitev6_exit(void);
+extern int tcpv6_init(void);
+extern void tcpv6_exit(void);
+
+extern int udpv6_connect(struct sock *sk,
+ struct sockaddr *uaddr,
+ int addr_len);
+
+extern int ip6_datagram_recv_ctl(struct sock *sk,
+ struct msghdr *msg,
+ struct sk_buff *skb);
+
+extern int ip6_datagram_send_ctl(struct net *net,
+ struct sock *sk,
+ struct msghdr *msg,
+ struct flowi6 *fl6,
+ struct ipv6_txoptions *opt,
+ int *hlimit, int *tclass,
+ int *dontfrag);
+
+#define IPV6_SEQ_DGRAM_HEADER \
+ " sl " \
+ "local_address " \
+ "remote_address " \
+ "st tx_queue rx_queue tr tm->when retrnsmt" \
+ " uid timeout inode ref pointer drops\n"
+
+extern void ip6_dgram_sock_seq_show(struct seq_file *seq,
+ struct sock *sp,
+ __u16 srcp,
+ __u16 destp,
+ int bucket);
#define LOOPBACK4_IPV6 cpu_to_be32(0x7f000006)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 4b56cbb..197e6f4 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -879,3 +879,30 @@ exit_f:
return err;
}
EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);
+
+void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp,
+ __u16 srcp, __u16 destp, int bucket)
+{
+ struct ipv6_pinfo *np = inet6_sk(sp);
+ const struct in6_addr *dest, *src;
+
+ dest = &np->daddr;
+ src = &np->rcv_saddr;
+ seq_printf(seq,
+ "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
+ "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
+ bucket,
+ src->s6_addr32[0], src->s6_addr32[1],
+ src->s6_addr32[2], src->s6_addr32[3], srcp,
+ dest->s6_addr32[0], dest->s6_addr32[1],
+ dest->s6_addr32[2], dest->s6_addr32[3], destp,
+ sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0,
+ from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
+ 0,
+ sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops));
+}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index eedff8c..83bef86 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -1226,45 +1226,16 @@ struct proto rawv6_prot = {
};
#ifdef CONFIG_PROC_FS
-static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
-{
- struct ipv6_pinfo *np = inet6_sk(sp);
- const struct in6_addr *dest, *src;
- __u16 destp, srcp;
-
- dest = &np->daddr;
- src = &np->rcv_saddr;
- destp = 0;
- srcp = inet_sk(sp)->inet_num;
- seq_printf(seq,
- "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
- i,
- src->s6_addr32[0], src->s6_addr32[1],
- src->s6_addr32[2], src->s6_addr32[3], srcp,
- dest->s6_addr32[0], dest->s6_addr32[1],
- dest->s6_addr32[2], dest->s6_addr32[3], destp,
- sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
- 0,
- sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
-}
-
static int raw6_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
- seq_printf(seq,
- " sl "
- "local_address "
- "remote_address "
- "st tx_queue rx_queue tr tm->when retrnsmt"
- " uid timeout inode ref pointer drops\n");
- else
- raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ struct sock *sp = v;
+ __u16 srcp = inet_sk(sp)->inet_num;
+ ip6_dgram_sock_seq_show(seq, v, srcp, 0,
+ raw_seq_private(seq)->bucket);
+ }
return 0;
}
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 42923b1..b580853 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1359,48 +1359,17 @@ static const struct inet6_protocol udpv6_protocol = {
/* ------------------------------------------------------------------------ */
#ifdef CONFIG_PROC_FS
-
-static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket)
-{
- struct inet_sock *inet = inet_sk(sp);
- struct ipv6_pinfo *np = inet6_sk(sp);
- const struct in6_addr *dest, *src;
- __u16 destp, srcp;
-
- dest = &np->daddr;
- src = &np->rcv_saddr;
- destp = ntohs(inet->inet_dport);
- srcp = ntohs(inet->inet_sport);
- seq_printf(seq,
- "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
- "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
- bucket,
- src->s6_addr32[0], src->s6_addr32[1],
- src->s6_addr32[2], src->s6_addr32[3], srcp,
- dest->s6_addr32[0], dest->s6_addr32[1],
- dest->s6_addr32[2], dest->s6_addr32[3], destp,
- sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)),
- 0,
- sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
- atomic_read(&sp->sk_drops));
-}
-
int udp6_seq_show(struct seq_file *seq, void *v)
{
- if (v == SEQ_START_TOKEN)
- seq_printf(seq,
- " sl "
- "local_address "
- "remote_address "
- "st tx_queue rx_queue tr tm->when retrnsmt"
- " uid timeout inode ref pointer drops\n");
- else
- udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket);
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ int bucket = ((struct udp_iter_state *)seq->private)->bucket;
+ struct inet_sock *inet = inet_sk(v);
+ __u16 srcp = ntohs(inet->inet_sport);
+ __u16 destp = ntohs(inet->inet_dport);
+ ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket);
+ }
return 0;
}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6.
2013-05-28 14:45 [PATCH 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
@ 2013-05-28 14:45 ` Lorenzo Colitti
2013-05-29 2:31 ` Lorenzo Colitti
0 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-28 14:45 UTC (permalink / raw)
To: netdev
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
The format is based on /proc/net/icmp and /proc/net/{udp,raw}6.
Compiles and displays reasonable results with CONFIG_IPV6={n,m,y}
Couldn't figure out how to test without CONFIG_PROC_FS enabled.
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
include/net/ping.h | 8 +++++
net/ipv4/ping.c | 21 ++++++-----
net/ipv6/ping.c | 103 +++++++++++++++++++++++++++++++++++++++++------------
3 files changed, 100 insertions(+), 32 deletions(-)
diff --git a/include/net/ping.h b/include/net/ping.h
index b9282f0..db04802 100644
--- a/include/net/ping.h
+++ b/include/net/ping.h
@@ -95,6 +95,14 @@ struct ping_seq_afinfo {
const struct seq_operations seq_ops;
};
+extern const struct file_operations ping_seq_fops;
+
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family);
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void ping_seq_stop(struct seq_file *seq, void *v);
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo);
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo);
+
extern int __init ping_proc_init(void);
extern void ping_proc_exit(void);
#endif
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 8c2da9b..3552a45 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1035,8 +1035,7 @@ static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
return pos ? NULL : sk;
}
-static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
- sa_family_t family)
+void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family)
{
struct ping_iter_state *state = seq->private;
state->bucket = 0;
@@ -1046,13 +1045,14 @@ static void *ping_seq_start(struct seq_file *seq, loff_t *pos,
return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
}
+EXPORT_SYMBOL_GPL(ping_seq_start);
static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos)
{
return ping_seq_start(seq, pos, AF_INET);
}
-static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct sock *sk;
@@ -1064,11 +1064,13 @@ static void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos;
return sk;
}
+EXPORT_SYMBOL_GPL(ping_seq_next);
-static void ping_seq_stop(struct seq_file *seq, void *v)
+void ping_seq_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&ping_table.lock);
}
+EXPORT_SYMBOL_GPL(ping_seq_stop);
static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
int bucket, int *len)
@@ -1122,12 +1124,13 @@ static int ping_seq_open(struct inode *inode, struct file *file)
sizeof(struct ping_iter_state));
}
-static const struct file_operations ping_seq_fops = {
+const struct file_operations ping_seq_fops = {
.open = ping_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
+EXPORT_SYMBOL_GPL(ping_seq_fops);
static struct ping_seq_afinfo ping_v4_seq_afinfo = {
.name = "icmp",
@@ -1141,7 +1144,7 @@ static struct ping_seq_afinfo ping_v4_seq_afinfo = {
},
};
-static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
+int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
{
struct proc_dir_entry *p;
p = proc_create_data(afinfo->name, S_IRUGO, net->proc_net,
@@ -1150,13 +1153,13 @@ static int ping_proc_register(struct net *net, struct ping_seq_afinfo *afinfo)
return -ENOMEM;
return 0;
}
+EXPORT_SYMBOL_GPL(ping_proc_register);
-static void ping_proc_unregister(struct net *net,
- struct ping_seq_afinfo *afinfo)
+void ping_proc_unregister(struct net *net, struct ping_seq_afinfo *afinfo)
{
remove_proc_entry(afinfo->name, net->proc_net);
}
-
+EXPORT_SYMBOL_GPL(ping_proc_unregister);
static int __net_init ping_v4_proc_init_net(struct net *net)
{
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index a6462d6..46461b0 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -78,29 +78,6 @@ int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
return 0;
}
-int __init pingv6_init(void)
-{
- pingv6_ops.ipv6_recv_error = ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
- return inet6_register_protosw(&pingv6_protosw);
-}
-
-/* This never gets called because it's not possible to unload the ipv6 module,
- * but just in case.
- */
-void pingv6_exit(void)
-{
- pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
- pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
- pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
- pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
- pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
- inet6_unregister_protosw(&pingv6_protosw);
-}
-
int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len)
{
@@ -214,3 +191,83 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return err;
}
+
+#ifdef CONFIG_PROC_FS
+static void *ping_v6_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ return ping_seq_start(seq, pos, AF_INET6);
+}
+
+int ping_v6_seq_show(struct seq_file *seq, void *v)
+{
+ if (v == SEQ_START_TOKEN) {
+ seq_puts(seq, IPV6_SEQ_DGRAM_HEADER);
+ } else {
+ int bucket = ((struct ping_iter_state *) seq->private)->bucket;
+ struct inet_sock *inet = inet_sk(v);
+ __u16 srcp = ntohs(inet->inet_sport);
+ __u16 destp = ntohs(inet->inet_dport);
+ ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket);
+ }
+ return 0;
+}
+
+static struct ping_seq_afinfo ping_v6_seq_afinfo = {
+ .name = "icmp6",
+ .family = AF_INET6,
+ .seq_fops = &ping_seq_fops,
+ .seq_ops = {
+ .start = ping_v6_seq_start,
+ .show = ping_v6_seq_show,
+ .next = ping_seq_next,
+ .stop = ping_seq_stop,
+ },
+};
+
+static int __net_init ping_v6_proc_init_net(struct net *net)
+{
+ return ping_proc_register(net, &ping_v6_seq_afinfo);
+}
+
+static void __net_init ping_v6_proc_exit_net(struct net *net)
+{
+ return ping_proc_unregister(net, &ping_v6_seq_afinfo);
+}
+
+static struct pernet_operations ping_v6_net_ops = {
+ .init = ping_v6_proc_init_net,
+ .exit = ping_v6_proc_exit_net,
+};
+#endif
+
+int __init pingv6_init(void)
+{
+ int ret;
+ pingv6_ops.ipv6_recv_error = ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
+#ifdef CONFIG_PROC_FS
+ ret = register_pernet_subsys(&ping_v6_net_ops);
+ if (ret)
+ return ret;
+#endif
+ return inet6_register_protosw(&pingv6_protosw);
+}
+
+/* This never gets called because it's not possible to unload the ipv6 module,
+ * but just in case.
+ */
+void pingv6_exit(void)
+{
+ pingv6_ops.ipv6_recv_error = dummy_ipv6_recv_error;
+ pingv6_ops.ip6_datagram_recv_ctl = dummy_ip6_datagram_recv_ctl;
+ pingv6_ops.icmpv6_err_convert = dummy_icmpv6_err_convert;
+ pingv6_ops.ipv6_icmp_error = dummy_ipv6_icmp_error;
+ pingv6_ops.ipv6_chk_addr = dummy_ipv6_chk_addr;
+#ifdef CONFIG_PROC_FS
+ unregister_pernet_subsys(&ping_v6_net_ops);
+#endif
+ inet6_unregister_protosw(&pingv6_protosw);
+}
--
1.8.2.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6.
2013-05-28 14:45 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
@ 2013-05-29 2:31 ` Lorenzo Colitti
2013-05-29 3:15 ` Cong Wang
0 siblings, 1 reply; 10+ messages in thread
From: Lorenzo Colitti @ 2013-05-29 2:31 UTC (permalink / raw)
To: netdev@vger.kernel.org
Cc: Eric Dumazet, David Miller, YOSHIFUJI Hideaki, Vasiliy Kulikov,
Lorenzo Colitti
On Tue, May 28, 2013 at 11:45 PM, Lorenzo Colitti <lorenzo@google.com> wrote:
> +int __init pingv6_init(void)
> +{
> + int ret;
> + pingv6_ops.ipv6_recv_error = ipv6_recv_error;
> + pingv6_ops.ip6_datagram_recv_ctl = ip6_datagram_recv_ctl;
> + pingv6_ops.icmpv6_err_convert = icmpv6_err_convert;
> + pingv6_ops.ipv6_icmp_error = ipv6_icmp_error;
> + pingv6_ops.ipv6_chk_addr = ipv6_chk_addr;
> +#ifdef CONFIG_PROC_FS
> + ret = register_pernet_subsys(&ping_v6_net_ops);
> + if (ret)
> + return ret;
Nit: if register_pernet_subsys fails (ENOMEM?) then we return failure
and stop the IPv6 module from loading, but the function pointers
inside pingv6_ops are never cleared.
I don't think this has any impact, because if this happens, the proto
isn't registered, so there's no way to create an IPv6 socket and call
these function pointers. Still, for completeness' sake I'll shortly
send out another patch 3/3 that checks the result of
register_pernet_subsys before updating the function pointers. The
other two patches in the set don't need to change.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6.
2013-05-29 2:31 ` Lorenzo Colitti
@ 2013-05-29 3:15 ` Cong Wang
0 siblings, 0 replies; 10+ messages in thread
From: Cong Wang @ 2013-05-29 3:15 UTC (permalink / raw)
To: netdev
On Wed, 29 May 2013 at 02:31 GMT, Lorenzo Colitti <lorenzo@google.com> wrote:
> I don't think this has any impact, because if this happens, the proto
> isn't registered, so there's no way to create an IPv6 socket and call
> these function pointers. Still, for completeness' sake I'll shortly
> send out another patch 3/3 that checks the result of
> register_pernet_subsys before updating the function pointers. The
> other two patches in the set don't need to change.
You have to resend all of them, not just one, per netdev rules.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-06-01 1:01 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <ko3rsc@ger.gmane.org>
2013-05-29 5:47 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
2013-06-01 0:01 ` David Miller
2013-06-01 1:00 ` Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 2/3] net: ipv4: make the ping /proc code AF-independent Lorenzo Colitti
2013-05-29 5:47 ` [PATCH v3 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2013-05-29 2:36 [PATCH " Lorenzo Colitti
-- strict thread matches above, loose matches on Subject: below --
2013-05-28 14:45 [PATCH 1/3] net: ipv6: Unify {raw,udp}6_sock_seq_show Lorenzo Colitti
2013-05-28 14:45 ` [PATCH 3/3] net: ipv6: Implement /proc/net/icmp6 Lorenzo Colitti
2013-05-29 2:31 ` Lorenzo Colitti
2013-05-29 3:15 ` Cong Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).