Subject: Re: netipsec/ipsec6.h prototype changes for NetBSD/FreeBSD diffs
To: None <tech-net@NetBSD.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-net
Date: 11/20/2003 13:43:18
And here's the macro version. (Its from a slightly different tree,
where some of the socket-pointer lossage is handled somewhat
differently).

Assume that sys/netipsec provides the following macros for NetBSD
(I'd have gone for shorter names, if macros could start with 4 or 6):

	#define PCB_T		struct inpcb_hdr
	#define PCB_FAMILY(p)	((p)->inp_head.inph_af)

	#define PCB_TO_IN4PCB(p) ((struct inpcb *)(p))
	#define PCB_TO_IN6PCB(p) ((struct in6pcb *)(p))

	#define IN4PCB_TO_PCB(p) ((PCB_T *)&(p)->inp_head)
	#define IN6PCB_TO_PCB(p) ((PCB_T *)&(p)->in6p_head)

Note these macros could also be defined for the KAME model, where the
"generic pcb" is a struct socket *, which may be converted to an inpcb
or in6pcb pointer via pointer-chasing, and the family of the
"generic pcb" can be found by slightly deeper pointer-chasing.



The code fragment then becomes:

Index: ipsec.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/ipsec.c,v
retrieving revision 1.4
diff -u -5 -r1.4 ipsec.c
--- ipsec.c	2003/10/06 22:05:15	1.4
+++ ipsec.c	2003/11/20 21:32:59
@@ -76,10 +76,11 @@
 #ifdef INET6
 #include <netinet6/ip6_var.h>
 #endif
 #include <netinet/in_pcb.h>
 #ifdef INET6
+#include <netinet6/in6_pcb.h>
 #include <netinet/icmp6.h>
 #endif
 
 #include <netipsec/ipsec.h>
 #ifdef INET6
@@ -124,10 +125,13 @@
  * -1	require software support
  *  0	take anything
  */
 int	crypto_support = 0;
 
+static struct secpolicy *ipsec_getpolicybysock(struct mbuf *, u_int,
+	PCB_T *, int *);
+
 #ifdef __FreeBSD__
 SYSCTL_DECL(_net_inet_ipsec);
 
 /* net.inet.ipsec */
 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
@@ -156,19 +160,21 @@
 	crypto_support,	CTLFLAG_RW,	&crypto_support,0, "");
 SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
 	ipsecstats,	CTLFLAG_RD,	&newipsecstat,	newipsecstat, "");
 #endif /* __FreeBSD__ */
 
-
 #ifdef INET6
 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
+struct secpolicy ip6_def_policy;
 int ip6_ipsec_ecn = 0;		/* ECN ignore(-1)/forbidden(0)/allowed(1) */
 int ip6_esp_randpad = -1;
 
+
+#ifdef __FreeBSD__
 SYSCTL_DECL(_net_inet6_ipsec6);
 
 /* net.inet6.ipsec6 */
 #ifdef COMPAT_KAME
 SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
@@ -189,10 +195,11 @@
 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
 	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
 	esp_randpad, CTLFLAG_RW,	&ip6_esp_randpad,	0, "");
 #endif /* INET6 */
+#endif __FreeBSD__
 
 static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *pcb));
 #ifdef INET6
 static int ipsec6_setspidx_in6pcb __P((struct mbuf *, struct in6pcb *pcb));
 #endif
@@ -277,15 +284,15 @@
  *		others	: error occured.
  *	others:	a pointer to SP
  *
  * NOTE: IPv6 mapped adddress concern is implemented here.
  */
-struct secpolicy *
+static struct secpolicy *
 ipsec_getpolicybysock(m, dir, inp, error)
 	struct mbuf *m;
 	u_int dir;
-	struct inpcb *inp;
+	PCB_T *inp;
 	int *error;
 {
 	struct inpcbpolicy *pcbsp = NULL;
 	struct secpolicy *currsp = NULL;	/* policy on socket */
 	struct secpolicy *sp;
@@ -294,27 +301,36 @@
 	IPSEC_ASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
 	IPSEC_ASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
 	IPSEC_ASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
 	IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
 		("ipsec_getpolicybysock: invalid direction %u", dir));
+
+	IPSEC_ASSERT(inp->inp_socket != NULL,
+	    ("ipsec_getppolicybysock: null socket\n"));
 
