Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Feb 2008 00:15:26 -0300
From:      "Marcelo Araujo (araujo@FreeBSD.org)" <araujo@FreeBSD.org>
To:        "FreeBSD gnats submit" <FreeBSD-gnats-submit@FreeBSD.org>
Subject:   kern/121108: [ipfw] [patch] add support to ToS IP PRECEDENCE fields
Message-ID:  <1203995726.2841@island.freebsd.org>
Resent-Message-ID: <200802260350.m1Q3o1V8028611@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         121108
>Category:       kern
>Synopsis:       [ipfw] [patch] add support to ToS IP PRECEDENCE fields
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 26 03:50:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Marcelo Araujo (araujo@FreeBSD.org)
>Release:        FreeBSD 7.0-PRERELEASE i386
>Organization:
FreeBSD 
>Environment:


System: FreeBSD 7.0-PRERELEASE #10: Mon Feb 25 08:41:00 BRT 2008
    araujo@island.freebsd.org:/usr/obj/usr/src/sys/ISLAND



>Description:


The patch add some features described in:
- RFC 0791
- RFC 1122
- RFC 1349 
- http://www3.tools.ietf.org/html/draft-xiao-tcp-prec-01

You can change the IP PRECEDENCE fields within ToS header, you can also check packages that have this mark within your network, some benefits are relevant, you can classifies many type of packages and prioritize it in your network.

1 - Set some type of IP PRECEDENCE inside a package:

ipfw add 10 iptospre flashover ip from any to any

2 - You can check packages within your network that have the IP PRECEDENCE fields:

ipfw add 11 count ip from any to any iptospre flashover

The patch is based in PR kern/102471, 
novel@ thanks for your help.

References:
http://code.google.com/p/exports/wiki/ToSWorkAround


>How-To-Repeat:





>Fix:


--- ipfw-ToS8bits.diff begins here ---
Index: sbin/ipfw/ipfw2.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.117
diff -u -r1.117 ipfw2.c
--- sbin/ipfw/ipfw2.c	24 Feb 2008 15:37:45 -0000	1.117
+++ sbin/ipfw/ipfw2.c	26 Feb 2008 02:37:05 -0000
@@ -177,6 +177,20 @@
 	{ NULL,	0 }
 };
 
+/* ToS PRECEDENCE fields supporting. */
+static struct _s_x f_iptospre[] = {
+	{ "netcontrol",		IPTOSPRE_NETCONTROL}, 	/* 0xe0 = 111 */
+	{ "intercontrol",	IPTOSPRE_INTERCONTROL},	/* 0xc0 = 110 */
+	{ "criticecp",		IPTOSPRE_CRITICECP},		/* 0xa0 = 101 */
+	{ "flashover",		IPTOSPRE_FLASHOVER},		/* 0x80 = 100 */
+	{ "flash",			IPTOSPRE_FLASH},			/* 0x60 = 011 */
+	{ "immediate",		IPTOSPRE_IMMEDIATE},		/* 0x40 = 010 */
+	{ "priority",		IPTOSPRE_PRIORITY},		/* 0x20 = 001 */
+	{ "routine",		IPTOSPRE_ROUTINE},		/* 0x00 = 000 */
+	{ NULL, 0 }
+};
+/* ToS PRECEDENCE fields supporting. */
+
 static struct _s_x f_iptos[] = {
 	{ "lowdelay",	IPTOS_LOWDELAY},
 	{ "throughput",	IPTOS_THROUGHPUT},
@@ -282,6 +296,7 @@
 	TOK_IPLEN,
 	TOK_IPID,
 	TOK_IPPRECEDENCE,
+	TOK_IPTOSPRE, /* Add ToS PRECEDENCE supporting. */
 	TOK_IPTOS,
 	TOK_IPTTL,
 	TOK_IPVER,
@@ -317,6 +332,7 @@
 	TOK_GRED,
 	TOK_DROPTAIL,
 	TOK_PROTO,
+	TOK_SETIPTOSPRE, /* Add ToS PRECEDENCE supporting. */
 	TOK_WEIGHT,
 	TOK_IP,
 	TOK_IF,
@@ -411,6 +427,7 @@
 	{ "unreach6",		TOK_UNREACH6 },
 	{ "unreach",		TOK_UNREACH },
 	{ "check-state",	TOK_CHECKSTATE },
+	{ "iptospre",		TOK_SETIPTOSPRE }, /* Set IP ToS PRECEDENCE. */
 	{ "//",			TOK_COMMENT },
 	{ "nat",                TOK_NAT },
 	{ NULL, 0 }	/* terminator */
@@ -449,6 +466,7 @@
 	{ "ipid",		TOK_IPID },
 	{ "ipprecedence",	TOK_IPPRECEDENCE },
 	{ "iptos",		TOK_IPTOS },
+	{ "iptospre",	TOK_IPTOSPRE }, /* Add ToS PRECEDENCE supporting. */
 	{ "ipttl",		TOK_IPTTL },
 	{ "ipversion",		TOK_IPVER },
 	{ "ipver",		TOK_IPVER },
@@ -1599,6 +1617,13 @@
 		    }
 			break;
 
