From owner-svn-src-all@freebsd.org Sun Sep 27 21:43:21 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2F164372B14; Sun, 27 Sep 2020 21:43:21 +0000 (UTC) (envelope-from rscheff@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Bzzfd0TB8z4SDm; Sun, 27 Sep 2020 21:43:21 +0000 (UTC) (envelope-from rscheff@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E7C41136C0; Sun, 27 Sep 2020 21:43:20 +0000 (UTC) (envelope-from rscheff@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 08RLhKVL028903; Sun, 27 Sep 2020 21:43:20 GMT (envelope-from rscheff@FreeBSD.org) Received: (from rscheff@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 08RLhJs4028898; Sun, 27 Sep 2020 21:43:19 GMT (envelope-from rscheff@FreeBSD.org) Message-Id: <202009272143.08RLhJs4028898@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rscheff set sender to rscheff@FreeBSD.org using -f From: Richard Scheffenegger Date: Sun, 27 Sep 2020 21:43:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r366206 - head/usr.sbin/ctld X-SVN-Group: head X-SVN-Commit-Author: rscheff X-SVN-Commit-Paths: head/usr.sbin/ctld X-SVN-Commit-Revision: 366206 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Sep 2020 21:43:21 -0000 Author: rscheff Date: Sun Sep 27 21:43:19 2020 New Revision: 366206 URL: https://svnweb.freebsd.org/changeset/base/366206 Log: Add DSCP support for network QoS to iscsi target. In order to prioritize iSCSI traffic across a network, DSCP can be used. In order not to rely on "ipfw setdscp" or in-network reclassification, this adds the dscp value directly to the portal group (where TCP sessions are accepted). The incoming iSCSI session is first handled by ctld for any CHAP authentication and the socket is then handed off to the in-kernel iscsi driver without modification of the socket parameters. Simply setting up the socket in ctld is sufficient to keep sending outgoing iSCSI related traffic with the configured DSCP value. Reviewed by: mav, trasz MFC after: 2 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D26385 Modified: head/usr.sbin/ctld/ctl.conf.5 head/usr.sbin/ctld/ctld.c head/usr.sbin/ctld/ctld.h head/usr.sbin/ctld/parse.y head/usr.sbin/ctld/token.l head/usr.sbin/ctld/uclparse.c Modified: head/usr.sbin/ctld/ctl.conf.5 ============================================================================== --- head/usr.sbin/ctld/ctl.conf.5 Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/ctl.conf.5 Sun Sep 27 21:43:19 2020 (r366206) @@ -250,6 +250,14 @@ Specifies that this .Sy portal-group is listened by some other host. This host will announce it on discovery stage, but won't listen. +.It Ic dscp Ar value +The DiffServ Codepoint used for sending data. The DSCP can be +set to numeric, or hexadecimal values directly, as well as the +well-defined +.Qq Ar CSx +and +.Qq Ar AFxx +codepoints. .El .Ss target Context .Bl -tag -width indent Modified: head/usr.sbin/ctld/ctld.c ============================================================================== --- head/usr.sbin/ctld/ctld.c Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/ctld.c Sun Sep 27 21:43:19 2020 (r366206) @@ -625,6 +625,7 @@ portal_group_new(struct conf *conf, const char *name) TAILQ_INIT(&pg->pg_ports); pg->pg_conf = conf; pg->pg_tag = 0; /* Assigned later in conf_apply(). */ + pg->pg_dscp = -1; TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); return (pg); @@ -2180,6 +2181,32 @@ conf_apply(struct conf *oldconf, struct conf *newconf) newp->p_socket = 0; cumulated_error++; continue; + } + if (newpg->pg_dscp != -1) { + struct sockaddr sa; + int len = sizeof(sa); + getsockname(newp->p_socket, &sa, &len); + /* + * Only allow the 6-bit DSCP + * field to be modified + */ + int tos = newpg->pg_dscp << 2; + if (sa.sa_family == AF_INET) { + if (setsockopt(newp->p_socket, + IPPROTO_IP, IP_TOS, + &tos, sizeof(tos)) == -1) + log_warn("setsockopt(IP_TOS) " + "failed for %s", + newp->p_listen); + } else + if (sa.sa_family == AF_INET6) { + if (setsockopt(newp->p_socket, + IPPROTO_IPV6, IPV6_TCLASS, + &tos, sizeof(tos)) == -1) + log_warn("setsockopt(IPV6_TCLASS) " + "failed for %s", + newp->p_listen); + } } error = bind(newp->p_socket, newp->p_ai->ai_addr, newp->p_ai->ai_addrlen); Modified: head/usr.sbin/ctld/ctld.h ============================================================================== --- head/usr.sbin/ctld/ctld.h Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/ctld.h Sun Sep 27 21:43:19 2020 (r366206) @@ -127,6 +127,7 @@ struct portal_group { TAILQ_HEAD(, port) pg_ports; char *pg_offload; char *pg_redirection; + int pg_dscp; uint16_t pg_tag; }; Modified: head/usr.sbin/ctld/parse.y ============================================================================== --- head/usr.sbin/ctld/parse.y Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/parse.y Sun Sep 27 21:43:19 2020 (r366206) @@ -41,6 +41,8 @@ #include #include "ctld.h" +#include +#include extern FILE *yyin; extern char *yytext; @@ -60,11 +62,13 @@ extern void yyrestart(FILE *); %token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL %token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE -%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN +%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER DSCP FOREIGN %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT %token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION %token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR %token TAG TARGET TIMEOUT +%token AF11 AF12 AF13 AF21 AF22 AF23 AF31 AF32 AF33 AF41 AF42 AF43 +%token BE EF CS0 CS1 CS2 CS3 CS4 CS5 CS6 CS7 %union { @@ -353,6 +357,8 @@ portal_group_entry: portal_group_redirect | portal_group_tag + | + portal_group_dscp ; portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR @@ -462,6 +468,50 @@ portal_group_tag: TAG STR portal_group->pg_tag = tmp; } ; + +portal_group_dscp +: DSCP STR + { + uint64_t tmp; + + if (strcmp($2, "0x") == 0) { + tmp = strtol($2 + 2, NULL, 16); + } else if (expand_number($2, &tmp) != 0) { + yyerror("invalid numeric value"); + free($2); + return(1); + } + if (tmp >= 0x40) { + yyerror("invalid dscp value"); + return(1); + } + + portal_group->pg_dscp = tmp; + } +| DSCP BE { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; } +| DSCP EF { portal_group->pg_dscp = IPTOS_DSCP_EF >> 2 ; } +| DSCP CS0 { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; } +| DSCP CS1 { portal_group->pg_dscp = IPTOS_DSCP_CS1 >> 2 ; } +| DSCP CS2 { portal_group->pg_dscp = IPTOS_DSCP_CS2 >> 2 ; } +| DSCP CS3 { portal_group->pg_dscp = IPTOS_DSCP_CS3 >> 2 ; } +| DSCP CS4 { portal_group->pg_dscp = IPTOS_DSCP_CS4 >> 2 ; } +| DSCP CS5 { portal_group->pg_dscp = IPTOS_DSCP_CS5 >> 2 ; } +| DSCP CS6 { portal_group->pg_dscp = IPTOS_DSCP_CS6 >> 2 ; } +| DSCP CS7 { portal_group->pg_dscp = IPTOS_DSCP_CS7 >> 2 ; } +| DSCP AF11 { portal_group->pg_dscp = IPTOS_DSCP_AF11 >> 2 ; } +| DSCP AF12 { portal_group->pg_dscp = IPTOS_DSCP_AF12 >> 2 ; } +| DSCP AF13 { portal_group->pg_dscp = IPTOS_DSCP_AF13 >> 2 ; } +| DSCP AF21 { portal_group->pg_dscp = IPTOS_DSCP_AF21 >> 2 ; } +| DSCP AF22 { portal_group->pg_dscp = IPTOS_DSCP_AF22 >> 2 ; } +| DSCP AF23 { portal_group->pg_dscp = IPTOS_DSCP_AF23 >> 2 ; } +| DSCP AF31 { portal_group->pg_dscp = IPTOS_DSCP_AF31 >> 2 ; } +| DSCP AF32 { portal_group->pg_dscp = IPTOS_DSCP_AF32 >> 2 ; } +| DSCP AF33 { portal_group->pg_dscp = IPTOS_DSCP_AF33 >> 2 ; } +| DSCP AF41 { portal_group->pg_dscp = IPTOS_DSCP_AF41 >> 2 ; } +| DSCP AF42 { portal_group->pg_dscp = IPTOS_DSCP_AF42 >> 2 ; } +| DSCP AF43 { portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2 ; } + ; + lun: LUN lun_name OPENING_BRACKET lun_entries CLOSING_BRACKET Modified: head/usr.sbin/ctld/token.l ============================================================================== --- head/usr.sbin/ctld/token.l Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/token.l Sun Sep 27 21:43:19 2020 (r366206) @@ -63,6 +63,7 @@ device-id { return DEVICE_ID; } device-type { return DEVICE_TYPE; } discovery-auth-group { return DISCOVERY_AUTH_GROUP; } discovery-filter { return DISCOVERY_FILTER; } +dscp { return DSCP; } foreign { return FOREIGN; } initiator-name { return INITIATOR_NAME; } initiator-portal { return INITIATOR_PORTAL; } @@ -85,6 +86,28 @@ size { return SIZE; } tag { return TAG; } target { return TARGET; } timeout { return TIMEOUT; } +af11 { return AF11; } +af12 { return AF12; } +af13 { return AF13; } +af21 { return AF21; } +af22 { return AF22; } +af23 { return AF23; } +af31 { return AF31; } +af32 { return AF32; } +af33 { return AF33; } +af41 { return AF41; } +af42 { return AF42; } +af43 { return AF43; } +be { return CS0; } +ef { return EF; } +cs0 { return CS0; } +cs1 { return CS1; } +cs2 { return CS2; } +cs3 { return CS3; } +cs4 { return CS4; } +cs5 { return CS5; } +cs6 { return CS6; } +cs7 { return CS7; } \"[^"]+\" { yylval.str = strndup(yytext + 1, strlen(yytext) - 2); return STR; } [a-zA-Z0-9\.\-@_/\:\[\]]+ { yylval.str = strdup(yytext); return STR; } Modified: head/usr.sbin/ctld/uclparse.c ============================================================================== --- head/usr.sbin/ctld/uclparse.c Sun Sep 27 18:47:06 2020 (r366205) +++ head/usr.sbin/ctld/uclparse.c Sun Sep 27 21:43:19 2020 (r366206) @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "ctld.h" @@ -607,7 +609,70 @@ uclparse_portal_group(const char *name, const ucl_obje ucl_object_tostring_forced(tmp)); } } - } + + if (!strcmp(key, "dscp")) { + if ((obj->type != UCL_STRING) && (obj->type != UCL_INT)) { + log_warnx("\"dscp\" property of portal group " + "\"%s\" is not a string or integer", portal_group->pg_name); + return(1); + } + if (obj->type == UCL_INT) + portal_group->pg_dscp = ucl_object_toint(obj); + else { + key = ucl_object_tostring(obj); + if (strcmp(key, "0x") == 0) + portal_group->pg_dscp = strtol(key + 2, NULL, 16); + else if (strcmp(key, "be") || strcmp(key, "cs0")) + portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2; + else if (strcmp(key, "ef")) + portal_group->pg_dscp = IPTOS_DSCP_EF >> 2; + else if (strcmp(key, "cs0")) + portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2; + else if (strcmp(key, "cs1")) + portal_group->pg_dscp = IPTOS_DSCP_CS1 >> 2; + else if (strcmp(key, "cs2")) + portal_group->pg_dscp = IPTOS_DSCP_CS2 >> 2; + else if (strcmp(key, "cs3")) + portal_group->pg_dscp = IPTOS_DSCP_CS3 >> 2; + else if (strcmp(key, "cs4")) + portal_group->pg_dscp = IPTOS_DSCP_CS4 >> 2; + else if (strcmp(key, "cs5")) + portal_group->pg_dscp = IPTOS_DSCP_CS5 >> 2; + else if (strcmp(key, "cs6")) + portal_group->pg_dscp = IPTOS_DSCP_CS6 >> 2; + else if (strcmp(key, "cs7")) + portal_group->pg_dscp = IPTOS_DSCP_CS7 >> 2; + else if (strcmp(key, "af11")) + portal_group->pg_dscp = IPTOS_DSCP_AF11 >> 2; + else if (strcmp(key, "af12")) + portal_group->pg_dscp = IPTOS_DSCP_AF12 >> 2; + else if (strcmp(key, "af13")) + portal_group->pg_dscp = IPTOS_DSCP_AF13 >> 2; + else if (strcmp(key, "af21")) + portal_group->pg_dscp = IPTOS_DSCP_AF21 >> 2; + else if (strcmp(key, "af22")) + portal_group->pg_dscp = IPTOS_DSCP_AF22 >> 2; + else if (strcmp(key, "af23")) + portal_group->pg_dscp = IPTOS_DSCP_AF23 >> 2; + else if (strcmp(key, "af31")) + portal_group->pg_dscp = IPTOS_DSCP_AF31 >> 2; + else if (strcmp(key, "af32")) + portal_group->pg_dscp = IPTOS_DSCP_AF32 >> 2; + else if (strcmp(key, "af33")) + portal_group->pg_dscp = IPTOS_DSCP_AF33 >> 2; + else if (strcmp(key, "af41")) + portal_group->pg_dscp = IPTOS_DSCP_AF41 >> 2; + else if (strcmp(key, "af42")) + portal_group->pg_dscp = IPTOS_DSCP_AF42 >> 2; + else if (strcmp(key, "af43")) + portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2; + else { + log_warnx("\"dscp\" property value is not a supported textual value"); + return (1); + } + } + } + } return (0); }