-	af = inp->inp_socket->so_proto->pr_domain->dom_family;
+	/* XXX FIXME inpcb/in6pcb  vs socket*/
+	af = PCB_FAMILY(inp);
 	IPSEC_ASSERT(af == AF_INET || af == AF_INET6,
 		("ipsec_getpolicybysock: unexpected protocol family %u", af));
 
 	switch (af) {
-	case AF_INET:
+	case AF_INET: {
+		struct inpcb *in4p = PCB_TO_IN4PCB(inp);
 		/* set spidx in pcb */
-		*error = ipsec4_setspidx_inpcb(m, inp);
-		pcbsp = inp->inp_sp;
+		*error = ipsec4_setspidx_inpcb(m, in4p);
+		pcbsp = in4p->inp_sp;
 		break;
-#ifdef INET6
-	case AF_INET6:
+		}
+
+#if defined(INET6)
+	case AF_INET6: {
+		struct in6pcb *in6p = PCB_TO_IN6PCB(inp);
 		/* set spidx in pcb */
-		*error = ipsec6_setspidx_in6pcb(m, inp);
-		pcbsp = inp->in6p_sp;
+		*error = ipsec6_setspidx_in6pcb(m, in6p);
+		pcbsp = in6p->in6p_sp;
 		break;
+		}
 #endif
 	default:
 		*error = EPFNOSUPPORT;
 		break;
 	}
@@ -445,14 +461,17 @@
 	struct inpcb *inp;
 {
 	struct secpolicy *sp;
 
 	*error = 0;
-	if (inp == NULL)
+
+
+	/* XXX KAME IPv6 calls us with non-null inp but bogus inp_socket? */
+	if (inp == NULL || inp->inp_socket == NULL) {
 		sp = ipsec_getpolicybyaddr(m, dir, flag, error);
-	else
-		sp = ipsec_getpolicybysock(m, dir, inp, error);
+	} else
+		sp = ipsec_getpolicybysock(m, dir, IN4PCB_TO_PCB(inp), error);
 	if (sp == NULL) {
 		IPSEC_ASSERT(*error != 0,
 			("ipsec4_checkpolicy: getpolicy failed w/o error"));
 		newipsecstat.ips_out_inval++;
 		return NULL;
@@ -480,10 +499,11 @@
 	}
 	if (*error != 0) {
 		KEY_FREESP(&sp);
 		sp = NULL;
 	}
+	DPRINTF(("ipsecpol: done, sp %p error %d, \n", sp, *error));
 	return sp;
 }
 
 static int
 ipsec4_setspidx_inpcb(m, pcb)
@@ -1451,11 +1471,12 @@
 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 	 */
 	if (inp == NULL)
 		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 	else
-		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
+		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
+					   IN4PCB_TO_PCB(inp), &error);
 
 	if (sp != NULL) {
 		result = ipsec_in_reject(sp, m);
 		if (result)
 			newipsecstat.ips_in_polvio++;
@@ -1473,13 +1494,13 @@
  * Check AH/ESP integrity.
  * This function is called from tcp6_input(), udp6_input(),
  * and {ah,esp}6_input for tunnel mode
  */
 int
-ipsec6_in_reject(m, inp)
+ipsec6_in_reject(m, in6p)
 	struct mbuf *m;
-	struct inpcb *inp;
+	struct in6pcb *in6p;
 {
 	struct secpolicy *sp = NULL;
 	int error;
 	int result;
 
@@ -1489,14 +1510,16 @@
 
 	/* get SP for this packet.
 	 * When we are called from ip_forward(), we call
 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 	 */
-	if (inp == NULL)
+	if (in6p == NULL)
 		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
 	else
-		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
+		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND,
+			IN6PCB_TO_PCB(in6p),
+			&error);
 
 	if (sp != NULL) {
 		result = ipsec_in_reject(sp, m);
 		if (result)
 			newipsecstat.ips_in_polvio++;
@@ -1592,11 +1615,12 @@
 	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
 	 */
 	if (inp == NULL)
 		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 	else
-		sp = ipsec_getpolicybysock(m, dir, inp, &error);
+		sp = ipsec_getpolicybysock(m, dir,
+					   IN4PCB_TO_PCB(inp), &error);
 
 	if (sp != NULL) {
 		size = ipsec_hdrsiz(sp);
 		KEYDEBUG(KEYDEBUG_IPSEC_DATA,
 			printf("ipsec4_hdrsiz: size:%lu.\n",
@@ -1630,11 +1654,13 @@
 	/* get SP for this packet */
 	/* XXX Is it right to call with IP_FORWARDING. */
 	if (in6p == NULL)
 		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
 	else
-		sp = ipsec_getpolicybysock(m, dir, in6p, &error);
+		sp = ipsec_getpolicybysock(m, dir, 
+			IN6PCB_TO_PCB(in6p),
+			&error);
 
 	if (sp == NULL)
 		return 0;
 	size = ipsec_hdrsiz(sp);
 	KEYDEBUG(KEYDEBUG_IPSEC_DATA,