And the user space patch this time. I should probably start a new thread
with less confusion ...
Cheers,
Roberto Nibali, ratz
--
-------------------------------------------------------------
addr://Kasinostrasse 30, CH-5001 Aarau tel://++41 62 823 9355
http://www.terreactive.com fax://++41 62 823 9356
-------------------------------------------------------------
terreActive AG Wir sichern Ihren Erfolg
-------------------------------------------------------------
diff -X ../2.4.x/dontdiff -Nur ipvsadm-1.21-11/Makefile
ipvsadm-1.21-11-ratz/Makefile
--- ipvsadm-1.21-11/Makefile 2005-01-22 05:07:42 +0100
+++ ipvsadm-1.21-11-ratz/Makefile 2005-10-17 13:46:08 +0200
@@ -38,6 +38,7 @@
else
CFLAGS = -Wall -Wunused -Wstrict-prototypes -g -O2
endif
+LDFLAGS =
SBIN = $(BUILD_ROOT)/sbin
MANDIR = usr/man
MAN = $(BUILD_ROOT)/$(MANDIR)/man8
@@ -87,7 +88,7 @@
all: ipvsadm
ipvsadm: $(OBJS) $(STATIC_LIBS)
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS)
install: ipvsadm
if [ ! -d $(SBIN) ]; then $(MKDIR) -p $(SBIN); fi
Files ipvsadm-1.21-11/ipvsadm and ipvsadm-1.21-11-ratz/ipvsadm differ
diff -X ../2.4.x/dontdiff -Nur ipvsadm-1.21-11/ipvsadm.c
ipvsadm-1.21-11-ratz/ipvsadm.c
--- ipvsadm-1.21-11/ipvsadm.c 2005-01-22 05:07:42 +0100
+++ ipvsadm-1.21-11-ratz/ipvsadm.c 2005-11-04 09:04:00 +0100
@@ -54,6 +54,7 @@
* processing options.
* Horms : added to load ip_vs_ftp for VS/NAT at port 21
* Alexandre Cassen : added SyncID support
+ * Roberto Nibali, ratz: added support for threshold limitation
*
*
* ippfvsadm - Port Fowarding & Virtual Server ADMinistration program
@@ -168,7 +169,11 @@
#define OPT_RATE 0x02000
#define OPT_SORT 0x04000
#define OPT_SYNCID 0x08000
-#define NUMBER_OF_OPT 16
+#define OPT_UTHRESHOLD 0x10000
+#define OPT_LTHRESHOLD 0x20000
+#define OPT_THRESHOLDS 0x40000
+#define OPT_OVERFLOW 0x80000
+#define NUMBER_OF_OPT 20
static const char* optnames[] = {
"numeric",
@@ -187,6 +192,10 @@
"rate",
"sort",
"syncid",
+ "u_threshold",
+ "l_threshold",
+ "thresholds",
+ "overflow",
};
/*
@@ -199,22 +208,22 @@
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
{
- /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt sid */
-/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', ' '},
-/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' ', 'x'},
-/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x', ' '},
-/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', ' '},
-/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+ /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt sid -x -y thr -o */
+/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x'},
+/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' ', 'x', 'x', 'x', ' ', '1'},
+/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x', ' ', ' ', 'x', ' '},
+/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x', ' ', ' ', 'x', ' '},
+/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x'},
+/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x'},
+/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
};
/* printing format flags */
@@ -224,6 +233,7 @@
#define FMT_STATS 0x0004
#define FMT_RATE 0x0008
#define FMT_SORT 0x0010
+#define FMT_THRESHOLDS 0x0020
#define SERVICE_NONE 0x0
#define SERVICE_ADDR 0x1
@@ -246,7 +256,7 @@
/* various parsing helpers & parsing functions */
static int str_is_digit(const char *str);
-static int string_to_number(const char *s, int min, int max);
+static int string_to_number(const char *s, unsigned int min, unsigned int max);
static int host_to_addr(const char *name, struct in_addr *addr);
static char * addr_to_host(struct in_addr *addr);
static char * addr_to_anyname(struct in_addr *addr);
@@ -346,8 +356,7 @@
{"udp-service", 'u', POPT_ARG_STRING, &optarg, 'u'},
{"fwmark-service", 'f', POPT_ARG_STRING, &optarg, 'f'},
{"scheduler", 's', POPT_ARG_STRING, &optarg, 's'},
- {"persistent", 'p', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL,
- &optarg, 'p'},
+ {"persistent", 'p', POPT_ARG_STRING, &optarg, 'p'},
{"netmask", 'M', POPT_ARG_STRING, &optarg, 'M'},
{"real-server", 'r', POPT_ARG_STRING, &optarg, 'r'},
{"masquerading", 'm', POPT_ARG_NONE, NULL, 'm'},
@@ -363,6 +372,10 @@
{"stats", '\0', POPT_ARG_NONE, NULL, '7'},
{"rate", '\0', POPT_ARG_NONE, NULL, '8'},
{"sort", '\0', POPT_ARG_NONE, NULL, '9'},
+ {"u_threshold", 'x', POPT_ARG_STRING, &optarg, 'x'},
+ {"l_threshold", 'y', POPT_ARG_STRING, &optarg, 'y'},
+ {"thresholds", '\0', POPT_ARG_NONE, NULL, '0'},
+ {"overflow", 'o', POPT_ARG_NONE, NULL, 'o'},
{NULL, 0, 0, NULL, 0}
};
@@ -468,6 +481,10 @@
ur->vs_flags = IP_VS_SVC_F_PERSISTENT;
ur->timeout = parse_timeout(optarg, 1, MAX_TIMEOUT);
break;
+ case 'o':
+ set_option(options, OPT_OVERFLOW);
+ ur->dest_flags |= IP_VS_DEST_F_OVERFLOW;
+ break;
case 'M':
set_option(options, OPT_NETMASK);
parse = parse_netmask(optarg, &ur->netmask);
@@ -503,9 +520,24 @@
case 'w':
set_option(options, OPT_WEIGHT);
if ((ur->weight =
- string_to_number(optarg, 0, 65535)) == -1)
+ string_to_number(optarg, 0, UINT16_MAX)) == -1)
fail(2, "illegal weight specified");
break;
+ case 'x':
+ set_option(options, OPT_UTHRESHOLD);
+ if ((ur->u_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal u_threshold specified");
+ break;
+ case 'y':
+ set_option(options, OPT_LTHRESHOLD);
+ if ((ur->l_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal l_threshold specified");
+ if (ur->l_threshold > ur->u_threshold) {
+ fail(2, "l_threshold must be smaller than
u_threshold");
+ }
+ break;
case 'c':
set_option(options, OPT_CONNECTION);
break;
@@ -541,6 +573,10 @@
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case '0':
+ set_option(options, OPT_THRESHOLDS);
+ *format |= FMT_THRESHOLDS;
+ break;
default:
fail(2, "invalid option");
}
@@ -586,7 +622,7 @@
int *cmd, unsigned int *options, unsigned int *format)
{
int c, parse;
- const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn";
+ const char *optstring = "AEDCZSRaedlLhvot:u:f:s:M:p::w:r:x:y:gmicn";
const struct option long_options[] = {
{"add-service", 0, 0, 'A'},
{"edit-service", 0, 0, 'E'},
@@ -599,6 +635,7 @@
{"delete-server", 0, 0, 'd'},
{"help", 0, 0, 'h'},
{"version", 0, 0, 'v'},
+ {"overflow", 0, 0, 'o'},
{"save", 0, 0, 'S'},
{"restore", 0, 0, 'R'},
{"set", 1, 0, '4'},
@@ -624,6 +661,9 @@
{"stats", 0, 0, '7'},
{"rate", 0, 0, '8'},
{"sort", 0, 0, '9'},
+ {"u_threshold", 1, 0, 'x'},
+ {"l_threshold", 1, 0, 'y'},
+ {"thresholds", 0, 0, '0'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
@@ -744,6 +784,10 @@
set_option(options, OPT_SCHEDULER);
strncpy(ur->sched_name, optarg, IP_VS_SCHEDNAME_MAXLEN);
break;
+ case 'o':
+ set_option(options, OPT_OVERFLOW);
+ ur->dest_flags |= IP_VS_DEST_F_OVERFLOW;
+ break;
case 'p':
set_option(options, OPT_PERSISTENT);
ur->vs_flags = IP_VS_SVC_F_PERSISTENT;
@@ -787,9 +831,24 @@
case 'w':
set_option(options, OPT_WEIGHT);
if ((ur->weight =
- string_to_number(optarg, 0, 65535)) == -1)
+ string_to_number(optarg, 0, UINT16_MAX)) == -1)
fail(2, "illegal weight specified");
break;
+ case 'x':
+ set_option(options, OPT_UTHRESHOLD);
+ if ((ur->u_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal u_threshold specified");
+ break;
+ case 'y':
+ set_option(options, OPT_LTHRESHOLD);
+ if ((ur->l_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal l_threshold specified");
+ if (ur->l_threshold > ur->u_threshold) {
+ fail(2, "l_threshold must be smaller than
u_threshold");
+ }
+ break;
case 'c':
set_option(options, OPT_CONNECTION);
break;
@@ -825,6 +884,10 @@
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case '0':
+ set_option(options, OPT_THRESHOLDS);
+ *format |= FMT_THRESHOLDS;
+ break;
default:
fail(2, "invalid option");
}
@@ -884,7 +947,8 @@
if ((options & OPT_CONNECTION
|| options & OPT_TIMEOUT
|| options & OPT_DAEMON)
- && (options & OPT_STATS || options & OPT_RATE))
+ && (options & OPT_STATS || options & OPT_RATE
+ || options & OPT_THRESHOLDS))
fail(2, "options conflicts in the list command");
if (options & OPT_CONNECTION)
@@ -955,13 +1019,13 @@
}
-static int string_to_number(const char *s, int min, int max)
+static int string_to_number(const char *s, unsigned int min, unsigned int max)
{
- long number;
+ unsigned long number;
char *end;
errno = 0;
- number = strtol(s, &end, 10);
+ number = strtoul(s, &end, 10);
if (*end == '\0' && end != s) {
/* We parsed a number, let's see if we want this. */
if (errno != ERANGE && min <= number && number <= max)
@@ -1064,9 +1128,9 @@
if (portp != NULL){
result |= SERVICE_PORT;
- if ((portn=string_to_number(portp+1, 0, 65535)) != -1)
+ if ((portn=string_to_number(portp + 1, 0, UINT16_MAX)) != -1)
*port = htons(portn);
- else if ((portn=service_to_port(portp+1, proto)) != -1)
+ else if ((portn=service_to_port(portp + 1, proto)) != -1)
*port = htons(portn);
else
return SERVICE_NONE;
@@ -1207,6 +1271,8 @@
" --ipip -i ipip encapsulation
(tunneling)\n"
" --masquerading -m masquerading (NAT)\n"
" --weight -w weight capacity of real
server\n"
+ " --u_threshold -x uthreshold upper threshold for
amount of connections per RS\n"
+ " --l_threshold -y lthreshold lower threshold for
amount of connections per RS\n"
" --mcast-interface interface multicast interface for
connection sync\n"
" --syncid sid syncid for connection
sync (default=255)\n"
" --connection -c output of current IPVS
connections\n"
@@ -1214,6 +1280,8 @@
" --daemon output of daemon
information\n"
" --stats output of statistics
information\n"
" --rate output of rate
information\n"
+ " --thresholds information on threshold
settings\n"
+ " --overflow -o flag realserver as
spillover server\n"
" --sort sorting output of
service/server entries\n"
" --numeric -n numeric output of
addresses and ports\n",
DEF_SCHED);
@@ -1453,6 +1521,14 @@
" -> RemoteAddress:Port\n",
"Prot LocalAddress:Port",
"CPS", "InPPS", "OutPPS", "InBPS", "OutBPS");
+ else if (format & FMT_THRESHOLDS)
+ printf("%-33s %-7s %-6s %-10s %-10s %-10s %-10s %-10s %-10s
%-10s\n"
+ " -> RemoteAddress:Port\n",
+ "Prot LocalAddress:Port",
+ "Forward", "Weight",
+ "Uthreshold", "Lthreshold",
+ "ActiveConn", "InActConn", "PersConn",
+ "RS-Usage", "RS-Status");
else if (!(format & FMT_RULE))
printf("Prot LocalAddress:Port Scheduler Flags\n"
" -> RemoteAddress:Port Forward Weight
ActiveConn InActConn\n");
@@ -1510,6 +1586,15 @@
printf(" -M %s", inet_ntoa(mask));
}
}
+ if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
+ printf(" %s", "PERSISTENT");
+ }
+ if (svc->flags & IP_VS_SVC_F_HASHED) {
+ printf(" %s", "HASHED");
+ }
+ if (svc->flags & IP_VS_SVC_F_OVERLOAD) {
+ printf(" %s", "OVERLOAD");
+ }
} else if (format & FMT_STATS) {
printf("%-33s", svc_name);
print_largenum(svc->stats.conns);
@@ -1528,11 +1613,15 @@
printf("%s %s", svc_name, svc->sched_name);
if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
printf(" persistent %u", svc->timeout);
- if (svc->netmask != (unsigned long int) 0xffffffff) {
+ //if (svc->netmask != (unsigned long int) 0xffffffff) {
struct in_addr mask;
mask.s_addr = svc->netmask;
printf(" mask %s", inet_ntoa(mask));
- }
+ //}
+ }
+ printf(" avail_dests: %d", svc->avail_dests);
+ if (svc->flags & IP_VS_SVC_F_OVERLOAD) {
+ printf(" %s", "OVERLOAD");
}
}
printf("\n");
@@ -1569,6 +1658,13 @@
print_largenum(e->stats.inbps);
print_largenum(e->stats.outbps);
printf("\n");
+ } else if (format & FMT_THRESHOLDS) {
+ printf(" -> %-28s %-7s %-6d %-10u %-10u %-10u %-10u
%-10u %-10s %s\n", dname,
+ fwd_name(e->flags), e->weight,
+ e->u_threshold, e->l_threshold,
+ e->activeconns, e->inactconns, e->persistconns,
+ e->dest_flags & IP_VS_DEST_F_OVERFLOW ?
"SPILLOVER" : "POOL",
+ e->dest_flags & IP_VS_DEST_F_OVERLOAD ?
"OVERLOADED" : "ONLINE");
} else
printf(" -> %-28s %-7s %-6d %-10u %-10u\n",
dname, fwd_name(e->flags),
|