Add support for --sync-maxlen, --mcast-group, --mcast-port and
--mcast-ttl options for the --start-daemon command.
Signed-off-by: Julian Anastasov <ja@xxxxxx>
---
ipvsadm.8 | 55 ++++++++++++++-----
ipvsadm.c | 137 +++++++++++++++++++++++++++++++++++++---------
libipvs/ip_vs.h | 31 +++++++++++
libipvs/ip_vs_nl_policy.c | 6 ++
libipvs/libipvs.c | 71 ++++++++++++++++++++++--
5 files changed, 256 insertions(+), 44 deletions(-)
It is related to the kernel patches for new parameters for
the sync daemon. If needed I'll post it again later for
inclusion after the kernel patches are included.
diff --git a/ipvsadm.8 b/ipvsadm.8
index 3df3b83..dad1712 100644
--- a/ipvsadm.8
+++ b/ipvsadm.8
@@ -59,7 +59,7 @@ ipvsadm \- Linux Virtual Server administration
.br
.B ipvsadm --set \fItcp\fP \fItcpfin\fP \fIudp\fP
.br
-.B ipvsadm --start-daemon \fIstate\fP [--mcast-interface \fIinterface\fP]
+.B ipvsadm --start-daemon \fIstate\fP [daemon-options]
.ti 15
.B [--syncid \fIsyncid\fP]
.br
@@ -167,7 +167,7 @@ balancer fails, a backup load balancer will takeover, and
it has state
of almost all connections, so that almost all established connections
can continue to access the service.
.PP
-The sync daemon currently only supports IPv4 connections.
+The sync daemon supports IPv4 and IPv6 connections.
.TP
.B --stop-daemon
Stop the connection synchronization daemon.
@@ -359,18 +359,6 @@ connections drops below its lower connection threshold. If
will receive new connections when the number of its connections drops
below three forth of its upper connection threshold.
.TP
-.B --mcast-interface \fIinterface\fP
-Specify the multicast interface that the sync master daemon sends
-outgoing multicasts through, or the sync backup daemon listens to for
-multicasts.
-.TP
-.B --syncid \fIsyncid\fP
-Specify the \fIsyncid\fP that the sync master daemon fills in the
-SyncID header while sending multicast messages, or the sync backup
-daemon uses to filter out multicast messages not matched with the
-SyncID value. The valid values of \fIsyncid\fP are 0 through to
-255. The default is 0, which means no filtering at all.
-.TP
.B -c, --connection
Connection output. The \fIlist\fP command with this option will list
current IPVS connections.
@@ -438,6 +426,45 @@ One-packet scheduling.
Used in conjunction with a UDP virtual service or
a fwmark virtual service that handles only UDP packets.
All connections are created such that they only schedule one packet.
+.SS PARAMETERS FOR SYNCHRONIZATION DAEMON
+The --start-daemon requires zero or more of the following
+parameters.
+.TP
+.B --syncid \fIsyncid\fP
+Specify the \fIsyncid\fP that the sync master daemon fills in the
+SyncID header while sending multicast messages, or the sync backup
+daemon uses to filter out multicast messages not matched with the
+SyncID value. The valid values of \fIsyncid\fP are 0 through to
+255. The default is 0, which means no filtering at all.
+.TP
+.B --sync-maxlen \fIlength\fP
+Specify the desired length of sync messages (UDP payload size).
+It is expected that backup server will use value not less than
+the used value in master server.
+The valid values of \fIlength\fP are in the 1 .. (65535 - 20 - 8)
+range but the kernel ensures a space for at least one sync message.
+If value is lower than MTU the sync messages will be fragmented by
+IP layer.
+The default value is derived from the MTU value when daemon is started
+but master daemon will not default to value above 1500 for compatibility
+reasons.
+.TP
+.B --mcast-interface \fIinterface\fP
+Specify the multicast interface that the sync master daemon sends
+outgoing multicasts through, or the sync backup daemon listens to for
+multicasts.
+.TP
+.B --mcast-group \fIaddress\fP
+Specify IPv4 or IPv6 multicast address for the sync messages.
+The default value is 224.0.0.81.
+.TP
+.B --mcast-port \fIport\fP
+Specify the UDP port for sync messages.
+The default value is 8848.
+.TP
+.B --mcast-ttl \fIttl\fP
+Specify the TTL value for sync messages (1 .. 255).
+The default value is 1.
.SH EXAMPLE 1 - Simple Virtual Service
The following commands configure a Linux Director to distribute
incoming requests addressed to port 80 on 207.175.44.110 equally to
diff --git a/ipvsadm.c b/ipvsadm.c
index ff1601e..4d1e86e 100644
--- a/ipvsadm.c
+++ b/ipvsadm.c
@@ -183,7 +183,11 @@ static const char* cmdnames[] = {
#define OPT_ONEPACKET 0x200000
#define OPT_PERSISTENCE_ENGINE 0x400000
#define OPT_SCHED_FLAGS 0x800000
-#define NUMBER_OF_OPT 24
+#define OPT_MCAST_GROUP 0x01000000
+#define OPT_MCAST_PORT 0x02000000
+#define OPT_MCAST_TTL 0x04000000
+#define OPT_SYNC_MAXLEN 0x08000000
+#define NUMBER_OF_OPT 28
static const char* optnames[] = {
"numeric",
@@ -210,6 +214,10 @@ static const char* optnames[] = {
"ops",
"pe",
"sched-flags",
+ "mcast-group",
+ "mcast-port",
+ "mcast-ttl",
+ "sync-maxlen",
};
/*
@@ -222,21 +230,21 @@ static const char* optnames[] = {
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
{
- /* -n -c svc -s -p -M -r fwd -w -x -y -mc tot
dmn -st -rt thr -pc srt sid -ex ops -pe -b */
-/*ADD*/ {'x', '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', 'x', ' ', ' ', ' '},
-/*DEL*/ {'x', 'x', '+', 'x', 'x', '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', 'x', 'x', 'x', 'x'},
-/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1',
'1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 'x'},
-/*ADDSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*DELSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
-/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', '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', 'x', 'x', 'x', 'x'},
-/*STARTD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x',
'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x'},
-/*STOPD*/ {'x', 'x', 'x', 'x', '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', 'x', 'x', 'x', 'x'},
-/*SAVE*/ {' ', 'x', 'x', 'x', 'x', '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', 'x', 'x', 'x', 'x'},
+ /* -n -c svc -s -p -M -r fwd -w -x -y -mc tot
dmn -st -rt thr -pc srt sid -ex ops -pe -b grp port ttl size */
+/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', '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', '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', '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', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1',
'1', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*ADDSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*DELSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDITSRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', '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', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*STARTD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x',
'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x', ' ', ' ', ' ', ' '},
+/*STOPD*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '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', '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', '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', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
};
/* printing format flags */
@@ -288,6 +296,10 @@ enum {
TAG_NO_SORT,
TAG_PERSISTENCE_ENGINE,
TAG_SCTP_SERVICE,
+ TAG_MCAST_GROUP,
+ TAG_MCAST_PORT,
+ TAG_MCAST_TTL,
+ TAG_SYNC_MAXLEN,
};
/* various parsing helpers & parsing functions */
@@ -475,6 +487,14 @@ parse_options(int argc, char **argv, struct
ipvs_command_entry *ce,
NULL, NULL },
{ "sched-flags", 'b', POPT_ARG_STRING, &optarg, 'b',
NULL, NULL },
+ { "mcast-group", '\0', POPT_ARG_STRING, &optarg,
+ TAG_MCAST_GROUP, NULL, NULL },
+ { "mcast-port", '\0', POPT_ARG_STRING, &optarg,
+ TAG_MCAST_PORT, NULL, NULL },
+ { "mcast-ttl", '\0', POPT_ARG_STRING, &optarg,
+ TAG_MCAST_TTL, NULL, NULL },
+ { "sync-maxlen", '\0', POPT_ARG_STRING, &optarg,
+ TAG_SYNC_MAXLEN, NULL, NULL },
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
@@ -712,6 +732,47 @@ parse_options(int argc, char **argv, struct
ipvs_command_entry *ce,
snprintf(sched_flags_arg, sizeof(sched_flags_arg),
"%s", optarg);
break;
+ case TAG_MCAST_GROUP:
+ set_option(options, OPT_MCAST_GROUP);
+ if (strchr(optarg, ':')) {
+ if (inet_pton(AF_INET6, optarg,
+ &ce->daemon.mcast_group) <= 0 ||
+ !IN6_IS_ADDR_MULTICAST(
+ &ce->daemon.mcast_group.in6))
+ fail(2, "invalid IPv6 mcast-group `%s'",
+ optarg);
+ ce->daemon.mcast_af = AF_INET6;
+ } else {
+ if (inet_pton(AF_INET, optarg,
+ &ce->daemon.mcast_group) <= 0 ||
+ !IN_MULTICAST(ntohl(
+ ce->daemon.mcast_group.ip)))
+ fail(2, "invalid IPv4 mcast-group `%s'",
+ optarg);
+ ce->daemon.mcast_af = AF_INET;
+ }
+ break;
+ case TAG_MCAST_PORT:
+ set_option(options, OPT_MCAST_PORT);
+ parse = string_to_number(optarg, 1, 65535);
+ if (parse == -1)
+ fail(2, "illegal mcast-port specified");
+ ce->daemon.mcast_port = parse;
+ break;
+ case TAG_MCAST_TTL:
+ set_option(options, OPT_MCAST_TTL);
+ parse = string_to_number(optarg, 1, 255);
+ if (parse == -1)
+ fail(2, "illegal mcast-ttl specified");
+ ce->daemon.mcast_ttl = parse;
+ break;
+ case TAG_SYNC_MAXLEN:
+ set_option(options, OPT_SYNC_MAXLEN);
+ parse = string_to_number(optarg, 1, 65535 - 20 - 8);
+ if (parse == -1)
+ fail(2, "illegal sync-maxlen specified");
+ ce->daemon.sync_maxlen = parse;
+ break;
default:
fail(2, "invalid option `%s'",
poptBadOption(context, POPT_BADOPTION_NOALIAS));
@@ -1182,8 +1243,8 @@ static void usage_exit(const char *program, const int
exit_status)
" %s -L|l [virtual-service] [options]\n"
" %s -Z [virtual-service]\n"
" %s --set tcp tcpfin udp\n"
- " %s --start-daemon state [--mcast-interface interface]
[--syncid sid]\n"
- " %s --stop-daemon state\n"
+ " %s --start-daemon {master|backup} [daemon-options]\n"
+ " %s --stop-daemon {master|backup}\n"
" %s -h\n\n",
program, program, program,
program, program, program, program, program,
@@ -1233,8 +1294,6 @@ static void usage_exit(const char *program, const int
exit_status)
" --weight -w weight capacity of real
server\n"
" --u-threshold -x uthreshold upper threshold of
connections\n"
" --l-threshold -y lthreshold lower threshold of
connections\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"
" --timeout output of timeout (tcp
tcpfin udp)\n"
" --daemon output of daemon
information\n"
@@ -1250,6 +1309,16 @@ static void usage_exit(const char *program, const int
exit_status)
" --sched-flags -b flags scheduler flags
(comma-separated)\n",
DEF_SCHED);
+ fprintf(stream,
+ "Daemon Options:\n"
+ " --syncid sid syncid for connection
sync (default=255)\n"
+ " --sync-maxlen length Max sync message length
(default=1472)\n"
+ " --mcast-interface interface multicast interface for
connection sync\n"
+ " --mcast-group address IPv4/IPv6 group
(default=224.0.0.81)\n"
+ " --mcast-port port UDP port
(default=8848)\n"
+ " --mcast-ttl ttl Multicast TTL
(default=1)\n"
+ );
+
exit(exit_status);
}
@@ -1793,12 +1862,30 @@ static void list_daemon(void)
exit(1);
for (i = 0; i < 2; i++) {
+ char *type;
+
if (u[i].state & IP_VS_STATE_MASTER)
- printf("master sync daemon (mcast=%s, syncid=%d)\n",
- u[i].mcast_ifn, u[i].syncid);
- if (u[i].state & IP_VS_STATE_BACKUP)
- printf("backup sync daemon (mcast=%s, syncid=%d)\n",
- u[i].mcast_ifn, u[i].syncid);
+ type = "master";
+ else if (u[i].state & IP_VS_STATE_BACKUP)
+ type = "backup";
+ else
+ continue;
+ printf("%s sync daemon (mcast=%s, syncid=%d",
+ type, u[i].mcast_ifn, u[i].syncid);
+ if (u[i].sync_maxlen)
+ printf(", maxlen=%u", u[i].sync_maxlen);
+ if (u[i].mcast_af != AF_UNSPEC) {
+ char addr[INET6_ADDRSTRLEN];
+
+ if (inet_ntop(u[i].mcast_af, &u[i].mcast_group,
+ addr, sizeof(addr)))
+ printf(", group=%s", addr);
+ }
+ if (u[i].mcast_port)
+ printf(", port=%u", u[i].mcast_port);
+ if (u[i].mcast_ttl)
+ printf(", ttl=%u", u[i].mcast_ttl);
+ printf(")\n");
}
free(u);
}
diff --git a/libipvs/ip_vs.h b/libipvs/ip_vs.h
index 5a42a0c..f855cc6 100644
--- a/libipvs/ip_vs.h
+++ b/libipvs/ip_vs.h
@@ -348,6 +348,17 @@ struct ip_vs_timeout_user {
/* The argument to IP_VS_SO_GET_DAEMON */
+struct ip_vs_daemon_kern {
+ /* sync daemon state (master/backup) */
+ int state;
+
+ /* multicast interface name */
+ char mcast_ifn[IP_VS_IFNAME_MAXLEN];
+
+ /* SyncID we belong to */
+ int syncid;
+};
+
struct ip_vs_daemon_user {
/* sync daemon state (master/backup) */
int state;
@@ -357,6 +368,21 @@ struct ip_vs_daemon_user {
/* SyncID we belong to */
int syncid;
+
+ /* UDP Payload Size */
+ int sync_maxlen;
+
+ /* Multicast Port (base) */
+ u_int16_t mcast_port;
+
+ /* Multicast TTL */
+ u_int16_t mcast_ttl;
+
+ /* Multicast Address Family */
+ u_int16_t mcast_af;
+
+ /* Multicast Address */
+ union nf_inet_addr mcast_group;
};
@@ -488,6 +514,11 @@ enum {
IPVS_DAEMON_ATTR_STATE, /* sync daemon state (master/backup) */
IPVS_DAEMON_ATTR_MCAST_IFN, /* multicast interface name */
IPVS_DAEMON_ATTR_SYNC_ID, /* SyncID we belong to */
+ IPVS_DAEMON_ATTR_SYNC_MAXLEN, /* UDP Payload Size */
+ IPVS_DAEMON_ATTR_MCAST_GROUP, /* IPv4 Multicast Address */
+ IPVS_DAEMON_ATTR_MCAST_GROUP6, /* IPv6 Multicast Address */
+ IPVS_DAEMON_ATTR_MCAST_PORT, /* Multicast Port (base) */
+ IPVS_DAEMON_ATTR_MCAST_TTL, /* Multicast TTL */
__IPVS_DAEMON_ATTR_MAX,
};
diff --git a/libipvs/ip_vs_nl_policy.c b/libipvs/ip_vs_nl_policy.c
index c80083e..2d65224 100644
--- a/libipvs/ip_vs_nl_policy.c
+++ b/libipvs/ip_vs_nl_policy.c
@@ -65,6 +65,12 @@ struct nla_policy ipvs_daemon_policy[IPVS_DAEMON_ATTR_MAX +
1] = {
[IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_STRING,
.maxlen = IP_VS_IFNAME_MAXLEN },
[IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 },
+ [IPVS_DAEMON_ATTR_SYNC_MAXLEN] = { .type = NLA_U16 },
+ [IPVS_DAEMON_ATTR_MCAST_GROUP] = { .type = NLA_U32 },
+ [IPVS_DAEMON_ATTR_MCAST_GROUP6] = { .type = NLA_UNSPEC,
+ .maxlen = sizeof(struct in6_addr) },
+ [IPVS_DAEMON_ATTR_MCAST_PORT] = { .type = NLA_U16 },
+ [IPVS_DAEMON_ATTR_MCAST_TTL] = { .type = NLA_U8 },
};
#endif /* LIBIPVS_USE_NL */
diff --git a/libipvs/libipvs.c b/libipvs/libipvs.c
index 0bfb428..614001d 100644
--- a/libipvs/libipvs.c
+++ b/libipvs/libipvs.c
@@ -485,6 +485,8 @@ nla_put_failure:
int ipvs_start_daemon(ipvs_daemon_t *dm)
{
+ struct ip_vs_daemon_kern dmk;
+
ipvs_func = ipvs_start_daemon;
#ifdef LIBIPVS_USE_NL
if (try_nl) {
@@ -499,6 +501,22 @@ int ipvs_start_daemon(ipvs_daemon_t *dm)
NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_STATE, dm->state);
NLA_PUT_STRING(msg, IPVS_DAEMON_ATTR_MCAST_IFN, dm->mcast_ifn);
NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_SYNC_ID, dm->syncid);
+ if (dm->sync_maxlen)
+ NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_SYNC_MAXLEN,
+ dm->sync_maxlen);
+ if (dm->mcast_port)
+ NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_MCAST_PORT,
+ dm->mcast_port);
+ if (dm->mcast_ttl)
+ NLA_PUT_U8(msg, IPVS_DAEMON_ATTR_MCAST_TTL,
+ dm->mcast_ttl);
+ if (AF_INET6 == dm->mcast_af)
+ NLA_PUT(msg, IPVS_DAEMON_ATTR_MCAST_GROUP6,
+ sizeof(dm->mcast_group.in6),
+ &dm->mcast_group.in6);
+ else if (AF_INET == dm->mcast_af)
+ NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_MCAST_GROUP,
+ dm->mcast_group.ip);
nla_nest_end(msg, nl_daemon);
@@ -509,13 +527,19 @@ nla_put_failure:
return -1;
}
#endif
+ memset(&dmk, 0, sizeof(dmk));
+ dmk.state = dm->state;
+ strcpy(dmk.mcast_ifn, dm->mcast_ifn);
+ dmk.syncid = dm->syncid;
return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STARTDAEMON,
- (char *)dm, sizeof(*dm));
+ (char *)&dmk, sizeof(dmk));
}
int ipvs_stop_daemon(ipvs_daemon_t *dm)
{
+ struct ip_vs_daemon_kern dmk;
+
ipvs_func = ipvs_stop_daemon;
#ifdef LIBIPVS_USE_NL
if (try_nl) {
@@ -540,8 +564,10 @@ nla_put_failure:
return -1;
}
#endif
+ memset(&dmk, 0, sizeof(dmk));
+ dmk.state = dm->state;
return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STOPDAEMON,
- (char *)dm, sizeof(*dm));
+ (char *)&dmk, sizeof(dmk));
}
#ifdef LIBIPVS_USE_NL
@@ -1065,6 +1091,7 @@ static int ipvs_daemon_parse_cb(struct nl_msg *msg, void
*arg)
struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1];
struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1];
ipvs_daemon_t *u = (ipvs_daemon_t *)arg;
+ struct nlattr *a;
int i = 0;
/* We may get two daemons. If we've already got one, this is the
second */
@@ -1089,26 +1116,54 @@ static int ipvs_daemon_parse_cb(struct nl_msg *msg,
void *arg)
IP_VS_IFNAME_MAXLEN);
u[i].syncid = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID]);
+ a = daemon_attrs[IPVS_DAEMON_ATTR_SYNC_MAXLEN];
+ if (a)
+ u[i].sync_maxlen = nla_get_u16(a);
+
+ a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_PORT];
+ if (a)
+ u[i].mcast_port = nla_get_u16(a);
+
+ a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_TTL];
+ if (a)
+ u[i].mcast_ttl = nla_get_u8(a);
+
+ a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_GROUP];
+ if (a) {
+ u[i].mcast_af = AF_INET;
+ u[i].mcast_group.ip = nla_get_u32(a);
+ } else {
+ a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_GROUP6];
+ if (a) {
+ u[i].mcast_af = AF_INET6;
+ memcpy(&u[i].mcast_group.in6, nla_data(a),
+ sizeof(u[i].mcast_group.in6));
+ }
+ }
+
return NL_OK;
}
#endif
ipvs_daemon_t *ipvs_get_daemon(void)
{
+ struct ip_vs_daemon_kern dmk[2];
ipvs_daemon_t *u;
socklen_t len;
+ int i;
/* note that we need to get the info about two possible
daemons, master and backup. */
len = sizeof(*u) * 2;
- if (!(u = malloc(len)))
+ u = calloc(len, 1);
+ if (!u)
return NULL;
ipvs_func = ipvs_get_daemon;
#ifdef LIBIPVS_USE_NL
if (try_nl) {
struct nl_msg *msg;
- memset(u, 0, len);
+
msg = ipvs_nl_message(IPVS_CMD_GET_DAEMON, NLM_F_DUMP);
if (msg && (ipvs_nl_send_message(msg, ipvs_daemon_parse_cb, u)
== 0))
return u;
@@ -1117,10 +1172,16 @@ ipvs_daemon_t *ipvs_get_daemon(void)
return NULL;
}
#endif
- if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DAEMON, (char *)u,
&len)) {
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DAEMON, (char *)dmk,
+ &len)) {
free(u);
return NULL;
}
+ for (i = 0; i < 2; i++) {
+ u[i].state = dmk[i].state;
+ strncpy(u[i].mcast_ifn, dmk[i].mcast_ifn, IP_VS_IFNAME_MAXLEN);
+ u[i].syncid = dmk[i].syncid;
+ }
return u;
}
--
1.9.3
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|