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
0d2cfd9d
Commit
0d2cfd9d
authored
Sep 15, 2003
by
Stephen Hemminger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[IPVS]: Convert to seq_file.
parent
c31c7015
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
392 additions
and
242 deletions
+392
-242
net/ipv4/ipvs/ip_vs_app.c
net/ipv4/ipvs/ip_vs_app.c
+83
-33
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_conn.c
+105
-53
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_ctl.c
+204
-156
No files found.
net/ipv4/ipvs/ip_vs_app.c
View file @
0d2cfd9d
...
...
@@ -35,6 +35,7 @@
#include <asm/system.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/ip_vs.h>
...
...
@@ -480,55 +481,104 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb)
}
#ifdef CONFIG_PROC_FS
/*
* /proc/net/ip_vs_app entry function
*/
static
int
ip_vs_app_getinfo
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
#define SEQ_START_TOKEN ((void *)1)
static
struct
ip_vs_app
*
ip_vs_app_idx
(
loff_t
pos
)
{
off_t
pos
=
0
;
int
len
=
0
;
char
temp
[
64
];
struct
ip_vs_app
*
app
,
*
inc
;
loff_t
off
=
0
;
struct
list_head
*
e
,
*
i
;
pos
=
64
;
if
(
pos
>
offset
)
{
len
+=
sprintf
(
buffer
+
len
,
"%-63s
\n
"
,
"prot port usecnt name"
);
list_for_each
(
e
,
&
ip_vs_app_list
)
{
struct
ip_vs_app
*
app
=
list_entry
(
e
,
struct
ip_vs_app
,
a_list
);
list_for_each
(
i
,
&
app
->
incs_list
)
{
if
(
off
==
pos
)
return
list_entry
(
i
,
struct
ip_vs_app
,
a_list
);
++
off
;
}
}
return
NULL
;
}
static
void
*
ip_vs_app_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
down
(
&
__ip_vs_app_mutex
);
list_for_each
(
e
,
&
ip_vs_app_list
)
{
return
*
pos
?
ip_vs_app_idx
(
*
pos
-
1
)
:
SEQ_START_TOKEN
;
}
static
void
*
ip_vs_app_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
struct
ip_vs_app
*
inc
,
*
app
;
struct
list_head
*
i
,
*
e
;
++*
pos
;
if
(
v
==
SEQ_START_TOKEN
)
return
ip_vs_app_idx
(
0
);
inc
=
v
;
app
=
inc
->
app
;
if
((
i
=
inc
->
a_list
.
next
)
!=
&
app
->
incs_list
)
return
list_entry
(
i
,
struct
ip_vs_app
,
a_list
);
/* go on to next application */
for
(
e
=
app
->
a_list
.
next
;
e
!=
&
ip_vs_app_list
;
e
=
e
->
next
)
{
app
=
list_entry
(
e
,
struct
ip_vs_app
,
a_list
);
list_for_each
(
i
,
&
app
->
incs_list
)
{
inc
=
list_entry
(
i
,
struct
ip_vs_app
,
a_list
);
pos
+=
64
;
if
(
pos
<=
offset
)
continue
;
sprintf
(
temp
,
"%-3s %-7u %-6d %-17s"
,
ip_vs_proto_name
(
inc
->
protocol
),
ntohs
(
inc
->
port
),
atomic_read
(
&
inc
->
usecnt
),
inc
->
name
);
len
+=
sprintf
(
buffer
+
len
,
"%-63s
\n
"
,
temp
);
if
(
pos
>=
offset
+
length
)
goto
done
;
return
list_entry
(
i
,
struct
ip_vs_app
,
a_list
);
}
}
done:
return
NULL
;
}
static
void
ip_vs_app_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
up
(
&
__ip_vs_app_mutex
);
}
static
int
ip_vs_app_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
if
(
v
==
SEQ_START_TOKEN
)
seq_puts
(
seq
,
"prot port usecnt name
\n
"
);
else
{
const
struct
ip_vs_app
*
inc
=
v
;
seq_printf
(
seq
,
"%-3s %-7u %-6d %-17s
\n
"
,
ip_vs_proto_name
(
inc
->
protocol
),
ntohs
(
inc
->
port
),
atomic_read
(
&
inc
->
usecnt
),
inc
->
name
);
}
return
0
;
}
static
struct
seq_operations
ip_vs_app_seq_ops
=
{
.
start
=
ip_vs_app_seq_start
,
.
next
=
ip_vs_app_seq_next
,
.
stop
=
ip_vs_app_seq_stop
,
.
show
=
ip_vs_app_seq_show
,
};
*
start
=
buffer
+
len
-
(
pos
-
offset
);
/* Start of wanted data */
len
=
pos
-
offset
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
static
int
ip_vs_app_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
ip_vs_app_seq_ops
);
}
static
struct
file_operations
ip_vs_app_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
ip_vs_app_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
#endif
/*
* Replace a segment of data with a new segment
...
...
@@ -577,7 +627,7 @@ int ip_vs_skb_replace(struct sk_buff *skb, int pri,
int
ip_vs_app_init
(
void
)
{
/* we will replace it with proc_net_ipvs_create() soon */
proc_net_
create
(
"ip_vs_app"
,
0
,
ip_vs_app_getinfo
);
proc_net_
fops_create
(
"ip_vs_app"
,
0
,
&
ip_vs_app_fops
);
return
0
;
}
...
...
net/ipv4/ipvs/ip_vs_conn.c
View file @
0d2cfd9d
...
...
@@ -30,6 +30,7 @@
#include <linux/compiler.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
/* for proc_net_* */
#include <linux/seq_file.h>
#include <linux/jhash.h>
#include <linux/random.h>
...
...
@@ -188,14 +189,13 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
{
unsigned
hash
;
struct
ip_vs_conn
*
cp
;
struct
list_head
*
l
,
*
e
;
struct
list_head
*
e
;
hash
=
ip_vs_conn_hashkey
(
protocol
,
s_addr
,
s_port
);
l
=
&
ip_vs_conn_tab
[
hash
];
ct_read_lock
(
hash
);
for
(
e
=
l
->
next
;
e
!=
l
;
e
=
e
->
next
)
{
list_for_each
(
e
,
&
ip_vs_conn_tab
[
hash
]
)
{
cp
=
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
if
(
s_addr
==
cp
->
caddr
&&
s_port
==
cp
->
cport
&&
d_port
==
cp
->
vport
&&
d_addr
==
cp
->
vaddr
&&
...
...
@@ -242,17 +242,16 @@ struct ip_vs_conn *ip_vs_conn_out_get
{
unsigned
hash
;
struct
ip_vs_conn
*
cp
,
*
ret
=
NULL
;
struct
list_head
*
l
,
*
e
;
struct
list_head
*
e
;
/*
* Check for "full" addressed entries
*/
hash
=
ip_vs_conn_hashkey
(
protocol
,
d_addr
,
d_port
);
l
=
&
ip_vs_conn_tab
[
hash
];
ct_read_lock
(
hash
);
for
(
e
=
l
->
next
;
e
!=
l
;
e
=
e
->
next
)
{
list_for_each
(
e
,
&
ip_vs_conn_tab
[
hash
]
)
{
cp
=
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
if
(
d_addr
==
cp
->
caddr
&&
d_port
==
cp
->
cport
&&
s_port
==
cp
->
dport
&&
s_addr
==
cp
->
daddr
&&
...
...
@@ -615,61 +614,116 @@ ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
/*
* /proc/net/ip_vs_conn entries
*/
static
int
ip_vs_conn_getinfo
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
)
{
off_t
pos
=
0
;
int
idx
,
len
=
0
;
char
temp
[
70
];
struct
ip_vs_conn
*
cp
;
struct
list_head
*
l
,
*
e
;
#ifdef CONFIG_PROC_FS
pos
=
128
;
if
(
pos
>
offset
)
{
len
+=
sprintf
(
buffer
+
len
,
"%-127s
\n
"
,
"Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires"
);
}
#define SEQ_START_TOKEN ((void *)1)
static
void
*
ip_vs_conn_array
(
struct
seq_file
*
seq
,
loff_t
pos
)
{
struct
list_head
*
e
;
int
idx
;
loff_t
off
=
0
;
for
(
idx
=
0
;
idx
<
IP_VS_CONN_TAB_SIZE
;
idx
++
)
{
/*
* Lock is actually only need in next loop
* we are called from uspace: must stop bh.
*/
ct_read_lock_bh
(
idx
);
list_for_each
(
e
,
&
ip_vs_conn_tab
[
idx
])
{
if
(
off
==
pos
)
{
seq
->
private
=
&
ip_vs_conn_tab
[
idx
];
return
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
}
++
off
;
}
ct_read_unlock_bh
(
idx
);
}
l
=
&
ip_vs_conn_tab
[
idx
];
for
(
e
=
l
->
next
;
e
!=
l
;
e
=
e
->
next
)
{
cp
=
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
pos
+=
128
;
if
(
pos
<=
offset
)
continue
;
sprintf
(
temp
,
"%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu"
,
return
NULL
;
}
static
void
*
ip_vs_conn_seq_start
(
struct
seq_file
*
seq
,
loff_t
*
pos
)
{
seq
->
private
=
NULL
;
return
*
pos
?
ip_vs_conn_array
(
seq
,
*
pos
-
1
)
:
SEQ_START_TOKEN
;
}
static
void
*
ip_vs_conn_seq_next
(
struct
seq_file
*
seq
,
void
*
v
,
loff_t
*
pos
)
{
struct
ip_vs_conn
*
cp
=
v
;
struct
list_head
*
e
,
*
l
=
seq
->
private
;
int
idx
;
++*
pos
;
if
(
v
==
SEQ_START_TOKEN
)
return
ip_vs_conn_array
(
seq
,
0
);
/* more on same hash chain? */
if
((
e
=
cp
->
c_list
.
next
)
!=
l
)
return
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
idx
=
l
-
ip_vs_conn_tab
;
ct_read_unlock_bh
(
idx
);
while
(
++
idx
<
IP_VS_CONN_TAB_SIZE
)
{
ct_read_lock_bh
(
idx
);
list_for_each
(
e
,
&
ip_vs_conn_tab
[
idx
])
{
seq
->
private
=
&
ip_vs_conn_tab
[
idx
];
return
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
}
ct_read_unlock_bh
(
idx
);
}
seq
->
private
=
NULL
;
return
NULL
;
}
static
void
ip_vs_conn_seq_stop
(
struct
seq_file
*
seq
,
void
*
v
)
{
struct
list_head
*
l
=
seq
->
private
;
if
(
l
)
ct_read_unlock
(
l
-
ip_vs_conn_tab
);
}
static
int
ip_vs_conn_seq_show
(
struct
seq_file
*
seq
,
void
*
v
)
{
if
(
v
==
SEQ_START_TOKEN
)
seq_puts
(
seq
,
"Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires
\n
"
);
else
{
const
struct
ip_vs_conn
*
cp
=
v
;
seq_printf
(
seq
,
"%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
ntohl
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
ntohl
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
ntohl
(
cp
->
daddr
),
ntohs
(
cp
->
dport
),
ip_vs_state_name
(
cp
->
protocol
,
cp
->
state
),
(
cp
->
timer
.
expires
-
jiffies
)
/
HZ
);
len
+=
sprintf
(
buffer
+
len
,
"%-127s
\n
"
,
temp
);
if
(
pos
>=
offset
+
length
)
{
ct_read_unlock_bh
(
idx
);
goto
done
;
}
}
ct_read_unlock_bh
(
idx
);
}
return
0
;
}
static
struct
seq_operations
ip_vs_conn_seq_ops
=
{
.
start
=
ip_vs_conn_seq_start
,
.
next
=
ip_vs_conn_seq_next
,
.
stop
=
ip_vs_conn_seq_stop
,
.
show
=
ip_vs_conn_seq_show
,
};
done:
*
start
=
buffer
+
len
-
(
pos
-
offset
);
/* Start of wanted data */
len
=
pos
-
offset
;
if
(
len
>
length
)
len
=
length
;
if
(
len
<
0
)
len
=
0
;
return
len
;
static
int
ip_vs_conn_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
seq_open
(
file
,
&
ip_vs_conn_seq_ops
);
}
static
struct
file_operations
ip_vs_conn_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
ip_vs_conn_open
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
seq_release
,
};
#endif
/*
* Randomly drop connection entries before running out of memory
...
...
@@ -707,7 +761,7 @@ void ip_vs_random_dropentry(void)
{
int
idx
;
struct
ip_vs_conn
*
cp
;
struct
list_head
*
l
,
*
e
;
struct
list_head
*
e
;
struct
ip_vs_conn
*
ct
;
/*
...
...
@@ -721,8 +775,7 @@ void ip_vs_random_dropentry(void)
*/
ct_write_lock
(
hash
);
l
=
&
ip_vs_conn_tab
[
hash
];
for
(
e
=
l
->
next
;
e
!=
l
;
e
=
e
->
next
)
{
list_for_each
(
e
,
&
ip_vs_conn_tab
[
hash
])
{
cp
=
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
if
(
!
cp
->
cport
&&
!
(
cp
->
flags
&
IP_VS_CONN_F_NO_CPORT
))
/* connection template */
...
...
@@ -775,7 +828,7 @@ static void ip_vs_conn_flush(void)
{
int
idx
;
struct
ip_vs_conn
*
cp
;
struct
list_head
*
l
,
*
e
;
struct
list_head
*
e
;
struct
ip_vs_conn
*
ct
;
flush_again:
...
...
@@ -785,8 +838,7 @@ static void ip_vs_conn_flush(void)
*/
ct_write_lock_bh
(
idx
);
l
=
&
ip_vs_conn_tab
[
idx
];
for
(
e
=
l
->
next
;
e
!=
l
;
e
=
e
->
next
)
{
list_for_each
(
e
,
&
ip_vs_conn_tab
[
idx
])
{
cp
=
list_entry
(
e
,
struct
ip_vs_conn
,
c_list
);
atomic_inc
(
&
cp
->
refcnt
);
ct_write_unlock
(
idx
);
...
...
@@ -848,7 +900,7 @@ int ip_vs_conn_init(void)
__ip_vs_conntbl_lock_array
[
idx
].
l
=
RW_LOCK_UNLOCKED
;
}
proc_net_
create
(
"ip_vs_conn"
,
0
,
ip_vs_conn_getinfo
);
proc_net_
fops_create
(
"ip_vs_conn"
,
0
,
&
ip_vs_conn_fops
);
/* calculate the random value for connection hash */
get_random_bytes
(
&
ip_vs_conn_rnd
,
sizeof
(
ip_vs_conn_rnd
));
...
...
net/ipv4/ipvs/ip_vs_ctl.c
View file @
0d2cfd9d
This diff is collapsed.
Click to expand it.
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