git: 347dd0539f3a - main - tcp: add TH_AE capabilities to ppp and pf

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Fri, 29 Nov 2024 09:50:29 UTC
The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=347dd0539f3a75fdf2128dd4620ca99e96f311e9

commit 347dd0539f3a75fdf2128dd4620ca99e96f311e9
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2024-11-29 08:50:24 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2024-11-29 09:04:31 +0000

    tcp: add TH_AE capabilities to ppp and pf
    
    Add support for the AE Flag in the TCP header to pf and ppp.
    Commonalize to the use of "E"(ECE), "W"(CWR) and "e"(AE)
    for the TCP header flags, in line with tcpdump.
    
    Reviewers: kp, cc, tuexen, cy, #transport!
    Sponsored by: NetApp, Inc.
    Differential Revision: https://reviews.freebsd.org/D47106
---
 sbin/ipf/common/ipf.h                    |  4 ++--
 sbin/ipf/ipf/ipf.5                       |  4 ++--
 sbin/ipf/ipftest/ipftest.1               |  2 +-
 sbin/ipf/iplang/iplang_y.y               |  8 ++++----
 sbin/ipf/ipmon/ipmon.c                   |  5 +++--
 sbin/ipf/ipsend/ip.c                     |  2 +-
 sbin/ipf/ipsend/ipsend.5                 |  3 ++-
 sbin/ipf/ipsend/ipsend.c                 | 25 +++++++++++++++++--------
 sbin/ipf/ipsend/iptests.c                | 23 +++++++++++------------
 sbin/ipf/ipsend/resend.c                 |  4 ++--
 sbin/ipf/libipf/flags.c                  |  9 ++++++---
 sbin/ipf/libipf/ipft_tx.c                | 22 +++++++++++-----------
 sbin/ipf/libipf/printpacket.c            | 23 +++++++++++++----------
 sbin/ipf/libipf/printtcpflags.c          |  6 +++---
 sbin/ipf/libipf/tcp_flags.c              | 12 ++++++------
 sbin/ipf/libipf/tcpflags.c               | 11 +++++++----
 sbin/pfctl/pfctl_parser.c                | 11 ++++++-----
 sbin/pfctl/pfctl_parser.h                |  2 --
 sys/net/pfvar.h                          |  2 +-
 sys/netinet/tcp.h                        |  2 +-
 sys/netpfil/ipfilter/netinet/ip_compat.h |  8 ++++----
 sys/netpfil/pf/pf.c                      |  4 +++-
 usr.sbin/ppp/ip.c                        |  4 ++--
 23 files changed, 108 insertions(+), 88 deletions(-)

diff --git a/sbin/ipf/common/ipf.h b/sbin/ipf/common/ipf.h
index 20a0087ed5a1..3e6ee594b8b6 100644
--- a/sbin/ipf/common/ipf.h
+++ b/sbin/ipf/common/ipf.h
@@ -178,7 +178,7 @@ typedef	int	(* copyfunc_t)(void *, void *, size_t);
 
 extern	char	thishost[MAXHOSTNAMELEN];
 extern	char	flagset[];
-extern	u_char	flags[];
+extern	uint16_t flags[];
 extern	struct ipopt_names ionames[];
 extern	struct ipopt_names secclass[];
 extern	char	*icmpcodes[MAX_ICMPCODE + 1];
@@ -330,7 +330,7 @@ extern int remove_hash(struct iphtable_s *, ioctlfunc_t);
 extern int remove_hashnode(int, char *, struct iphtent_s *, ioctlfunc_t);
 extern int remove_pool(ip_pool_t *, ioctlfunc_t);
 extern int remove_poolnode(int, char *, ip_pool_node_t *, ioctlfunc_t);
-extern u_char tcpflags(char *);
+extern uint16_t tcpflags(char *);
 extern void printc(struct frentry *);
 extern void printC(int);
 extern void emit(int, int, void *, struct frentry *);
