00001
00002
00003
00004
00005
00006
#ifndef _IP_VS_H
00007
#define _IP_VS_H
00008
00009
#include <asm/types.h>
00010
00011 #define IP_VS_VERSION_CODE 0x01000A
00012 #define NVERSION(version) \
00013
(version >> 16) & 0xFF, \
00014
(version >> 8) & 0xFF, \
00015
version & 0xFF
00016
00017
00018
00019
00020 #define IP_VS_SVC_F_PERSISTENT 0x0001
00021 #define IP_VS_SVC_F_HASHED 0x0002
00022
00023
00024
00025
00026 #define IP_VS_DEST_F_AVAILABLE 0x0001
00027
00028
00029
00030
00031 #define IP_VS_STATE_NONE 0
00032 #define IP_VS_STATE_MASTER 1
00033 #define IP_VS_STATE_BACKUP 2
00034
00035
00036
00037
00038 #define IP_VS_BASE_CTL (64+1024+64)
00039
00040 #define IP_VS_SO_SET_NONE IP_VS_BASE_CTL
00041 #define IP_VS_SO_SET_INSERT (IP_VS_BASE_CTL+1)
00042 #define IP_VS_SO_SET_ADD (IP_VS_BASE_CTL+2)
00043 #define IP_VS_SO_SET_EDIT (IP_VS_BASE_CTL+3)
00044 #define IP_VS_SO_SET_DEL (IP_VS_BASE_CTL+4)
00045 #define IP_VS_SO_SET_FLUSH (IP_VS_BASE_CTL+5)
00046 #define IP_VS_SO_SET_LIST (IP_VS_BASE_CTL+6)
00047 #define IP_VS_SO_SET_ADDDEST (IP_VS_BASE_CTL+7)
00048 #define IP_VS_SO_SET_DELDEST (IP_VS_BASE_CTL+8)
00049 #define IP_VS_SO_SET_EDITDEST (IP_VS_BASE_CTL+9)
00050 #define IP_VS_SO_SET_TIMEOUTS (IP_VS_BASE_CTL+10)
00051 #define IP_VS_SO_SET_STARTDAEMON (IP_VS_BASE_CTL+11)
00052 #define IP_VS_SO_SET_STOPDAEMON (IP_VS_BASE_CTL+12)
00053 #define IP_VS_SO_SET_RESTORE (IP_VS_BASE_CTL+13)
00054 #define IP_VS_SO_SET_SAVE (IP_VS_BASE_CTL+14)
00055 #define IP_VS_SO_SET_ZERO (IP_VS_BASE_CTL+15)
00056 #define IP_VS_SO_SET_MAX IP_VS_SO_SET_ZERO
00057
00058 #define IP_VS_SO_GET_VERSION IP_VS_BASE_CTL
00059 #define IP_VS_SO_GET_INFO (IP_VS_BASE_CTL+1)
00060 #define IP_VS_SO_GET_SERVICES (IP_VS_BASE_CTL+2)
00061 #define IP_VS_SO_GET_SERVICE (IP_VS_BASE_CTL+3)
00062 #define IP_VS_SO_GET_DESTS (IP_VS_BASE_CTL+4)
00063 #define IP_VS_SO_GET_DEST (IP_VS_BASE_CTL+5)
00064 #define IP_VS_SO_GET_TIMEOUTS (IP_VS_BASE_CTL+6)
00065 #define IP_VS_SO_GET_DAEMON (IP_VS_BASE_CTL+7)
00066 #define IP_VS_SO_GET_MAX IP_VS_SO_GET_DAEMON
00067
00068
00069
00070
00071
00072 #define IP_VS_CONN_F_FWD_MASK 0x0007
00073 #define IP_VS_CONN_F_MASQ 0x0000
00074 #define IP_VS_CONN_F_LOCALNODE 0x0001
00075 #define IP_VS_CONN_F_TUNNEL 0x0002
00076 #define IP_VS_CONN_F_DROUTE 0x0003
00077 #define IP_VS_CONN_F_BYPASS 0x0004
00078 #define IP_VS_CONN_F_HASHED 0x0040
00079 #define IP_VS_CONN_F_NOOUTPUT 0x0080
00080 #define IP_VS_CONN_F_INACTIVE 0x0100
00081 #define IP_VS_CONN_F_OUT_SEQ 0x0200
00082 #define IP_VS_CONN_F_IN_SEQ 0x0400
00083 #define IP_VS_CONN_F_SEQ_MASK 0x0600
00084 #define IP_VS_CONN_F_NO_CPORT 0x0800
00085
00086
00087 #define NFC_IPVS_PROPERTY 0x10000
00088
00089 #define IP_VS_SCHEDNAME_MAXLEN 16
00090 #define IP_VS_IFNAME_MAXLEN 16
00091
00092 struct ip_vs_rule_user {
00093
00094 int tcp_timeout;
00095 int tcp_fin_timeout;
00096 int udp_timeout;
00097 int state;
00098 char mcast_ifn[
IP_VS_IFNAME_MAXLEN];
00099
00100
00101
00102 u_int16_t
protocol;
00103 u_int32_t
vaddr;
00104 u_int16_t
vport;
00105 u_int32_t
vfwmark;
00106 char sched_name[
IP_VS_SCHEDNAME_MAXLEN];
00107 unsigned vs_flags;
00108 unsigned timeout;
00109 u_int32_t
netmask;
00110
00111
00112 u_int32_t
daddr;
00113 u_int16_t
dport;
00114 unsigned conn_flags;
00115 int weight;
00116 };
00117
00118
00119
00120
00121
00122 struct ip_vs_stats_user
00123 {
00124 __u32
conns;
00125 __u32
inpkts;
00126 __u32
outpkts;
00127 __u64
inbytes;
00128 __u64
outbytes;
00129
00130 __u32
cps;
00131 __u32
inpps;
00132 __u32
outpps;
00133 __u32
inbps;
00134 __u32
outbps;
00135 };
00136
00137
00138
00139 struct ip_vs_getinfo {
00140
00141 unsigned int version;
00142
00143
00144 unsigned int size;
00145
00146
00147 unsigned int num_services;
00148 };
00149
00150
00151 struct ip_vs_service_user {
00152
00153 u_int16_t
protocol;
00154 u_int32_t
addr;
00155 u_int16_t
port;
00156 u_int32_t
fwmark;
00157
00158
00159 char sched_name[
IP_VS_SCHEDNAME_MAXLEN];
00160 unsigned flags;
00161 unsigned timeout;
00162 u_int32_t
netmask;
00163
00164
00165 unsigned int num_dests;
00166
00167
00168 struct ip_vs_stats_user stats;
00169 };
00170
00171 struct ip_vs_dest_user {
00172 u_int32_t
addr;
00173 u_int16_t
port;
00174 unsigned flags;
00175 int weight;
00176 u_int32_t
activeconns;
00177 u_int32_t
inactconns;
00178
00179
00180 struct ip_vs_stats_user stats;
00181 };
00182
00183
00184 struct ip_vs_get_dests {
00185
00186 u_int16_t
protocol;
00187 u_int32_t
addr;
00188 u_int16_t
port;
00189 u_int32_t
fwmark;
00190
00191
00192 unsigned int num_dests;
00193
00194
00195 struct ip_vs_dest_user entrytable[0];
00196 };
00197
00198
00199 struct ip_vs_get_services {
00200
00201 unsigned int num_services;
00202
00203
00204 struct ip_vs_service_user entrytable[0];
00205 };
00206
00207
00208 struct ip_vs_timeout_user {
00209 int tcp_timeout;
00210 int tcp_fin_timeout;
00211 int udp_timeout;
00212 };
00213
00214
00215 struct ip_vs_daemon_user {
00216 int state;
00217 char mcast_ifn[
IP_VS_IFNAME_MAXLEN];
00218 };
00219
00220
00221
#ifdef __KERNEL__
00222
00223
#include <linux/config.h>
00224
#include <linux/list.h>
00225
#include <linux/spinlock.h>
00226
#include <linux/skbuff.h>
00227
#include <linux/ip.h>
00228
#include <asm/atomic.h>
00229
#include <linux/netdevice.h>
00230
#include <net/dst.h>
00231
#include <net/route.h>
00232
#include <net/tcp.h>
00233
#include <net/udp.h>
00234
00235
00236
#ifdef CONFIG_IP_VS_DEBUG
00237
extern int ip_vs_get_debug_level(
void);
00238
#define IP_VS_DBG(level, msg...) \
00239
do { \
00240
if (level <= ip_vs_get_debug_level()) \
00241
printk(KERN_DEBUG "IPVS: " msg); \
00242
} while (0)
00243
#define IP_VS_DBG_RL(msg...) \
00244
do { \
00245
if (net_ratelimit()) \
00246
printk(KERN_DEBUG "IPVS: " msg); \
00247
} while (0)
00248
#else
00249 #define IP_VS_DBG(level, msg...) do {} while (0)
00250 #define IP_VS_DBG_RL(msg...) do {} while (0)
00251
#endif
00252
00253 #define IP_VS_BUG() BUG()
00254 #define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg)
00255 #define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg)
00256 #define IP_VS_WARNING(msg...) \
00257
printk(KERN_WARNING "IPVS: " msg)
00258 #define IP_VS_ERR_RL(msg...) \
00259
do { \
00260
if (net_ratelimit()) \
00261
printk(KERN_ERR "IPVS: " msg); \
00262
} while (0)
00263
00264
#ifdef CONFIG_IP_VS_DEBUG
00265
#define EnterFunction(level) \
00266
do { \
00267
if (level <= ip_vs_get_debug_level()) \
00268
printk(KERN_DEBUG "Enter: %s, %s line %i\n", \
00269
__FUNCTION__, __FILE__, __LINE__); \
00270
} while (0)
00271
#define LeaveFunction(level) \
00272
do { \
00273
if (level <= ip_vs_get_debug_level()) \
00274
printk(KERN_DEBUG "Leave: %s, %s line %i\n", \
00275
__FUNCTION__, __FILE__, __LINE__); \
00276
} while (0)
00277
#else
00278 #define EnterFunction(level) do {} while (0)
00279 #define LeaveFunction(level) do {} while (0)
00280
#endif
00281
00282
00283
00284
00285
00286 #define FTPPORT __constant_htons(21)
00287 #define FTPDATA __constant_htons(20)
00288
00289
00290
00291
00292
00293 #define NET_IPV4_VS 21
00294
00295
enum {
00296
NET_IPV4_VS_DEBUG_LEVEL=1,
00297
NET_IPV4_VS_AMEMTHRESH=2,
00298
NET_IPV4_VS_AMDROPRATE=3,
00299
NET_IPV4_VS_DROP_ENTRY=4,
00300
NET_IPV4_VS_DROP_PACKET=5,
00301
NET_IPV4_VS_SECURE_TCP=6,
00302
NET_IPV4_VS_TO_ES=7,
00303
NET_IPV4_VS_TO_SS=8,
00304
NET_IPV4_VS_TO_SR=9,
00305
NET_IPV4_VS_TO_FW=10,
00306
NET_IPV4_VS_TO_TW=11,
00307
NET_IPV4_VS_TO_CL=12,
00308
NET_IPV4_VS_TO_CW=13,
00309
NET_IPV4_VS_TO_LA=14,
00310
NET_IPV4_VS_TO_LI=15,
00311
NET_IPV4_VS_TO_SA=16,
00312
NET_IPV4_VS_TO_UDP=17,
00313
NET_IPV4_VS_TO_ICMP=18,
00314
NET_IPV4_VS_LBLC_EXPIRE=19,
00315
NET_IPV4_VS_LBLCR_EXPIRE=20,
00316
NET_IPV4_VS_CACHE_BYPASS=22,
00317
NET_IPV4_VS_EXPIRE_NODEST_CONN=23,
00318
NET_IPV4_VS_SYNC_THRESHOLD=24,
00319
NET_IPV4_VS_NAT_ICMP_SEND=25,
00320
NET_IPV4_VS_LAST
00321 };
00322
00323
00324
00325
00326
00327
enum {
00328
IP_VS_S_NONE = 0,
00329
IP_VS_S_ESTABLISHED,
00330
IP_VS_S_SYN_SENT,
00331
IP_VS_S_SYN_RECV,
00332
IP_VS_S_FIN_WAIT,
00333
IP_VS_S_TIME_WAIT,
00334
IP_VS_S_CLOSE,
00335
IP_VS_S_CLOSE_WAIT,
00336
IP_VS_S_LAST_ACK,
00337
IP_VS_S_LISTEN,
00338
IP_VS_S_SYNACK,
00339
IP_VS_S_UDP,
00340
IP_VS_S_ICMP,
00341
IP_VS_S_LAST
00342 };
00343
00344
00345 struct ip_vs_timeout_table {
00346 atomic_t
refcnt;
00347 int scale;
00348 int timeout[
IP_VS_S_LAST+1];
00349 };
00350
00351
00352
00353
00354
00355 union ip_vs_tphdr {
00356 unsigned char *
raw;
00357 struct udphdr *
uh;
00358 struct tcphdr *
th;
00359 struct icmphdr *
icmph;
00360 __u16 *
portp;
00361 };
00362
00363
00364
00365
00366
00367
00368
00369 struct ip_vs_seq {
00370 __u32
init_seq;
00371 __u32
delta;
00372 __u32
previous_delta;
00373
00374 };
00375
00376
00377
00378
00379
00380 struct ip_vs_stats
00381 {
00382 __u32
conns;
00383 __u32
inpkts;
00384 __u32
outpkts;
00385 __u64
inbytes;
00386 __u64
outbytes;
00387
00388 __u32
cps;
00389 __u32
inpps;
00390 __u32
outpps;
00391 __u32
inbps;
00392 __u32
outbps;
00393
00394 spinlock_t
lock;
00395 };
00396
00397
00398
00399
00400
00401 struct ip_vs_conn {
00402 struct list_head c_list;
00403
00404
00405 __u32
caddr;
00406 __u32
vaddr;
00407 __u32
daddr;
00408 __u16
cport;
00409 __u16
vport;
00410 __u16
dport;
00411 __u16
protocol;
00412
00413
00414 atomic_t
refcnt;
00415 struct timer_list timer;
00416 volatile unsigned long timeout;
00417 struct ip_vs_timeout_table *
timeout_table;
00418
00419
00420 spinlock_t
lock;
00421 volatile __u16
flags;
00422 volatile __u16
state;
00423
00424
00425 struct ip_vs_conn *
control;
00426 atomic_t
n_control;
00427 struct ip_vs_dest *
dest;
00428 atomic_t
in_pkts;
00429
00430
00431 int (*packet_xmit)(
struct sk_buff *skb,
struct ip_vs_conn *cp);
00432
00433
00434
00435
00436 struct ip_vs_app *
app;
00437 void *
app_data;
00438 struct ip_vs_seq in_seq;
00439 struct ip_vs_seq out_seq;
00440 };
00441
00442
00443
00444
00445
00446
00447 struct ip_vs_service {
00448 struct list_head s_list;
00449 struct list_head f_list;
00450 atomic_t
refcnt;
00451 atomic_t
usecnt;
00452
00453 __u16
protocol;
00454 __u32
addr;
00455 __u16
port;
00456 __u32
fwmark;
00457 unsigned flags;
00458 unsigned timeout;
00459 __u32
netmask;
00460
00461 struct list_head destinations;
00462 __u32
num_dests;
00463 struct ip_vs_stats stats;
00464
00465
00466 struct ip_vs_scheduler *
scheduler;
00467 rwlock_t
sched_lock;
00468 void *
sched_data;
00469 };
00470
00471
00472
00473
00474
00475
00476 struct ip_vs_dest {
00477 struct list_head n_list;
00478 struct list_head d_list;
00479
00480 __u32
addr;
00481 __u16
port;
00482 unsigned flags;
00483 atomic_t
weight;
00484 atomic_t
conn_flags;
00485 atomic_t
activeconns;
00486 atomic_t
inactconns;
00487 atomic_t
refcnt;
00488 struct ip_vs_stats stats;
00489
00490
00491 spinlock_t
dst_lock;
00492 struct dst_entry *
dst_cache;
00493 u32
dst_rtos;
00494
00495
00496 struct ip_vs_service *
svc;
00497 __u16
protocol;
00498 __u32
vaddr;
00499 __u16
vport;
00500 __u32
vfwmark;
00501 };
00502
00503
00504
00505
00506
00507 struct ip_vs_scheduler {
00508 struct list_head n_list;
00509 char *
name;
00510 atomic_t
refcnt;
00511 struct module *
module;
00512
00513
00514 int (*init_service)(
struct ip_vs_service *svc);
00515
00516 int (*done_service)(
struct ip_vs_service *svc);
00517
00518 int (*update_service)(
struct ip_vs_service *svc);
00519
00520
00521
struct ip_vs_dest* (*schedule)(
struct ip_vs_service *svc,
00522
struct iphdr *iph);
00523 };
00524
00525
00526
00527
00528
00529 struct ip_vs_app
00530 {
00531 struct list_head n_list;
00532 char *
name;
00533 unsigned type;
00534
00535 struct module *
module;
00536
00537
00538 int (*init_conn)(
struct ip_vs_app *,
struct ip_vs_conn *);
00539
00540 int (*done_conn)(
struct ip_vs_app *,
struct ip_vs_conn *);
00541
00542 int (*pkt_out)(
struct ip_vs_app *,
00543
struct ip_vs_conn *,
struct sk_buff *);
00544
00545 int (*pkt_in)(
struct ip_vs_app *,
00546
struct ip_vs_conn *,
struct sk_buff *);
00547 };
00548
00549
00550
00551
00552
00553
00554
extern const char *
ip_vs_proto_name(
unsigned proto);
00555
extern unsigned int check_for_ip_vs_out(
struct sk_buff **skb_p,
00556
int (*okfn)(
struct sk_buff *));
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
#ifndef CONFIG_IP_VS_TAB_BITS
00568 #define CONFIG_IP_VS_TAB_BITS 12
00569
#endif
00570
00571
#if CONFIG_IP_VS_TAB_BITS < 8
00572
#define IP_VS_CONN_TAB_BITS 8
00573
#endif
00574
#if CONFIG_IP_VS_TAB_BITS > 20
00575
#define IP_VS_CONN_TAB_BITS 20
00576
#endif
00577
#if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20
00578 #define IP_VS_CONN_TAB_BITS CONFIG_IP_VS_TAB_BITS
00579
#endif
00580 #define IP_VS_CONN_TAB_SIZE (1 << IP_VS_CONN_TAB_BITS)
00581 #define IP_VS_CONN_TAB_MASK (IP_VS_CONN_TAB_SIZE - 1)
00582
00583 #define VS_STATE_INPUT 0
00584 #define VS_STATE_OUTPUT 4
00585 #define VS_STATE_INPUT_ONLY 8
00586
00587
extern struct ip_vs_timeout_table vs_timeout_table;
00588
extern struct ip_vs_timeout_table vs_timeout_table_dos;
00589
00590
extern struct ip_vs_conn *
ip_vs_conn_in_get
00591 (
int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
00592
extern struct ip_vs_conn *
ip_vs_conn_out_get
00593 (
int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port);
00594
00595
00596 static inline void __ip_vs_conn_put(
struct ip_vs_conn *cp)
00597 {
00598 atomic_dec(&cp->
refcnt);
00599 }
00600
extern void ip_vs_conn_put(
struct ip_vs_conn *cp);
00601
00602
extern struct ip_vs_conn *
00603
ip_vs_conn_new(
int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport,
00604 __u32 daddr, __u16 dport,
unsigned flags,
00605
struct ip_vs_dest *dest);
00606
extern void ip_vs_conn_expire_now(
struct ip_vs_conn *cp);
00607
00608
extern const char *
ip_vs_state_name(
int state);
00609
extern int ip_vs_set_state(
struct ip_vs_conn *cp,
int state_off,
00610
struct iphdr *iph,
void *tp);
00611
extern int ip_vs_conn_listen(
struct ip_vs_conn *cp);
00612
extern int ip_vs_check_template(
struct ip_vs_conn *ct);
00613
extern void ip_vs_secure_tcp_set(
int on);
00614
extern void ip_vs_random_dropentry(
void);
00615
extern int ip_vs_conn_init(
void);
00616
extern void ip_vs_conn_cleanup(
void);
00617
00618 static inline void ip_vs_control_del(
struct ip_vs_conn *cp)
00619 {
00620
struct ip_vs_conn *ctl_cp = cp->
control;
00621
if (!ctl_cp) {
00622
IP_VS_ERR(
"request control DEL for uncontrolled: "
00623
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
00624 NIPQUAD(cp->
caddr),ntohs(cp->
cport),
00625 NIPQUAD(cp->
vaddr),ntohs(cp->
vport));
00626
return;
00627 }
00628
00629
IP_VS_DBG(7,
"DELeting control for: "
00630
"cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
00631 NIPQUAD(cp->
caddr),ntohs(cp->
cport),
00632 NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport));
00633
00634 cp->
control = NULL;
00635
if (atomic_read(&ctl_cp->n_control) == 0) {
00636
IP_VS_ERR(
"BUG control DEL with n=0 : "
00637
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
00638 NIPQUAD(cp->
caddr),ntohs(cp->
cport),
00639 NIPQUAD(cp->
vaddr),ntohs(cp->
vport));
00640
return;
00641 }
00642 atomic_dec(&ctl_cp->n_control);
00643 }
00644
00645
static inline void
00646 ip_vs_control_add(
struct ip_vs_conn *cp,
struct ip_vs_conn *ctl_cp)
00647 {
00648
if (cp->
control) {
00649
IP_VS_ERR(
"request control ADD for already controlled: "
00650
"%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
00651 NIPQUAD(cp->
caddr),ntohs(cp->
cport),
00652 NIPQUAD(cp->
vaddr),ntohs(cp->
vport));
00653
ip_vs_control_del(cp);
00654 }
00655
00656
IP_VS_DBG(7,
"ADDing control for: "
00657
"cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
00658 NIPQUAD(cp->
caddr),ntohs(cp->
cport),
00659 NIPQUAD(ctl_cp->
caddr),ntohs(ctl_cp->
cport));
00660
00661 cp->
control = ctl_cp;
00662 atomic_inc(&ctl_cp->
n_control);
00663 }
00664
00665
00666
00667
00668
00669
00670 #define IP_VS_APP_MAX_PORTS 8
00671
extern int register_ip_vs_app(
struct ip_vs_app *mapp,
00672
unsigned short proto, __u16 port);
00673
extern int unregister_ip_vs_app(
struct ip_vs_app *mapp);
00674
extern struct ip_vs_app *
ip_vs_bind_app(
struct ip_vs_conn *cp);
00675
extern int ip_vs_unbind_app(
struct ip_vs_conn *cp);
00676
extern int ip_vs_app_pkt_out(
struct ip_vs_conn *,
struct sk_buff *skb);
00677
extern int ip_vs_app_pkt_in(
struct ip_vs_conn *,
struct sk_buff *skb);
00678
extern int ip_vs_skb_replace(
struct sk_buff *skb,
int pri,
00679
char *o_buf,
int o_len,
char *n_buf,
int n_len);
00680
extern int ip_vs_app_init(
void);
00681
extern void ip_vs_app_cleanup(
void);
00682
00683
00684
00685
00686
00687
00688
extern int register_ip_vs_scheduler(
struct ip_vs_scheduler *scheduler);
00689
extern int unregister_ip_vs_scheduler(
struct ip_vs_scheduler *scheduler);
00690
extern int ip_vs_bind_scheduler(
struct ip_vs_service *svc,
00691
struct ip_vs_scheduler *scheduler);
00692
extern int ip_vs_unbind_scheduler(
struct ip_vs_service *svc);
00693
extern struct ip_vs_scheduler *
ip_vs_scheduler_get(
const char *sched_name);
00694
extern void ip_vs_scheduler_put(
struct ip_vs_scheduler *scheduler);
00695
00696
00697
00698
00699
00700
00701
extern int sysctl_ip_vs_cache_bypass;
00702
extern int sysctl_ip_vs_expire_nodest_conn;
00703
extern int sysctl_ip_vs_sync_threshold;
00704
extern int sysctl_ip_vs_nat_icmp_send;
00705
extern struct ip_vs_stats ip_vs_stats;
00706
00707
extern struct ip_vs_service *
ip_vs_service_get(__u32 fwmark,
00708 __u16 protocol,
00709 __u32 vaddr, __u16 vport);
00710 static inline void ip_vs_service_put(
struct ip_vs_service *svc)
00711 {
00712 atomic_dec(&svc->
usecnt);
00713 }
00714
00715
extern struct ip_vs_dest *
00716
ip_vs_lookup_real_service(__u16 protocol, __u32 daddr, __u16 dport);
00717
extern void ip_vs_random_dropentry(
void);
00718
extern int ip_vs_control_init(
void);
00719
extern void ip_vs_control_cleanup(
void);
00720
00721
00722
00723
00724
00725
00726
extern volatile int ip_vs_sync_state;
00727
extern char ip_vs_mcast_ifn[
IP_VS_IFNAME_MAXLEN];
00728
extern int start_sync_thread(
int state,
char *mcast_ifn);
00729
extern int stop_sync_thread(
void);
00730
extern void ip_vs_sync_conn(
struct ip_vs_conn *cp);
00731
00732
00733
00734
00735
00736
extern int ip_vs_new_estimator(
struct ip_vs_stats *stats);
00737
extern void ip_vs_kill_estimator(
struct ip_vs_stats *stats);
00738
extern void ip_vs_zero_estimator(
struct ip_vs_stats *stats);
00739
00740
00741
00742
00743
00744
00745
00746
extern int ip_vs_drop_rate;
00747
extern int ip_vs_drop_counter;
00748
00749 static __inline__
int ip_vs_todrop(
void)
00750 {
00751
if (!
ip_vs_drop_rate)
return 0;
00752
if (--
ip_vs_drop_counter > 0)
return 0;
00753
ip_vs_drop_counter =
ip_vs_drop_rate;
00754
return 1;
00755 }
00756
00757
00758
00759
00760
00761 #define IP_VS_FWD_METHOD(cp) (cp->flags & IP_VS_CONN_F_FWD_MASK)
00762
00763 extern __inline__
char ip_vs_fwd_tag(
struct ip_vs_conn *cp)
00764 {
00765
char fwd;
00766
00767
switch (
IP_VS_FWD_METHOD(cp)) {
00768
case IP_VS_CONN_F_MASQ:
00769 fwd =
'M';
break;
00770
case IP_VS_CONN_F_LOCALNODE:
00771 fwd =
'L';
break;
00772
case IP_VS_CONN_F_TUNNEL:
00773 fwd =
'T';
break;
00774
case IP_VS_CONN_F_DROUTE:
00775 fwd =
'R';
break;
00776
case IP_VS_CONN_F_BYPASS:
00777 fwd =
'B';
break;
00778
default:
00779 fwd =
'?';
break;
00780 }
00781
return fwd;
00782 }
00783
00784
00785
00786
00787
00788 extern inline int ip_vs_header_check(
struct sk_buff *skb,
int proto,
int ihl)
00789 {
00790
int len;
00791
00792
switch (proto) {
00793
case IPPROTO_TCP:
00794 len = ihl +
sizeof(
struct tcphdr);
00795
00796
break;
00797
case IPPROTO_UDP:
00798 len = ihl +
sizeof(
struct udphdr);
00799
break;
00800
default:
00801 len = 0;
00802 }
00803
00804
00805
if (!
pskb_may_pull(skb, len))
00806
return -1;
00807
else
00808
return 0;
00809 }
00810
00811
00812
00813
00814
00815
static inline void
00816 __ip_vs_dst_set(
struct ip_vs_dest *dest, u32 rtos,
struct dst_entry *dst)
00817 {
00818
struct dst_entry *old_dst;
00819
00820 old_dst = dest->
dst_cache;
00821 dest->
dst_cache = dst;
00822 dest->
dst_rtos = rtos;
00823
dst_release(old_dst);
00824 }
00825
00826
static inline void
00827 __ip_vs_dst_reset(
struct ip_vs_dest *dest)
00828 {
00829
struct dst_entry *old_dst;
00830
00831 old_dst = dest->
dst_cache;
00832 dest->
dst_cache = NULL;
00833
dst_release(old_dst);
00834 }
00835
00836
static inline struct dst_entry *
00837 __ip_vs_dst_check(
struct ip_vs_dest *dest, u32 rtos, u32 cookie)
00838 {
00839
struct dst_entry *dst = dest->
dst_cache;
00840
00841
if (!dst)
00842
return NULL;
00843
if ((dst->obsolete || rtos != dest->
dst_rtos) &&
00844 dst->ops->check(dst, cookie) == NULL) {
00845 dest->
dst_cache = 0;
00846
return NULL;
00847 }
00848
dst_hold(dst);
00849
return dst;
00850 }
00851
00852
static inline struct rtable *
00853 __ip_vs_get_out_rt(
struct ip_vs_conn *cp, u32 rtos)
00854 {
00855
struct rtable *rt;
00856
struct ip_vs_dest *dest = cp->
dest;
00857
00858
if (dest) {
00859 spin_lock(&dest->dst_lock);
00860
if (!(rt = (
struct rtable *)
00861
__ip_vs_dst_check(dest, rtos, 0))) {
00862
if (
ip_route_output(&rt, dest->addr, 0, rtos, 0)) {
00863 spin_unlock(&dest->dst_lock);
00864
IP_VS_DBG_RL(
"ip_route_output error, "
00865
"dest: %u.%u.%u.%u\n",
00866 NIPQUAD(dest->addr));
00867
return NULL;
00868 }
00869
__ip_vs_dst_set(dest, rtos,
dst_clone(&rt->u.dst));
00870
IP_VS_DBG(10,
"new dst %u.%u.%u.%u, refcnt=%d, rtos=%X\n",
00871 NIPQUAD(dest->addr),
00872 atomic_read(&rt->u.dst.__refcnt), rtos);
00873 }
00874 spin_unlock(&dest->dst_lock);
00875 }
else {
00876
if (
ip_route_output(&rt, cp->
daddr, 0, rtos, 0)) {
00877
IP_VS_DBG_RL(
"ip_route_output error, dest: "
00878
"%u.%u.%u.%u\n", NIPQUAD(cp->
daddr));
00879
return NULL;
00880 }
00881 }
00882
00883
return rt;
00884 }
00885
00886 static inline u16
ip_vs_check_diff(u32 old, u32
new, u16 oldsum)
00887 {
00888 u32 diff[2] = { old,
new };
00889
00890
return csum_fold(
csum_partial((
char *) diff,
sizeof(diff),
00891 oldsum ^ 0xFFFF));
00892 }
00893
00894 static inline void ip_vs_fast_check_update(
union ip_vs_tphdr *h,
00895 u32 oldip, u32 newip, u16 oldport, u16 newport, u8 protocol)
00896 {
00897 u16 *checkp;
00898
00899
if (protocol ==
IPPROTO_TCP)
00900 checkp = &h->
th->check;
00901
else
00902 checkp = &h->
uh->check;
00903 *checkp =
ip_vs_check_diff(~oldip, newip,
00904
ip_vs_check_diff(oldport ^ 0xFFFF,
00905 newport, *checkp));
00906
if (!*checkp && protocol ==
IPPROTO_UDP)
00907 *checkp = 0xFFFF;
00908 }
00909
00910
static inline int
00911 ip_vs_skb_cow(
struct sk_buff *skb,
unsigned int headroom,
00912
struct iphdr **iph_p,
unsigned char **t_p)
00913 {
00914
int delta = (headroom > 16 ? headroom : 16) -
skb_headroom(skb);
00915
00916
if (delta < 0)
00917 delta = 0;
00918
00919
if (delta ||
skb_cloned(skb)) {
00920
if (
pskb_expand_head(skb, (delta+15)&~15, 0, GFP_ATOMIC))
00921
return -ENOMEM;
00922
00923
00924 *iph_p = skb->
nh.iph;
00925 *t_p = (
char*) (*iph_p) + (*iph_p)->ihl * 4;
00926 }
00927
return 0;
00928 }
00929
00930
#endif
00931
00932
#endif