kern/103454: [ipfw] [patch] add a facility to modify DF bit of the
IP packet
Roman Bogorodskiy
novel at FreeBSD.org
Thu Sep 21 03:30:21 PDT 2006
>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:
More information about the freebsd-bugs
mailing list