91beabb
--- sendmail-8.14.4/cf/m4/proto.m4.orig	2011-01-11 20:02:14.000000000 -0700
91beabb
+++ sendmail-8.14.4/cf/m4/proto.m4	2011-01-11 20:02:14.000000000 -0700
f823fb2
@@ -251,6 +251,9 @@ _OPTION(SevenBitInput, `confSEVEN_BIT_IN
f823fb2
 # 8-bit data handling
f823fb2
 _OPTION(EightBitMode, `confEIGHT_BIT_HANDLING', `pass8')
f823fb2
 
f823fb2
+# DSCP marking of traffic (IP_TOS)
f823fb2
+_OPTION(InetQoS, `confINET_QOS', `none')
f823fb2
+
f823fb2
 # wait for alias file rebuild (default units: minutes)
f823fb2
 _OPTION(AliasWait, `confALIAS_WAIT', `5m')
f823fb2
 
91beabb
--- sendmail-8.14.4/cf/cf/submit.mc.orig	2011-01-11 20:02:14.000000000 -0700
91beabb
+++ sendmail-8.14.4/cf/cf/submit.mc	2011-01-11 20:02:14.000000000 -0700
91beabb
@@ -22,6 +22,8 @@ define(`__OSTYPE__',`')dnl dirty hack to
f823fb2
 define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet
f823fb2
 define(`confTIME_ZONE', `USE_TZ')dnl
f823fb2
 define(`confDONT_INIT_GROUPS', `True')dnl
f823fb2
+dnl # If you're operating in a DSCP/RFC-4594 environment with QoS
f823fb2
+dnl define(`confINET_QOS', `AF11')dnl
80a10db
 define(`confPID_FILE', `/run/sm-client.pid')dnl
f823fb2
 dnl define(`confDIRECT_SUBMISSION_MODIFIERS',`C')dnl
f823fb2
 FEATURE(`use_ct_file')dnl
91beabb
--- sendmail-8.14.4/sendmail/sendmail.h.orig	2009-12-18 10:08:01.000000000 -0700
91beabb
+++ sendmail-8.14.4/sendmail/sendmail.h	2011-01-11 20:39:35.000000000 -0700
91beabb
@@ -2387,7 +2387,14 @@ EXTERN struct termescape	TermEscape;	/* 
f823fb2
 EXTERN SOCKADDR	ConnectOnlyTo;	/* override connection address (for testing) */
f823fb2
 EXTERN SOCKADDR RealHostAddr;	/* address of host we are talking to */
f823fb2
 extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */
f823fb2
-
91beabb
+#if _FFR_QOS
91beabb
+# if !defined(SOL_IP) && defined(IPPROTO_IP)
91beabb
+#  define SOL_IP IPPROTO_IP
91beabb
+# endif
91beabb
+# if defined(SOL_IP) && defined(IP_TOS)
91beabb
+EXTERN int	InetQoS;	/* QoS mapping */
91beabb
+# endif
f823fb2
+#endif
f823fb2
 
f823fb2
 EXTERN int ConnectionRateWindowSize;
3074bae
 #if STARTTLS && USE_OPENSSL_ENGINE
91beabb
--- sendmail-8.14.4/sendmail/conf.c.orig	2011-01-11 20:02:14.000000000 -0700
91beabb
+++ sendmail-8.14.4/sendmail/conf.c	2011-01-11 20:24:29.000000000 -0700
91beabb
@@ -6298,6 +6298,10 @@ char	*FFRCompileOptions[] =
91beabb
 #if _FFR_QF_PARANOIA
91beabb
 	"_FFR_QF_PARANOIA",
91beabb
 #endif /* _FFR_QF_PARANOIA */
91beabb
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
91beabb
+	/* QoS */
91beabb
+	"_FFR_QOS",
91beabb
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
91beabb
 #if _FFR_QUEUEDELAY
91beabb
 	/* Exponential queue delay; disabled in 8.13 since it isn't used. */
91beabb
 	"_FFR_QUEUEDELAY",
91beabb
--- sendmail-8.14.4/sendmail/daemon.c.orig	2009-12-17 18:12:40.000000000 -0700
91beabb
+++ sendmail-8.14.4/sendmail/daemon.c	2011-01-11 20:46:37.000000000 -0700
91beabb
@@ -104,6 +104,10 @@ static int	NDaemons = 0;			/* actual num
f823fb2
 
f823fb2
 static time_t	NextDiskSpaceCheck = 0;
f823fb2
 
91beabb
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
f823fb2
+int		InetQoS = 0;			/* none by default */
91beabb
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
f823fb2
+
f823fb2
 /*
f823fb2
 **  GETREQUESTS -- open mail IPC port and get requests.
f823fb2
 **
91beabb
@@ -1131,6 +1135,16 @@ opendaemonsocket(d, firsttime)
f823fb2
 			(void) setsockopt(d->d_socket, SOL_SOCKET,
f823fb2
 					  SO_KEEPALIVE, (char *)&on, sizeof(on));
f823fb2
 
91beabb
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
91beabb
+			if (InetQoS != 0x00
91beabb
+			 && (d->d_addr.sa.sa_family == AF_INET
91beabb
+			  || (d->d_addr.sin6.sin6_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(d->d_addr.sin6.sin6_addr.s6_addr32)))) {
91beabb
+				if (setsockopt(d->d_socket, SOL_IP,
91beabb
+						  IP_TOS, (char *)&InetQoS, sizeof(InetQoS)) < 0)
91beabb
+					syserr("opendaemonsock: daemon %s: setsockopt(IP_TOS)", d->d_name);
91beabb
+			}
91beabb
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
f823fb2
+
f823fb2
 #ifdef SO_RCVBUF
f823fb2
 			if (d->d_tcprcvbufsize > 0)
f823fb2
 			{
91beabb
@@ -2565,6 +2579,16 @@ gothostent:
91beabb
 			return EX_TEMPFAIL;
91beabb
 		}
91beabb
 
91beabb
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
91beabb
+		if (InetQoS != 0x00
91beabb
+		 && (family == AF_INET
91beabb
+		  || (family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(addr.sin6.sin6_addr.s6_addr32))))
91beabb
+		{
91beabb
+			if (setsockopt(s, SOL_IP, IP_TOS,
91beabb
+					  (char *)&InetQoS, sizeof(InetQoS)) < 0)
91beabb
+				syserr("makeconnection: setsockopt(IP_TOS)");
91beabb
+		}
91beabb
+#endif /* _FFR_QOS && defined(SOL_IP) && defined(IP_TOS) */
91beabb
 #ifdef SO_SNDBUF
91beabb
 		if (ClientSettings[family].d_tcpsndbufsize > 0)
91beabb
 		{
707c52d
--- sendmail-8.14.7/sendmail/readcf.c.orig	2013-03-15 18:54:12.000000000 +0100
707c52d
+++ sendmail-8.14.7/sendmail/readcf.c	2013-04-21 17:58:19.000000000 +0200
91beabb
@@ -18,6 +18,7 @@
91beabb
 
91beabb
 #if NETINET || NETINET6
91beabb
 # include <arpa/inet.h>
91beabb
+# include <netinet/ip.h>
91beabb
 #endif /* NETINET || NETINET6 */
91beabb
 
3074bae
 
707c52d
@@ -2280,8 +2281,8 @@
f823fb2
 # define O_RCPTTHROTDELAY	0xe6
f823fb2
 	{ "BadRcptThrottleDelay",	O_RCPTTHROTDELAY,	OI_SAFE	},
f823fb2
 #endif /* _FFR_RCPTTHROTDELAY */
3074bae
-#if 0 && _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
3074bae
-# define O_INETQOS	0xe7	/* reserved for FFR_QOS */
91beabb
+#if _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
f823fb2
+# define O_INETQOS		0xe7
3074bae
 	{ "InetQoS",			O_INETQOS,	OI_NONE },
3074bae
 #endif
707c52d
 #if STARTTLS && _FFR_FIPSMODE
707c52d
@@ -2389,6 +2390,77 @@
f823fb2
 };
f823fb2
 #endif /* STARTTLS && _FFR_TLS_1 */
f823fb2
 
f823fb2
+#ifdef O_INETQOS
f823fb2
+static struct qosmap
f823fb2
+{
f823fb2
+	char	*name;		/* name of the setting */
f823fb2
+	int	value;		/* corresponding setsockopt() value */
f823fb2
+} QoSMap[] = {
91beabb
+#ifdef IPTOS_CLASS_CS0
91beabb
+	{ "CS0",	IPTOS_CLASS_CS0 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS1
91beabb
+	{ "CS1",	IPTOS_CLASS_CS1 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF11
91beabb
+	{ "AF11",	IPTOS_DSCP_AF11 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF12
91beabb
+	{ "AF12",	IPTOS_DSCP_AF12 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF13
91beabb
+	{ "AF13",	IPTOS_DSCP_AF13 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS2
91beabb
+	{ "CS2",	IPTOS_CLASS_CS2 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF21
91beabb
+	{ "AF21",	IPTOS_DSCP_AF21 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF22
91beabb
+	{ "AF22",	IPTOS_DSCP_AF22 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF23
91beabb
+	{ "AF23",	IPTOS_DSCP_AF23 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS3
91beabb
+	{ "CS3",	IPTOS_CLASS_CS3 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF31
91beabb
+	{ "AF31",	IPTOS_DSCP_AF31 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF32
91beabb
+	{ "AF32",	IPTOS_DSCP_AF32 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF33
91beabb
+	{ "AF33",	IPTOS_DSCP_AF33 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS4
91beabb
+	{ "CS4",	IPTOS_CLASS_CS4 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF41
91beabb
+	{ "AF41",	IPTOS_DSCP_AF41 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF42
91beabb
+	{ "AF42",	IPTOS_DSCP_AF42 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_DSCP_AF43
91beabb
+	{ "AF43",	IPTOS_DSCP_AF43 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS5
91beabb
+	{ "CS5",	IPTOS_CLASS_CS5 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS6
91beabb
+	{ "CS6",	IPTOS_CLASS_CS6 },
91beabb
+#endif
91beabb
+#ifdef IPTOS_CLASS_CS7
91beabb
+	{ "CS7",	IPTOS_CLASS_CS7 },
91beabb
+#endif
f823fb2
+	{ "none",	0x00 },
f823fb2
+	{ NULL,		0    }
f823fb2
+};
f823fb2
+#endif
f823fb2
+
f823fb2
 
f823fb2
 # define CANONIFY(val)
f823fb2
 
707c52d
@@ -4035,6 +4107,33 @@
f823fb2
 		break;
707c52d
 #endif /* _FFR_REJECT_NUL_BYTE */
f823fb2
 
f823fb2
+#ifdef O_INETQOS
f823fb2
+	  case O_INETQOS:
f823fb2
+		{
f823fb2
+			struct qosmap *qmp;
f823fb2
+			InetQoS = -1;
f823fb2
+
f823fb2
+			for (qmp = QoSMap; qmp->name != NULL; ++qmp) {
f823fb2
+				if (!strcmp(val, qmp->name)) {
f823fb2
+					InetQoS = qmp->value;
f823fb2
+					break;
f823fb2
+				}
f823fb2
+			}
f823fb2
+
f823fb2
+			/*
f823fb2
+			** we could allow writing it as a hex value, but
f823fb2
+ 			** we don't at this time.
f823fb2
+ 			**/
f823fb2
+			if (qmp->name == NULL) {
f823fb2
+				(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
f823fb2
+						     "Warning: Option: %s unknown parameter '%s'\n",
f823fb2
+						     OPTNAME, val);
f823fb2
+				break;
f823fb2
+			}
f823fb2
+			break;
f823fb2
+		}
f823fb2
+#endif
f823fb2
+
f823fb2
 	  default:
f823fb2
 		if (tTd(37, 1))
f823fb2
 		{