diff --git a/sbin/ipf/ipf/ipf.5 b/sbin/ipf/ipf/ipf.5
index 32e9913353a0..4ff33290814a 100644
--- a/sbin/ipf/ipf/ipf.5
+++ b/sbin/ipf/ipf/ipf.5
@@ -533,10 +533,10 @@ When matching TCP flags, it is normal to just list the flag that you
 wish to be set. By default the set of flags it is compared against
 is "FSRPAU". Rules that say "flags S" will be displayed by ipfstat(8)
 as having "flags S/FSRPAU". This is normal.
-The last two flags, "C" and "E", are optional - they
+The last three flags, "E", "W" and "e", are optional - they
 may or may not be used by an end host and have no bearing on either
 the acceptance of data nor control of the connection. Masking them
-out with "flags S/FSRPAUCE" may cause problems for remote hosts
+out with "flags S/FSRPAUEWe" may cause problems for remote hosts
 making a successful connection.
 .PP
 .nf
diff --git a/sbin/ipf/ipftest/ipftest.1 b/sbin/ipf/ipftest/ipftest.1
index 5c5fe60901a0..456304c9d0b2 100644
--- a/sbin/ipf/ipftest/ipftest.1
+++ b/sbin/ipf/ipftest/ipftest.1
@@ -125,7 +125,7 @@ This is the default if no \fB\-F\fP argument is specified.
 The format used is as follows:
 .nf
 	"in"|"out" "on" if ["tcp"|"udp"|"icmp"]
-		srchost[,srcport] dsthost[,destport] [FSRPAU]
+		srchost[,srcport] dsthost[,destport] [FSRPAUEWe]
 .fi
 .PP
 This allows for a packet going "in" or "out" of an interface (if) to be
diff --git a/sbin/ipf/iplang/iplang_y.y b/sbin/ipf/iplang/iplang_y.y
index c5c7c729e0a9..ce55ad277c1a 100644
--- a/sbin/ipf/iplang/iplang_y.y
+++ b/sbin/ipf/iplang/iplang_y.y
@@ -1045,9 +1045,9 @@ void set_tcpsum(char **arg)
 
 void set_tcpflags(char **arg)
 {
-	static	char	flags[] = "ASURPF";
+	static	char	flags[] = "ASURPFEWe";
 	static	int	flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH,
-				    TH_FIN } ;
+				    TH_FIN, TH_ECE, TH_CWR, TH_AE } ;
 	char *s, *t;
 
 	for (s = *arg; *s; s++)
@@ -1056,10 +1056,10 @@ void set_tcpflags(char **arg)
 				fprintf(stderr, "unknown TCP flag %c\n", *s);
 				break;
 			}
-			tcp->th_flags = strtol(*arg, NULL, 0);
+			__tcp_set_flags(tcp, strtol(*arg, NULL, 0));
 			break;
 		} else
-			tcp->th_flags |= flagv[t - flags];
+			__tcp_set_flags(tcp, __tcp_get_flags(tcp) | flagv[t - flags]);
 	free(*arg);
 	*arg = NULL;
 }
diff --git a/sbin/ipf/ipmon/ipmon.c b/sbin/ipf/ipmon/ipmon.c
index 80d1d406529a..a07401ff5e88 100644
--- a/sbin/ipf/ipmon/ipmon.c
+++ b/sbin/ipf/ipmon/ipmon.c
@@ -77,7 +77,8 @@ struct	flags	tcpfl[] = {
 	{ TH_URG, 'U' },
 	{ TH_PUSH,'P' },
 	{ TH_ECN, 'E' },
-	{ TH_CWR, 'C' },
+	{ TH_CWR, 'W' },
+	{ TH_AE,  'e' },
 	{ 0, '\0' }
 };
 
@@ -1196,7 +1197,7 @@ print_ipflog(config_t *conf, char *buf, int blen)
 				*t++ = ' ';
 				*t++ = '-';
 				for (i = 0; tcpfl[i].value; i++)
