Index: head/share/man/man4/carp.4 =================================================================== --- head/share/man/man4/carp.4 +++ head/share/man/man4/carp.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 7, 2018 +.Dd July 1, 2018 .Dt CARP 4 .Os .Sh NAME @@ -104,6 +104,12 @@ When enabled, a vhid in a backup state would preempt a master that is announcing itself with a lower advskew. Disabled by default. +.It Va net.inet.carp.dscp +DSCP value in carp packet. +Valid Values are 0 to 63. +A value of 4 is equivalent to the old standard of TOS LOW_DELAY. +TOS values were deprecated and replaced by DSCP in 1998. +The default value is 56 (CS7/Network Control). .It Va net.inet.carp.log Determines what events relating to .Nm Index: head/sys/netinet/ip.h =================================================================== --- head/sys/netinet/ip.h +++ head/sys/netinet/ip.h @@ -94,6 +94,11 @@ #define IPTOS_PREC_ROUTINE IPTOS_DSCP_CS0 /* + * Offset of Diffserv decimal value to convert it to tos value . + */ +#define IPTOS_DSCP_OFFSET 2 + +/* * Definitions for DiffServ Codepoints as per RFC2474 and RFC5865. */ #define IPTOS_DSCP_CS0 0x00 Index: head/sys/netinet/ip6.h =================================================================== --- head/sys/netinet/ip6.h +++ head/sys/netinet/ip6.h @@ -104,6 +104,7 @@ #define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */ #endif /* LITTLE_ENDIAN */ #endif +#define IPV6_FLOWLABEL_LEN 20 #if 1 /* ECN bits proposed by Sally Floyd */ #define IP6TOS_CE 0x01 /* congestion experienced */ Index: head/sys/netinet/ip_carp.c =================================================================== --- head/sys/netinet/ip_carp.c +++ head/sys/netinet/ip_carp.c @@ -190,6 +190,10 @@ static VNET_DEFINE(int, carp_allow) = 1; #define V_carp_allow VNET(carp_allow) +/* Set DSCP in outgoing CARP packets. */ +static VNET_DEFINE(int, carp_dscp) = 56; +#define V_carp_dscp VNET(carp_dscp) + /* Preempt slower nodes. */ static VNET_DEFINE(int, carp_preempt) = 0; #define V_carp_preempt VNET(carp_preempt) @@ -211,12 +215,16 @@ #define V_carp_ifdown_adj VNET(carp_ifdown_adj) static int carp_allow_sysctl(SYSCTL_HANDLER_ARGS); +static int carp_dscp_sysctl(SYSCTL_HANDLER_ARGS); static int carp_demote_adj_sysctl(SYSCTL_HANDLER_ARGS); SYSCTL_NODE(_net_inet, IPPROTO_CARP, carp, CTLFLAG_RW, 0, "CARP"); SYSCTL_PROC(_net_inet_carp, OID_AUTO, allow, CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, carp_allow_sysctl, "I", "Accept incoming CARP packets"); +SYSCTL_PROC(_net_inet_carp, OID_AUTO, dscp, + CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, carp_dscp_sysctl, "I", + "DSCP value for carp packets"); SYSCTL_INT(_net_inet_carp, OID_AUTO, preempt, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(carp_preempt), 0, "High-priority backup preemption mode"); SYSCTL_INT(_net_inet_carp, OID_AUTO, log, CTLFLAG_VNET | CTLFLAG_RW, @@ -933,7 +941,7 @@ ip = mtod(m, struct ip *); ip->ip_v = IPVERSION; ip->ip_hl = sizeof(*ip) >> 2; - ip->ip_tos = IPTOS_LOWDELAY; + ip->ip_tos = V_carp_dscp << IPTOS_DSCP_OFFSET; ip->ip_len = htons(len); ip->ip_off = htons(IP_DF); ip->ip_ttl = CARP_DFLTTL; @@ -983,6 +991,10 @@ ip6 = mtod(m, struct ip6_hdr *); bzero(ip6, sizeof(*ip6)); ip6->ip6_vfc |= IPV6_VERSION; + /* Traffic class isn't defined in ip6 struct instead + * it gets offset into flowid field */ + ip6->ip6_flow |= htonl(V_carp_dscp << (IPV6_FLOWLABEL_LEN + + IPTOS_DSCP_OFFSET)); ip6->ip6_hlim = CARP_DFLTTL; ip6->ip6_nxt = IPPROTO_CARP; @@ -2097,6 +2109,24 @@ } mtx_unlock(&carp_mtx); } + + return (0); +} + +static int +carp_dscp_sysctl(SYSCTL_HANDLER_ARGS) +{ + int new, error; + + new = V_carp_dscp; + error = sysctl_handle_int(oidp, &new, 0, req); + if (error || !req->newptr) + return (error); + + if (new < 0 || new > 63) + return (EINVAL); + + V_carp_dscp = new; return (0); }