Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Sep 2006 10:27:14 GMT
From:      Roman Bogorodskiy <novel@FreeBSD.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/103454: [ipfw] [patch] add a facility to modify DF bit of the IP packet
Message-ID:  <200609211027.k8LARErU054745@freefall.freebsd.org>
Resent-Message-ID: <200609211030.k8LAUJVA054840@freefall.freebsd.org>

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

>Number:         103454
>Category:       kern
>Synopsis:       [ipfw] [patch] add a facility to modify DF bit of the IP packet
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep 21 10:30:19 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Roman Bogorodskiy
>Release:        FreeBSD 6.0-STABLE i386
>Organization:
>Environment:
>Description:
Add a facility to modify DF bit of the IP packet with ipfw.
Example:
  ipfw add 100 setdf 0 all from any to any

This will set DF to 0 (May Fragment) for all packets. Possible
valuea are 0 (May Fragment) and 1 (Don't Fragment).

References:
  RFC 791 (http://www.ietf.org/rfc/rfc0791.txt)

Patch was tested on -CURRENT. It's avaible via web as well:
http://people.freebsd.org/~novel/patches/freebsd/ipfw_setdf_20060921_2_CURRENT.diff
>How-To-Repeat:
>Fix:

--- ipfw_setdf_20060921_2_CURRENT.diff begins here ---
? sbin/ipfw/ipfw
Index: sbin/ipfw/ipfw.8
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw.8,v
retrieving revision 1.195
diff -u -r1.195 ipfw.8
--- sbin/ipfw/ipfw.8	18 Sep 2006 11:55:10 -0000	1.195
+++ sbin/ipfw/ipfw.8	21 Sep 2006 10:12:51 -0000
@@ -822,6 +822,11 @@
 and
 .Cm ngtee
 actions.
+.It Cm setdf Ar value
+Changes
+.Cm DF
+bit of the IP packet.
+Value may be 0 (May Fragment) or 1 (Don't Fragment).
 .El
 .Ss RULE BODY
 The body of a rule contains zero or more patterns (such as
Index: sbin/ipfw/ipfw2.c
===================================================================
RCS file: /home/ncvs/src/sbin/ipfw/ipfw2.c,v
retrieving revision 1.98
diff -u -r1.98 ipfw2.c
--- sbin/ipfw/ipfw2.c	16 Sep 2006 19:27:40 -0000	1.98
+++ sbin/ipfw/ipfw2.c	21 Sep 2006 10:12:51 -0000
@@ -247,7 +247,8 @@
 	TOK_RESET,
 	TOK_UNREACH,
 	TOK_CHECKSTATE,
-
+	TOK_SETDF,
+	
 	TOK_ALTQ,
 	TOK_LOG,
 	TOK_TAG,
@@ -374,6 +375,7 @@
 	{ "unreach6",		TOK_UNREACH6 },
 	{ "unreach",		TOK_UNREACH },
 	{ "check-state",	TOK_CHECKSTATE },
+	{ "setdf",		TOK_SETDF },
 	{ "//",			TOK_COMMENT },
 	{ NULL, 0 }	/* terminator */
 };
@@ -1555,6 +1557,10 @@
 		    }
 			break;
 
+		case O_SET_IPDF:
+			PRINT_UINT_ARG("setdf ", cmd->arg1);
+			break;
+
 		case O_LOG: /* O_LOG is printed last */
 			logptr = (ipfw_insn_log *)cmd;
 			break;
@@ -2635,7 +2641,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\n"
+"               pipe N | queue N | setdf DF\n"
 "PARAMS: 	[log [logamount LOGLIMIT]] [altq QUEUE_NAME]\n"
 "ADDR:		[ MAC dst src ether_type ] \n"
 "		[ ip from IPADDR [ PORT ] to IPADDR [ PORTLIST ] ]\n"
@@ -3970,6 +3976,20 @@
 		action->opcode = O_COUNT;
 		break;
 
+	case TOK_SETDF:
+	   {
+		int df;
+		   
+		NEED1("need setdf arg\n");
+		df = strtoul(*av, NULL, 0);
+		if (df < 0 || df > 1)
+			errx(EX_DATAERR, "illegal argument for %s",
+				*(av - 1));
+		fill_cmd(action, O_SET_IPDF, 0, df);
+		ac--; av++;
+	   }
+		break;
+		
 	case TOK_QUEUE:
 		action->opcode = O_QUEUE;
 		goto chkarg;
Index: sys/netinet/ip_fw.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.108
diff -u -r1.108 ip_fw.h
--- sys/netinet/ip_fw.h	18 Aug 2006 22:36:04 -0000	1.108
+++ sys/netinet/ip_fw.h	21 Sep 2006 10:13:15 -0000
@@ -160,6 +160,8 @@
 	O_TAG,   		/* arg1=tag number */
 	O_TAGGED,		/* arg1=tag number */
 
+	O_SET_IPDF,		/* arg1=[0|1] */
+	
 	O_LAST_OPCODE		/* not an opcode!		*/
 };
 
Index: sys/netinet/ip_fw2.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw2.c,v
retrieving revision 1.147
diff -u -r1.147 ip_fw2.c
--- sys/netinet/ip_fw2.c	16 Sep 2006 10:27:05 -0000	1.147
+++ sys/netinet/ip_fw2.c	21 Sep 2006 10:13:15 -0000
@@ -3127,6 +3127,22 @@
 				goto done;
 			}
 
+			case O_SET_IPDF:
+				switch (cmd->arg1) {
+					case 0:
+						ip->ip_off &= ~IP_DF;
+						break;
+					case 1:
+						ip->ip_off |= IP_DF;
+						break;
+					default:
+						break;
+				}
+				f->pcnt++;
+				f->bcnt += pktlen;
+				f->timestamp = time_second;
+				goto next_rule;
+
 			case O_COUNT:
 			case O_SKIPTO:
 				f->pcnt++;	/* update stats */
@@ -3654,6 +3670,10 @@
 				goto bad_size;
 			break;
 
+		case O_SET_IPDF:
+			have_action = 1;
+			break;
+
 		case O_UID:
 		case O_GID:
 		case O_JAIL:
--- ipfw_setdf_20060921_2_CURRENT.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?200609211027.k8LARErU054745>