+		/* Set ToS PRECEDENCE. */
+		/* O erro pode estar aqui....(araujo). */
+		case O_SETIPTOSPRE:
+			printf("iptospre %s", match_value(f_iptospre, cmd->arg1));
+			break;
+		/* Set ToS PRECEDENCE. */
+
 		case O_LOG: /* O_LOG is printed last */
 			logptr = (ipfw_insn_log *)cmd;
 			break;
@@ -1906,6 +1931,12 @@
 				print_icmptypes((ipfw_insn_u32 *)cmd);
 				break;
 
+			/* Print ToS PRE in ipfw show */
+			case O_IPTOSPRE:
+				printf(" iptospre %s", match_value(f_iptospre, cmd->arg1));
+				break;
+			/* Print ToS PRE in ipfw show */
+
 			case O_ESTAB:
 				printf(" established");
 				break;
@@ -2712,7 +2743,7 @@
 "RULE-BODY:	check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n"
 "ACTION:	check-state | allow | count | deny | unreach{,6} CODE |\n"
 "               skipto N | {divert|tee} PORT | forward ADDR |\n"
-"               pipe N | queue N | nat N\n"
+"               pipe N | queue N | iptospre CODE | nat N\n"
 "PARAMS: 	[log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n"
 "ADDR:		[ MAC dst src ether_type ] \n"
 "		[ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
@@ -2724,7 +2755,7 @@
 "OPTION_LIST:	OPTION [OPTION_LIST]\n"
 "OPTION:	bridged | diverted | diverted-loopback | diverted-output |\n"
 "	{dst-ip|src-ip} IPADDR | {dst-ip6|src-ip6|dst-ipv6|src-ipv6} IP6ADDR |\n"
-"	{dst-port|src-port} LIST |\n"
+"	iptospre CODE | {dst-ip|src-ip} IPADDR |\n"
 "	estab | frag | {gid|uid} N | icmptypes LIST | in | out | ipid LIST |\n"
 "	iplen LIST | ipoptions SPEC | ipprecedence | ipsec | iptos SPEC |\n"
 "	ipttl LIST | ipversion VER | keep-state | layer2 | limit ... |\n"
@@ -4848,10 +4879,21 @@
 		action->opcode = O_COUNT;
 		break;
 
+<<<<<<< ipfw2.c
+	/* Setting ToS PRECEDENCE fields. */
+	case TOK_SETIPTOSPRE:
+		NEED1("need iptospre arg\n");
+		fill_flags(action, O_SETIPTOSPRE, f_iptospre, *av);
+		ac--; av++;
+		break;
+	/* Setting ToS PRECEDENCE fields. */
+
+=======
 	case TOK_NAT:
  		action->opcode = O_NAT;
  		action->len = F_INSN_SIZE(ipfw_insn_nat);
 		goto chkarg;
+>>>>>>> 1.117
 	case TOK_QUEUE:
 		action->opcode = O_QUEUE;
 		goto chkarg;
@@ -5334,6 +5376,14 @@
 			ac--; av++;
 			break;
 
+		/* Some args to ToS PRECEDENCE. */
+		case TOK_IPTOSPRE:
+			NEED1("missing argument for iptospre");
+			fill_flags(cmd, O_IPTOSPRE, f_iptospre, *av);
+			ac--; av++;
+			break;
+		/* Some args to ToS PRECEDENCE. */
+
 		case TOK_IPTOS:
 			NEED1("missing argument for iptos");
 			fill_flags(cmd, O_IPTOS, f_iptos, *av);
Index: sys/netinet/ip_fw.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.111
diff -u -r1.111 ip_fw.h
--- sys/netinet/ip_fw.h	25 Jan 2008 14:38:27 -0000	1.111
+++ sys/netinet/ip_fw.h	26 Feb 2008 02:37:06 -0000
@@ -161,6 +161,9 @@
 	O_TAG,   		/* arg1=tag number */
 	O_TAGGED,		/* arg1=tag number */
 
+	O_SETIPTOSPRE,	/* setting ToS PRECEDENCE field. */
+	O_IPTOSPRE,		/* Add ToS PRECEDENCE supporting. */
+
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
 
@@ -510,6 +513,18 @@
 #define	IP_FW_IPOPT_RR		0x04
 #define	IP_FW_IPOPT_TS		0x08
 