-					if (tp->th_flags & tcpfl[i].value)
+					if (__tcp_get_flags(tp) & tcpfl[i].value)
 						*t++ = tcpfl[i].flag;
 				if (ipmonopts & IPMON_VERBOSE) {
 					sprintf(t, " %lu %lu %hu",
diff --git a/sbin/ipf/ipsend/ip.c b/sbin/ipf/ipsend/ip.c
index 177563e65c9c..8cdfca893d15 100644
--- a/sbin/ipf/ipsend/ip.c
+++ b/sbin/ipf/ipsend/ip.c
@@ -261,7 +261,7 @@ send_tcp(int nfd, int mtu, ip_t *ip, struct in_addr gwip)
 
 	i = sizeof(struct tcpiphdr) / sizeof(long);
 
-	if ((t2->th_flags == TH_SYN) && !ntohs(ip->ip_off) &&
+	if ((__tcp_get_flags(t2) == TH_SYN) && !ntohs(ip->ip_off) &&
 	    (lbuf[i] != htonl(0x020405b4))) {
 		lbuf[i] = htonl(0x020405b4);
 		bcopy((char *)ip + hlen + thlen, (char *)ip + hlen + thlen + 4,
diff --git a/sbin/ipf/ipsend/ipsend.5 b/sbin/ipf/ipsend/ipsend.5
index 440cb0a5f23b..67c456e54d34 100644
--- a/sbin/ipf/ipsend/ipsend.5
+++ b/sbin/ipf/ipsend/ipsend.5
@@ -250,7 +250,8 @@ unset, it defaults to 0 and is automatically calculated.
 .TP
 .B flags <tcp-flags>
 sets the TCP flags field to match the flags specified.  Valid flags are
-"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH).
+"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH),
+"E" (ECE), "W" (CWR), "e" (AE).
 .TP
 .B opt
 indicates that TCP header options follow.  As TCP options are added to the
diff --git a/sbin/ipf/ipsend/ipsend.c b/sbin/ipf/ipsend/ipsend.c
index 83440d7cb097..2e2cf8f36fa2 100644
--- a/sbin/ipf/ipsend/ipsend.c
+++ b/sbin/ipf/ipsend/ipsend.c
@@ -365,22 +365,31 @@ main(int argc, char **argv)
 			switch(c)
 			{
 			case 'S' : case 's' :
-				tcp->th_flags |= TH_SYN;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_SYN);
 				break;
 			case 'A' : case 'a' :
-				tcp->th_flags |= TH_ACK;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_ACK);
 				break;
 			case 'F' : case 'f' :
-				tcp->th_flags |= TH_FIN;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_FIN);
 				break;
 			case 'R' : case 'r' :
-				tcp->th_flags |= TH_RST;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_RST);
 				break;
 			case 'P' : case 'p' :
-				tcp->th_flags |= TH_PUSH;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_PUSH);
 				break;
 			case 'U' : case 'u' :
-				tcp->th_flags |= TH_URG;
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_URG);
+				break;
+			case 'E' :
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_ECE);
+				break;
+			case 'W' :
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_CWR);
+				break;
+			case 'e' :
+				__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_AE);
 				break;
 			}
 
@@ -390,8 +399,8 @@ main(int argc, char **argv)
 	printf("Source:  %s\n", inet_ntoa(ip->ip_src));
 	printf("Dest:    %s\n", inet_ntoa(ip->ip_dst));
 	printf("Gateway: %s\n", inet_ntoa(gwip));
