On Sat, Jan 31, 2015 at 10:41:08AM +0200, Julian Anastasov wrote: > SCTP support in kernel is from 2.6.34 but ipvsadm > restricts users to fwmark-based virtual services.
Better late than never :) > * Add option --sctp-service to specify the virtual service > > * Update man page to use virtual-service and the new option > > Signed-off-by: Julian Anastasov <j...@ssi.bg> Acked-by: Simon Horman <ho...@verge.net.au> > --- > ipvsadm.8 | 30 +++++++++++-------- > ipvsadm.c | 100 > +++++++++++++++++++++++++++++++++++++++++++++++++------------- > 2 files changed, 98 insertions(+), 32 deletions(-) > > diff --git a/ipvsadm.8 b/ipvsadm.8 > index 9a9e9b3..3df3b83 100644 > --- a/ipvsadm.8 > +++ b/ipvsadm.8 > @@ -35,11 +35,11 @@ > .SH NAME > ipvsadm \- Linux Virtual Server administration > .SH SYNOPSIS > -.B ipvsadm -A|E -t|u|f \fIservice-address\fP [-s \fIscheduler\fP] > +.B ipvsadm -A|E \fIvirtual-service\fP [-s \fIscheduler\fP] > .ti 15 > .B [-p [\fItimeout\fP]] [-M \fInetmask\fP] [-b \fIsched-flags\fP] > .br > -.B ipvsadm -D -t|u|f \fIservice-address\fP > +.B ipvsadm -D \fIvirtual-service\fP > .br > .B ipvsadm -C > .br > @@ -47,15 +47,15 @@ ipvsadm \- Linux Virtual Server administration > .br > .B ipvsadm -S [-n] > .br > -.B ipvsadm -a|e -t|u|f \fIservice-address\fP -r \fIserver-address\fP > +.B ipvsadm -a|e \fIvirtual-service\fP -r \fIserver-address\fP > .ti 15 > .B [-g|i|m] [-w \fIweight\fP] [-x \fIupper\fP] [-y \fIlower\fP] > .br > -.B ipvsadm -d -t|u|f \fIservice-address\fP -r \fIserver-address\fP > +.B ipvsadm -d \fIvirtual-service\fP -r \fIserver-address\fP > .br > -.B ipvsadm -L|l [options] > +.B ipvsadm -L|l [\fIvirtual-service\fP] [options] > .br > -.B ipvsadm -Z [-t|u|f \fIservice-address\fP] > +.B ipvsadm -Z [\fIvirtual-service\fP] > .br > .B ipvsadm --set \fItcp\fP \fItcpfin\fP \fIudp\fP > .br > @@ -72,7 +72,7 @@ server table in the Linux kernel. The Linux Virtual Server > can be used > to build scalable network services based on a cluster of two or more > nodes. The active node of the cluster redirects service requests to a > collection of server hosts that will actually perform the > -services. Supported features include two protocols (TCP and UDP), > +services. Supported features include three protocols (TCP, UDP and SCTP), > three packet-forwarding methods (NAT, tunneling, and direct routing), > and eight load balancing algorithms (round robin, weighted round > robin, least-connection, weighted least-connection, locality-based > @@ -81,11 +81,11 @@ destination-hashing, and source-hashing). > .PP > The command has two basic formats for execution: > .TP > -.B ipvsadm \fICOMMAND\fP [\fIprotocol\fP] \fIservice-address\fP > +.B ipvsadm \fICOMMAND\fP \fIvirtual-service\fP > .ti 15 > .B [\fIscheduling-method\fP] [\fIpersistence options\fP] > .TP > -.B ipvsadm \fIcommand\fP [\fIprotocol\fP] \fIservice-address\fP > +.B ipvsadm \fIcommand\fP \fIvirtual-service\fP > .ti 15 > .B \fIserver-address\fP [\fIpacket-forwarding-method\fP] > .ti 15 > @@ -174,9 +174,8 @@ Stop the connection synchronization daemon. > .TP > \fB-h, --help\fR > Display a description of the command syntax. > -.SS PARAMETERS > -The commands above accept or require zero or more of the following > -parameters. > +.SS virtual-service > +Specifies the virtual service based on protocol/addr/port or firewall mark. > .TP > .B -t, --tcp-service \fIservice-address\fP > Use TCP service. The \fIservice-address\fP is of the form > @@ -191,6 +190,10 @@ wild-card port, that is connections will be accepted to > any port. > Use UDP service. See the -t|--tcp-service for the description of the > \fIservice-address\fP. > .TP > +.B --sctp-service \fIservice-address\fP > +Use SCTP service. See the -t|--tcp-service for the description of the > +\fIservice-address\fP. > +.TP > .B -f, --fwmark-service \fIinteger\fP > Use a firewall-mark, an integer value greater than zero, to denote a > virtual service instead of an address, port and protocol (UDP or > @@ -206,6 +209,9 @@ single virtual service. This is useful for both > simplifying > configuration if a large number of virtual services are required and > grouping persistence across what would otherwise be multiple virtual > services. > +.SS PARAMETERS > +The commands above accept or require zero or more of the following > +parameters. > .TP > .B -s, --scheduler \fIscheduling-method\fP > \fIscheduling-method\fP Algorithm for allocating TCP connections and > diff --git a/ipvsadm.c b/ipvsadm.c > index a33ecfa..1669634 100644 > --- a/ipvsadm.c > +++ b/ipvsadm.c > @@ -287,6 +287,7 @@ enum { > TAG_SORT, > TAG_NO_SORT, > TAG_PERSISTENCE_ENGINE, > + TAG_SCTP_SERVICE, > }; > > /* various parsing helpers & parsing functions */ > @@ -359,6 +360,47 @@ int main(int argc, char **argv) > return result; > } > > +static int option_to_protocol(int opt) > +{ > + switch (opt) { > + case 't': > + return IPPROTO_TCP; > + case 'u': > + return IPPROTO_UDP; > + case TAG_SCTP_SERVICE: > + return IPPROTO_SCTP; > + default: > + return IPPROTO_IP; > + } > +} > + > +static char *option_from_protocol(int proto) > +{ > + switch (proto) { > + case IPPROTO_TCP: > + return "-t"; > + case IPPROTO_UDP: > + return "-u"; > + case IPPROTO_SCTP: > + return "--sctp-service"; > + default: > + return NULL; > + } > +} > + > +static char *protocol_name(int proto) > +{ > + switch (proto) { > + case IPPROTO_TCP: > + return "TCP"; > + case IPPROTO_UDP: > + return "UDP"; > + case IPPROTO_SCTP: > + return "SCTP"; > + default: > + return "?"; > + } > +} > > static int > parse_options(int argc, char **argv, struct ipvs_command_entry *ce, > @@ -391,6 +433,8 @@ parse_options(int argc, char **argv, struct > ipvs_command_entry *ce, > NULL, NULL }, > { "udp-service", 'u', POPT_ARG_STRING, &optarg, 'u', > NULL, NULL }, > + { "sctp-service", '\0', POPT_ARG_STRING, &optarg, > + TAG_SCTP_SERVICE, NULL, NULL }, > { "fwmark-service", 'f', POPT_ARG_STRING, &optarg, 'f', > NULL, NULL }, > { "scheduler", 's', POPT_ARG_STRING, &optarg, 's', NULL, NULL }, > @@ -510,9 +554,9 @@ parse_options(int argc, char **argv, struct > ipvs_command_entry *ce, > switch (c) { > case 't': > case 'u': > + case TAG_SCTP_SERVICE: > set_option(options, OPT_SERVICE); > - ce->svc.protocol = > - (c=='t' ? IPPROTO_TCP : IPPROTO_UDP); > + ce->svc.protocol = option_to_protocol(c); > parse = parse_service(optarg, &ce->svc); > if (!(parse & SERVICE_ADDR)) > fail(2, "illegal virtual server " > @@ -1128,15 +1172,15 @@ static void usage_exit(const char *program, const int > exit_status) > version(stream); > fprintf(stream, > "Usage:\n" > - " %s -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] > [-M netmask] [--pe persistence_engine] [-b sched-flags]\n" > - " %s -D -t|u|f service-address\n" > + " %s -A|E virtual-service [-s scheduler] [-p [timeout]] [-M > netmask] [--pe persistence_engine] [-b sched-flags]\n" > + " %s -D virtual-service\n" > " %s -C\n" > " %s -R\n" > " %s -S [-n]\n" > - " %s -a|e -t|u|f service-address -r server-address [options]\n" > - " %s -d -t|u|f service-address -r server-address\n" > - " %s -L|l [options]\n" > - " %s -Z [-t|u|f service-address]\n" > + " %s -a|e virtual-service -r server-address [options]\n" > + " %s -d virtual-service -r server-address\n" > + " %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" > @@ -1166,10 +1210,15 @@ static void usage_exit(const char *program, const int > exit_status) > ); > > fprintf(stream, > + "virtual-service:\n" > + " --tcp-service|-t service-address service-address is > host[:port]\n" > + " --udp-service|-u service-address service-address is > host[:port]\n" > + " --sctp-service service-address service-address is > host[:port]\n" > + " --fwmark-service|-f fwmark fwmark is an integer > greater than zero\n" > + "\n"); > + > + fprintf(stream, > "Options:\n" > - " --tcp-service -t service-address service-address is > host[:port]\n" > - " --udp-service -u service-address service-address is > host[:port]\n" > - " --fwmark-service -f fwmark fwmark is an integer > greater than zero\n" > " --ipv6 -6 fwmark entry uses IPv6\n" > " --scheduler -s scheduler one of " SCHEDULERS ",\n" > " the default scheduler is > %s.\n" > @@ -1316,6 +1365,8 @@ static void print_conn(char *buf, unsigned int format) > proto = IPPROTO_TCP; > else if (strcmp(protocol, "UDP") == 0) > proto = IPPROTO_UDP; > + else if (strcmp(protocol, "SCTP") == 0) > + proto = IPPROTO_SCTP; > else > proto = 0; > > @@ -1518,7 +1569,7 @@ static void > print_service_entry(ipvs_service_entry_t *se, unsigned int format) > { > struct ip_vs_get_dests *d; > - char svc_name[64]; > + char svc_name[1024]; > int i; > > if (!(d = ipvs_get_dests(se))) { > @@ -1543,14 +1594,17 @@ print_service_entry(ipvs_service_entry_t *se, > unsigned int format) > if (!(vname = addrport_to_anyname(se->af, &se->addr, > ntohs(se->port), > se->protocol, format))) > fail(2, "addrport_to_anyname: %s", strerror(errno)); > - if (format & FMT_RULE) > - sprintf(svc_name, "%s %s", > - se->protocol==IPPROTO_TCP?"-t":"-u", > - vname); > - else { > - sprintf(svc_name, "%s %s", > - se->protocol==IPPROTO_TCP?"TCP":"UDP", > - vname); > + if (format & FMT_RULE) { > + char *stype = option_from_protocol(se->protocol) ? : > + "--xxx-service"; > + > + snprintf(svc_name, sizeof(svc_name), "%s %s", > + stype, vname); > + } else { > + char *stype = protocol_name(se->protocol); > + > + snprintf(svc_name, sizeof(svc_name), "%-4s %s", > + stype, vname); > if (se->af != AF_INET6) > svc_name[33] = '\0'; > } > @@ -1806,6 +1860,9 @@ int service_to_port(const char *name, unsigned short > proto) > else if (proto == IPPROTO_UDP > && (service = getservbyname(name, "udp")) != NULL) > return ntohs((unsigned short) service->s_port); > + else if (proto == IPPROTO_SCTP > + && (service = getservbyname(name, "sctp")) != NULL) > + return ntohs((unsigned short) service->s_port); > else > return -1; > } > @@ -1821,6 +1878,9 @@ static char * port_to_service(unsigned short port, > unsigned short proto) > else if (proto == IPPROTO_UDP && > (service = getservbyport(htons(port), "udp")) != NULL) > return service->s_name; > + else if (proto == IPPROTO_SCTP && > + (service = getservbyport(htons(port), "sctp")) != NULL) > + return service->s_name; > else > return (char *) NULL; > } > -- > 1.9.3 > _______________________________________________ Please read the documentation before posting - it's available at: http://www.linuxvirtualserver.org/ LinuxVirtualServer.org mailing list - lvs-users@LinuxVirtualServer.org Send requests to lvs-users-requ...@linuxvirtualserver.org or go to http://lists.graemef.net/mailman/listinfo/lvs-users