summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkp <kp@FreeBSD.org>2016-10-13 20:34:44 +0000
committerLuiz Souza <luiz@netgate.com>2017-07-17 19:15:17 -0500
commit59d32cb1534a80f7a00afd01d7593e74f634f3dc (patch)
tree220a8bb47fef72e167c78a67d884d0148ddd1dea
parent143eb5e93fc882f6bfe7be8d04839c70d76bdb69 (diff)
downloadFreeBSD-src-59d32cb1534a80f7a00afd01d7593e74f634f3dc.zip
FreeBSD-src-59d32cb1534a80f7a00afd01d7593e74f634f3dc.tar.gz
pf: port extended DSCP support from OpenBSD
Ignore the ECN bits on 'tos' and 'set-tos' and allow to use DCSP names instead of having to embed their TOS equivalents as plain numbers. Obtained from: OpenBSD Sponsored by: OPNsense Differential Revision: https://reviews.freebsd.org/D8165 (cherry picked from commit 3fbefcb2d1d30bf4f987d8ce451572c6722f0601)
-rw-r--r--sbin/pfctl/parse.y73
-rw-r--r--share/man/man5/pf.conf.517
-rw-r--r--sys/netpfil/pf/pf.c2
-rw-r--r--sys/netpfil/pf/pf_norm.c2
4 files changed, 81 insertions, 13 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index c5b86cf..7830032 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -360,6 +360,8 @@ void decide_address_family(struct node_host *, sa_family_t *);
void remove_invalid_hosts(struct node_host **, sa_family_t *);
int invalid_redirect(struct node_host *, sa_family_t);
u_int16_t parseicmpspec(char *, sa_family_t);
+int kw_casecmp(const void *, const void *);
+int map_tos(char *string, int *);
TAILQ_HEAD(loadanchorshead, loadanchors)
loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead);
@@ -3665,15 +3667,17 @@ icmp6type : STRING {
;
tos : STRING {
- if (!strcmp($1, "lowdelay"))
- $$ = IPTOS_LOWDELAY;
- else if (!strcmp($1, "throughput"))
- $$ = IPTOS_THROUGHPUT;
- else if (!strcmp($1, "reliability"))
- $$ = IPTOS_RELIABILITY;
- else if ($1[0] == '0' && $1[1] == 'x')
- $$ = strtoul($1, NULL, 16);
- else
+ int val;
+ char *end;
+
+ if (map_tos($1, &val))
+ $$ = val;
+ else if ($1[0] == '0' && $1[1] == 'x') {
+ errno = 0;
+ $$ = strtoul($1, &end, 16);
+ if (errno || *end != '\0')
+ $$ = 256;
+ } else
$$ = 256; /* flag bad argument */
if ($$ < 0 || $$ > 255) {
yyerror("illegal tos value %s", $1);
@@ -6414,6 +6418,57 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
}
int
+kw_casecmp(const void *k, const void *e)
+{
+ return (strcasecmp(k, ((const struct keywords *)e)->k_name));
+}
+
+int
+map_tos(char *s, int *val)
+{
+ /* DiffServ Codepoints and other TOS mappings */
+ const struct keywords toswords[] = {
+ { "af11", IPTOS_DSCP_AF11 },
+ { "af12", IPTOS_DSCP_AF12 },
+ { "af13", IPTOS_DSCP_AF13 },
+ { "af21", IPTOS_DSCP_AF21 },
+ { "af22", IPTOS_DSCP_AF22 },
+ { "af23", IPTOS_DSCP_AF23 },
+ { "af31", IPTOS_DSCP_AF31 },
+ { "af32", IPTOS_DSCP_AF32 },
+ { "af33", IPTOS_DSCP_AF33 },
+ { "af41", IPTOS_DSCP_AF41 },
+ { "af42", IPTOS_DSCP_AF42 },
+ { "af43", IPTOS_DSCP_AF43 },
+ { "critical", IPTOS_PREC_CRITIC_ECP },
+ { "cs0", IPTOS_DSCP_CS0 },
+ { "cs1", IPTOS_DSCP_CS1 },
+ { "cs2", IPTOS_DSCP_CS2 },
+ { "cs3", IPTOS_DSCP_CS3 },
+ { "cs4", IPTOS_DSCP_CS4 },
+ { "cs5", IPTOS_DSCP_CS5 },
+ { "cs6", IPTOS_DSCP_CS6 },
+ { "cs7", IPTOS_DSCP_CS7 },
+ { "ef", IPTOS_DSCP_EF },
+ { "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
+ { "lowdelay", IPTOS_LOWDELAY },
+ { "netcontrol", IPTOS_PREC_NETCONTROL },
+ { "reliability", IPTOS_RELIABILITY },
+ { "throughput", IPTOS_THROUGHPUT }
+ };
+ const struct keywords *p;
+
+ p = bsearch(s, toswords, sizeof(toswords)/sizeof(toswords[0]),
+ sizeof(toswords[0]), kw_casecmp);
+
+ if (p) {
+ *val = p->k_val;
+ return (1);
+ }
+ return (0);
+}
+
+int
rt_tableid_max(void)
{
#ifdef __FreeBSD__
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index 3ff63bb..6a7eebe 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 9, 2016
+.Dd October 6, 2016
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -648,9 +648,16 @@ for matching IP packets.
.Em TOS
may be
given as one of
+.Ar critical ,
+.Ar inetcontrol ,
.Ar lowdelay ,
+.Ar netcontrol ,
.Ar throughput ,
.Ar reliability ,
+or one of the DiffServ Code Points:
+.Ar ef ,
+.Ar af11 No ... Ar af43 ,
+.Ar cs0 No ... Ar cs7 ;
or as either hex or decimal.
.It Ar random-id
Replaces the IP identification field with random values to compensate
@@ -1697,9 +1704,16 @@ bits set.
.Em TOS
may be
given as one of
+.Ar critical ,
+.Ar inetcontrol ,
.Ar lowdelay ,
+.Ar netcontrol ,
.Ar throughput ,
.Ar reliability ,
+or one of the DiffServ Code Points:
+.Ar ef ,
+.Ar af11 No ... Ar af43 ,
+.Ar cs0 No ... Ar cs7 ;
or as either hex or decimal.
.Pp
For example, the following rules are identical:
@@ -1803,7 +1817,6 @@ pass in proto tcp to port 25 set prio 2
pass in proto tcp to port 22 set prio (2, 5)
.Ed
.Pp
-
.It Ar tag Aq Ar string
Packets matching this rule will be tagged with the
specified string.
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 47f534e..3bc692e 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -6295,7 +6295,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp)
pd.sidx = (dir == PF_IN) ? 0 : 1;
pd.didx = (dir == PF_IN) ? 1 : 0;
pd.af = AF_INET;
- pd.tos = h->ip_tos;
+ pd.tos = h->ip_tos & ~IPTOS_ECN_MASK;
pd.tot_len = ntohs(h->ip_len);
/* handle fragments that didn't get reassembled by normalization */
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index f54e038..81ef54d 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -1815,7 +1815,7 @@ pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
u_int16_t ov, nv;
ov = *(u_int16_t *)h;
- h->ip_tos = tos;
+ h->ip_tos = tos | (h->ip_tos & IPTOS_ECN_MASK);
nv = *(u_int16_t *)h;
h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
OpenPOWER on IntegriCloud