git: 489482e276cf - main - ipsec: isolate knowledge about protocols that are last header

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 17 Aug 2022 15:24:54 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=489482e276cf301ba3c47e022a50b0f4f6d2b6f2

commit 489482e276cf301ba3c47e022a50b0f4f6d2b6f2
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-17 15:24:11 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-08-17 15:24:28 +0000

    ipsec: isolate knowledge about protocols that are last header
    
    Retire PR_LASTHDR protosw flag.
    
    Reviewed by:            ae
    Differential revision:  https://reviews.freebsd.org/D36155
---
 sys/kern/uipc_debug.c      |  4 ----
 sys/netinet/in_proto.c     | 22 +++++++++++-----------
 sys/netinet/sctp_module.c  |  8 ++++----
 sys/netinet6/in6_proto.c   | 16 ++++++++--------
 sys/netipsec/ipsec_input.c | 41 ++++++++++++++++++++++++++++++++++-------
 sys/sys/protosw.h          |  2 +-
 6 files changed, 58 insertions(+), 35 deletions(-)

diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c
index ead7d0e506c0..c553ee1047b6 100644
--- a/sys/kern/uipc_debug.c
+++ b/sys/kern/uipc_debug.c
@@ -288,10 +288,6 @@ db_print_prflags(short pr_flags)
 		db_printf("%sPR_IMPLOPCL", comma ? ", " : "");
 		comma = 1;
 	}
-	if (pr_flags & PR_LASTHDR) {
-		db_printf("%sPR_LASTHDR", comma ? ", " : "");
-		comma = 1;
-	}
 }
 
 static void
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index b9f506518cce..81c078e2f306 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -145,7 +145,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_SEQPACKET,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_WANTRCVD,
 	.pr_input =		sctp_input,
 	.pr_ctlinput =		sctp_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -156,7 +156,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_STREAM,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD,
 	.pr_input =		sctp_input,
 	.pr_ctlinput =		sctp_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -188,7 +188,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_ICMP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		icmp_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -197,7 +197,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_IGMP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		igmp_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_fasttimo =		igmp_fasttimo,
@@ -208,7 +208,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_RSVP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		rsvp_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -217,7 +217,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_IPV4,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -226,7 +226,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_MOBILE,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -235,7 +235,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_ETHERIP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -244,7 +244,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_GRE,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -254,7 +254,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_IPV6,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
@@ -264,7 +264,7 @@ struct protosw inetsw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_PIM,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap4_input,
 	.pr_ctloutput =		rip_ctloutput,
 	.pr_usrreqs =		&rip_usrreqs
