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,