diff options
author | ae <ae@FreeBSD.org> | 2017-04-17 09:42:05 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2017-04-17 09:42:05 +0000 |
commit | fed97f3094ee0c71bc2ae864dce888257108122c (patch) | |
tree | 183af123a8e5234f5555cf59f3154a14ffa856ae /sbin | |
parent | 93c66f329a5c7a8161ceef873184cc5c7b69431c (diff) | |
download | FreeBSD-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.8 | 16 | ||||
-rw-r--r-- | sbin/ipfw/ipfw2.c | 23 | ||||
-rw-r--r-- | sbin/ipfw/ipfw2.h | 2 |
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, }; /* |