LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH] ipvsadm: add SCTP support

To: Jesper Dangaard Brouer <brouer@xxxxxxxxxx>
Subject: [PATCH] ipvsadm: add SCTP support
Cc: Simon Horman <horms@xxxxxxxxxxxx>, lvs-devel@xxxxxxxxxxxxxxx, lvs-users@xxxxxxxxxxxxxxxxxxxxxx, overcastsky.zhao@xxxxxxxxx
From: Julian Anastasov <ja@xxxxxx>
Date: Sat, 31 Jan 2015 10:41:08 +0200
SCTP support in kernel is from 2.6.34 but ipvsadm
restricts users to fwmark-based virtual services.

* 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 <ja@xxxxxx>
---
 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

--
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

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] ipvsadm: add SCTP support, Julian Anastasov <=