Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
dacc62db
L
linux
项目概览
Linux-御风守护者
/
linux
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
dacc62db
编写于
9月 09, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'lvs-next-2.6' of
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-2.6
上级
47abf28d
c051a0a2
变更
23
展开全部
隐藏空白更改
内联
并排
Showing
23 changed file
with
2469 addition
and
796 deletion
+2469
-796
include/net/ip_vs.h
include/net/ip_vs.h
+238
-70
net/ipv4/ipvs/Kconfig
net/ipv4/ipvs/Kconfig
+10
-1
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_conn.c
+168
-81
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_core.c
+609
-197
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_ctl.c
+355
-168
net/ipv4/ipvs/ip_vs_dh.c
net/ipv4/ipvs/ip_vs_dh.c
+4
-1
net/ipv4/ipvs/ip_vs_est.c
net/ipv4/ipvs/ip_vs_est.c
+20
-20
net/ipv4/ipvs/ip_vs_ftp.c
net/ipv4/ipvs/ip_vs_ftp.c
+39
-22
net/ipv4/ipvs/ip_vs_lblc.c
net/ipv4/ipvs/ip_vs_lblc.c
+5
-2
net/ipv4/ipvs/ip_vs_lblcr.c
net/ipv4/ipvs/ip_vs_lblcr.c
+7
-4
net/ipv4/ipvs/ip_vs_lc.c
net/ipv4/ipvs/ip_vs_lc.c
+7
-4
net/ipv4/ipvs/ip_vs_nq.c
net/ipv4/ipvs/ip_vs_nq.c
+9
-6
net/ipv4/ipvs/ip_vs_proto.c
net/ipv4/ipvs/ip_vs_proto.c
+60
-5
net/ipv4/ipvs/ip_vs_proto_ah_esp.c
net/ipv4/ipvs/ip_vs_proto_ah_esp.c
+66
-34
net/ipv4/ipvs/ip_vs_proto_tcp.c
net/ipv4/ipvs/ip_vs_proto_tcp.c
+185
-68
net/ipv4/ipvs/ip_vs_proto_udp.c
net/ipv4/ipvs/ip_vs_proto_udp.c
+165
-61
net/ipv4/ipvs/ip_vs_rr.c
net/ipv4/ipvs/ip_vs_rr.c
+8
-5
net/ipv4/ipvs/ip_vs_sed.c
net/ipv4/ipvs/ip_vs_sed.c
+9
-6
net/ipv4/ipvs/ip_vs_sh.c
net/ipv4/ipvs/ip_vs_sh.c
+4
-1
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/ipvs/ip_vs_sync.c
+25
-15
net/ipv4/ipvs/ip_vs_wlc.c
net/ipv4/ipvs/ip_vs_wlc.c
+9
-6
net/ipv4/ipvs/ip_vs_wrr.c
net/ipv4/ipvs/ip_vs_wrr.c
+9
-6
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/ipvs/ip_vs_xmit.c
+458
-13
未找到文件。
include/net/ip_vs.h
浏览文件 @
dacc62db
...
...
@@ -21,11 +21,103 @@
#include <linux/timer.h>
#include <net/checksum.h>
#include <linux/netfilter.h>
/* for union nf_inet_addr */
#include <linux/ipv6.h>
/* for struct ipv6hdr */
#include <net/ipv6.h>
/* for ipv6_addr_copy */
struct
ip_vs_iphdr
{
int
len
;
__u8
protocol
;
union
nf_inet_addr
saddr
;
union
nf_inet_addr
daddr
;
};
static
inline
void
ip_vs_fill_iphdr
(
int
af
,
const
void
*
nh
,
struct
ip_vs_iphdr
*
iphdr
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
{
const
struct
ipv6hdr
*
iph
=
nh
;
iphdr
->
len
=
sizeof
(
struct
ipv6hdr
);
iphdr
->
protocol
=
iph
->
nexthdr
;
ipv6_addr_copy
(
&
iphdr
->
saddr
.
in6
,
&
iph
->
saddr
);
ipv6_addr_copy
(
&
iphdr
->
daddr
.
in6
,
&
iph
->
daddr
);
}
else
#endif
{
const
struct
iphdr
*
iph
=
nh
;
iphdr
->
len
=
iph
->
ihl
*
4
;
iphdr
->
protocol
=
iph
->
protocol
;
iphdr
->
saddr
.
ip
=
iph
->
saddr
;
iphdr
->
daddr
.
ip
=
iph
->
daddr
;
}
}
static
inline
void
ip_vs_addr_copy
(
int
af
,
union
nf_inet_addr
*
dst
,
const
union
nf_inet_addr
*
src
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
ipv6_addr_copy
(
&
dst
->
in6
,
&
src
->
in6
);
else
#endif
dst
->
ip
=
src
->
ip
;
}
static
inline
int
ip_vs_addr_equal
(
int
af
,
const
union
nf_inet_addr
*
a
,
const
union
nf_inet_addr
*
b
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
return
ipv6_addr_equal
(
&
a
->
in6
,
&
b
->
in6
);
#endif
return
a
->
ip
==
b
->
ip
;
}
#ifdef CONFIG_IP_VS_DEBUG
#include <linux/net.h>
extern
int
ip_vs_get_debug_level
(
void
);
static
inline
const
char
*
ip_vs_dbg_addr
(
int
af
,
char
*
buf
,
size_t
buf_len
,
const
union
nf_inet_addr
*
addr
,
int
*
idx
)
{
int
len
;
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
len
=
snprintf
(
&
buf
[
*
idx
],
buf_len
-
*
idx
,
"["
NIP6_FMT
"]"
,
NIP6
(
addr
->
in6
))
+
1
;
else
#endif
len
=
snprintf
(
&
buf
[
*
idx
],
buf_len
-
*
idx
,
NIPQUAD_FMT
,
NIPQUAD
(
addr
->
ip
))
+
1
;
*
idx
+=
len
;
BUG_ON
(
*
idx
>
buf_len
+
1
);
return
&
buf
[
*
idx
-
len
];
}
#define IP_VS_DBG_BUF(level, msg...) \
do { \
char ip_vs_dbg_buf[160]; \
int ip_vs_dbg_idx = 0; \
if (level <= ip_vs_get_debug_level()) \
printk(KERN_DEBUG "IPVS: " msg); \
} while (0)
#define IP_VS_ERR_BUF(msg...) \
do { \
char ip_vs_dbg_buf[160]; \
int ip_vs_dbg_idx = 0; \
printk(KERN_ERR "IPVS: " msg); \
} while (0)
/* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */
#define IP_VS_DBG_ADDR(af, addr) \
ip_vs_dbg_addr(af, ip_vs_dbg_buf, \
sizeof(ip_vs_dbg_buf), addr, \
&ip_vs_dbg_idx)
#define IP_VS_DBG(level, msg...) \
do { \
if (level <= ip_vs_get_debug_level()) \
...
...
@@ -48,6 +140,8 @@ extern int ip_vs_get_debug_level(void);
pp->debug_packet(pp, skb, ofs, msg); \
} while (0)
#else
/* NO DEBUGGING at ALL */
#define IP_VS_DBG_BUF(level, msg...) do {} while (0)
#define IP_VS_ERR_BUF(msg...) do {} while (0)
#define IP_VS_DBG(level, msg...) do {} while (0)
#define IP_VS_DBG_RL(msg...) do {} while (0)
#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0)
...
...
@@ -160,27 +254,10 @@ struct ip_vs_estimator {
struct
ip_vs_stats
{
__u32
conns
;
/* connections scheduled */
__u32
inpkts
;
/* incoming packets */
__u32
outpkts
;
/* outgoing packets */
__u64
inbytes
;
/* incoming bytes */
__u64
outbytes
;
/* outgoing bytes */
__u32
cps
;
/* current connection rate */
__u32
inpps
;
/* current in packet rate */
__u32
outpps
;
/* current out packet rate */
__u32
inbps
;
/* current in byte rate */
__u32
outbps
;
/* current out byte rate */
/*
* Don't add anything before the lock, because we use memcpy() to copy
* the members before the lock to struct ip_vs_stats_user in
* ip_vs_ctl.c.
*/
struct
ip_vs_stats_user
ustats
;
/* statistics */
struct
ip_vs_estimator
est
;
/* estimator */
spinlock_t
lock
;
/* spin lock */
struct
ip_vs_estimator
est
;
/* estimator */
};
struct
dst_entry
;
...
...
@@ -202,21 +279,23 @@ struct ip_vs_protocol {
void
(
*
exit
)(
struct
ip_vs_protocol
*
pp
);
int
(
*
conn_schedule
)(
struct
sk_buff
*
skb
,
int
(
*
conn_schedule
)(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
int
*
verdict
,
struct
ip_vs_conn
**
cpp
);
struct
ip_vs_conn
*
(
*
conn_in_get
)(
const
struct
sk_buff
*
skb
,
(
*
conn_in_get
)(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
const
struct
ip
_vs_ip
hdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
);
struct
ip_vs_conn
*
(
*
conn_out_get
)(
const
struct
sk_buff
*
skb
,
(
*
conn_out_get
)(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
const
struct
ip
_vs_ip
hdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
);
...
...
@@ -226,7 +305,8 @@ struct ip_vs_protocol {
int
(
*
dnat_handler
)(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
);
int
(
*
csum_check
)(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
);
int
(
*
csum_check
)(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
);
const
char
*
(
*
state_name
)(
int
state
);
...
...
@@ -259,9 +339,10 @@ struct ip_vs_conn {
struct
list_head
c_list
;
/* hashed list heads */
/* Protocol, addresses and port numbers */
__be32
caddr
;
/* client address */
__be32
vaddr
;
/* virtual address */
__be32
daddr
;
/* destination address */
u16
af
;
/* address family */
union
nf_inet_addr
caddr
;
/* client address */
union
nf_inet_addr
vaddr
;
/* virtual address */
union
nf_inet_addr
daddr
;
/* destination address */
__be16
cport
;
__be16
vport
;
__be16
dport
;
...
...
@@ -304,6 +385,45 @@ struct ip_vs_conn {
};
/*
* Extended internal versions of struct ip_vs_service_user and
* ip_vs_dest_user for IPv6 support.
*
* We need these to conveniently pass around service and destination
* options, but unfortunately, we also need to keep the old definitions to
* maintain userspace backwards compatibility for the setsockopt interface.
*/
struct
ip_vs_service_user_kern
{
/* virtual service addresses */
u16
af
;
u16
protocol
;
union
nf_inet_addr
addr
;
/* virtual ip address */
u16
port
;
u32
fwmark
;
/* firwall mark of service */
/* virtual service options */
char
*
sched_name
;
unsigned
flags
;
/* virtual service flags */
unsigned
timeout
;
/* persistent timeout in sec */
u32
netmask
;
/* persistent netmask */
};
struct
ip_vs_dest_user_kern
{
/* destination server address */
union
nf_inet_addr
addr
;
u16
port
;
/* real server options */
unsigned
conn_flags
;
/* connection flags */
int
weight
;
/* destination weight */
/* thresholds for active connections */
u32
u_threshold
;
/* upper threshold */
u32
l_threshold
;
/* lower threshold */
};
/*
* The information about the virtual service offered to the net
* and the forwarding entries
...
...
@@ -314,8 +434,9 @@ struct ip_vs_service {
atomic_t
refcnt
;
/* reference counter */
atomic_t
usecnt
;
/* use counter */
u16
af
;
/* address family */
__u16
protocol
;
/* which protocol (TCP/UDP) */
__be32
addr
;
/* IP address for virtual service */
union
nf_inet_addr
addr
;
/* IP address for virtual service */
__be16
port
;
/* port number for the service */
__u32
fwmark
;
/* firewall mark of the service */
unsigned
flags
;
/* service status flags */
...
...
@@ -342,7 +463,8 @@ struct ip_vs_dest {
struct
list_head
n_list
;
/* for the dests in the service */
struct
list_head
d_list
;
/* for table with all the dests */
__be32
addr
;
/* IP address of the server */
u16
af
;
/* address family */
union
nf_inet_addr
addr
;
/* IP address of the server */
__be16
port
;
/* port number of the server */
volatile
unsigned
flags
;
/* dest status flags */
atomic_t
conn_flags
;
/* flags to copy to conn */
...
...
@@ -366,7 +488,7 @@ struct ip_vs_dest {
/* for virtual service */
struct
ip_vs_service
*
svc
;
/* service it belongs to */
__u16
protocol
;
/* which protocol (TCP/UDP) */
__be32
vaddr
;
/* virtual IP address */
union
nf_inet_addr
vaddr
;
/* virtual IP address */
__be16
vport
;
/* virtual port number */
__u32
vfwmark
;
/* firewall mark of service */
};
...
...
@@ -380,6 +502,9 @@ struct ip_vs_scheduler {
char
*
name
;
/* scheduler name */
atomic_t
refcnt
;
/* reference counter */
struct
module
*
module
;
/* THIS_MODULE/NULL */
#ifdef CONFIG_IP_VS_IPV6
int
supports_ipv6
;
/* scheduler has IPv6 support */
#endif
/* scheduler initializing service */
int
(
*
init_service
)(
struct
ip_vs_service
*
svc
);
...
...
@@ -479,16 +604,8 @@ extern void ip_vs_init_hash_table(struct list_head *table, int rows);
#ifndef CONFIG_IP_VS_TAB_BITS
#define CONFIG_IP_VS_TAB_BITS 12
#endif
/* make sure that IP_VS_CONN_TAB_BITS is located in [8, 20] */
#if CONFIG_IP_VS_TAB_BITS < 8
#define IP_VS_CONN_TAB_BITS 8
#endif
#if CONFIG_IP_VS_TAB_BITS > 20
#define IP_VS_CONN_TAB_BITS 20
#endif
#if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20
#define IP_VS_CONN_TAB_BITS CONFIG_IP_VS_TAB_BITS
#endif
#define IP_VS_CONN_TAB_SIZE (1 << IP_VS_CONN_TAB_BITS)
#define IP_VS_CONN_TAB_MASK (IP_VS_CONN_TAB_SIZE - 1)
...
...
@@ -500,11 +617,16 @@ enum {
};
extern
struct
ip_vs_conn
*
ip_vs_conn_in_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
);
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
);
extern
struct
ip_vs_conn
*
ip_vs_ct_in_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
);
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
);
extern
struct
ip_vs_conn
*
ip_vs_conn_out_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
);
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
);
/* put back the conn without restarting its timer */
static
inline
void
__ip_vs_conn_put
(
struct
ip_vs_conn
*
cp
)
...
...
@@ -515,8 +637,9 @@ extern void ip_vs_conn_put(struct ip_vs_conn *cp);
extern
void
ip_vs_conn_fill_cport
(
struct
ip_vs_conn
*
cp
,
__be16
cport
);
extern
struct
ip_vs_conn
*
ip_vs_conn_new
(
int
proto
,
__be32
caddr
,
__be16
cport
,
__be32
vaddr
,
__be16
vport
,
__be32
daddr
,
__be16
dport
,
unsigned
flags
,
ip_vs_conn_new
(
int
af
,
int
proto
,
const
union
nf_inet_addr
*
caddr
,
__be16
cport
,
const
union
nf_inet_addr
*
vaddr
,
__be16
vport
,
const
union
nf_inet_addr
*
daddr
,
__be16
dport
,
unsigned
flags
,
struct
ip_vs_dest
*
dest
);
extern
void
ip_vs_conn_expire_now
(
struct
ip_vs_conn
*
cp
);
...
...
@@ -532,24 +655,32 @@ static inline void ip_vs_control_del(struct ip_vs_conn *cp)
{
struct
ip_vs_conn
*
ctl_cp
=
cp
->
control
;
if
(
!
ctl_cp
)
{
IP_VS_ERR
(
"request control DEL for uncontrolled: "
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d
\n
"
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
IP_VS_ERR_BUF
(
"request control DEL for uncontrolled: "
"%s:%d to %s:%d
\n
"
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
return
;
}
IP_VS_DBG
(
7
,
"DELeting control for: "
"cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d
\n
"
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
ctl_cp
->
caddr
),
ntohs
(
ctl_cp
->
cport
));
IP_VS_DBG_BUF
(
7
,
"DELeting control for: "
"cp.dst=%s:%d ctl_cp.dst=%s:%d
\n
"
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
ctl_cp
->
caddr
),
ntohs
(
ctl_cp
->
cport
));
cp
->
control
=
NULL
;
if
(
atomic_read
(
&
ctl_cp
->
n_control
)
==
0
)
{
IP_VS_ERR
(
"BUG control DEL with n=0 : "
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d
\n
"
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
IP_VS_ERR_BUF
(
"BUG control DEL with n=0 : "
"%s:%d to %s:%d
\n
"
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
return
;
}
atomic_dec
(
&
ctl_cp
->
n_control
);
...
...
@@ -559,17 +690,22 @@ static inline void
ip_vs_control_add
(
struct
ip_vs_conn
*
cp
,
struct
ip_vs_conn
*
ctl_cp
)
{
if
(
cp
->
control
)
{
IP_VS_ERR
(
"request control ADD for already controlled: "
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d
\n
"
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
IP_VS_ERR_BUF
(
"request control ADD for already controlled: "
"%s:%d to %s:%d
\n
"
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
));
ip_vs_control_del
(
cp
);
}
IP_VS_DBG
(
7
,
"ADDing control for: "
"cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d
\n
"
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
ctl_cp
->
caddr
),
ntohs
(
ctl_cp
->
cport
));
IP_VS_DBG_BUF
(
7
,
"ADDing control for: "
"cp.dst=%s:%d ctl_cp.dst=%s:%d
\n
"
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
ctl_cp
->
caddr
),
ntohs
(
ctl_cp
->
cport
));
cp
->
control
=
ctl_cp
;
atomic_inc
(
&
ctl_cp
->
n_control
);
...
...
@@ -647,7 +783,8 @@ extern struct ip_vs_stats ip_vs_stats;
extern
const
struct
ctl_path
net_vs_ctl_path
[];
extern
struct
ip_vs_service
*
ip_vs_service_get
(
__u32
fwmark
,
__u16
protocol
,
__be32
vaddr
,
__be16
vport
);
ip_vs_service_get
(
int
af
,
__u32
fwmark
,
__u16
protocol
,
const
union
nf_inet_addr
*
vaddr
,
__be16
vport
);
static
inline
void
ip_vs_service_put
(
struct
ip_vs_service
*
svc
)
{
...
...
@@ -655,14 +792,16 @@ static inline void ip_vs_service_put(struct ip_vs_service *svc)
}
extern
struct
ip_vs_dest
*
ip_vs_lookup_real_service
(
__u16
protocol
,
__be32
daddr
,
__be16
dport
);
ip_vs_lookup_real_service
(
int
af
,
__u16
protocol
,
const
union
nf_inet_addr
*
daddr
,
__be16
dport
);
extern
int
ip_vs_use_count_inc
(
void
);
extern
void
ip_vs_use_count_dec
(
void
);
extern
int
ip_vs_control_init
(
void
);
extern
void
ip_vs_control_cleanup
(
void
);
extern
struct
ip_vs_dest
*
ip_vs_find_dest
(
__be32
daddr
,
__be16
dport
,
__be32
vaddr
,
__be16
vport
,
__u16
protocol
);
ip_vs_find_dest
(
int
af
,
const
union
nf_inet_addr
*
daddr
,
__be16
dport
,
const
union
nf_inet_addr
*
vaddr
,
__be16
vport
,
__u16
protocol
);
extern
struct
ip_vs_dest
*
ip_vs_try_bind_dest
(
struct
ip_vs_conn
*
cp
);
...
...
@@ -706,6 +845,19 @@ extern int ip_vs_icmp_xmit
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
,
int
offset
);
extern
void
ip_vs_dst_reset
(
struct
ip_vs_dest
*
dest
);
#ifdef CONFIG_IP_VS_IPV6
extern
int
ip_vs_bypass_xmit_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
);
extern
int
ip_vs_nat_xmit_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
);
extern
int
ip_vs_tunnel_xmit_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
);
extern
int
ip_vs_dr_xmit_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
);
extern
int
ip_vs_icmp_xmit_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_conn
*
cp
,
struct
ip_vs_protocol
*
pp
,
int
offset
);
#endif
/*
* This is a simple mechanism to ignore packets when
...
...
@@ -750,7 +902,12 @@ static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
}
extern
void
ip_vs_nat_icmp
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
,
int
dir
);
struct
ip_vs_conn
*
cp
,
int
dir
);
#ifdef CONFIG_IP_VS_IPV6
extern
void
ip_vs_nat_icmp_v6
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
,
int
dir
);
#endif
extern
__sum16
ip_vs_checksum_complete
(
struct
sk_buff
*
skb
,
int
offset
);
...
...
@@ -761,6 +918,17 @@ static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)
return
csum_partial
((
char
*
)
diff
,
sizeof
(
diff
),
oldsum
);
}
#ifdef CONFIG_IP_VS_IPV6
static
inline
__wsum
ip_vs_check_diff16
(
const
__be32
*
old
,
const
__be32
*
new
,
__wsum
oldsum
)
{
__be32
diff
[
8
]
=
{
~
old
[
3
],
~
old
[
2
],
~
old
[
1
],
~
old
[
0
],
new
[
3
],
new
[
2
],
new
[
1
],
new
[
0
]
};
return
csum_partial
((
char
*
)
diff
,
sizeof
(
diff
),
oldsum
);
}
#endif
static
inline
__wsum
ip_vs_check_diff2
(
__be16
old
,
__be16
new
,
__wsum
oldsum
)
{
__be16
diff
[
2
]
=
{
~
old
,
new
};
...
...
net/ipv4/ipvs/Kconfig
浏览文件 @
dacc62db
...
...
@@ -24,6 +24,14 @@ menuconfig IP_VS
if IP_VS
config IP_VS_IPV6
bool "IPv6 support for IPVS (DANGEROUS)"
depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6)
---help---
Add IPv6 support to IPVS. This is incomplete and might be dangerous.
Say N if unsure.
config IP_VS_DEBUG
bool "IP virtual server debugging"
---help---
...
...
@@ -33,7 +41,8 @@ config IP_VS_DEBUG
config IP_VS_TAB_BITS
int "IPVS connection table size (the Nth power of 2)"
default "12"
range 8 20
default 12
---help---
The IPVS connection hash table uses the chaining scheme to handle
hash collisions. Using a big IPVS connection hash table will greatly
...
...
net/ipv4/ipvs/ip_vs_conn.c
浏览文件 @
dacc62db
...
...
@@ -114,9 +114,18 @@ static inline void ct_write_unlock_bh(unsigned key)
/*
* Returns hash value for IPVS connection entry
*/
static
unsigned
int
ip_vs_conn_hashkey
(
unsigned
proto
,
__be32
addr
,
__be16
port
)
static
unsigned
int
ip_vs_conn_hashkey
(
int
af
,
unsigned
proto
,
const
union
nf_inet_addr
*
addr
,
__be16
port
)
{
return
jhash_3words
((
__force
u32
)
addr
,
(
__force
u32
)
port
,
proto
,
ip_vs_conn_rnd
)
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
return
jhash_3words
(
jhash
(
addr
,
16
,
ip_vs_conn_rnd
),
(
__force
u32
)
port
,
proto
,
ip_vs_conn_rnd
)
&
IP_VS_CONN_TAB_MASK
;
#endif
return
jhash_3words
((
__force
u32
)
addr
->
ip
,
(
__force
u32
)
port
,
proto
,
ip_vs_conn_rnd
)
&
IP_VS_CONN_TAB_MASK
;
}
...
...
@@ -131,7 +140,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
int
ret
;
/* Hash by protocol, client address and port */
hash
=
ip_vs_conn_hashkey
(
cp
->
protocol
,
cp
->
caddr
,
cp
->
cport
);
hash
=
ip_vs_conn_hashkey
(
cp
->
af
,
cp
->
protocol
,
&
cp
->
caddr
,
cp
->
cport
);
ct_write_lock
(
hash
);
...
...
@@ -162,7 +171,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
int
ret
;
/* unhash it and decrease its reference counter */
hash
=
ip_vs_conn_hashkey
(
cp
->
protocol
,
cp
->
caddr
,
cp
->
cport
);
hash
=
ip_vs_conn_hashkey
(
cp
->
af
,
cp
->
protocol
,
&
cp
->
caddr
,
cp
->
cport
);
ct_write_lock
(
hash
);
...
...
@@ -187,20 +196,23 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
* d_addr, d_port: pkt dest address (load balancer)
*/
static
inline
struct
ip_vs_conn
*
__ip_vs_conn_in_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
)
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
)
{
unsigned
hash
;
struct
ip_vs_conn
*
cp
;
hash
=
ip_vs_conn_hashkey
(
protocol
,
s_addr
,
s_port
);
hash
=
ip_vs_conn_hashkey
(
af
,
protocol
,
s_addr
,
s_port
);
ct_read_lock
(
hash
);
list_for_each_entry
(
cp
,
&
ip_vs_conn_tab
[
hash
],
c_list
)
{
if
(
s_addr
==
cp
->
caddr
&&
s_port
==
cp
->
cport
&&
d_port
==
cp
->
vport
&&
d_addr
==
cp
->
vaddr
&&
if
(
cp
->
af
==
af
&&
ip_vs_addr_equal
(
af
,
s_addr
,
&
cp
->
caddr
)
&&
ip_vs_addr_equal
(
af
,
d_addr
,
&
cp
->
vaddr
)
&&
s_port
==
cp
->
cport
&&
d_port
==
cp
->
vport
&&
((
!
s_port
)
^
(
!
(
cp
->
flags
&
IP_VS_CONN_F_NO_CPORT
)))
&&
protocol
==
cp
->
protocol
)
{
protocol
==
cp
->
protocol
)
{
/* HIT */
atomic_inc
(
&
cp
->
refcnt
);
ct_read_unlock
(
hash
);
...
...
@@ -214,39 +226,44 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
}
struct
ip_vs_conn
*
ip_vs_conn_in_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
)
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
)
{
struct
ip_vs_conn
*
cp
;
cp
=
__ip_vs_conn_in_get
(
protocol
,
s_addr
,
s_port
,
d_addr
,
d_port
);
cp
=
__ip_vs_conn_in_get
(
af
,
protocol
,
s_addr
,
s_port
,
d_addr
,
d_port
);
if
(
!
cp
&&
atomic_read
(
&
ip_vs_conn_no_cport_cnt
))
cp
=
__ip_vs_conn_in_get
(
protocol
,
s_addr
,
0
,
d_addr
,
d_port
);
cp
=
__ip_vs_conn_in_get
(
af
,
protocol
,
s_addr
,
0
,
d_addr
,
d_port
);
IP_VS_DBG
(
9
,
"lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
NIPQUAD
(
s_addr
),
ntohs
(
s_port
),
NIPQUAD
(
d_addr
),
ntohs
(
d_port
),
cp
?
"hit"
:
"not hit"
);
IP_VS_DBG
_BUF
(
9
,
"lookup/in %s %s:%d->%s
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
IP_VS_DBG_ADDR
(
af
,
s_addr
),
ntohs
(
s_port
),
IP_VS_DBG_ADDR
(
af
,
d_addr
),
ntohs
(
d_port
),
cp
?
"hit"
:
"not hit"
);
return
cp
;
}
/* Get reference to connection template */
struct
ip_vs_conn
*
ip_vs_ct_in_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
)
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
)
{
unsigned
hash
;
struct
ip_vs_conn
*
cp
;
hash
=
ip_vs_conn_hashkey
(
protocol
,
s_addr
,
s_port
);
hash
=
ip_vs_conn_hashkey
(
af
,
protocol
,
s_addr
,
s_port
);
ct_read_lock
(
hash
);
list_for_each_entry
(
cp
,
&
ip_vs_conn_tab
[
hash
],
c_list
)
{
if
(
s_addr
==
cp
->
caddr
&&
s_port
==
cp
->
cport
&&
d_port
==
cp
->
vport
&&
d_addr
==
cp
->
vaddr
&&
if
(
cp
->
af
==
af
&&
ip_vs_addr_equal
(
af
,
s_addr
,
&
cp
->
caddr
)
&&
ip_vs_addr_equal
(
af
,
d_addr
,
&
cp
->
vaddr
)
&&
s_port
==
cp
->
cport
&&
d_port
==
cp
->
vport
&&
cp
->
flags
&
IP_VS_CONN_F_TEMPLATE
&&
protocol
==
cp
->
protocol
)
{
protocol
==
cp
->
protocol
)
{
/* HIT */
atomic_inc
(
&
cp
->
refcnt
);
goto
out
;
...
...
@@ -257,11 +274,11 @@ struct ip_vs_conn *ip_vs_ct_in_get
out:
ct_read_unlock
(
hash
);
IP_VS_DBG
(
9
,
"template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
NIPQUAD
(
s_addr
),
ntohs
(
s_port
),
NIPQUAD
(
d_addr
),
ntohs
(
d_port
),
cp
?
"hit"
:
"not hit"
);
IP_VS_DBG
_BUF
(
9
,
"template lookup/in %s %s:%d->%s
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
IP_VS_DBG_ADDR
(
af
,
s_addr
),
ntohs
(
s_port
),
IP_VS_DBG_ADDR
(
af
,
d_addr
),
ntohs
(
d_port
),
cp
?
"hit"
:
"not hit"
);
return
cp
;
}
...
...
@@ -273,7 +290,8 @@ struct ip_vs_conn *ip_vs_ct_in_get
* d_addr, d_port: pkt dest address (foreign host)
*/
struct
ip_vs_conn
*
ip_vs_conn_out_get
(
int
protocol
,
__be32
s_addr
,
__be16
s_port
,
__be32
d_addr
,
__be16
d_port
)
(
int
af
,
int
protocol
,
const
union
nf_inet_addr
*
s_addr
,
__be16
s_port
,
const
union
nf_inet_addr
*
d_addr
,
__be16
d_port
)
{
unsigned
hash
;
struct
ip_vs_conn
*
cp
,
*
ret
=
NULL
;
...
...
@@ -281,13 +299,15 @@ struct ip_vs_conn *ip_vs_conn_out_get
/*
* Check for "full" addressed entries
*/
hash
=
ip_vs_conn_hashkey
(
protocol
,
d_addr
,
d_port
);
hash
=
ip_vs_conn_hashkey
(
af
,
protocol
,
d_addr
,
d_port
);
ct_read_lock
(
hash
);
list_for_each_entry
(
cp
,
&
ip_vs_conn_tab
[
hash
],
c_list
)
{
if
(
d_addr
==
cp
->
caddr
&&
d_port
==
cp
->
cport
&&
s_port
==
cp
->
dport
&&
s_addr
==
cp
->
daddr
&&
if
(
cp
->
af
==
af
&&
ip_vs_addr_equal
(
af
,
d_addr
,
&
cp
->
caddr
)
&&
ip_vs_addr_equal
(
af
,
s_addr
,
&
cp
->
daddr
)
&&
d_port
==
cp
->
cport
&&
s_port
==
cp
->
dport
&&
protocol
==
cp
->
protocol
)
{
/* HIT */
atomic_inc
(
&
cp
->
refcnt
);
...
...
@@ -298,11 +318,11 @@ struct ip_vs_conn *ip_vs_conn_out_get
ct_read_unlock
(
hash
);
IP_VS_DBG
(
9
,
"lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
NIPQUAD
(
s_addr
),
ntohs
(
s_port
),
NIPQUAD
(
d_addr
),
ntohs
(
d_port
),
ret
?
"hit"
:
"not hit"
);
IP_VS_DBG
_BUF
(
9
,
"lookup/out %s %s:%d->%s
:%d %s
\n
"
,
ip_vs_proto_name
(
protocol
),
IP_VS_DBG_ADDR
(
af
,
s_addr
),
ntohs
(
s_port
),
IP_VS_DBG_ADDR
(
af
,
d_addr
),
ntohs
(
d_port
),
ret
?
"hit"
:
"not hit"
);
return
ret
;
}
...
...
@@ -369,6 +389,33 @@ static inline void ip_vs_bind_xmit(struct ip_vs_conn *cp)
}
}
#ifdef CONFIG_IP_VS_IPV6
static
inline
void
ip_vs_bind_xmit_v6
(
struct
ip_vs_conn
*
cp
)
{
switch
(
IP_VS_FWD_METHOD
(
cp
))
{
case
IP_VS_CONN_F_MASQ
:
cp
->
packet_xmit
=
ip_vs_nat_xmit_v6
;
break
;
case
IP_VS_CONN_F_TUNNEL
:
cp
->
packet_xmit
=
ip_vs_tunnel_xmit_v6
;
break
;
case
IP_VS_CONN_F_DROUTE
:
cp
->
packet_xmit
=
ip_vs_dr_xmit_v6
;
break
;
case
IP_VS_CONN_F_LOCALNODE
:
cp
->
packet_xmit
=
ip_vs_null_xmit
;
break
;
case
IP_VS_CONN_F_BYPASS
:
cp
->
packet_xmit
=
ip_vs_bypass_xmit_v6
;
break
;
}
}
#endif
static
inline
int
ip_vs_dest_totalconns
(
struct
ip_vs_dest
*
dest
)
{
...
...
@@ -402,16 +449,16 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
cp
->
flags
|=
atomic_read
(
&
dest
->
conn_flags
);
cp
->
dest
=
dest
;
IP_VS_DBG
(
7
,
"Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u
:%d "
"d:%u.%u.%u.%u
:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
"dest->refcnt:%d
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
NIPQUAD
(
cp
->
daddr
),
ntohs
(
cp
->
dport
),
ip_vs_fwd_tag
(
cp
),
cp
->
state
,
cp
->
flags
,
atomic_read
(
&
cp
->
refcnt
),
atomic_read
(
&
dest
->
refcnt
));
IP_VS_DBG
_BUF
(
7
,
"Bind-dest %s c:%s:%d v:%s
:%d "
"d:%s
:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
"dest->refcnt:%d
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
daddr
),
ntohs
(
cp
->
dport
),
ip_vs_fwd_tag
(
cp
),
cp
->
state
,
cp
->
flags
,
atomic_read
(
&
cp
->
refcnt
),
atomic_read
(
&
dest
->
refcnt
));
/* Update the connection counters */
if
(
!
(
cp
->
flags
&
IP_VS_CONN_F_TEMPLATE
))
{
...
...
@@ -444,8 +491,9 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
struct
ip_vs_dest
*
dest
;
if
((
cp
)
&&
(
!
cp
->
dest
))
{
dest
=
ip_vs_find_dest
(
cp
->
daddr
,
cp
->
dport
,
cp
->
vaddr
,
cp
->
vport
,
cp
->
protocol
);
dest
=
ip_vs_find_dest
(
cp
->
af
,
&
cp
->
daddr
,
cp
->
dport
,
&
cp
->
vaddr
,
cp
->
vport
,
cp
->
protocol
);
ip_vs_bind_dest
(
cp
,
dest
);
return
dest
;
}
else
...
...
@@ -464,16 +512,16 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
if
(
!
dest
)
return
;
IP_VS_DBG
(
7
,
"Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u
:%d "
"d:%u.%u.%u.%u
:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
"dest->refcnt:%d
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
NIPQUAD
(
cp
->
daddr
),
ntohs
(
cp
->
dport
),
ip_vs_fwd_tag
(
cp
),
cp
->
state
,
cp
->
flags
,
atomic_read
(
&
cp
->
refcnt
),
atomic_read
(
&
dest
->
refcnt
));
IP_VS_DBG
_BUF
(
7
,
"Unbind-dest %s c:%s:%d v:%s
:%d "
"d:%s
:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
"dest->refcnt:%d
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
daddr
),
ntohs
(
cp
->
dport
),
ip_vs_fwd_tag
(
cp
),
cp
->
state
,
cp
->
flags
,
atomic_read
(
&
cp
->
refcnt
),
atomic_read
(
&
dest
->
refcnt
));
/* Update the connection counters */
if
(
!
(
cp
->
flags
&
IP_VS_CONN_F_TEMPLATE
))
{
...
...
@@ -526,13 +574,16 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
!
(
dest
->
flags
&
IP_VS_DEST_F_AVAILABLE
)
||
(
sysctl_ip_vs_expire_quiescent_template
&&
(
atomic_read
(
&
dest
->
weight
)
==
0
)))
{
IP_VS_DBG
(
9
,
"check_template: dest not available for "
"protocol %s s:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
"-> d:%u.%u.%u.%u:%d
\n
"
,
ip_vs_proto_name
(
ct
->
protocol
),
NIPQUAD
(
ct
->
caddr
),
ntohs
(
ct
->
cport
),
NIPQUAD
(
ct
->
vaddr
),
ntohs
(
ct
->
vport
),
NIPQUAD
(
ct
->
daddr
),
ntohs
(
ct
->
dport
));
IP_VS_DBG_BUF
(
9
,
"check_template: dest not available for "
"protocol %s s:%s:%d v:%s:%d "
"-> d:%s:%d
\n
"
,
ip_vs_proto_name
(
ct
->
protocol
),
IP_VS_DBG_ADDR
(
ct
->
af
,
&
ct
->
caddr
),
ntohs
(
ct
->
cport
),
IP_VS_DBG_ADDR
(
ct
->
af
,
&
ct
->
vaddr
),
ntohs
(
ct
->
vport
),
IP_VS_DBG_ADDR
(
ct
->
af
,
&
ct
->
daddr
),
ntohs
(
ct
->
dport
));
/*
* Invalidate the connection template
...
...
@@ -625,8 +676,9 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
* Create a new connection entry and hash it into the ip_vs_conn_tab
*/
struct
ip_vs_conn
*
ip_vs_conn_new
(
int
proto
,
__be32
caddr
,
__be16
cport
,
__be32
vaddr
,
__be16
vport
,
__be32
daddr
,
__be16
dport
,
unsigned
flags
,
ip_vs_conn_new
(
int
af
,
int
proto
,
const
union
nf_inet_addr
*
caddr
,
__be16
cport
,
const
union
nf_inet_addr
*
vaddr
,
__be16
vport
,
const
union
nf_inet_addr
*
daddr
,
__be16
dport
,
unsigned
flags
,
struct
ip_vs_dest
*
dest
)
{
struct
ip_vs_conn
*
cp
;
...
...
@@ -640,12 +692,13 @@ ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport
INIT_LIST_HEAD
(
&
cp
->
c_list
);
setup_timer
(
&
cp
->
timer
,
ip_vs_conn_expire
,
(
unsigned
long
)
cp
);
cp
->
af
=
af
;
cp
->
protocol
=
proto
;
cp
->
caddr
=
caddr
;
ip_vs_addr_copy
(
af
,
&
cp
->
caddr
,
caddr
)
;
cp
->
cport
=
cport
;
cp
->
vaddr
=
vaddr
;
ip_vs_addr_copy
(
af
,
&
cp
->
vaddr
,
vaddr
)
;
cp
->
vport
=
vport
;
cp
->
daddr
=
daddr
;
ip_vs_addr_copy
(
af
,
&
cp
->
daddr
,
daddr
)
;
cp
->
dport
=
dport
;
cp
->
flags
=
flags
;
spin_lock_init
(
&
cp
->
lock
);
...
...
@@ -672,7 +725,12 @@ ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport
cp
->
timeout
=
3
*
HZ
;
/* Bind its packet transmitter */
ip_vs_bind_xmit
(
cp
);
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
ip_vs_bind_xmit_v6
(
cp
);
else
#endif
ip_vs_bind_xmit
(
cp
);
if
(
unlikely
(
pp
&&
atomic_read
(
&
pp
->
appcnt
)))
ip_vs_bind_app
(
cp
,
pp
);
...
...
@@ -760,12 +818,26 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
else
{
const
struct
ip_vs_conn
*
cp
=
v
;
seq_printf
(
seq
,
"%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu
\n
"
,
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
seq_printf
(
seq
,
"%-3s "
NIP6_FMT
" %04X "
NIP6_FMT
" %04X "
NIP6_FMT
" %04X %-11s %7lu
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
NIP6
(
cp
->
caddr
.
in6
),
ntohs
(
cp
->
cport
),
NIP6
(
cp
->
vaddr
.
in6
),
ntohs
(
cp
->
vport
),
NIP6
(
cp
->
daddr
.
in6
),
ntohs
(
cp
->
dport
),
ip_vs_state_name
(
cp
->
protocol
,
cp
->
state
),
(
cp
->
timer
.
expires
-
jiffies
)
/
HZ
);
else
#endif
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
),
ntohl
(
cp
->
caddr
.
ip
),
ntohs
(
cp
->
cport
),
ntohl
(
cp
->
vaddr
.
ip
),
ntohs
(
cp
->
vport
),
ntohl
(
cp
->
daddr
.
ip
),
ntohs
(
cp
->
dport
),
ip_vs_state_name
(
cp
->
protocol
,
cp
->
state
),
(
cp
->
timer
.
expires
-
jiffies
)
/
HZ
);
}
...
...
@@ -809,12 +881,27 @@ static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)
else
{
const
struct
ip_vs_conn
*
cp
=
v
;
seq_printf
(
seq
,
"%-3s %08X %04X %08X %04X %08X %04X %-11s %-6s %7lu
\n
"
,
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
seq_printf
(
seq
,
"%-3s "
NIP6_FMT
" %04X "
NIP6_FMT
" %04X "
NIP6_FMT
" %04X %-11s %-6s %7lu
\n
"
,
ip_vs_proto_name
(
cp
->
protocol
),
NIP6
(
cp
->
caddr
.
in6
),
ntohs
(
cp
->
cport
),
NIP6
(
cp
->
vaddr
.
in6
),
ntohs
(
cp
->
vport
),
NIP6
(
cp
->
daddr
.
in6
),
ntohs
(
cp
->
dport
),
ip_vs_state_name
(
cp
->
protocol
,
cp
->
state
),
ip_vs_origin_name
(
cp
->
flags
),
(
cp
->
timer
.
expires
-
jiffies
)
/
HZ
);
else
#endif
seq_printf
(
seq
,
"%-3s %08X %04X %08X %04X "
"%08X %04X %-11s %-6s %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
),
ntohl
(
cp
->
caddr
.
ip
),
ntohs
(
cp
->
cport
),
ntohl
(
cp
->
vaddr
.
ip
),
ntohs
(
cp
->
vport
),
ntohl
(
cp
->
daddr
.
ip
),
ntohs
(
cp
->
dport
),
ip_vs_state_name
(
cp
->
protocol
,
cp
->
state
),
ip_vs_origin_name
(
cp
->
flags
),
(
cp
->
timer
.
expires
-
jiffies
)
/
HZ
);
...
...
net/ipv4/ipvs/ip_vs_core.c
浏览文件 @
dacc62db
此差异已折叠。
点击以展开。
net/ipv4/ipvs/ip_vs_ctl.c
浏览文件 @
dacc62db
此差异已折叠。
点击以展开。
net/ipv4/ipvs/ip_vs_dh.c
浏览文件 @
dacc62db
...
...
@@ -218,7 +218,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG
(
6
,
"DH: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d
\n
"
,
NIPQUAD
(
iph
->
daddr
),
NIPQUAD
(
dest
->
addr
),
NIPQUAD
(
dest
->
addr
.
ip
),
ntohs
(
dest
->
port
));
return
dest
;
...
...
@@ -234,6 +234,9 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_dh_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
0
,
#endif
.
init_service
=
ip_vs_dh_init_svc
,
.
done_service
=
ip_vs_dh_done_svc
,
.
update_service
=
ip_vs_dh_update_svc
,
...
...
net/ipv4/ipvs/ip_vs_est.c
浏览文件 @
dacc62db
...
...
@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg)
s
=
container_of
(
e
,
struct
ip_vs_stats
,
est
);
spin_lock
(
&
s
->
lock
);
n_conns
=
s
->
conns
;
n_inpkts
=
s
->
inpkts
;
n_outpkts
=
s
->
outpkts
;
n_inbytes
=
s
->
inbytes
;
n_outbytes
=
s
->
outbytes
;
n_conns
=
s
->
ustats
.
conns
;
n_inpkts
=
s
->
ustats
.
inpkts
;
n_outpkts
=
s
->
ustats
.
outpkts
;
n_inbytes
=
s
->
ustats
.
inbytes
;
n_outbytes
=
s
->
ustats
.
outbytes
;
/* scaled by 2^10, but divided 2 seconds */
rate
=
(
n_conns
-
e
->
last_conns
)
<<
9
;
e
->
last_conns
=
n_conns
;
e
->
cps
+=
((
long
)
rate
-
(
long
)
e
->
cps
)
>>
2
;
s
->
cps
=
(
e
->
cps
+
0x1FF
)
>>
10
;
s
->
ustats
.
cps
=
(
e
->
cps
+
0x1FF
)
>>
10
;
rate
=
(
n_inpkts
-
e
->
last_inpkts
)
<<
9
;
e
->
last_inpkts
=
n_inpkts
;
e
->
inpps
+=
((
long
)
rate
-
(
long
)
e
->
inpps
)
>>
2
;
s
->
inpps
=
(
e
->
inpps
+
0x1FF
)
>>
10
;
s
->
ustats
.
inpps
=
(
e
->
inpps
+
0x1FF
)
>>
10
;
rate
=
(
n_outpkts
-
e
->
last_outpkts
)
<<
9
;
e
->
last_outpkts
=
n_outpkts
;
e
->
outpps
+=
((
long
)
rate
-
(
long
)
e
->
outpps
)
>>
2
;
s
->
outpps
=
(
e
->
outpps
+
0x1FF
)
>>
10
;
s
->
ustats
.
outpps
=
(
e
->
outpps
+
0x1FF
)
>>
10
;
rate
=
(
n_inbytes
-
e
->
last_inbytes
)
<<
4
;
e
->
last_inbytes
=
n_inbytes
;
e
->
inbps
+=
((
long
)
rate
-
(
long
)
e
->
inbps
)
>>
2
;
s
->
inbps
=
(
e
->
inbps
+
0xF
)
>>
5
;
s
->
ustats
.
inbps
=
(
e
->
inbps
+
0xF
)
>>
5
;
rate
=
(
n_outbytes
-
e
->
last_outbytes
)
<<
4
;
e
->
last_outbytes
=
n_outbytes
;
e
->
outbps
+=
((
long
)
rate
-
(
long
)
e
->
outbps
)
>>
2
;
s
->
outbps
=
(
e
->
outbps
+
0xF
)
>>
5
;
s
->
ustats
.
outbps
=
(
e
->
outbps
+
0xF
)
>>
5
;
spin_unlock
(
&
s
->
lock
);
}
spin_unlock
(
&
est_lock
);
...
...
@@ -108,20 +108,20 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats)
INIT_LIST_HEAD
(
&
est
->
list
);
est
->
last_conns
=
stats
->
conns
;
est
->
cps
=
stats
->
cps
<<
10
;
est
->
last_conns
=
stats
->
ustats
.
conns
;
est
->
cps
=
stats
->
ustats
.
cps
<<
10
;
est
->
last_inpkts
=
stats
->
inpkts
;
est
->
inpps
=
stats
->
inpps
<<
10
;
est
->
last_inpkts
=
stats
->
ustats
.
inpkts
;
est
->
inpps
=
stats
->
ustats
.
inpps
<<
10
;
est
->
last_outpkts
=
stats
->
outpkts
;
est
->
outpps
=
stats
->
outpps
<<
10
;
est
->
last_outpkts
=
stats
->
ustats
.
outpkts
;
est
->
outpps
=
stats
->
ustats
.
outpps
<<
10
;
est
->
last_inbytes
=
stats
->
inbytes
;
est
->
inbps
=
stats
->
inbps
<<
5
;
est
->
last_inbytes
=
stats
->
ustats
.
inbytes
;
est
->
inbps
=
stats
->
ustats
.
inbps
<<
5
;
est
->
last_outbytes
=
stats
->
outbytes
;
est
->
outbps
=
stats
->
outbps
<<
5
;
est
->
last_outbytes
=
stats
->
ustats
.
outbytes
;
est
->
outbps
=
stats
->
ustats
.
outbps
<<
5
;
spin_lock_bh
(
&
est_lock
);
list_add
(
&
est
->
list
,
&
est_list
);
...
...
net/ipv4/ipvs/ip_vs_ftp.c
浏览文件 @
dacc62db
...
...
@@ -140,13 +140,21 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct
tcphdr
*
th
;
char
*
data
,
*
data_limit
;
char
*
start
,
*
end
;
__be32
from
;
union
nf_inet_addr
from
;
__be16
port
;
struct
ip_vs_conn
*
n_cp
;
char
buf
[
24
];
/* xxx.xxx.xxx.xxx,ppp,ppp\000 */
unsigned
buf_len
;
int
ret
;
#ifdef CONFIG_IP_VS_IPV6
/* This application helper doesn't work with IPv6 yet,
* so turn this into a no-op for IPv6 packets
*/
if
(
cp
->
af
==
AF_INET6
)
return
1
;
#endif
*
diff
=
0
;
/* Only useful for established sessions */
...
...
@@ -166,24 +174,25 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
if
(
ip_vs_ftp_get_addrport
(
data
,
data_limit
,
SERVER_STRING
,
sizeof
(
SERVER_STRING
)
-
1
,
')'
,
&
from
,
&
port
,
&
from
.
ip
,
&
port
,
&
start
,
&
end
)
!=
1
)
return
1
;
IP_VS_DBG
(
7
,
"PASV response (%u.%u.%u.%u:%d) -> "
"%u.%u.%u.%u:%d detected
\n
"
,
NIPQUAD
(
from
),
ntohs
(
port
),
NIPQUAD
(
cp
->
caddr
),
0
);
NIPQUAD
(
from
.
ip
),
ntohs
(
port
),
NIPQUAD
(
cp
->
caddr
.
ip
),
0
);
/*
* Now update or create an connection entry for it
*/
n_cp
=
ip_vs_conn_out_get
(
iph
->
protocol
,
from
,
port
,
cp
->
caddr
,
0
);
n_cp
=
ip_vs_conn_out_get
(
AF_INET
,
iph
->
protocol
,
&
from
,
port
,
&
cp
->
caddr
,
0
);
if
(
!
n_cp
)
{
n_cp
=
ip_vs_conn_new
(
IPPROTO_TCP
,
cp
->
caddr
,
0
,
cp
->
vaddr
,
port
,
from
,
port
,
n_cp
=
ip_vs_conn_new
(
AF_INET
,
IPPROTO_TCP
,
&
cp
->
caddr
,
0
,
&
cp
->
vaddr
,
port
,
&
from
,
port
,
IP_VS_CONN_F_NO_CPORT
,
cp
->
dest
);
if
(
!
n_cp
)
...
...
@@ -196,9 +205,9 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
/*
* Replace the old passive address with the new one
*/
from
=
n_cp
->
vaddr
;
from
.
ip
=
n_cp
->
vaddr
.
ip
;
port
=
n_cp
->
vport
;
sprintf
(
buf
,
"%d,%d,%d,%d,%d,%d"
,
NIPQUAD
(
from
),
sprintf
(
buf
,
"%d,%d,%d,%d,%d,%d"
,
NIPQUAD
(
from
.
ip
),
(
ntohs
(
port
)
>>
8
)
&
255
,
ntohs
(
port
)
&
255
);
buf_len
=
strlen
(
buf
);
...
...
@@ -243,10 +252,18 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
struct
tcphdr
*
th
;
char
*
data
,
*
data_start
,
*
data_limit
;
char
*
start
,
*
end
;
__be32
to
;
union
nf_inet_addr
to
;
__be16
port
;
struct
ip_vs_conn
*
n_cp
;
#ifdef CONFIG_IP_VS_IPV6
/* This application helper doesn't work with IPv6 yet,
* so turn this into a no-op for IPv6 packets
*/
if
(
cp
->
af
==
AF_INET6
)
return
1
;
#endif
/* no diff required for incoming packets */
*
diff
=
0
;
...
...
@@ -291,12 +308,12 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/
if
(
ip_vs_ftp_get_addrport
(
data_start
,
data_limit
,
CLIENT_STRING
,
sizeof
(
CLIENT_STRING
)
-
1
,
'\r'
,
&
to
,
&
port
,
'\r'
,
&
to
.
ip
,
&
port
,
&
start
,
&
end
)
!=
1
)
return
1
;
IP_VS_DBG
(
7
,
"PORT %u.%u.%u.%u:%d detected
\n
"
,
NIPQUAD
(
to
),
ntohs
(
port
));
NIPQUAD
(
to
.
ip
),
ntohs
(
port
));
/* Passive mode off */
cp
->
app_data
=
NULL
;
...
...
@@ -306,16 +323,16 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
*/
IP_VS_DBG
(
7
,
"protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d
\n
"
,
ip_vs_proto_name
(
iph
->
protocol
),
NIPQUAD
(
to
),
ntohs
(
port
),
NIPQUAD
(
cp
->
vaddr
),
0
);
NIPQUAD
(
to
.
ip
),
ntohs
(
port
),
NIPQUAD
(
cp
->
vaddr
.
ip
),
0
);
n_cp
=
ip_vs_conn_in_get
(
iph
->
protocol
,
to
,
port
,
cp
->
vaddr
,
htons
(
ntohs
(
cp
->
vport
)
-
1
));
n_cp
=
ip_vs_conn_in_get
(
AF_INET
,
iph
->
protocol
,
&
to
,
port
,
&
cp
->
vaddr
,
htons
(
ntohs
(
cp
->
vport
)
-
1
));
if
(
!
n_cp
)
{
n_cp
=
ip_vs_conn_new
(
IPPROTO_TCP
,
to
,
port
,
cp
->
vaddr
,
htons
(
ntohs
(
cp
->
vport
)
-
1
),
cp
->
daddr
,
htons
(
ntohs
(
cp
->
dport
)
-
1
),
n_cp
=
ip_vs_conn_new
(
AF_INET
,
IPPROTO_TCP
,
&
to
,
port
,
&
cp
->
vaddr
,
htons
(
ntohs
(
cp
->
vport
)
-
1
),
&
cp
->
daddr
,
htons
(
ntohs
(
cp
->
dport
)
-
1
),
0
,
cp
->
dest
);
if
(
!
n_cp
)
...
...
net/ipv4/ipvs/ip_vs_lblc.c
浏览文件 @
dacc62db
...
...
@@ -422,7 +422,7 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
IP_VS_DBG
(
6
,
"LBLC: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
NIPQUAD
(
least
->
addr
.
ip
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
...
...
@@ -506,7 +506,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG
(
6
,
"LBLC: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d
\n
"
,
NIPQUAD
(
iph
->
daddr
),
NIPQUAD
(
dest
->
addr
),
NIPQUAD
(
dest
->
addr
.
ip
),
ntohs
(
dest
->
port
));
return
dest
;
...
...
@@ -522,6 +522,9 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_lblc_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
0
,
#endif
.
init_service
=
ip_vs_lblc_init_svc
,
.
done_service
=
ip_vs_lblc_done_svc
,
.
schedule
=
ip_vs_lblc_schedule
,
...
...
net/ipv4/ipvs/ip_vs_lblcr.c
浏览文件 @
dacc62db
...
...
@@ -204,7 +204,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
IP_VS_DBG
(
6
,
"ip_vs_dest_set_min: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
NIPQUAD
(
least
->
addr
.
ip
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
...
...
@@ -250,7 +250,7 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
IP_VS_DBG
(
6
,
"ip_vs_dest_set_max: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
most
->
addr
),
ntohs
(
most
->
port
),
NIPQUAD
(
most
->
addr
.
ip
),
ntohs
(
most
->
port
),
atomic_read
(
&
most
->
activeconns
),
atomic_read
(
&
most
->
refcnt
),
atomic_read
(
&
most
->
weight
),
moh
);
...
...
@@ -598,7 +598,7 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
IP_VS_DBG
(
6
,
"LBLCR: server %d.%d.%d.%d:%d "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
NIPQUAD
(
least
->
addr
.
ip
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
...
...
@@ -706,7 +706,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG
(
6
,
"LBLCR: destination IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d
\n
"
,
NIPQUAD
(
iph
->
daddr
),
NIPQUAD
(
dest
->
addr
),
NIPQUAD
(
dest
->
addr
.
ip
),
ntohs
(
dest
->
port
));
return
dest
;
...
...
@@ -722,6 +722,9 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_lblcr_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
0
,
#endif
.
init_service
=
ip_vs_lblcr_init_svc
,
.
done_service
=
ip_vs_lblcr_done_svc
,
.
schedule
=
ip_vs_lblcr_schedule
,
...
...
net/ipv4/ipvs/ip_vs_lc.c
浏览文件 @
dacc62db
...
...
@@ -67,10 +67,10 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
}
if
(
least
)
IP_VS_DBG
(
6
,
"LC: server %u.%u.%u.%u
:%u activeconns %d inactconns %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
inactconns
));
IP_VS_DBG
_BUF
(
6
,
"LC: server %s
:%u activeconns %d inactconns %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
inactconns
));
return
least
;
}
...
...
@@ -81,6 +81,9 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_lc_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
schedule
=
ip_vs_lc_schedule
,
};
...
...
net/ipv4/ipvs/ip_vs_nq.c
浏览文件 @
dacc62db
...
...
@@ -99,12 +99,12 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
return
NULL
;
out:
IP_VS_DBG
(
6
,
"NQ: server %u.%u.%u.%u
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
IP_VS_DBG
_BUF
(
6
,
"NQ: server %s
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
return
least
;
}
...
...
@@ -116,6 +116,9 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_nq_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
schedule
=
ip_vs_nq_schedule
,
};
...
...
net/ipv4/ipvs/ip_vs_proto.c
浏览文件 @
dacc62db
...
...
@@ -151,11 +151,11 @@ const char * ip_vs_state_name(__u16 proto, int state)
}
void
ip_vs_tcpudp_debug_packet
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
static
void
ip_vs_tcpudp_debug_packet
_v4
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
char
buf
[
128
];
struct
iphdr
_iph
,
*
ih
;
...
...
@@ -189,6 +189,61 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
printk
(
KERN_DEBUG
"IPVS: %s: %s
\n
"
,
msg
,
buf
);
}
#ifdef CONFIG_IP_VS_IPV6
static
void
ip_vs_tcpudp_debug_packet_v6
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
char
buf
[
192
];
struct
ipv6hdr
_iph
,
*
ih
;
ih
=
skb_header_pointer
(
skb
,
offset
,
sizeof
(
_iph
),
&
_iph
);
if
(
ih
==
NULL
)
sprintf
(
buf
,
"%s TRUNCATED"
,
pp
->
name
);
else
if
(
ih
->
nexthdr
==
IPPROTO_FRAGMENT
)
sprintf
(
buf
,
"%s "
NIP6_FMT
"->"
NIP6_FMT
" frag"
,
pp
->
name
,
NIP6
(
ih
->
saddr
),
NIP6
(
ih
->
daddr
));
else
{
__be16
_ports
[
2
],
*
pptr
;
pptr
=
skb_header_pointer
(
skb
,
offset
+
sizeof
(
struct
ipv6hdr
),
sizeof
(
_ports
),
_ports
);
if
(
pptr
==
NULL
)
sprintf
(
buf
,
"%s TRUNCATED "
NIP6_FMT
"->"
NIP6_FMT
,
pp
->
name
,
NIP6
(
ih
->
saddr
),
NIP6
(
ih
->
daddr
));
else
sprintf
(
buf
,
"%s "
NIP6_FMT
":%u->"
NIP6_FMT
":%u"
,
pp
->
name
,
NIP6
(
ih
->
saddr
),
ntohs
(
pptr
[
0
]),
NIP6
(
ih
->
daddr
),
ntohs
(
pptr
[
1
]));
}
printk
(
KERN_DEBUG
"IPVS: %s: %s
\n
"
,
msg
,
buf
);
}
#endif
void
ip_vs_tcpudp_debug_packet
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
skb
->
protocol
==
__constant_htons
(
ETH_P_IPV6
))
ip_vs_tcpudp_debug_packet_v6
(
pp
,
skb
,
offset
,
msg
);
else
#endif
ip_vs_tcpudp_debug_packet_v4
(
pp
,
skb
,
offset
,
msg
);
}
int
__init
ip_vs_protocol_init
(
void
)
{
...
...
net/ipv4/ipvs/ip_vs_proto_ah_esp.c
浏览文件 @
dacc62db
...
...
@@ -39,25 +39,23 @@ struct isakmp_hdr {
static
struct
ip_vs_conn
*
ah_esp_conn_in_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
ah_esp_conn_in_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
struct
ip_vs_conn
*
cp
;
if
(
likely
(
!
inverse
))
{
cp
=
ip_vs_conn_in_get
(
IPPROTO_UDP
,
iph
->
saddr
,
cp
=
ip_vs_conn_in_get
(
af
,
IPPROTO_UDP
,
&
iph
->
saddr
,
htons
(
PORT_ISAKMP
),
iph
->
daddr
,
&
iph
->
daddr
,
htons
(
PORT_ISAKMP
));
}
else
{
cp
=
ip_vs_conn_in_get
(
IPPROTO_UDP
,
iph
->
daddr
,
cp
=
ip_vs_conn_in_get
(
af
,
IPPROTO_UDP
,
&
iph
->
daddr
,
htons
(
PORT_ISAKMP
),
iph
->
saddr
,
&
iph
->
saddr
,
htons
(
PORT_ISAKMP
));
}
...
...
@@ -66,12 +64,12 @@ ah_esp_conn_in_get(const struct sk_buff *skb,
* We are not sure if the packet is from our
* service, so our conn_schedule hook should return NF_ACCEPT
*/
IP_VS_DBG
(
12
,
"Unknown ISAKMP entry for outin packet "
"%s%s %u.%u.%u.%u->%u.%u.%u.%u
\n
"
,
inverse
?
"ICMP+"
:
""
,
pp
->
name
,
NIPQUAD
(
iph
->
saddr
),
NIPQUAD
(
iph
->
daddr
));
IP_VS_DBG
_BUF
(
12
,
"Unknown ISAKMP entry for outin packet "
"%s%s %s->%s
\n
"
,
inverse
?
"ICMP+"
:
""
,
pp
->
name
,
IP_VS_DBG_ADDR
(
af
,
&
iph
->
saddr
),
IP_VS_DBG_ADDR
(
af
,
&
iph
->
daddr
));
}
return
cp
;
...
...
@@ -79,32 +77,35 @@ ah_esp_conn_in_get(const struct sk_buff *skb,
static
struct
ip_vs_conn
*
ah_esp_conn_out_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
ah_esp_conn_out_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
struct
ip_vs_conn
*
cp
;
if
(
likely
(
!
inverse
))
{
cp
=
ip_vs_conn_out_get
(
IPPROTO_UDP
,
iph
->
saddr
,
cp
=
ip_vs_conn_out_get
(
af
,
IPPROTO_UDP
,
&
iph
->
saddr
,
htons
(
PORT_ISAKMP
),
iph
->
daddr
,
&
iph
->
daddr
,
htons
(
PORT_ISAKMP
));
}
else
{
cp
=
ip_vs_conn_out_get
(
IPPROTO_UDP
,
iph
->
daddr
,
cp
=
ip_vs_conn_out_get
(
af
,
IPPROTO_UDP
,
&
iph
->
daddr
,
htons
(
PORT_ISAKMP
),
iph
->
saddr
,
&
iph
->
saddr
,
htons
(
PORT_ISAKMP
));
}
if
(
!
cp
)
{
IP_VS_DBG
(
12
,
"Unknown ISAKMP entry for inout packet "
"%s%s %u.%u.%u.%u->%u.%u.%u.%u
\n
"
,
inverse
?
"ICMP+"
:
""
,
pp
->
name
,
NIPQUAD
(
iph
->
saddr
),
NIPQUAD
(
iph
->
daddr
));
IP_VS_DBG
_BUF
(
12
,
"Unknown ISAKMP entry for inout packet "
"%s%s %s->%s
\n
"
,
inverse
?
"ICMP+"
:
""
,
pp
->
name
,
IP_VS_DBG_ADDR
(
af
,
&
iph
->
saddr
),
IP_VS_DBG_ADDR
(
af
,
&
iph
->
daddr
));
}
return
cp
;
...
...
@@ -112,8 +113,7 @@ ah_esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static
int
ah_esp_conn_schedule
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
ah_esp_conn_schedule
(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
int
*
verdict
,
struct
ip_vs_conn
**
cpp
)
{
/*
...
...
@@ -125,8 +125,8 @@ ah_esp_conn_schedule(struct sk_buff *skb,
static
void
ah_esp_debug_packet
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
ah_esp_debug_packet
_v4
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
char
buf
[
256
];
struct
iphdr
_iph
,
*
ih
;
...
...
@@ -142,6 +142,38 @@ ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
printk
(
KERN_DEBUG
"IPVS: %s: %s
\n
"
,
msg
,
buf
);
}
#ifdef CONFIG_IP_VS_IPV6
static
void
ah_esp_debug_packet_v6
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
char
buf
[
256
];
struct
ipv6hdr
_iph
,
*
ih
;
ih
=
skb_header_pointer
(
skb
,
offset
,
sizeof
(
_iph
),
&
_iph
);
if
(
ih
==
NULL
)
sprintf
(
buf
,
"%s TRUNCATED"
,
pp
->
name
);
else
sprintf
(
buf
,
"%s "
NIP6_FMT
"->"
NIP6_FMT
,
pp
->
name
,
NIP6
(
ih
->
saddr
),
NIP6
(
ih
->
daddr
));
printk
(
KERN_DEBUG
"IPVS: %s: %s
\n
"
,
msg
,
buf
);
}
#endif
static
void
ah_esp_debug_packet
(
struct
ip_vs_protocol
*
pp
,
const
struct
sk_buff
*
skb
,
int
offset
,
const
char
*
msg
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
skb
->
protocol
==
__constant_htons
(
ETH_P_IPV6
))
ah_esp_debug_packet_v6
(
pp
,
skb
,
offset
,
msg
);
else
#endif
ah_esp_debug_packet_v4
(
pp
,
skb
,
offset
,
msg
);
}
static
void
ah_esp_init
(
struct
ip_vs_protocol
*
pp
)
{
...
...
net/ipv4/ipvs/ip_vs_proto_tcp.c
浏览文件 @
dacc62db
...
...
@@ -25,8 +25,9 @@
static
struct
ip_vs_conn
*
tcp_conn_in_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
tcp_conn_in_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
__be16
_ports
[
2
],
*
pptr
;
...
...
@@ -35,19 +36,20 @@ tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
return
NULL
;
if
(
likely
(
!
inverse
))
{
return
ip_vs_conn_in_get
(
iph
->
protocol
,
iph
->
saddr
,
pptr
[
0
],
iph
->
daddr
,
pptr
[
1
]);
return
ip_vs_conn_in_get
(
af
,
iph
->
protocol
,
&
iph
->
saddr
,
pptr
[
0
],
&
iph
->
daddr
,
pptr
[
1
]);
}
else
{
return
ip_vs_conn_in_get
(
iph
->
protocol
,
iph
->
daddr
,
pptr
[
1
],
iph
->
saddr
,
pptr
[
0
]);
return
ip_vs_conn_in_get
(
af
,
iph
->
protocol
,
&
iph
->
daddr
,
pptr
[
1
],
&
iph
->
saddr
,
pptr
[
0
]);
}
}
static
struct
ip_vs_conn
*
tcp_conn_out_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
tcp_conn_out_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
__be16
_ports
[
2
],
*
pptr
;
...
...
@@ -56,34 +58,36 @@ tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
return
NULL
;
if
(
likely
(
!
inverse
))
{
return
ip_vs_conn_out_get
(
iph
->
protocol
,
iph
->
saddr
,
pptr
[
0
],
iph
->
daddr
,
pptr
[
1
]);
return
ip_vs_conn_out_get
(
af
,
iph
->
protocol
,
&
iph
->
saddr
,
pptr
[
0
],
&
iph
->
daddr
,
pptr
[
1
]);
}
else
{
return
ip_vs_conn_out_get
(
iph
->
protocol
,
iph
->
daddr
,
pptr
[
1
],
iph
->
saddr
,
pptr
[
0
]);
return
ip_vs_conn_out_get
(
af
,
iph
->
protocol
,
&
iph
->
daddr
,
pptr
[
1
],
&
iph
->
saddr
,
pptr
[
0
]);
}
}
static
int
tcp_conn_schedule
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
tcp_conn_schedule
(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
int
*
verdict
,
struct
ip_vs_conn
**
cpp
)
{
struct
ip_vs_service
*
svc
;
struct
tcphdr
_tcph
,
*
th
;
struct
ip_vs_iphdr
iph
;
th
=
skb_header_pointer
(
skb
,
ip_hdrlen
(
skb
),
sizeof
(
_tcph
),
&
_tcph
);
ip_vs_fill_iphdr
(
af
,
skb_network_header
(
skb
),
&
iph
);
th
=
skb_header_pointer
(
skb
,
iph
.
len
,
sizeof
(
_tcph
),
&
_tcph
);
if
(
th
==
NULL
)
{
*
verdict
=
NF_DROP
;
return
0
;
}
if
(
th
->
syn
&&
(
svc
=
ip_vs_service_get
(
skb
->
mark
,
ip_hdr
(
skb
)
->
protocol
,
ip_hdr
(
skb
)
->
daddr
,
th
->
dest
)))
{
(
svc
=
ip_vs_service_get
(
af
,
skb
->
mark
,
iph
.
protocol
,
&
iph
.
daddr
,
th
->
dest
)))
{
if
(
ip_vs_todrop
())
{
/*
* It seems that we are very loaded.
...
...
@@ -110,22 +114,62 @@ tcp_conn_schedule(struct sk_buff *skb,
static
inline
void
tcp_fast_csum_update
(
struct
tcphdr
*
tcph
,
__be32
oldip
,
__be32
newip
,
tcp_fast_csum_update
(
int
af
,
struct
tcphdr
*
tcph
,
const
union
nf_inet_addr
*
oldip
,
const
union
nf_inet_addr
*
newip
,
__be16
oldport
,
__be16
newport
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
tcph
->
check
=
csum_fold
(
ip_vs_check_diff16
(
oldip
->
ip6
,
newip
->
ip6
,
ip_vs_check_diff2
(
oldport
,
newport
,
~
csum_unfold
(
tcph
->
check
))));
else
#endif
tcph
->
check
=
csum_fold
(
ip_vs_check_diff4
(
oldip
,
new
ip
,
csum_fold
(
ip_vs_check_diff4
(
oldip
->
ip
,
newip
->
ip
,
ip_vs_check_diff2
(
oldport
,
newport
,
~
csum_unfold
(
tcph
->
check
))));
}
static
inline
void
tcp_partial_csum_update
(
int
af
,
struct
tcphdr
*
tcph
,
const
union
nf_inet_addr
*
oldip
,
const
union
nf_inet_addr
*
newip
,
__be16
oldlen
,
__be16
newlen
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
tcph
->
check
=
csum_fold
(
ip_vs_check_diff16
(
oldip
->
ip6
,
newip
->
ip6
,
ip_vs_check_diff2
(
oldlen
,
newlen
,
~
csum_unfold
(
tcph
->
check
))));
else
#endif
tcph
->
check
=
csum_fold
(
ip_vs_check_diff4
(
oldip
->
ip
,
newip
->
ip
,
ip_vs_check_diff2
(
oldlen
,
newlen
,
~
csum_unfold
(
tcph
->
check
))));
}
static
int
tcp_snat_handler
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
)
{
struct
tcphdr
*
tcph
;
const
unsigned
int
tcphoff
=
ip_hdrlen
(
skb
);
unsigned
int
tcphoff
;
int
oldlen
;
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
tcphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
tcphoff
=
ip_hdrlen
(
skb
);
oldlen
=
skb
->
len
-
tcphoff
;
/* csum_check requires unshared skb */
if
(
!
skb_make_writable
(
skb
,
tcphoff
+
sizeof
(
*
tcph
)))
...
...
@@ -133,7 +177,7 @@ tcp_snat_handler(struct sk_buff *skb,
if
(
unlikely
(
cp
->
app
!=
NULL
))
{
/* Some checks before mangling */
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
skb
,
pp
))
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
cp
->
af
,
skb
,
pp
))
return
0
;
/* Call application helper if needed */
...
...
@@ -141,13 +185,17 @@ tcp_snat_handler(struct sk_buff *skb,
return
0
;
}
tcph
=
(
void
*
)
ip_hd
r
(
skb
)
+
tcphoff
;
tcph
=
(
void
*
)
skb_network_heade
r
(
skb
)
+
tcphoff
;
tcph
->
source
=
cp
->
vport
;
/* Adjust TCP checksums */
if
(
!
cp
->
app
)
{
if
(
skb
->
ip_summed
==
CHECKSUM_PARTIAL
)
{
tcp_partial_csum_update
(
cp
->
af
,
tcph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
htonl
(
oldlen
),
htonl
(
skb
->
len
-
tcphoff
));
}
else
if
(
!
cp
->
app
)
{
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update
(
tcph
,
cp
->
daddr
,
cp
->
vaddr
,
tcp_fast_csum_update
(
cp
->
af
,
tcph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
cp
->
dport
,
cp
->
vport
);
if
(
skb
->
ip_summed
==
CHECKSUM_COMPLETE
)
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -155,9 +203,20 @@ tcp_snat_handler(struct sk_buff *skb,
/* full checksum calculation */
tcph
->
check
=
0
;
skb
->
csum
=
skb_checksum
(
skb
,
tcphoff
,
skb
->
len
-
tcphoff
,
0
);
tcph
->
check
=
csum_tcpudp_magic
(
cp
->
vaddr
,
cp
->
caddr
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
tcph
->
check
=
csum_ipv6_magic
(
&
cp
->
vaddr
.
in6
,
&
cp
->
caddr
.
in6
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
else
#endif
tcph
->
check
=
csum_tcpudp_magic
(
cp
->
vaddr
.
ip
,
cp
->
caddr
.
ip
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
IP_VS_DBG
(
11
,
"O-pkt: %s O-csum=%d (+%zd)
\n
"
,
pp
->
name
,
tcph
->
check
,
(
char
*
)
&
(
tcph
->
check
)
-
(
char
*
)
tcph
);
...
...
@@ -171,7 +230,16 @@ tcp_dnat_handler(struct sk_buff *skb,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
)
{
struct
tcphdr
*
tcph
;
const
unsigned
int
tcphoff
=
ip_hdrlen
(
skb
);
unsigned
int
tcphoff
;
int
oldlen
;
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
tcphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
tcphoff
=
ip_hdrlen
(
skb
);
oldlen
=
skb
->
len
-
tcphoff
;
/* csum_check requires unshared skb */
if
(
!
skb_make_writable
(
skb
,
tcphoff
+
sizeof
(
*
tcph
)))
...
...
@@ -179,7 +247,7 @@ tcp_dnat_handler(struct sk_buff *skb,
if
(
unlikely
(
cp
->
app
!=
NULL
))
{
/* Some checks before mangling */
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
skb
,
pp
))
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
cp
->
af
,
skb
,
pp
))
return
0
;
/*
...
...
@@ -190,15 +258,19 @@ tcp_dnat_handler(struct sk_buff *skb,
return
0
;
}
tcph
=
(
void
*
)
ip_hd
r
(
skb
)
+
tcphoff
;
tcph
=
(
void
*
)
skb_network_heade
r
(
skb
)
+
tcphoff
;
tcph
->
dest
=
cp
->
dport
;
/*
* Adjust TCP checksums
*/
if
(
!
cp
->
app
)
{
if
(
skb
->
ip_summed
==
CHECKSUM_PARTIAL
)
{
tcp_partial_csum_update
(
cp
->
af
,
tcph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
htonl
(
oldlen
),
htonl
(
skb
->
len
-
tcphoff
));
}
else
if
(
!
cp
->
app
)
{
/* Only port and addr are changed, do fast csum update */
tcp_fast_csum_update
(
tcph
,
cp
->
vaddr
,
cp
->
daddr
,
tcp_fast_csum_update
(
cp
->
af
,
tcph
,
&
cp
->
vaddr
,
&
cp
->
daddr
,
cp
->
vport
,
cp
->
dport
);
if
(
skb
->
ip_summed
==
CHECKSUM_COMPLETE
)
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -206,9 +278,19 @@ tcp_dnat_handler(struct sk_buff *skb,
/* full checksum calculation */
tcph
->
check
=
0
;
skb
->
csum
=
skb_checksum
(
skb
,
tcphoff
,
skb
->
len
-
tcphoff
,
0
);
tcph
->
check
=
csum_tcpudp_magic
(
cp
->
caddr
,
cp
->
daddr
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
tcph
->
check
=
csum_ipv6_magic
(
&
cp
->
caddr
.
in6
,
&
cp
->
daddr
.
in6
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
else
#endif
tcph
->
check
=
csum_tcpudp_magic
(
cp
->
caddr
.
ip
,
cp
->
daddr
.
ip
,
skb
->
len
-
tcphoff
,
cp
->
protocol
,
skb
->
csum
);
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
}
return
1
;
...
...
@@ -216,21 +298,43 @@ tcp_dnat_handler(struct sk_buff *skb,
static
int
tcp_csum_check
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
)
tcp_csum_check
(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
)
{
const
unsigned
int
tcphoff
=
ip_hdrlen
(
skb
);
unsigned
int
tcphoff
;
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
tcphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
tcphoff
=
ip_hdrlen
(
skb
);
switch
(
skb
->
ip_summed
)
{
case
CHECKSUM_NONE
:
skb
->
csum
=
skb_checksum
(
skb
,
tcphoff
,
skb
->
len
-
tcphoff
,
0
);
case
CHECKSUM_COMPLETE
:
if
(
csum_tcpudp_magic
(
ip_hdr
(
skb
)
->
saddr
,
ip_hdr
(
skb
)
->
daddr
,
skb
->
len
-
tcphoff
,
ip_hdr
(
skb
)
->
protocol
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
{
if
(
csum_ipv6_magic
(
&
ipv6_hdr
(
skb
)
->
saddr
,
&
ipv6_hdr
(
skb
)
->
daddr
,
skb
->
len
-
tcphoff
,
ipv6_hdr
(
skb
)
->
nexthdr
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
}
else
#endif
if
(
csum_tcpudp_magic
(
ip_hdr
(
skb
)
->
saddr
,
ip_hdr
(
skb
)
->
daddr
,
skb
->
len
-
tcphoff
,
ip_hdr
(
skb
)
->
protocol
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
break
;
default:
/* No need to checksum. */
...
...
@@ -419,19 +523,23 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
if
(
new_state
!=
cp
->
state
)
{
struct
ip_vs_dest
*
dest
=
cp
->
dest
;
IP_VS_DBG
(
8
,
"%s %s [%c%c%c%c] %u.%u.%u.%u:%d->"
"%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d
\n
"
,
pp
->
name
,
(
state_off
==
TCP_DIR_OUTPUT
)
?
"output "
:
"input "
,
th
->
syn
?
'S'
:
'.'
,
th
->
fin
?
'F'
:
'.'
,
th
->
ack
?
'A'
:
'.'
,
th
->
rst
?
'R'
:
'.'
,
NIPQUAD
(
cp
->
daddr
),
ntohs
(
cp
->
dport
),
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
tcp_state_name
(
cp
->
state
),
tcp_state_name
(
new_state
),
atomic_read
(
&
cp
->
refcnt
));
IP_VS_DBG_BUF
(
8
,
"%s %s [%c%c%c%c] %s:%d->"
"%s:%d state: %s->%s conn->refcnt:%d
\n
"
,
pp
->
name
,
((
state_off
==
TCP_DIR_OUTPUT
)
?
"output "
:
"input "
),
th
->
syn
?
'S'
:
'.'
,
th
->
fin
?
'F'
:
'.'
,
th
->
ack
?
'A'
:
'.'
,
th
->
rst
?
'R'
:
'.'
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
daddr
),
ntohs
(
cp
->
dport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
tcp_state_name
(
cp
->
state
),
tcp_state_name
(
new_state
),
atomic_read
(
&
cp
->
refcnt
));
if
(
dest
)
{
if
(
!
(
cp
->
flags
&
IP_VS_CONN_F_INACTIVE
)
&&
(
new_state
!=
IP_VS_TCP_S_ESTABLISHED
))
{
...
...
@@ -461,7 +569,13 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
{
struct
tcphdr
_tcph
,
*
th
;
th
=
skb_header_pointer
(
skb
,
ip_hdrlen
(
skb
),
sizeof
(
_tcph
),
&
_tcph
);
#ifdef CONFIG_IP_VS_IPV6
int
ihl
=
cp
->
af
==
AF_INET
?
ip_hdrlen
(
skb
)
:
sizeof
(
struct
ipv6hdr
);
#else
int
ihl
=
ip_hdrlen
(
skb
);
#endif
th
=
skb_header_pointer
(
skb
,
ihl
,
sizeof
(
_tcph
),
&
_tcph
);
if
(
th
==
NULL
)
return
0
;
...
...
@@ -546,12 +660,15 @@ tcp_app_conn_bind(struct ip_vs_conn *cp)
break
;
spin_unlock
(
&
tcp_app_lock
);
IP_VS_DBG
(
9
,
"%s: Binding conn %u.%u.%u.%u:%u->"
"%u.%u.%u.%u:%u to app %s on port %u
\n
"
,
__func__
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
inc
->
name
,
ntohs
(
inc
->
port
));
IP_VS_DBG_BUF
(
9
,
"%s: Binding conn %s:%u->"
"%s:%u to app %s on port %u
\n
"
,
__func__
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
inc
->
name
,
ntohs
(
inc
->
port
));
cp
->
app
=
inc
;
if
(
inc
->
init_conn
)
result
=
inc
->
init_conn
(
inc
,
cp
);
...
...
net/ipv4/ipvs/ip_vs_proto_udp.c
浏览文件 @
dacc62db
...
...
@@ -24,8 +24,9 @@
#include <net/ip.h>
static
struct
ip_vs_conn
*
udp_conn_in_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
udp_conn_in_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
struct
ip_vs_conn
*
cp
;
__be16
_ports
[
2
],
*
pptr
;
...
...
@@ -35,13 +36,13 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
return
NULL
;
if
(
likely
(
!
inverse
))
{
cp
=
ip_vs_conn_in_get
(
iph
->
protocol
,
iph
->
saddr
,
pptr
[
0
],
iph
->
daddr
,
pptr
[
1
]);
cp
=
ip_vs_conn_in_get
(
af
,
iph
->
protocol
,
&
iph
->
saddr
,
pptr
[
0
],
&
iph
->
daddr
,
pptr
[
1
]);
}
else
{
cp
=
ip_vs_conn_in_get
(
iph
->
protocol
,
iph
->
daddr
,
pptr
[
1
],
iph
->
saddr
,
pptr
[
0
]);
cp
=
ip_vs_conn_in_get
(
af
,
iph
->
protocol
,
&
iph
->
daddr
,
pptr
[
1
],
&
iph
->
saddr
,
pptr
[
0
]);
}
return
cp
;
...
...
@@ -49,25 +50,25 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static
struct
ip_vs_conn
*
udp_conn_out_get
(
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
udp_conn_out_get
(
int
af
,
const
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
const
struct
ip_vs_iphdr
*
iph
,
unsigned
int
proto_off
,
int
inverse
)
{
struct
ip_vs_conn
*
cp
;
__be16
_ports
[
2
],
*
pptr
;
pptr
=
skb_header_pointer
(
skb
,
ip_hdrlen
(
skb
),
sizeof
(
_ports
),
_ports
);
pptr
=
skb_header_pointer
(
skb
,
proto_off
,
sizeof
(
_ports
),
_ports
);
if
(
pptr
==
NULL
)
return
NULL
;
if
(
likely
(
!
inverse
))
{
cp
=
ip_vs_conn_out_get
(
iph
->
protocol
,
iph
->
saddr
,
pptr
[
0
],
iph
->
daddr
,
pptr
[
1
]);
cp
=
ip_vs_conn_out_get
(
af
,
iph
->
protocol
,
&
iph
->
saddr
,
pptr
[
0
],
&
iph
->
daddr
,
pptr
[
1
]);
}
else
{
cp
=
ip_vs_conn_out_get
(
iph
->
protocol
,
iph
->
daddr
,
pptr
[
1
],
iph
->
saddr
,
pptr
[
0
]);
cp
=
ip_vs_conn_out_get
(
af
,
iph
->
protocol
,
&
iph
->
daddr
,
pptr
[
1
],
&
iph
->
saddr
,
pptr
[
0
]);
}
return
cp
;
...
...
@@ -75,21 +76,24 @@ udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
static
int
udp_conn_schedule
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
udp_conn_schedule
(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
int
*
verdict
,
struct
ip_vs_conn
**
cpp
)
{
struct
ip_vs_service
*
svc
;
struct
udphdr
_udph
,
*
uh
;
struct
ip_vs_iphdr
iph
;
ip_vs_fill_iphdr
(
af
,
skb_network_header
(
skb
),
&
iph
);
uh
=
skb_header_pointer
(
skb
,
ip_hdrlen
(
skb
),
sizeof
(
_udph
),
&
_udph
);
uh
=
skb_header_pointer
(
skb
,
iph
.
len
,
sizeof
(
_udph
),
&
_udph
);
if
(
uh
==
NULL
)
{
*
verdict
=
NF_DROP
;
return
0
;
}
if
((
svc
=
ip_vs_service_get
(
skb
->
mark
,
ip_hdr
(
skb
)
->
protocol
,
ip_hdr
(
skb
)
->
daddr
,
uh
->
dest
)))
{
svc
=
ip_vs_service_get
(
af
,
skb
->
mark
,
iph
.
protocol
,
&
iph
.
daddr
,
uh
->
dest
);
if
(
svc
)
{
if
(
ip_vs_todrop
())
{
/*
* It seems that we are very loaded.
...
...
@@ -116,23 +120,63 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
static
inline
void
udp_fast_csum_update
(
struct
udphdr
*
uhdr
,
__be32
oldip
,
__be32
newip
,
udp_fast_csum_update
(
int
af
,
struct
udphdr
*
uhdr
,
const
union
nf_inet_addr
*
oldip
,
const
union
nf_inet_addr
*
newip
,
__be16
oldport
,
__be16
newport
)
{
uhdr
->
check
=
csum_fold
(
ip_vs_check_diff4
(
oldip
,
newip
,
ip_vs_check_diff2
(
oldport
,
newport
,
~
csum_unfold
(
uhdr
->
check
))));
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
uhdr
->
check
=
csum_fold
(
ip_vs_check_diff16
(
oldip
->
ip6
,
newip
->
ip6
,
ip_vs_check_diff2
(
oldport
,
newport
,
~
csum_unfold
(
uhdr
->
check
))));
else
#endif
uhdr
->
check
=
csum_fold
(
ip_vs_check_diff4
(
oldip
->
ip
,
newip
->
ip
,
ip_vs_check_diff2
(
oldport
,
newport
,
~
csum_unfold
(
uhdr
->
check
))));
if
(
!
uhdr
->
check
)
uhdr
->
check
=
CSUM_MANGLED_0
;
}
static
inline
void
udp_partial_csum_update
(
int
af
,
struct
udphdr
*
uhdr
,
const
union
nf_inet_addr
*
oldip
,
const
union
nf_inet_addr
*
newip
,
__be16
oldlen
,
__be16
newlen
)
{
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
uhdr
->
check
=
csum_fold
(
ip_vs_check_diff16
(
oldip
->
ip6
,
newip
->
ip6
,
ip_vs_check_diff2
(
oldlen
,
newlen
,
~
csum_unfold
(
uhdr
->
check
))));
else
#endif
uhdr
->
check
=
csum_fold
(
ip_vs_check_diff4
(
oldip
->
ip
,
newip
->
ip
,
ip_vs_check_diff2
(
oldlen
,
newlen
,
~
csum_unfold
(
uhdr
->
check
))));
}
static
int
udp_snat_handler
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
)
{
struct
udphdr
*
udph
;
const
unsigned
int
udphoff
=
ip_hdrlen
(
skb
);
unsigned
int
udphoff
;
int
oldlen
;
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
udphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
udphoff
=
ip_hdrlen
(
skb
);
oldlen
=
skb
->
len
-
udphoff
;
/* csum_check requires unshared skb */
if
(
!
skb_make_writable
(
skb
,
udphoff
+
sizeof
(
*
udph
)))
...
...
@@ -140,7 +184,7 @@ udp_snat_handler(struct sk_buff *skb,
if
(
unlikely
(
cp
->
app
!=
NULL
))
{
/* Some checks before mangling */
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
skb
,
pp
))
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
cp
->
af
,
skb
,
pp
))
return
0
;
/*
...
...
@@ -150,15 +194,19 @@ udp_snat_handler(struct sk_buff *skb,
return
0
;
}
udph
=
(
void
*
)
ip_hd
r
(
skb
)
+
udphoff
;
udph
=
(
void
*
)
skb_network_heade
r
(
skb
)
+
udphoff
;
udph
->
source
=
cp
->
vport
;
/*
* Adjust UDP checksums
*/
if
(
!
cp
->
app
&&
(
udph
->
check
!=
0
))
{
if
(
skb
->
ip_summed
==
CHECKSUM_PARTIAL
)
{
udp_partial_csum_update
(
cp
->
af
,
udph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
htonl
(
oldlen
),
htonl
(
skb
->
len
-
udphoff
));
}
else
if
(
!
cp
->
app
&&
(
udph
->
check
!=
0
))
{
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update
(
udph
,
cp
->
daddr
,
cp
->
vaddr
,
udp_fast_csum_update
(
cp
->
af
,
udph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
cp
->
dport
,
cp
->
vport
);
if
(
skb
->
ip_summed
==
CHECKSUM_COMPLETE
)
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -166,9 +214,19 @@ udp_snat_handler(struct sk_buff *skb,
/* full checksum calculation */
udph
->
check
=
0
;
skb
->
csum
=
skb_checksum
(
skb
,
udphoff
,
skb
->
len
-
udphoff
,
0
);
udph
->
check
=
csum_tcpudp_magic
(
cp
->
vaddr
,
cp
->
caddr
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
udph
->
check
=
csum_ipv6_magic
(
&
cp
->
vaddr
.
in6
,
&
cp
->
caddr
.
in6
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
else
#endif
udph
->
check
=
csum_tcpudp_magic
(
cp
->
vaddr
.
ip
,
cp
->
caddr
.
ip
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
if
(
udph
->
check
==
0
)
udph
->
check
=
CSUM_MANGLED_0
;
IP_VS_DBG
(
11
,
"O-pkt: %s O-csum=%d (+%zd)
\n
"
,
...
...
@@ -184,7 +242,16 @@ udp_dnat_handler(struct sk_buff *skb,
struct
ip_vs_protocol
*
pp
,
struct
ip_vs_conn
*
cp
)
{
struct
udphdr
*
udph
;
unsigned
int
udphoff
=
ip_hdrlen
(
skb
);
unsigned
int
udphoff
;
int
oldlen
;
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
udphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
udphoff
=
ip_hdrlen
(
skb
);
oldlen
=
skb
->
len
-
udphoff
;
/* csum_check requires unshared skb */
if
(
!
skb_make_writable
(
skb
,
udphoff
+
sizeof
(
*
udph
)))
...
...
@@ -192,7 +259,7 @@ udp_dnat_handler(struct sk_buff *skb,
if
(
unlikely
(
cp
->
app
!=
NULL
))
{
/* Some checks before mangling */
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
skb
,
pp
))
if
(
pp
->
csum_check
&&
!
pp
->
csum_check
(
cp
->
af
,
skb
,
pp
))
return
0
;
/*
...
...
@@ -203,15 +270,19 @@ udp_dnat_handler(struct sk_buff *skb,
return
0
;
}
udph
=
(
void
*
)
ip_hd
r
(
skb
)
+
udphoff
;
udph
=
(
void
*
)
skb_network_heade
r
(
skb
)
+
udphoff
;
udph
->
dest
=
cp
->
dport
;
/*
* Adjust UDP checksums
*/
if
(
!
cp
->
app
&&
(
udph
->
check
!=
0
))
{
if
(
skb
->
ip_summed
==
CHECKSUM_PARTIAL
)
{
udp_partial_csum_update
(
cp
->
af
,
udph
,
&
cp
->
daddr
,
&
cp
->
vaddr
,
htonl
(
oldlen
),
htonl
(
skb
->
len
-
udphoff
));
}
else
if
(
!
cp
->
app
&&
(
udph
->
check
!=
0
))
{
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update
(
udph
,
cp
->
vaddr
,
cp
->
daddr
,
udp_fast_csum_update
(
cp
->
af
,
udph
,
&
cp
->
vaddr
,
&
cp
->
daddr
,
cp
->
vport
,
cp
->
dport
);
if
(
skb
->
ip_summed
==
CHECKSUM_COMPLETE
)
skb
->
ip_summed
=
CHECKSUM_NONE
;
...
...
@@ -219,9 +290,19 @@ udp_dnat_handler(struct sk_buff *skb,
/* full checksum calculation */
udph
->
check
=
0
;
skb
->
csum
=
skb_checksum
(
skb
,
udphoff
,
skb
->
len
-
udphoff
,
0
);
udph
->
check
=
csum_tcpudp_magic
(
cp
->
caddr
,
cp
->
daddr
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
#ifdef CONFIG_IP_VS_IPV6
if
(
cp
->
af
==
AF_INET6
)
udph
->
check
=
csum_ipv6_magic
(
&
cp
->
caddr
.
in6
,
&
cp
->
daddr
.
in6
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
else
#endif
udph
->
check
=
csum_tcpudp_magic
(
cp
->
caddr
.
ip
,
cp
->
daddr
.
ip
,
skb
->
len
-
udphoff
,
cp
->
protocol
,
skb
->
csum
);
if
(
udph
->
check
==
0
)
udph
->
check
=
CSUM_MANGLED_0
;
skb
->
ip_summed
=
CHECKSUM_UNNECESSARY
;
...
...
@@ -231,10 +312,17 @@ udp_dnat_handler(struct sk_buff *skb,
static
int
udp_csum_check
(
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
)
udp_csum_check
(
int
af
,
struct
sk_buff
*
skb
,
struct
ip_vs_protocol
*
pp
)
{
struct
udphdr
_udph
,
*
uh
;
const
unsigned
int
udphoff
=
ip_hdrlen
(
skb
);
unsigned
int
udphoff
;
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
udphoff
=
sizeof
(
struct
ipv6hdr
);
else
#endif
udphoff
=
ip_hdrlen
(
skb
);
uh
=
skb_header_pointer
(
skb
,
udphoff
,
sizeof
(
_udph
),
&
_udph
);
if
(
uh
==
NULL
)
...
...
@@ -246,15 +334,28 @@ udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
skb
->
csum
=
skb_checksum
(
skb
,
udphoff
,
skb
->
len
-
udphoff
,
0
);
case
CHECKSUM_COMPLETE
:
if
(
csum_tcpudp_magic
(
ip_hdr
(
skb
)
->
saddr
,
ip_hdr
(
skb
)
->
daddr
,
skb
->
len
-
udphoff
,
ip_hdr
(
skb
)
->
protocol
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
#ifdef CONFIG_IP_VS_IPV6
if
(
af
==
AF_INET6
)
{
if
(
csum_ipv6_magic
(
&
ipv6_hdr
(
skb
)
->
saddr
,
&
ipv6_hdr
(
skb
)
->
daddr
,
skb
->
len
-
udphoff
,
ipv6_hdr
(
skb
)
->
nexthdr
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
}
else
#endif
if
(
csum_tcpudp_magic
(
ip_hdr
(
skb
)
->
saddr
,
ip_hdr
(
skb
)
->
daddr
,
skb
->
len
-
udphoff
,
ip_hdr
(
skb
)
->
protocol
,
skb
->
csum
))
{
IP_VS_DBG_RL_PKT
(
0
,
pp
,
skb
,
0
,
"Failed checksum for"
);
return
0
;
}
break
;
default:
/* No need to checksum. */
...
...
@@ -340,12 +441,15 @@ static int udp_app_conn_bind(struct ip_vs_conn *cp)
break
;
spin_unlock
(
&
udp_app_lock
);
IP_VS_DBG
(
9
,
"%s: Binding conn %u.%u.%u.%u:%u->"
"%u.%u.%u.%u:%u to app %s on port %u
\n
"
,
__func__
,
NIPQUAD
(
cp
->
caddr
),
ntohs
(
cp
->
cport
),
NIPQUAD
(
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
inc
->
name
,
ntohs
(
inc
->
port
));
IP_VS_DBG_BUF
(
9
,
"%s: Binding conn %s:%u->"
"%s:%u to app %s on port %u
\n
"
,
__func__
,
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
caddr
),
ntohs
(
cp
->
cport
),
IP_VS_DBG_ADDR
(
cp
->
af
,
&
cp
->
vaddr
),
ntohs
(
cp
->
vport
),
inc
->
name
,
ntohs
(
inc
->
port
));
cp
->
app
=
inc
;
if
(
inc
->
init_conn
)
result
=
inc
->
init_conn
(
inc
,
cp
);
...
...
net/ipv4/ipvs/ip_vs_rr.c
浏览文件 @
dacc62db
...
...
@@ -74,11 +74,11 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
out:
svc
->
sched_data
=
q
;
write_unlock
(
&
svc
->
sched_lock
);
IP_VS_DBG
(
6
,
"RR: server %u.%u.%u.%u
:%u "
"activeconns %d refcnt %d weight %d
\n
"
,
NIPQUAD
(
dest
->
addr
),
ntohs
(
dest
->
port
),
atomic_read
(
&
dest
->
activeconns
),
atomic_read
(
&
dest
->
refcnt
),
atomic_read
(
&
dest
->
weight
));
IP_VS_DBG
_BUF
(
6
,
"RR: server %s
:%u "
"activeconns %d refcnt %d weight %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
dest
->
addr
),
ntohs
(
dest
->
port
),
atomic_read
(
&
dest
->
activeconns
),
atomic_read
(
&
dest
->
refcnt
),
atomic_read
(
&
dest
->
weight
));
return
dest
;
}
...
...
@@ -89,6 +89,9 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_rr_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
init_service
=
ip_vs_rr_init_svc
,
.
update_service
=
ip_vs_rr_update_svc
,
.
schedule
=
ip_vs_rr_schedule
,
...
...
net/ipv4/ipvs/ip_vs_sed.c
浏览文件 @
dacc62db
...
...
@@ -101,12 +101,12 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
}
}
IP_VS_DBG
(
6
,
"SED: server %u.%u.%u.%u
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
IP_VS_DBG
_BUF
(
6
,
"SED: server %s
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
return
least
;
}
...
...
@@ -118,6 +118,9 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_sed_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
schedule
=
ip_vs_sed_schedule
,
};
...
...
net/ipv4/ipvs/ip_vs_sh.c
浏览文件 @
dacc62db
...
...
@@ -215,7 +215,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
IP_VS_DBG
(
6
,
"SH: source IP address %u.%u.%u.%u "
"--> server %u.%u.%u.%u:%d
\n
"
,
NIPQUAD
(
iph
->
saddr
),
NIPQUAD
(
dest
->
addr
),
NIPQUAD
(
dest
->
addr
.
ip
),
ntohs
(
dest
->
port
));
return
dest
;
...
...
@@ -231,6 +231,9 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_sh_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
0
,
#endif
.
init_service
=
ip_vs_sh_init_svc
,
.
done_service
=
ip_vs_sh_done_svc
,
.
update_service
=
ip_vs_sh_update_svc
,
...
...
net/ipv4/ipvs/ip_vs_sync.c
浏览文件 @
dacc62db
...
...
@@ -256,9 +256,9 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp)
s
->
cport
=
cp
->
cport
;
s
->
vport
=
cp
->
vport
;
s
->
dport
=
cp
->
dport
;
s
->
caddr
=
cp
->
caddr
;
s
->
vaddr
=
cp
->
vaddr
;
s
->
daddr
=
cp
->
daddr
;
s
->
caddr
=
cp
->
caddr
.
ip
;
s
->
vaddr
=
cp
->
vaddr
.
ip
;
s
->
daddr
=
cp
->
daddr
.
ip
;
s
->
flags
=
htons
(
cp
->
flags
&
~
IP_VS_CONN_F_HASHED
);
s
->
state
=
htons
(
cp
->
state
);
if
(
cp
->
flags
&
IP_VS_CONN_F_SEQ_MASK
)
{
...
...
@@ -366,21 +366,28 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
}
if
(
!
(
flags
&
IP_VS_CONN_F_TEMPLATE
))
cp
=
ip_vs_conn_in_get
(
s
->
protocol
,
s
->
caddr
,
s
->
cport
,
s
->
vaddr
,
s
->
vport
);
cp
=
ip_vs_conn_in_get
(
AF_INET
,
s
->
protocol
,
(
union
nf_inet_addr
*
)
&
s
->
caddr
,
s
->
cport
,
(
union
nf_inet_addr
*
)
&
s
->
vaddr
,
s
->
vport
);
else
cp
=
ip_vs_ct_in_get
(
s
->
protocol
,
s
->
caddr
,
s
->
cport
,
s
->
vaddr
,
s
->
vport
);
cp
=
ip_vs_ct_in_get
(
AF_INET
,
s
->
protocol
,
(
union
nf_inet_addr
*
)
&
s
->
caddr
,
s
->
cport
,
(
union
nf_inet_addr
*
)
&
s
->
vaddr
,
s
->
vport
);
if
(
!
cp
)
{
/*
* Find the appropriate destination for the connection.
* If it is not found the connection will remain unbound
* but still handled.
*/
dest
=
ip_vs_find_dest
(
s
->
daddr
,
s
->
dport
,
s
->
vaddr
,
s
->
vport
,
dest
=
ip_vs_find_dest
(
AF_INET
,
(
union
nf_inet_addr
*
)
&
s
->
daddr
,
s
->
dport
,
(
union
nf_inet_addr
*
)
&
s
->
vaddr
,
s
->
vport
,
s
->
protocol
);
/* Set the approprite ativity flag */
if
(
s
->
protocol
==
IPPROTO_TCP
)
{
...
...
@@ -389,10 +396,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
else
flags
&=
~
IP_VS_CONN_F_INACTIVE
;
}
cp
=
ip_vs_conn_new
(
s
->
protocol
,
s
->
caddr
,
s
->
cport
,
s
->
vaddr
,
s
->
vport
,
s
->
daddr
,
s
->
dport
,
cp
=
ip_vs_conn_new
(
AF_INET
,
s
->
protocol
,
(
union
nf_inet_addr
*
)
&
s
->
caddr
,
s
->
cport
,
(
union
nf_inet_addr
*
)
&
s
->
vaddr
,
s
->
vport
,
(
union
nf_inet_addr
*
)
&
s
->
daddr
,
s
->
dport
,
flags
,
dest
);
if
(
dest
)
atomic_dec
(
&
dest
->
refcnt
);
...
...
net/ipv4/ipvs/ip_vs_wlc.c
浏览文件 @
dacc62db
...
...
@@ -89,12 +89,12 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
}
}
IP_VS_DBG
(
6
,
"WLC: server %u.%u.%u.%u
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
NIPQUAD
(
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
IP_VS_DBG
_BUF
(
6
,
"WLC: server %s
:%u "
"activeconns %d refcnt %d weight %d overhead %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
least
->
addr
),
ntohs
(
least
->
port
),
atomic_read
(
&
least
->
activeconns
),
atomic_read
(
&
least
->
refcnt
),
atomic_read
(
&
least
->
weight
),
loh
);
return
least
;
}
...
...
@@ -106,6 +106,9 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_wlc_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
schedule
=
ip_vs_wlc_schedule
,
};
...
...
net/ipv4/ipvs/ip_vs_wrr.c
浏览文件 @
dacc62db
...
...
@@ -195,12 +195,12 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
}
}
IP_VS_DBG
(
6
,
"WRR: server %u.%u.%u.%u
:%u "
"activeconns %d refcnt %d weight %d
\n
"
,
NIPQUAD
(
dest
->
addr
),
ntohs
(
dest
->
port
),
atomic_read
(
&
dest
->
activeconns
),
atomic_read
(
&
dest
->
refcnt
),
atomic_read
(
&
dest
->
weight
));
IP_VS_DBG
_BUF
(
6
,
"WRR: server %s
:%u "
"activeconns %d refcnt %d weight %d
\n
"
,
IP_VS_DBG_ADDR
(
svc
->
af
,
&
dest
->
addr
),
ntohs
(
dest
->
port
),
atomic_read
(
&
dest
->
activeconns
),
atomic_read
(
&
dest
->
refcnt
),
atomic_read
(
&
dest
->
weight
));
out:
write_unlock
(
&
svc
->
sched_lock
);
...
...
@@ -213,6 +213,9 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
.
refcnt
=
ATOMIC_INIT
(
0
),
.
module
=
THIS_MODULE
,
.
n_list
=
LIST_HEAD_INIT
(
ip_vs_wrr_scheduler
.
n_list
),
#ifdef CONFIG_IP_VS_IPV6
.
supports_ipv6
=
1
,
#endif
.
init_service
=
ip_vs_wrr_init_svc
,
.
done_service
=
ip_vs_wrr_done_svc
,
.
update_service
=
ip_vs_wrr_update_svc
,
...
...
net/ipv4/ipvs/ip_vs_xmit.c
浏览文件 @
dacc62db
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录