diff --git a/sys/dev/iscsi/iscsi_ioctl.h b/sys/dev/iscsi/iscsi_ioctl.h index 334f14d4d1a3..ef31d31fe415 100644 --- a/sys/dev/iscsi/iscsi_ioctl.h +++ b/sys/dev/iscsi/iscsi_ioctl.h @@ -70,7 +70,8 @@ struct iscsi_session_conf { int isc_iser; char isc_offload[ISCSI_OFFLOAD_LEN]; int isc_enable; - int isc_spare[4]; + int isc_dscp; + int isc_spare[3]; }; /* diff --git a/usr.bin/iscsictl/Makefile b/usr.bin/iscsictl/Makefile index 7b04276c758e..ee70e519a8fb 100644 --- a/usr.bin/iscsictl/Makefile +++ b/usr.bin/iscsictl/Makefile @@ -7,7 +7,7 @@ CFLAGS+= -I${.CURDIR} CFLAGS+= -I${SRCTOP}/sys/dev/iscsi MAN= iscsi.conf.5 iscsictl.8 -LIBADD= xo +LIBADD= util xo YFLAGS+= -v LFLAGS+= -i diff --git a/usr.bin/iscsictl/iscsi.conf.5 b/usr.bin/iscsictl/iscsi.conf.5 index 6d80392fe3d8..f8b4bca4a4c9 100644 --- a/usr.bin/iscsictl/iscsi.conf.5 +++ b/usr.bin/iscsictl/iscsi.conf.5 @@ -145,6 +145,16 @@ for iSCSI over RDMA, or .Qq Ar iSCSI . Default is .Qq Ar iSCSI . +.It Cm dscp +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 cs +and +.Qq Ar af +codepoints. +Default is no specified dscp codepoint, which means the default +of the outgoing interface is used. .El .Sh FILES .Bl -tag -width indent diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c index c0859fcf9741..fa5754d3581f 100644 --- a/usr.bin/iscsictl/iscsictl.c +++ b/usr.bin/iscsictl/iscsictl.c @@ -87,6 +87,7 @@ target_new(struct conf *conf) if (targ == NULL) xo_err(1, "calloc"); targ->t_conf = conf; + targ->t_dscp = -1; TAILQ_INSERT_TAIL(&conf->conf_targets, targ, t_next); return (targ); @@ -358,6 +359,7 @@ conf_from_target(struct iscsi_session_conf *conf, conf->isc_data_digest = ISCSI_DIGEST_CRC32C; else conf->isc_data_digest = ISCSI_DIGEST_NONE; + conf->isc_dscp = targ->t_dscp; } static int @@ -535,6 +537,9 @@ kernel_list(int iscsi_fd, const struct target *targ __unused, "Target portal:", conf->isc_target_addr); xo_emit("{L:/%-26s}{V:alias/%s}\n", "Target alias:", state->iss_target_alias); + if (conf->isc_dscp != -1) + xo_emit("{L:/%-26s}{V:dscp/0x%02x}\n", + "Target DSCP:", conf->isc_dscp); xo_close_container("target"); xo_open_container("auth"); diff --git a/usr.bin/iscsictl/iscsictl.h b/usr.bin/iscsictl/iscsictl.h index aac86e768507..d5e2fd25c218 100644 --- a/usr.bin/iscsictl/iscsictl.h +++ b/usr.bin/iscsictl/iscsictl.h @@ -78,6 +78,7 @@ struct target { int t_session_type; int t_enable; int t_protocol; + int t_dscp; char *t_offload; char *t_user; char *t_secret; diff --git a/usr.bin/iscsictl/parse.y b/usr.bin/iscsictl/parse.y index 1e414a6f63ae..9e4a28b50fed 100644 --- a/usr.bin/iscsictl/parse.y +++ b/usr.bin/iscsictl/parse.y @@ -44,6 +44,8 @@ #include #include "iscsictl.h" +#include +#include extern FILE *yyin; extern char *yytext; @@ -61,7 +63,9 @@ extern void yyrestart(FILE *); %token AUTH_METHOD ENABLE HEADER_DIGEST DATA_DIGEST TARGET_NAME TARGET_ADDRESS %token INITIATOR_NAME INITIATOR_ADDRESS INITIATOR_ALIAS USER SECRET %token MUTUAL_USER MUTUAL_SECRET SEMICOLON SESSION_TYPE PROTOCOL OFFLOAD -%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET +%token IGNORED EQUALS OPENING_BRACKET CLOSING_BRACKET DSCP +%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 { @@ -127,6 +131,8 @@ target_entry: protocol | ignored + | + dscp ; target_name: TARGET_NAME EQUALS STR @@ -296,6 +302,48 @@ ignored: IGNORED EQUALS STR } ; +dscp: DSCP EQUALS STR + { + uint64_t tmp; + + if (strcmp($3, "0x") == 0) { + tmp = strtol($3 + 2, NULL, 16); + } else if (expand_number($3, &tmp) != 0) { + yyerror("invalid numeric value"); + free($3); + return(1); + } + if (tmp >= 0x40) { + yyerror("invalid dscp value"); + return(1); + } + + target->t_dscp = tmp; + } + | DSCP EQUALS BE { target->t_dscp = IPTOS_DSCP_CS0 >> 2 ; } + | DSCP EQUALS EF { target->t_dscp = IPTOS_DSCP_EF >> 2 ; } + | DSCP EQUALS CS0 { target->t_dscp = IPTOS_DSCP_CS0 >> 2 ; } + | DSCP EQUALS CS1 { target->t_dscp = IPTOS_DSCP_CS1 >> 2 ; } + | DSCP EQUALS CS2 { target->t_dscp = IPTOS_DSCP_CS2 >> 2 ; } + | DSCP EQUALS CS3 { target->t_dscp = IPTOS_DSCP_CS3 >> 2 ; } + | DSCP EQUALS CS4 { target->t_dscp = IPTOS_DSCP_CS4 >> 2 ; } + | DSCP EQUALS CS5 { target->t_dscp = IPTOS_DSCP_CS5 >> 2 ; } + | DSCP EQUALS CS6 { target->t_dscp = IPTOS_DSCP_CS6 >> 2 ; } + | DSCP EQUALS CS7 { target->t_dscp = IPTOS_DSCP_CS7 >> 2 ; } + | DSCP EQUALS AF11 { target->t_dscp = IPTOS_DSCP_AF11 >> 2 ; } + | DSCP EQUALS AF12 { target->t_dscp = IPTOS_DSCP_AF12 >> 2 ; } + | DSCP EQUALS AF13 { target->t_dscp = IPTOS_DSCP_AF13 >> 2 ; } + | DSCP EQUALS AF21 { target->t_dscp = IPTOS_DSCP_AF21 >> 2 ; } + | DSCP EQUALS AF22 { target->t_dscp = IPTOS_DSCP_AF22 >> 2 ; } + | DSCP EQUALS AF23 { target->t_dscp = IPTOS_DSCP_AF23 >> 2 ; } + | DSCP EQUALS AF31 { target->t_dscp = IPTOS_DSCP_AF31 >> 2 ; } + | DSCP EQUALS AF32 { target->t_dscp = IPTOS_DSCP_AF32 >> 2 ; } + | DSCP EQUALS AF33 { target->t_dscp = IPTOS_DSCP_AF33 >> 2 ; } + | DSCP EQUALS AF41 { target->t_dscp = IPTOS_DSCP_AF41 >> 2 ; } + | DSCP EQUALS AF42 { target->t_dscp = IPTOS_DSCP_AF42 >> 2 ; } + | DSCP EQUALS AF43 { target->t_dscp = IPTOS_DSCP_AF43 >> 2 ; } + ; + %% void diff --git a/usr.bin/iscsictl/token.l b/usr.bin/iscsictl/token.l index fc731f4e8196..9f6a0d707fb0 100644 --- a/usr.bin/iscsictl/token.l +++ b/usr.bin/iscsictl/token.l @@ -68,6 +68,7 @@ enable { return ENABLE; } protocol { return PROTOCOL; } offload { return OFFLOAD; } port { return IGNORED; } +dscp { return DSCP; } MaxConnections { return IGNORED; } TargetAlias { return IGNORED; } TargetPortalGroupTag { return IGNORED; } @@ -86,6 +87,28 @@ tags { return IGNORED; } maxluns { return IGNORED; } sockbufsize { return IGNORED; } chapDigest { return IGNORED; } +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; } diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c index aaf8f78d718b..5d121e83b158 100644 --- a/usr.sbin/iscsid/iscsid.c +++ b/usr.sbin/iscsid/iscsid.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -276,6 +277,25 @@ connection_new(int iscsi_fd, const struct iscsi_daemon_request *request) if (setsockopt(conn->conn_socket, SOL_SOCKET, SO_SNDBUF, &sockbuf, sizeof(sockbuf)) == -1) log_warn("setsockopt(SO_SNDBUF) failed"); + if (conn->conn_conf.isc_dscp != -1) { + int tos = conn->conn_conf.isc_dscp << 2; + if (to_ai->ai_family == AF_INET) { + if (setsockopt(conn->conn_socket, + IPPROTO_IP, IP_TOS, + &tos, sizeof(tos)) == -1) + log_warn("setsockopt(IP_TOS) " + "failed for %s", + from_addr); + } else + if (to_ai->ai_family == AF_INET6) { + if (setsockopt(conn->conn_socket, + IPPROTO_IPV6, IPV6_TCLASS, + &tos, sizeof(tos)) == -1) + log_warn("setsockopt(IPV6_TCLASS) " + "failed for %s", + from_addr); + } + } if (from_ai != NULL) { error = bind(conn->conn_socket, from_ai->ai_addr, from_ai->ai_addrlen);