+/* Definitions for IP ToS PRECEDENCE. */ 
+/* Thanks to: http://www.easycalculation.com/binary-converter.php */
+#define	IPTOSPRE_NETCONTROL		224	/* bin = 111 dec = 224 hex = 0xe0 */
+#define	IPTOSPRE_INTERCONTROL		192	/* bin = 110 dec = 192 hex = 0xc0 */
+#define	IPTOSPRE_CRITICECP		160	/* bin = 101 dec = 160 hex = 0xa0 */
+#define	IPTOSPRE_FLASHOVER		128	/* bin = 100 dec = 128 hex = 0x80 */
+#define	IPTOSPRE_FLASH			96 	/* bin = 011 dec = 96  hex = 0x60 */
+#define	IPTOSPRE_IMMEDIATE		64 	/* bin = 010 dec = 64  hex = 0x40 */
+#define	IPTOSPRE_PRIORITY			32 	/* bin = 001 dec = 32  hex = 0x20 */
+#define	IPTOSPRE_ROUTINE			0  	/* bin = 000 dec = 0   hex = 0x00 */
+/* Definitions for IP ToS PRECEDENCE. */ 
+
 /*
  * Definitions for TCP option names.
  */
@@ -626,5 +641,22 @@
 extern	ip_fw_chk_t	*ip_fw_chk_ptr;
 #define	IPFW_LOADED	(ip_fw_chk_ptr != NULL)
 
+/* Some novel@ code. */
+#define ADJUST_CHECKSUM(acc, cksum) \
+		do { \
+				acc += cksum; \
+				if (acc < 0) { \
+					acc = -acc; \
+					acc = (acc >> 16) + (acc & 0xffff); \
+					acc += acc >> 16; \
+					cksum = (u_short) ~acc; \
+				} else { \
+					acc = (acc >> 16) + (acc & 0xffff); \
+					acc += acc >> 16; \
+					cksum = (u_short) acc; \
+				} \
+		} while (0)
+/* Some novel@ code. */
+
 #endif /* _KERNEL */
 #endif /* _IPFW2_H */
Index: sys/netinet/ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.181
diff -u -r1.181 ip_fw2.c
--- sys/netinet/ip_fw2.c	24 Feb 2008 15:37:45 -0000	1.181
+++ sys/netinet/ip_fw2.c	26 Feb 2008 02:37:09 -0000
@@ -177,6 +177,21 @@
 
 extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
 
+/* some @novel code. */
+static __inline int
+twowords(void *p) {
+	uint8_t *c = p;
+#if BYTE_ORDER == LITTLE_ENDIAN
+	uint16_t s1 = ((uint16_t)c[1] << 8) + (uint16_t)c[0];
+	uint16_t s2 = ((uint16_t)c[3] << 8) + (uint16_t)c[2];
+#else
+	uint16_t s1 = ((uint16_t)c[0] << 8) + (uint16_t)c[1];
+	uint16_t s2 = ((uint16_t)c[2] << 8) + (uint16_t)c[3];
+#endif
+	return (s1 + s2);
+}
+/* some @novel code. */
+
 #ifdef SYSCTL_NODE
 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
 SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable,
@@ -2700,6 +2715,7 @@
 	for (; f; f = f->next) {
 		ipfw_insn *cmd;
 		uint32_t tablearg = 0;
+		int accumulate; /* Novel@ code. */
 		int l, cmdlen, skip_or; /* skip rest of OR block */
 
 again:
@@ -3005,6 +3021,12 @@
 				match = (is_ipv4 &&
 				    flags_match(cmd, ip->ip_tos));
 				break;
+			/* Add supporting ToS PRECEDENCE field. */
+			case O_IPTOSPRE:
+				match = (is_ipv4 &&
+				    flags_match(cmd, ip->ip_tos));
+					break;
+			/* Add supporting ToS PRECEDENCE field. */
 
 			case O_TCPDATALEN:
 				if (proto == IPPROTO_TCP && offset == 0) {
@@ -3322,6 +3344,18 @@
 				match = 1;
 				break;
 
+			/* Insert within IP ToS PRECEDENCE field. */
+			case O_SETIPTOSPRE:
+				accumulate = twowords(&ip->ip_tos);
+				ip->ip_tos= cmd->arg1;
+				accumulate -= twowords(&ip->ip_tos);
+				ADJUST_CHECKSUM(accumulate, ip->ip_sum);
+				f->pcnt++; /* update stats */
+				f->bcnt += pktlen;
+				f->timestamp = time_second;
+				goto next_rule;
+			/* Insert within IP ToS PRECEDENCE field. */
+
 			case O_PROBE_STATE:
 			case O_CHECK_STATE:
 				/*
@@ -4119,6 +4153,7 @@
 		case O_FRAG:
 		case O_DIVERTED:
 		case O_IPOPT:
+		case O_IPTOSPRE: /* Add ToS PRECEDENCE supporting. */
 		case O_IPTOS:
 		case O_IPPRECEDENCE:
 		case O_IPVER:
@@ -4142,6 +4177,10 @@
 				goto bad_size;
 			break;
 
+		case O_SETIPTOSPRE: /* Set ToS IP PRECEDENCE. */
+			have_action = 1;
+			break;
+
 		case O_UID:
 		case O_GID:
 		case O_JAIL:
--- ipfw-ToS8bits.diff ends here ---



>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1203995726.2841>