-	if (ip->ip_p == IPPROTO_TCP && tcp->th_flags)
-		printf("Flags:   %#x\n", tcp->th_flags);
+	if (ip->ip_p == IPPROTO_TCP && __tcp_get_flags(tcp))
+		printf("Flags:   %#x\n", __tcp_get_flags(tcp));
 	printf("mtu:     %d\n", mtu);
 
 	if (ip->ip_p == IPPROTO_UDP) {
diff --git a/sbin/ipf/ipsend/iptests.c b/sbin/ipf/ipsend/iptests.c
index 1015e74a3254..eb8001b579d8 100644
--- a/sbin/ipf/ipsend/iptests.c
+++ b/sbin/ipf/ipsend/iptests.c
@@ -924,9 +924,8 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 		 */
 		TCP_OFF_A(t, sizeof(*t) >> 2);
 		printf("5.1 Test TCP flag combinations\n");
-		for (i = 0; i <= (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN);
-		     i++) {
-			t->th_flags = i;
+		for (i = 0; i <= TH_FLAGS; i++) {
+			__tcp_set_flags(t, i);
 			(void) send_tcp(nfd, mtu, ip, gwip);
 			printf("%d\r", i);
 			fflush(stdout);
@@ -936,7 +935,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 	}
 
 	if (!ptest || (ptest == 2)) {
-		t->th_flags = TH_SYN;
+		__tcp_set_flags(t, TH_SYN);
 		/*
 		 * Test 2: seq = 0, seq = 1, seq = 0x7fffffff, seq=0x80000000,
 		 *         seq = 0xa000000, seq = 0xffffffff
@@ -979,7 +978,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 	}
 
 	if (!ptest || (ptest == 3)) {
-		t->th_flags = TH_ACK;
+		__tcp_set_flags(t, TH_ACK);
 		/*
 		 * Test 3: ack = 0, ack = 1, ack = 0x7fffffff, ack = 0x8000000
 		 *         ack = 0xa000000, ack = 0xffffffff
@@ -1022,7 +1021,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 	}
 
 	if (!ptest || (ptest == 4)) {
-		t->th_flags = TH_SYN;
+		__tcp_set_flags(t, TH_SYN);
 		/*
 		 * Test 4: win = 0, win = 32768, win = 65535
 		 */
@@ -1092,7 +1091,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 		/*
 		 * Test 5: urp
 		 */
-		t->th_flags = TH_ACK|TH_URG;
+		__tcp_set_flags(t, TH_ACK|TH_URG);
 		printf("5.5.1 TCP Urgent pointer, sport %hu dport %hu\n",
 			ntohs(t->th_sport), ntohs(t->th_dport));
 		t->th_urp = htons(1);
@@ -1111,7 +1110,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 		(void) send_tcp(nfd, mtu, ip, gwip);
 		PAUSE();
 		t->th_urp = 0;
-		t->th_flags &= ~TH_URG;
+		__tcp_set_flags(t, __tcp_get_flags(t) & ~TH_URG);
 		ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t);
 	}
 
@@ -1119,7 +1118,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct  in_addr gwip, int ptest)
 		/*
 		 * Test 6: data offset, off = 0, off is inside, off is outside
 		 */
-		t->th_flags = TH_ACK;
+		__tcp_set_flags(t, TH_ACK);
 		printf("5.6.1 TCP off = 1-15, len = 40\n");
 		for (i = 1; i < 16; i++) {
 			TCP_OFF_A(t, ntohs(i));
@@ -1141,7 +1140,7 @@ skip_five_and_six:
 	TCP_OFF_A(t, 0);
 
 	if (!ptest || (ptest == 7)) {
-		t->th_flags = TH_SYN;
+		__tcp_set_flags(t, TH_SYN);
 		/*
 		 * Test 7: sport = 0, sport = 1, sport = 32767
 		 *         sport = 32768, sport = 65535
@@ -1179,7 +1178,7 @@ skip_five_and_six:
 
 	if (!ptest || (ptest == 8)) {
 		t->th_sport = htons(1);
-		t->th_flags = TH_SYN;
+		__tcp_set_flags(t, TH_SYN);
 		/*
 		 * Test 8: dport = 0, dport = 1, dport = 32767
 		 *         dport = 32768, dport = 65535
@@ -1221,7 +1220,7 @@ skip_five_and_six:
 		/* chose SMTP port 25 */
 		t->th_sport = htons(25);
 		t->th_dport = htons(25);
-		t->th_flags = TH_SYN;
+		__tcp_set_flags(t, TH_SYN);
 		ip->ip_src = ip->ip_dst;
 		(void) send_tcp(nfd, mtu, ip, gwip);
 		fflush(stdout);
diff --git a/sbin/ipf/ipsend/resend.c b/sbin/ipf/ipsend/resend.c
index 1512f8293c8c..bbecf46e51c0 100644
--- a/sbin/ipf/ipsend/resend.c
+++ b/sbin/ipf/ipsend/resend.c
@@ -51,8 +51,8 @@ dumppacket(ip_t *ip)
 		printf(" seq %lu:%lu flags ",
 			(u_long)t->th_seq, (u_long)t->th_ack);
 		for (j = 0, i = 1; i < 256; i *= 2, j++)
-			if (t->th_flags & i)
-				printf("%c", "FSRPAU--"[j]);
+			if (__tcp_get_flags(t) & i)
+				printf("%c", "FSRPAUEWe"[j]);
 	}
 	putchar('\n');
 }
