Author: rscheff
Date: Sun Oct 11 13:39:04 2020
New Revision: 366627
URL: https://svnweb.freebsd.org/changeset/base/366627

Log:
  MFC r366206: 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).
  
  Reviewed by:  mav, trasz
  MFC after:    2 weeks
  Sponsored by: NetApp, Inc.
  Differential Revision:        https://reviews.freebsd.org/D26385

Modified:
  stable/12/usr.sbin/ctld/ctl.conf.5
  stable/12/usr.sbin/ctld/ctld.c
  stable/12/usr.sbin/ctld/ctld.h
  stable/12/usr.sbin/ctld/parse.y
  stable/12/usr.sbin/ctld/token.l
  stable/12/usr.sbin/ctld/uclparse.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/usr.sbin/ctld/ctl.conf.5
==============================================================================
--- stable/12/usr.sbin/ctld/ctl.conf.5  Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/ctl.conf.5  Sun Oct 11 13:39:04 2020        
(r366627)
@@ -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: stable/12/usr.sbin/ctld/ctld.c
==============================================================================
--- stable/12/usr.sbin/ctld/ctld.c      Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/ctld.c      Sun Oct 11 13:39:04 2020        
(r366627)
@@ -624,6 +624,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);
@@ -2179,6 +2180,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: stable/12/usr.sbin/ctld/ctld.h
==============================================================================
--- stable/12/usr.sbin/ctld/ctld.h      Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/ctld.h      Sun Oct 11 13:39:04 2020        
(r366627)
@@ -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: stable/12/usr.sbin/ctld/parse.y
==============================================================================
--- stable/12/usr.sbin/ctld/parse.y     Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/parse.y     Sun Oct 11 13:39:04 2020        
(r366627)
@@ -41,6 +41,8 @@
 #include <string.h>
 
 #include "ctld.h"
+#include <netinet/in.h>
+#include <netinet/ip.h>
 
 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: stable/12/usr.sbin/ctld/token.l
==============================================================================
--- stable/12/usr.sbin/ctld/token.l     Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/token.l     Sun Oct 11 13:39:04 2020        
(r366627)
@@ -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: stable/12/usr.sbin/ctld/uclparse.c
==============================================================================
--- stable/12/usr.sbin/ctld/uclparse.c  Sun Oct 11 10:40:11 2020        
(r366626)
+++ stable/12/usr.sbin/ctld/uclparse.c  Sun Oct 11 13:39:04 2020        
(r366627)
@@ -39,6 +39,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ucl.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
 
 #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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to