diff --git a/sys/netinet/sctp_module.c b/sys/netinet/sctp_module.c
index 70a9daeffc2a..faa7fca49d28 100644
--- a/sys/netinet/sctp_module.c
+++ b/sys/netinet/sctp_module.c
@@ -59,7 +59,7 @@ struct protosw sctp_stream_protosw = {
 	.pr_type =		SOCK_STREAM,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD,
 	.pr_input =		sctp_input,
 	.pr_ctlinput =		sctp_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -71,7 +71,7 @@ struct protosw sctp_seqpacket_protosw = {
 	.pr_type =		SOCK_SEQPACKET,
 	.pr_domain =		&inetdomain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_WANTRCVD,
 	.pr_input =		sctp_input,
 	.pr_ctlinput =		sctp_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -87,7 +87,7 @@ struct protosw sctp6_stream_protosw = {
 	.pr_type =		SOCK_STREAM,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD,
 	.pr_input =		sctp6_input,
 	.pr_ctlinput =		sctp6_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -99,7 +99,7 @@ struct protosw sctp6_seqpacket_protosw = {
 	.pr_type =		SOCK_SEQPACKET,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_WANTRCVD,
 	.pr_input =		sctp6_input,
 	.pr_ctlinput =		sctp6_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index b47b726a9a71..a34b7aa9cc7f 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -180,7 +180,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_SEQPACKET,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_WANTRCVD,
 	.pr_input =		sctp6_input,
 	.pr_ctlinput =		sctp6_ctlinput,
 	.pr_ctloutput =	sctp_ctloutput,
@@ -193,7 +193,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_STREAM,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_SCTP,
-	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR,
+	.pr_flags =		PR_CONNREQUIRED|PR_WANTRCVD,
 	.pr_input =		sctp6_input,
 	.pr_ctlinput =		sctp6_ctlinput,
 	.pr_ctloutput =		sctp_ctloutput,
@@ -225,7 +225,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_ICMPV6,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		icmp6_input,
 	.pr_ctlinput =		rip6_ctlinput,
 	.pr_ctloutput =		rip6_ctloutput,
@@ -262,7 +262,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_IPV4,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap6_input,
 	.pr_ctloutput =		rip6_ctloutput,
 	.pr_usrreqs =		&rip6_usrreqs
@@ -272,7 +272,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_IPV6,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap6_input,
 	.pr_ctloutput =		rip6_ctloutput,
 	.pr_usrreqs =		&rip6_usrreqs
@@ -281,7 +281,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_ETHERIP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap6_input,
 	.pr_ctloutput =		rip6_ctloutput,
 	.pr_usrreqs =		&rip6_usrreqs
@@ -290,7 +290,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_GRE,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap6_input,
 	.pr_ctloutput =		rip6_ctloutput,
 	.pr_usrreqs =		&rip6_usrreqs
@@ -299,7 +299,7 @@ struct protosw inet6sw[] = {
 	.pr_type =		SOCK_RAW,
 	.pr_domain =		&inet6domain,
 	.pr_protocol =		IPPROTO_PIM,
-	.pr_flags =		PR_ATOMIC|PR_ADDR|PR_LASTHDR,
+	.pr_flags =		PR_ATOMIC|PR_ADDR,
 	.pr_input =		encap6_input,
 	.pr_ctloutput =		rip6_ctloutput,
 	.pr_usrreqs =		&rip6_usrreqs
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c
index 268d8a797c35..1548a87c844d 100644
--- a/sys/netipsec/ipsec_input.c
+++ b/sys/netipsec/ipsec_input.c
@@ -228,8 +228,6 @@ ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
 }
 
 #ifdef INET
-extern struct protosw inetsw[];
-
 /*
  * IPSEC_INPUT() method implementation for IPv4.
  *  0 - Permitted by inbound security policy for further processing.
@@ -253,9 +251,21 @@ ipsec4_input(struct mbuf *m, int offset, int proto)
 		 * Protocols with further headers get their IPsec treatment
 		 * within the protocol specific processing.
 		 */
-		if ((inetsw[ip_protox[proto]].pr_flags & PR_LASTHDR) == 0)
+		switch (proto) {
+		case IPPROTO_ICMP:
+		case IPPROTO_IGMP:
+		case IPPROTO_IPV4:
+		case IPPROTO_IPV6:
+		case IPPROTO_RSVP:
+		case IPPROTO_GRE:
+		case IPPROTO_MOBILE:
+		case IPPROTO_ETHERIP:
+		case IPPROTO_PIM:
+		case IPPROTO_SCTP:
+			break;
+		default:
 			return (0);
-		/* FALLTHROUGH */
+		}
 	};
 	/*
 	 * Enforce IPsec policy checking if we are seeing last header.
@@ -501,6 +511,24 @@ bad_noepoch:
 #endif /* INET */
 
 #ifdef INET6
+static bool
+ipsec6_lasthdr(int proto)
+{
+
+	switch (proto) {
+	case IPPROTO_IPV4:
+	case IPPROTO_IPV6:
+	case IPPROTO_GRE:
+	case IPPROTO_ICMPV6:
+	case IPPROTO_ETHERIP:
+	case IPPROTO_PIM:
+	case IPPROTO_SCTP:
+		return (true);
+	default:
+		return (false);
+	};
+}
+
 /*
  * IPSEC_INPUT() method implementation for IPv6.
  *  0 - Permitted by inbound security policy for further processing.
@@ -524,7 +552,7 @@ ipsec6_input(struct mbuf *m, int offset, int proto)
 		 * Protocols with further headers get their IPsec treatment
 		 * within the protocol specific processing.
 		 */
-		if ((inet6sw[ip6_protox[proto]].pr_flags & PR_LASTHDR) == 0)
+		if (!ipsec6_lasthdr(proto))
 			return (0);
 		/* FALLTHROUGH */
 	};
@@ -728,8 +756,7 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
 		 * note that we do not visit this with protocols with pcb layer
 		 * code - like udp/tcp/raw ip.
 		 */
-		if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 &&
-		    ipsec6_in_reject(m, NULL)) {
+		if (ipsec6_lasthdr(nxt) && ipsec6_in_reject(m, NULL)) {
 			error = EINVAL;
 			goto bad;
 		}
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 1f48ef9ef55f..d08b20f24604 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -161,7 +161,7 @@ struct protosw {
 #define	PR_WANTRCVD	0x08		/* want PRU_RCVD calls */
 #define	PR_RIGHTS	0x10		/* passes capabilities */
 #define PR_IMPLOPCL	0x20		/* implied open/close */
-#define	PR_LASTHDR	0x40		/* enforce ipsec policy; last header */
+/* was	PR_LASTHDR	0x40		   enforce ipsec policy; last header */
 #define	PR_CAPATTACH	0x80		/* socket can attach in cap mode */
 #define	PR_SOCKBUF	0x100		/* private implementation of buffers */