diff --git a/sbin/ipf/libipf/flags.c b/sbin/ipf/libipf/flags.c
index f16624b97d4f..b476936e0dba 100644
--- a/sbin/ipf/libipf/flags.c
+++ b/sbin/ipf/libipf/flags.c
@@ -18,7 +18,10 @@
 #ifndef TH_CWR
 # define	TH_CWR  0x80
 #endif
+#ifndef TH_AE
+# define	TH_AE  0x100
+#endif
 
-char	flagset[] = "FSRPAUEC";
-u_char	flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
-		    TH_ECN, TH_CWR };
+char	flagset[] = "FSRPAUEWe";
+uint16_t flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
+		    TH_ECN, TH_CWR, TH_AE };
diff --git a/sbin/ipf/libipf/ipft_tx.c b/sbin/ipf/libipf/ipft_tx.c
index e54a7e15f982..87e0fcb449d2 100644
--- a/sbin/ipf/libipf/ipft_tx.c
+++ b/sbin/ipf/libipf/ipft_tx.c
@@ -20,9 +20,9 @@ static	int	text_open(char *), text_close(void);
 static	int	text_readip(mb_t *, char **, int *);
 static	int	parseline(char *, ip_t *, char **, int *);
 
-static	char	myflagset[] = "FSRPAUEC";
-static	u_char	myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
-				TH_ACK, TH_URG, TH_ECN, TH_CWR };
+static	char	myflagset[] = "FSRPAUEWe";
+static	uint16_t myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
+				TH_ACK, TH_URG, TH_ECN, TH_CWR, TH_AE };
 
 struct	ipread	iptext = { text_open, text_close, text_readip, R_DO_CKSUM };
 static	FILE	*tfp = NULL;
@@ -265,15 +265,15 @@ parseline(char *line, ip_t *ip, char **ifn, int *out)
 		if (*cpp != NULL) {
 			char	*s, *t;
 
-			tcp->th_flags = 0;
+			__tcp_set_flags(tcp, 0);
 			for (s = *cpp; *s; s++)
 				if ((t  = strchr(myflagset, *s)))
-					tcp->th_flags |= myflags[t-myflagset];
-			if (tcp->th_flags)
+					__tcp_set_flags(tcp, __tcp_get_flags(tcp) | myflags[t-myflagset]);
+			if (__tcp_get_flags(tcp))
 				cpp++;
 		}
 
