Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
5c675a44
Commit
5c675a44
authored
Sep 25, 2003
by
Stephen Hemminger
Committed by
David S. Miller
Sep 25, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPV4]: Convert ipmr to seq_file.
parent
b7617a50
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
244 additions
and
109 deletions
+244
-109
net/ipv4/ipmr.c
net/ipv4/ipmr.c
+244
-109
No files found.
net/ipv4/ipmr.c
View file @
5c675a44
...
...
@@ -46,6 +46,7 @@
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/mroute.h>
#include <linux/init.h>
#include <net/ip.h>
...
...
@@ -1602,133 +1603,267 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
/*
* The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
*/
static
int
ipmr_vif_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
struct
vif_device
*
vif
;
int
len
=
0
;
off_t
pos
=
0
;
off_t
begin
=
0
;
int
size
;
struct
ipmr_vif_iter
{
int
ct
;
};
len
+=
sprintf
(
buffer
,
"Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote
\n
"
);
pos
=
len
;
static
struct
vif_device
*
ipmr_vif_seq_idx
(
struct
ipmr_vif_iter
*
iter
,
loff_t
pos
)
{
for
(
iter
->
ct
=
0
;
iter
->
ct
<
maxvif
;
++
iter
->
ct
)
{
if
(
!
VIF_EXISTS
(
iter
->
ct
))
continue
;
if
(
pos
--
==
0
)
return
&
vif_table
[
iter
->
ct
];
}
return
NULL
;
}
static
void
*
ipmr_vif_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
read_lock
(
&
mrt_lock
);
for
(
ct
=
0
;
ct
<
maxvif
;
ct
++
)
{
char
*
name
=
"none"
;
vif
=&
vif_table
[
ct
];
if
(
!
VIF_EXISTS
(
ct
))
return
*
pos
?
ipmr_vif_seq_idx
(
seq
->
private
,
*
pos
-
1
)
:
SEQ_START_TOKEN
;
}
static
void
*
ipmr_vif_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
struct
ipmr_vif_iter
*
iter
=
seq
->
private
;
++*
pos
;
if
(
v
==
SEQ_START_TOKEN
)
return
ipmr_vif_seq_idx
(
iter
,
0
);
while
(
++
iter
->
ct
<
maxvif
)
{
if
(
!
VIF_EXISTS
(
iter
->
ct
))
continue
;
if
(
vif
->
dev
)
name
=
vif
->
dev
->
name
;
size
=
sprintf
(
buffer
+
len
,
"%2d %-10s %8ld %7ld %8ld %7ld %05X %08X %08X
\n
"
,
ct
,
name
,
vif
->
bytes_in
,
vif
->
pkt_in
,
vif
->
bytes_out
,
vif
->
pkt_out
,
vif
->
flags
,
vif
->
local
,
vif
->
remote
);
len
+=
size
;
pos
+=
size
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
break
;
return
&
vif_table
[
iter
->
ct
];
}
return
NULL
;
}
static
void
ipmr_vif_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
read_unlock
(
&
mrt_lock
);
}
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
static
int
ipmr_vif_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
if
(
v
==
SEQ_START_TOKEN
)
{
seq_puts
(
seq
,
"Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote
\n
"
);
}
else
{
const
struct
vif_device
*
vif
=
v
;
const
char
*
name
=
vif
->
dev
?
vif
->
dev
->
name
:
"none"
;
seq_printf
(
seq
,
"%2d %-10s %8ld %7ld %8ld %7ld %05X %08X %08X
\n
"
,
vif
-
vif_table
,
name
,
vif
->
bytes_in
,
vif
->
pkt_in
,
vif
->
bytes_out
,
vif
->
pkt_out
,
vif
->
flags
,
vif
->
local
,
vif
->
remote
);
}
return
0
;
}
static
int
ipmr_mfc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
static
struct
seq_operations
ipmr_vif_seq_ops
=
{
.
start
=
ipmr_vif_seq_start
,
.
next
=
ipmr_vif_seq_next
,
.
stop
=
ipmr_vif_seq_stop
,
.
show
=
ipmr_vif_seq_show
,
};
static
int
ipmr_vif_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
mfc_cache
*
mfc
;
int
len
=
0
;
off_t
pos
=
0
;
off_t
begin
=
0
;
int
size
;
struct
seq_file
*
seq
;
int
rc
=
-
ENOMEM
;
struct
ipmr_vif_iter
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
goto
out
;
rc
=
seq_open
(
file
,
&
ipmr_vif_seq_ops
);
if
(
rc
)
goto
out_kfree
;
s
->
ct
=
0
;
seq
=
file
->
private_data
;
seq
->
private
=
s
;
out:
return
rc
;
out_kfree:
kfree
(
s
);
goto
out
;
}
static
struct
file_operations
ipmr_vif_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
ipmr_vif_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
struct
ipmr_mfc_iter
{
struct
mfc_cache
**
cache
;
int
ct
;
};
len
+=
sprintf
(
buffer
,
"Group Origin Iif Pkts Bytes Wrong Oifs
\n
"
);
pos
=
len
;
static
struct
mfc_cache
*
ipmr_mfc_seq_idx
(
struct
ipmr_mfc_iter
*
it
,
loff_t
pos
)
{
struct
mfc_cache
*
mfc
;
it
->
cache
=
mfc_cache_array
;
read_lock
(
&
mrt_lock
);
for
(
ct
=
0
;
ct
<
MFC_LINES
;
ct
++
)
{
for
(
mfc
=
mfc_cache_array
[
ct
];
mfc
;
mfc
=
mfc
->
next
)
{
for
(
it
->
ct
=
0
;
it
->
ct
<
MFC_LINES
;
it
->
ct
++
)
for
(
mfc
=
mfc_cache_array
[
it
->
ct
];
mfc
;
mfc
=
mfc
->
next
)
if
(
pos
--
==
0
)
return
mfc
;
read_unlock
(
&
mrt_lock
);
it
->
cache
=
&
mfc_unres_queue
;
spin_lock_bh
(
&
mfc_unres_lock
);
for
(
mfc
=
mfc_unres_queue
;
mfc
;
mfc
=
mfc
->
next
)
if
(
pos
--
==
0
)
return
mfc
;
spin_unlock_bh
(
&
mfc_unres_lock
);
it
->
cache
=
NULL
;
return
NULL
;
}
static
void
*
ipmr_mfc_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
return
*
pos
?
ipmr_mfc_seq_idx
(
seq
->
private
,
*
pos
-
1
)
:
SEQ_START_TOKEN
;
}
static
void
*
ipmr_mfc_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
struct
mfc_cache
*
mfc
=
v
;
struct
ipmr_mfc_iter
*
it
=
seq
->
private
;
++*
pos
;
if
(
v
==
SEQ_START_TOKEN
)
return
ipmr_mfc_seq_idx
(
seq
->
private
,
0
);
if
(
mfc
->
next
)
return
mfc
->
next
;
if
(
it
->
cache
==
&
mfc_unres_queue
)
goto
end_of_list
;
BUG_ON
(
it
->
cache
!=
mfc_cache_array
);
while
(
++
it
->
ct
<
MFC_LINES
)
{
mfc
=
mfc_cache_array
[
it
->
ct
];
if
(
mfc
)
return
mfc
;
}
/* exhausted cache_array, show unresolved */
read_unlock
(
&
mrt_lock
);
it
->
cache
=
&
mfc_unres_queue
;
it
->
ct
=
0
;
spin_lock_bh
(
&
mfc_unres_lock
);
mfc
=
mfc_unres_queue
;
if
(
mfc
)
return
mfc
;
end_of_list:
spin_unlock_bh
(
&
mfc_unres_lock
);
it
->
cache
=
NULL
;
return
NULL
;
}
static
void
ipmr_mfc_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
struct
ipmr_mfc_iter
*
it
=
seq
->
private
;
if
(
it
->
cache
==
&
mfc_unres_queue
)
spin_unlock_bh
(
&
mfc_unres_lock
);
else
if
(
it
->
cache
==
mfc_cache_array
)
read_unlock
(
&
mrt_lock
);
}
static
int
ipmr_mfc_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
int
n
;
/*
* Interface forwarding map
*/
size
=
sprintf
(
buffer
+
len
,
"%08lX %08lX %-3d %8ld %8ld %8ld"
,
(
unsigned
long
)
mfc
->
mfc_mcastgrp
,
(
unsigned
long
)
mfc
->
mfc_origin
,
if
(
v
==
SEQ_START_TOKEN
)
{
seq_puts
(
seq
,
"Group Origin Iif Pkts Bytes Wrong Oifs
\n
"
);
}
else
{
const
struct
mfc_cache
*
mfc
=
v
;
const
struct
ipmr_mfc_iter
*
it
=
seq
->
private
;
seq_printf
(
seq
,
"%08lX %08lX %-3d %8ld %8ld %8ld"
,
(
unsigned
long
)
mfc
->
mfc_mcastgrp
,
(
unsigned
long
)
mfc
->
mfc_origin
,
mfc
->
mfc_parent
,
mfc
->
mfc_un
.
res
.
pkt
,
mfc
->
mfc_un
.
res
.
bytes
,
mfc
->
mfc_un
.
res
.
wrong_if
);
for
(
n
=
mfc
->
mfc_un
.
res
.
minvif
;
n
<
mfc
->
mfc_un
.
res
.
maxvif
;
n
++
)
{
if
(
VIF_EXISTS
(
n
)
&&
mfc
->
mfc_un
.
res
.
ttls
[
n
]
<
255
)
size
+=
sprintf
(
buffer
+
len
+
size
,
" %2d:%-3d"
,
n
,
mfc
->
mfc_un
.
res
.
ttls
[
n
]);
}
size
+=
sprintf
(
buffer
+
len
+
size
,
"
\n
"
);
len
+=
size
;
pos
+=
size
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
if
(
it
->
cache
!=
&
mfc_unres_queue
)
{
for
(
n
=
mfc
->
mfc_un
.
res
.
minvif
;
n
<
mfc
->
mfc_un
.
res
.
maxvif
;
n
++
)
{
if
(
VIF_EXISTS
(
n
)
&&
mfc
->
mfc_un
.
res
.
ttls
[
n
]
<
255
)
seq_printf
(
seq
,
" %2d:%-3d"
,
n
,
mfc
->
mfc_un
.
res
.
ttls
[
n
]);
}
if
(
pos
>
offset
+
length
)
goto
done
;
}
seq_putc
(
seq
,
'\n'
);
}
return
0
;
}
spin_lock_bh
(
&
mfc_unres_lock
);
for
(
mfc
=
mfc_unres_queue
;
mfc
;
mfc
=
mfc
->
next
)
{
size
=
sprintf
(
buffer
+
len
,
"%08lX %08lX %-3d %8ld %8ld %8ld
\n
"
,
(
unsigned
long
)
mfc
->
mfc_mcastgrp
,
(
unsigned
long
)
mfc
->
mfc_origin
,
-
1
,
(
long
)
mfc
->
mfc_un
.
unres
.
unresolved
.
qlen
,
0L
,
0L
);
len
+=
size
;
pos
+=
size
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
break
;
}
spin_unlock_bh
(
&
mfc_unres_lock
);
static
struct
seq_operations
ipmr_mfc_seq_ops
=
{
.
start
=
ipmr_mfc_seq_start
,
.
next
=
ipmr_mfc_seq_next
,
.
stop
=
ipmr_mfc_seq_stop
,
.
show
=
ipmr_mfc_seq_show
,
};
static
int
ipmr_mfc_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
struct
seq_file
*
seq
;
int
rc
=
-
ENOMEM
;
struct
ipmr_mfc_iter
*
s
=
kmalloc
(
sizeof
(
*
s
),
GFP_KERNEL
);
if
(
!
s
)
goto
out
;
rc
=
seq_open
(
file
,
&
ipmr_mfc_seq_ops
);
if
(
rc
)
goto
out_kfree
;
memset
(
s
,
0
,
sizeof
(
*
s
));
seq
=
file
->
private_data
;
seq
->
private
=
s
;
out:
return
rc
;
out_kfree:
kfree
(
s
);
goto
out
;
done:
read_unlock
(
&
mrt_lock
);
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
{
len
=
0
;
}
return
len
;
}
static
struct
file_operations
ipmr_mfc_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
ipmr_mfc_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
#endif
#ifdef CONFIG_IP_PIMSM_V2
...
...
@@ -1752,7 +1887,7 @@ void __init ip_mr_init(void)
ipmr_expire_timer
.
function
=
ipmr_expire_process
;
register_netdevice_notifier
(
&
ip_mr_notifier
);
#ifdef CONFIG_PROC_FS
proc_net_
create
(
"ip_mr_vif"
,
0
,
ipmr_vif_info
);
proc_net_
create
(
"ip_mr_cache"
,
0
,
ipmr_mfc_info
);
proc_net_
fops_create
(
"ip_mr_vif"
,
0
,
&
ipmr_vif_fops
);
proc_net_
fops_create
(
"ip_mr_cache"
,
0
,
&
ipmr_mfc_fops
);
#endif
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment