summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2017-04-17 09:42:05 +0000
committerae <ae@FreeBSD.org>2017-04-17 09:42:05 +0000
commitfed97f3094ee0c71bc2ae864dce888257108122c (patch)
tree183af123a8e5234f5555cf59f3154a14ffa856ae /sbin
parent93c66f329a5c7a8161ceef873184cc5c7b69431c (diff)
downloadFreeBSD-src-fed97f3094ee0c71bc2ae864dce888257108122c.zip
FreeBSD-src-fed97f3094ee0c71bc2ae864dce888257108122c.tar.gz
MFC r316435:
Add ipfw_pmod kernel module. The module is designed for modification of a packets of any protocols. For now it implements only TCP MSS modification. It adds the external action handler for "tcp-setmss" action. A rule with tcp-setmss action does additional check for protocol and TCP flags. If SYN flag is present, it parses TCP options and modifies MSS option if its value is greater than configured value in the rule. Then it adjustes TCP checksum if needed. After handling the search continues with the next rule. Obtained from: Yandex LLC Relnotes: yes Sponsored by: Yandex LLC Differential Revision: https://reviews.freebsd.org/D10150
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ipfw/ipfw.816
-rw-r--r--sbin/ipfw/ipfw2.c23
-rw-r--r--sbin/ipfw/ipfw2.h2
3 files changed, 40 insertions, 1 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index f7c3a78..999bf8a 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,7 +1,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 15, 2017
+.Dd April 3, 2017
.Dt IPFW 8
.Os
.Sh NAME
@@ -1118,6 +1118,20 @@ It is also possible to use the
keyword with setdscp.
If the tablearg value is not within the 0..64 range, lower 6 bits of supplied
value are used.
+.It Cm tcp-setmss Ar mss
+Set the Maximum Segment Size (MSS) in the TCP segment to value
+.Ar mss .
+The kernel module
+.Cm ipfw_pmod
+should be loaded or kernel should have
+.Cm options IPFIREWALL_PMOD
+to be able use this action.
+This command does not change a packet if original MSS value is lower than
+specified value.
+Both TCP over IPv4 and over IPv6 are supported.
+Regardless of matched a packet or not by the
+.Cm tcp-setmss
+rule, the search continues with the next rule.
.It Cm reass
Queue and reassemble IP fragments.
If the packet is not fragmented, counters are updated and
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index e001120..887a5a5 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -36,6 +36,7 @@
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
@@ -238,6 +239,7 @@ static struct _s_x rule_eactions[] = {
{ "nat64lsn", TOK_NAT64LSN },
{ "nat64stl", TOK_NAT64STL },
{ "nptv6", TOK_NPTV6 },
+ { "tcp-setmss", TOK_TCPSETMSS },
{ NULL, 0 } /* terminator */
};
@@ -272,6 +274,7 @@ static struct _s_x rule_actions[] = {
{ "call", TOK_CALL },
{ "return", TOK_RETURN },
{ "eaction", TOK_EACTION },
+ { "tcp-setmss", TOK_TCPSETMSS },
{ NULL, 0 } /* terminator */
};
@@ -4007,6 +4010,26 @@ chkarg:
fill_cmd(action, O_CALLRETURN, F_NOT, 0);
break;
+ case TOK_TCPSETMSS: {
+ u_long mss;
+ uint16_t idx;
+
+ idx = pack_object(tstate, "tcp-setmss", IPFW_TLV_EACTION);
+ if (idx == 0)
+ errx(EX_DATAERR, "pack_object failed");
+ fill_cmd(action, O_EXTERNAL_ACTION, 0, idx);
+ NEED1("Missing MSS value");
+ action = next_cmd(action, &ablen);
+ action->len = 1;
+ CHECK_ACTLEN;
+ mss = strtoul(*av, NULL, 10);
+ if (mss == 0 || mss > UINT16_MAX)
+ errx(EX_USAGE, "invalid MSS value %s", *av);
+ fill_cmd(action, O_EXTERNAL_DATA, 0, (uint16_t)mss);
+ av++;
+ break;
+ }
+
default:
av--;
if (match_token(rule_eactions, *av) == -1)
diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h
index 0b63e3b..13018f8 100644
--- a/sbin/ipfw/ipfw2.h
+++ b/sbin/ipfw/ipfw2.h
@@ -284,6 +284,8 @@ enum tokens {
TOK_INTPREFIX,
TOK_EXTPREFIX,
TOK_PREFIXLEN,
+
+ TOK_TCPSETMSS,
};
/*
OpenPOWER on IntegriCloud