-		if (tcp->th_flags & TH_URG)
+		if (__tcp_get_flags(tcp) & TH_URG)
 			tcp->th_urp = htons(1);
 
 		if (*cpp && !strncasecmp(*cpp, "seq=", 4)) {
@@ -436,15 +436,15 @@ parseipv6(char **cpp, ip6_t *ip6, char **ifn, int *out)
 		if (*cpp != NULL) {
 			char *s, *t;
 
-			tcp->th_flags = 0;
+			__tcp_set_flags(tcp, 0);
 			for (s = *cpp; *s; s++)
 				if ((t  = strchr(myflagset, *s)))
-					tcp->th_flags |= myflags[t-myflagset];
-			if (tcp->th_flags)
+					__tcp_set_flags(tcp, __tcp_get_flags(tcp) | myflags[t-myflagset]);
+			if (__tcp_get_flags(tcp))
 				cpp++;
 		}
 
-		if (tcp->th_flags & TH_URG)
+		if (__tcp_get_flags(tcp) & TH_URG)
 			tcp->th_urp = htons(1);
 
 		if (*cpp && !strncasecmp(*cpp, "seq=", 4)) {
diff --git a/sbin/ipf/libipf/printpacket.c b/sbin/ipf/libipf/printpacket.c
index a48725a220e0..5d1d79bb4bb9 100644
--- a/sbin/ipf/libipf/printpacket.c
+++ b/sbin/ipf/libipf/printpacket.c
@@ -19,6 +19,7 @@ printpacket(int dir, mb_t *m)
 {
 	u_short len, off;
 	tcphdr_t *tcp;
+	uint16_t tcpflags;
 	ip_t *ip;
 
 	ip = MTOD(m, ip_t *);
@@ -82,24 +83,26 @@ printpacket(int dir, mb_t *m)
 	if (!(off & IP_OFFMASK)) {
 		if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
 			PRINTF(",%d", ntohs(tcp->th_dport));
-		if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) {
+		if ((ip->ip_p == IPPROTO_TCP) && ((tcpflags = __tcp_get_flags(tcp)) != 0)) {
 			putchar(' ');
-			if (tcp->th_flags & TH_FIN)
+			if (tcpflags & TH_FIN)
 				putchar('F');
-			if (tcp->th_flags & TH_SYN)
+			if (tcpflags & TH_SYN)
 				putchar('S');
-			if (tcp->th_flags & TH_RST)
+			if (tcpflags & TH_RST)
 				putchar('R');
-			if (tcp->th_flags & TH_PUSH)
+			if (tcpflags & TH_PUSH)
 				putchar('P');
-			if (tcp->th_flags & TH_ACK)
+			if (tcpflags & TH_ACK)
 				putchar('A');
-			if (tcp->th_flags & TH_URG)
+			if (tcpflags & TH_URG)
 				putchar('U');
-			if (tcp->th_flags & TH_ECN)
+			if (tcpflags & TH_ECN)
 				putchar('E');
-			if (tcp->th_flags & TH_CWR)
-				putchar('C');
+			if (tcpflags & TH_CWR)
+				putchar('W');
+			if (tcpflags & TH_AE)
+				putchar('e');
 		}
 	}
 
diff --git a/sbin/ipf/libipf/printtcpflags.c b/sbin/ipf/libipf/printtcpflags.c
index d134fb4a3120..349e18be127e 100644
--- a/sbin/ipf/libipf/printtcpflags.c
+++ b/sbin/ipf/libipf/printtcpflags.c
@@ -4,10 +4,10 @@
 void
 printtcpflags(u_32_t tcpf, u_32_t tcpfm)
 {
-	u_char *t;
+	uint16_t *t;
 	char *s;
 
-	if (tcpf & ~TCPF_ALL) {
+	if (tcpf & ~TH_FLAGS) {
 		PRINTF("0x%x", tcpf);
 	} else {
 		for (s = flagset, t = flags; *s; s++, t++) {
@@ -18,7 +18,7 @@ printtcpflags(u_32_t tcpf, u_32_t tcpfm)
 
 	if (tcpfm) {
 		(void)putchar('/');
-		if (tcpfm & ~TCPF_ALL) {
+		if (tcpfm & ~TH_FLAGS) {
 			PRINTF("0x%x", tcpfm);
 		} else {
 			for (s = flagset, t = flags; *s; s++, t++)
diff --git a/sbin/ipf/libipf/tcp_flags.c b/sbin/ipf/libipf/tcp_flags.c
index 0156d8cd7f31..9247933ee85b 100644
--- a/sbin/ipf/libipf/tcp_flags.c
+++ b/sbin/ipf/libipf/tcp_flags.c
@@ -9,13 +9,13 @@
 
 #include "ipf.h"
 
-extern	char	flagset[];
-extern	u_char	flags[];
+extern	char	 flagset[];
+extern	uint16_t flags[];
 
 
-u_char tcp_flags(char *flgs, u_char *mask, int linenum)
+uint16_t tcp_flags(char *flgs, uint16_t *mask, int linenum)
 {
-	u_char tcpf = 0, tcpfm = 0;
+	uint16_t tcpf = 0, tcpfm = 0;
 	char *s;
 
 	s = strchr(flgs, '/');
@@ -37,9 +37,9 @@ u_char tcp_flags(char *flgs, u_char *mask, int linenum)
 
 	if (!tcpfm) {
 		if (tcpf == TH_SYN)
-			tcpfm = 0xff & ~(TH_ECN|TH_CWR);
+			tcpfm = TH_FLAGS & ~(TH_ECN|TH_CWR);
 		else
-			tcpfm = 0xff & ~(TH_ECN);
+			tcpfm = TH_FLAGS & ~(TH_ECN);
 	}
 	*mask = tcpfm;
 	return (tcpf);
diff --git a/sbin/ipf/libipf/tcpflags.c b/sbin/ipf/libipf/tcpflags.c
index 92437d1be798..46b64e96deda 100644
--- a/sbin/ipf/libipf/tcpflags.c
+++ b/sbin/ipf/libipf/tcpflags.c
@@ -19,14 +19,17 @@
 #ifndef TH_CWR
 # define	TH_CWR  0x80
 #endif
+#ifndef TH_AE
+# define	TH_AE  0x100
+#endif
 
-extern	char	flagset[];
-extern	u_char	flags[];
+extern	char	 flagset[];
+extern	uint16_t flags[];
 
 
-u_char tcpflags(char *flgs)
+uint16_t tcpflags(char *flgs)
 {
-	u_char tcpf = 0;
+	uint16_t tcpf = 0;
 	char *s, *t;
 
 	for (s = flgs; *s; s++) {
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index c25e96e645fb..d6d04ba2a7de 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -44,6 +44,7 @@
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/icmp6.h>
+#include <netinet/tcp.h>
 #include <net/pfvar.h>
 #include <arpa/inet.h>
 
@@ -67,7 +68,7 @@
 void		 print_op (u_int8_t, const char *, const char *);
 void		 print_port (u_int8_t, u_int16_t, u_int16_t, const char *, int);
 void		 print_ugid (u_int8_t, unsigned, unsigned, const char *, unsigned);
-void		 print_flags (u_int8_t);
+void		 print_flags (uint16_t);
 void		 print_fromto(struct pf_rule_addr *, pf_osfp_t,
 		    struct pf_rule_addr *, sa_family_t, u_int8_t, int, int);
 int		 ifa_skip_if(const char *filter, struct node_host *p);
@@ -77,7 +78,7 @@ struct node_host	*host_v4(const char *, int);
 struct node_host	*host_v6(const char *, int);
 struct node_host	*host_dns(const char *, int, int);
 
-const char * const tcpflags = "FSRPAUEW";
+const char * const tcpflags = "FSRPAUEWe";
 
 static const struct icmptypeent icmp_type[] = {
 	{ "echoreq",	ICMP_ECHO },
@@ -365,7 +366,7 @@ print_ugid(u_int8_t op, unsigned u1, unsigned u2, const char *t, unsigned umax)
 }
 
 void
-print_flags(u_int8_t f)
+print_flags(uint16_t f)
 {
 	int	i;
 
@@ -1286,7 +1287,7 @@ int
 parse_flags(char *s)
 {
 	char		*p, *q;
-	u_int8_t	 f = 0;
+	uint16_t	 f = 0;
 
 	for (p = s; *p; p++) {
 		if ((q = strchr(tcpflags, *p)) == NULL)
@@ -1294,7 +1295,7 @@ parse_flags(char *s)
 		else
 			f |= 1 << (q - tcpflags);
 	}
-	return (f ? f : PF_TH_ALL);
+	return (f ? f : TH_FLAGS);
 }
 
 void
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index e6959e0b95a7..498027f5968c 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -55,8 +55,6 @@
 #define PF_OPT_RECURSE		0x4000
 #define PF_OPT_KILLMATCH	0x8000
 
-#define PF_TH_ALL		0xFF
-
 #define PF_NAT_PROXY_PORT_LOW	50001
 #define PF_NAT_PROXY_PORT_HIGH	65535
 
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 51f525c7383b..0a0a17d2c754 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2343,7 +2343,7 @@ extern struct pf_ksrc_node	*pf_find_src_node(struct pf_addr *,
 extern void			 pf_unlink_src_node(struct pf_ksrc_node *);
 extern u_int			 pf_free_src_nodes(struct pf_ksrc_node_list *);
 extern void			 pf_print_state(struct pf_kstate *);
-extern void			 pf_print_flags(u_int8_t);
+extern void			 pf_print_flags(uint16_t);
 extern int			 pf_addr_wrap_neq(struct pf_addr_wrap *,
 				    struct pf_addr_wrap *);
 extern u_int16_t		 pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 613019a575e8..69a8116a2201 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -71,7 +71,7 @@ struct tcphdr {
 #define	TH_RES3	0x200
 #define	TH_RES2	0x400
 #define	TH_RES1	0x800
-#define	TH_FLAGS	(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR)
+#define	TH_FLAGS	(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR|TH_AE)
 #define	PRINT_TH_FLAGS	"\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE\10CWR\11AE"
 
 	u_short	th_win;			/* window */
diff --git a/sys/netpfil/ipfilter/netinet/ip_compat.h b/sys/netpfil/ipfilter/netinet/ip_compat.h
index c73af315b132..67fc878f65ba 100644
--- a/sys/netpfil/ipfilter/netinet/ip_compat.h
+++ b/sys/netpfil/ipfilter/netinet/ip_compat.h
@@ -695,9 +695,6 @@ typedef	struct	tcpiphdr	tcpiphdr_t;
 #endif
 #define	IPMINLEN(i, h)	((i)->ip_len >= (IP_HL(i) * 4 + sizeof(struct h)))
 
-#define	TCPF_ALL	(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|\
-			 TH_ECN|TH_CWR)
-
 #if !SOLARIS && !defined(m_act)
 # define	m_act	m_nextpkt
 #endif
@@ -1128,7 +1125,10 @@ typedef	struct	tcpiphdr	tcpiphdr_t;
 #ifndef TH_CWR
 # define	TH_CWR	0x80
 #endif
-#define	TH_ECNALL	(TH_ECN|TH_CWR)
+#ifndef TH_AE
+# define	TH_AE	0x100
+#endif
+#define	TH_ECNALL	(TH_ECN|TH_CWR|TH_AE)
 
 /*
  * TCP States
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 1e9cd8e0f7d3..db23559774d0 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -2934,7 +2934,7 @@ pf_print_state_parts(struct pf_kstate *s,
 }
 
 void
-pf_print_flags(u_int8_t f)
+pf_print_flags(uint16_t f)
 {
 	if (f)
 		printf(" ");
@@ -2954,6 +2954,8 @@ pf_print_flags(u_int8_t f)
 		printf("E");
 	if (f & TH_CWR)
 		printf("W");
+	if (f & TH_AE)
+		printf("e");
 }
 
 #define	PF_SET_SKIP_STEPS(i)					\
diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c
index 978470a875ac..b4c38f1933e5 100644
--- a/usr.sbin/ppp/ip.c
+++ b/usr.sbin/ppp/ip.c
@@ -561,7 +561,7 @@ PacketCheck(struct bundle *bundle, u_int32_t family,
 {
   char logbuf[200];
   static const char *const TcpFlags[] = {
-    "FIN", "SYN", "RST", "PSH", "ACK", "URG"
+    "FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECE", "CWR", "AE"
   };
   const struct tcphdr *th;
   const struct udphdr *uh;
@@ -830,7 +830,7 @@ PacketCheck(struct bundle *bundle, u_int32_t family,
                "%s:%d", ncpaddr_ntoa(&dstaddr), ntohs(th->th_dport));
       loglen += strlen(logbuf + loglen);
       n = 0;
-      for (mask = TH_FIN; mask != 0x40; mask <<= 1) {
+      for (mask = TH_FIN; mask <= TH_FLAGS; mask <<= 1) {
         if (__tcp_get_flags(th) & mask) {
           snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]);
           loglen += strlen(logbuf + loglen);