Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Nov 2016 19:06:29 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r308861 - projects/ipsec/sys/netinet
Message-ID:  <201611191906.uAJJ6T5V030247@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sat Nov 19 19:06:29 2016
New Revision: 308861
URL: https://svnweb.freebsd.org/changeset/base/308861

Log:
  Change ip_ipsec_output() to return only two values 0 and 1.
  
  It returns 1 when IPSec consumes mbuf or some fatal error occured.
  In case of error it frees mbuf. When no IPSec processing is required,
  it returns zero. Also change its prototype to take mbuf pointer,
  since we don't expect that mbuf can be changed, but not consumed.
  
  Add IPSEC_OUTPUT() wrapper macro to hide call to ip_ipsec_output().
  I guess such interface will be used by IPsec module.
  
  Remove direction argument from ipsec4_checkpolicy(). This function is
  intended to use only with OUTBOUND traffic.
  Also change ipsec4_process_packet() to take security policy returned by
  ipsec4_checkpolicy() instead of accession to ipsecrequest. Add inpcb
  pointer to arguments list, it will be needed to update hdrsz field of
  struct inpcbpolicy.

Modified:
  projects/ipsec/sys/netinet/ip_ipsec.c
  projects/ipsec/sys/netinet/ip_ipsec.h
  projects/ipsec/sys/netinet/ip_output.c

Modified: projects/ipsec/sys/netinet/ip_ipsec.c
==============================================================================
--- projects/ipsec/sys/netinet/ip_ipsec.c	Sat Nov 19 18:19:21 2016	(r308860)
+++ projects/ipsec/sys/netinet/ip_ipsec.c	Sat Nov 19 19:06:29 2016	(r308861)
@@ -145,19 +145,14 @@ ip_ipsec_mtu(struct mbuf *m, int mtu)
 }
 
 /*
- * 
  * Called from ip_output().
- * 1 = drop packet, 0 = continue processing packet,
- * -1 = packet was reinjected and stop processing packet
+ * 0 = continue processing packet
+ * 1 = packet was consumed, stop processing
  */
 int
-ip_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error)
+ip_ipsec_output(struct mbuf *m, struct inpcb *inp, int *error)
 {
 	struct secpolicy *sp;
-
-	if (!key_havesp(IPSEC_DIR_OUTBOUND))
-		return 0;
-
 	/*
 	 * Check the security policy (SP) for the packet and, if
 	 * required, do IPsec-related processing.  There are two
@@ -167,14 +162,13 @@ ip_ipsec_output(struct mbuf **m, struct 
 	 * AH, ESP, etc. processing), there will be a tag to bypass
 	 * the lookup and related policy checking.
 	 */
-	if (m_tag_find(*m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) {
-		*error = 0;
+	*error = 0;
+	if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL)
 		return (0);
-	}
-	sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, error, inp);
+	sp = ipsec4_checkpolicy(m, inp, error);
 	/*
 	 * There are four return cases:
-	 *    sp != NULL	 	    apply IPsec policy
+	 *    sp != NULL		    apply IPsec policy
 	 *    sp == NULL, error == 0	    no IPsec handling needed
 	 *    sp == NULL, error == -EINVAL  discard packet w/o error
 	 *    sp == NULL, error != 0	    discard packet, report error
@@ -184,22 +178,21 @@ ip_ipsec_output(struct mbuf **m, struct 
 		 * Do delayed checksums now because we send before
 		 * this is done in the normal processing path.
 		 */
-		if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
-			in_delayed_cksum(*m);
-			(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+		if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+			in_delayed_cksum(m);
+			m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 		}
 #ifdef SCTP
-		if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
-			struct ip *ip = mtod(*m, struct ip *);
+		if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
+			struct ip *ip = mtod(m, struct ip *);
 
-			sctp_delayed_cksum(*m, (uint32_t)(ip->ip_hl << 2));
-			(*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+			sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
+			m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
 		}
 #endif
 
-		/* NB: callee frees mbuf */
-		*error = ipsec4_process_packet(*m, sp->req);
-		KEY_FREESP(&sp);
+		/* NB: callee frees mbuf and releases reference to SP */
+		*error = ipsec4_process_packet(m, sp, inp);
 		if (*error == EJUSTRETURN) {
 			/*
 			 * We had a SP with a level of 'use' and no SA. We
@@ -207,20 +200,10 @@ ip_ipsec_output(struct mbuf **m, struct 
 			 * IPsec processing and return without error.
 			 */
 			*error = 0;
-			goto done;
+			return (0);
 		}
-		/*
-		 * Preserve KAME behaviour: ENOENT can be returned
-		 * when an SA acquire is in progress.  Don't propagate
-		 * this to user-level; it confuses applications.
-		 *
-		 * XXX this will go away when the SADB is redone.
-		 */
-		if (*error == ENOENT)
-			*error = 0;
-		goto reinjected;
+		return (1);	/* mbuf consumed by IPsec */
 	} else {	/* sp == NULL */
-
 		if (*error != 0) {
 			/*
 			 * Hack: -EINVAL is used to signal that a packet
@@ -230,16 +213,10 @@ ip_ipsec_output(struct mbuf **m, struct 
 			 */
 			if (*error == -EINVAL)
 				*error = 0;
-			goto bad;
+			m_freem(m);
+			return (1);
 		}
 		/* No IPsec processing for this packet. */
 	}
-done:
 	return (0);
-reinjected:
-	return (-1);
-bad:
-	if (sp != NULL)
-		KEY_FREESP(&sp);
-	return 1;
 }

Modified: projects/ipsec/sys/netinet/ip_ipsec.h
==============================================================================
--- projects/ipsec/sys/netinet/ip_ipsec.h	Sat Nov 19 18:19:21 2016	(r308860)
+++ projects/ipsec/sys/netinet/ip_ipsec.h	Sat Nov 19 19:06:29 2016	(r308861)
@@ -32,9 +32,11 @@
 #ifndef _NETINET_IP_IPSEC_H_
 #define _NETINET_IP_IPSEC_H_
 
+#define	IPSEC_OUTPUT(sc, m, inp, perr)	ip_ipsec_output((m), (inp), (perr))
+
 int	ip_ipsec_filtertunnel(struct mbuf *);
 int	ip_ipsec_fwd(struct mbuf *);
 int	ip_ipsec_input(struct mbuf *, int);
 int	ip_ipsec_mtu(struct mbuf *, int);
-int	ip_ipsec_output(struct mbuf **, struct inpcb *, int *);
+int	ip_ipsec_output(struct mbuf *, struct inpcb *, int *);
 #endif

Modified: projects/ipsec/sys/netinet/ip_output.c
==============================================================================
--- projects/ipsec/sys/netinet/ip_output.c	Sat Nov 19 18:19:21 2016	(r308860)
+++ projects/ipsec/sys/netinet/ip_output.c	Sat Nov 19 19:06:29 2016	(r308861)
@@ -556,15 +556,8 @@ again:
 
 sendit:
 #ifdef IPSEC
-	switch(ip_ipsec_output(&m, inp, &error)) {
-	case 1:
-		goto bad;
-	case -1:
+	if (IPSEC_OUTPUT(ipv4, m, inp, &error) != 0)
 		goto done;
-	case 0:
-	default:
-		break;	/* Continue with packet processing. */
-	}
 	/*
 	 * Check if there was a route for this packet; return error if not.
 	 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611191906.uAJJ6T5V030247>