Index: head/usr.sbin/ctld/ctl.conf.5 =================================================================== --- head/usr.sbin/ctld/ctl.conf.5 +++ head/usr.sbin/ctld/ctl.conf.5 @@ -258,6 +258,13 @@ and .Qq Ar AFxx codepoints. +.It Ic pcp Ar value +The 802.1Q Priority CodePoint used for sending packets. +The PCP can be set to a value in the range between +.Qq Ar 0 +to +.Qq Ar 7 . +When omitted, the default for the outgoing interface is used. .El .Ss target Context .Bl -tag -width indent Index: head/usr.sbin/ctld/ctld.h =================================================================== --- head/usr.sbin/ctld/ctld.h +++ head/usr.sbin/ctld/ctld.h @@ -128,6 +128,7 @@ char *pg_offload; char *pg_redirection; int pg_dscp; + int pg_pcp; uint16_t pg_tag; }; Index: head/usr.sbin/ctld/ctld.c =================================================================== --- head/usr.sbin/ctld/ctld.c +++ head/usr.sbin/ctld/ctld.c @@ -626,6 +626,7 @@ pg->pg_conf = conf; pg->pg_tag = 0; /* Assigned later in conf_apply(). */ pg->pg_dscp = -1; + pg->pg_pcp = -1; TAILQ_INSERT_TAIL(&conf->conf_portal_groups, pg, pg_next); return (pg); @@ -2210,6 +2211,32 @@ IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == -1) log_warn("setsockopt(IPV6_TCLASS) " + "failed for %s", + newp->p_listen); + } + } + if (newpg->pg_pcp != -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 pcp = newpg->pg_pcp; + if (sa.sa_family == AF_INET) { + if (setsockopt(newp->p_socket, + IPPROTO_IP, IP_VLAN_PCP, + &pcp, sizeof(pcp)) == -1) + log_warn("setsockopt(IP_VLAN_PCP) " + "failed for %s", + newp->p_listen); + } else + if (sa.sa_family == AF_INET6) { + if (setsockopt(newp->p_socket, + IPPROTO_IPV6, IPV6_VLAN_PCP, + &pcp, sizeof(pcp)) == -1) + log_warn("setsockopt(IPV6_VLAN_PCP) " "failed for %s", newp->p_listen); } Index: head/usr.sbin/ctld/parse.y =================================================================== --- head/usr.sbin/ctld/parse.y +++ head/usr.sbin/ctld/parse.y @@ -65,8 +65,8 @@ %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 PATH PCP PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL +%token SIZE STR 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 @@ -359,6 +359,8 @@ portal_group_tag | portal_group_dscp + | + portal_group_pcp ; portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR @@ -512,6 +514,24 @@ | DSCP AF43 { portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2 ; } ; +portal_group_pcp: PCP STR + { + uint64_t tmp; + + if (expand_number($2, &tmp) != 0) { + yyerror("invalid numeric value"); + free($2); + return (1); + } + if (!((tmp >= 0) && (tmp <= 7))) { + yyerror("invalid pcp value"); + free($2); + return (1); + } + + portal_group->pg_pcp = tmp; + } + ; lun: LUN lun_name OPENING_BRACKET lun_entries CLOSING_BRACKET Index: head/usr.sbin/ctld/token.l =================================================================== --- head/usr.sbin/ctld/token.l +++ head/usr.sbin/ctld/token.l @@ -64,6 +64,7 @@ discovery-auth-group { return DISCOVERY_AUTH_GROUP; } discovery-filter { return DISCOVERY_FILTER; } dscp { return DSCP; } +pcp { return PCP; } foreign { return FOREIGN; } initiator-name { return INITIATOR_NAME; } initiator-portal { return INITIATOR_PORTAL; } Index: head/usr.sbin/ctld/uclparse.c =================================================================== --- head/usr.sbin/ctld/uclparse.c +++ head/usr.sbin/ctld/uclparse.c @@ -672,6 +672,19 @@ } } } + + if (!strcmp(key, "pcp")) { + if (obj->type != UCL_INT) { + log_warnx("\"pcp\" property of portal group " + "\"%s\" is not an integer", portal_group->pg_name); + return(1); + } + portal_group->pg_pcp = ucl_object_toint(obj); + if (!((portal_group->pg_pcp >= 0) && (portal_group->pg_pcp <= 7))) { + log_warnx("invalid \"pcp\" value %d, using default", portal_group->pg_pcp); + portal_group->pg_pcp = -1; + } + } } return (0);