svn commit: r309358 - projects/ipsec/sys/netipsec
Andrey V. Elsukov
ae at FreeBSD.org
Thu Dec 1 11:57:17 UTC 2016
Author: ae
Date: Thu Dec 1 11:57:15 2016
New Revision: 309358
URL: https://svnweb.freebsd.org/changeset/base/309358
Log:
Add ipsec_setsockaddrs_inpcb() function to fill sockaddr_union unions
using information from INPCB. Add direction argument, it is used to
choose local or foreign addresses as source or destination.
Change ipsec_setspidx_inpcb() function to use ipsec_setsockaddrs_inpcb().
Modified:
projects/ipsec/sys/netipsec/ipsec.c
Modified: projects/ipsec/sys/netipsec/ipsec.c
==============================================================================
--- projects/ipsec/sys/netipsec/ipsec.c Thu Dec 1 09:14:58 2016 (r309357)
+++ projects/ipsec/sys/netipsec/ipsec.c Thu Dec 1 11:57:15 2016 (r309358)
@@ -247,7 +247,8 @@ SYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6,
static int ipsec_in_reject(struct secpolicy *, struct inpcb *,
const struct mbuf *);
-static void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *);
+static void ipsec_setspidx_inpcb(struct inpcb *, struct secpolicyindex *,
+ u_int);
static void ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
static void ipsec4_setspidx_ipaddr(const struct mbuf *,
@@ -285,7 +286,7 @@ ipsec_checkpolicy(struct secpolicy *sp,
{
uint32_t genid;
- if (inp != NULL &&
+ if (inp != NULL && inp->inp_sp != NULL &&
(inp->inp_sp->flags & INP_OUTBOUND_POLICY) == 0 &&
inp->inp_sp->sp_out == NULL) {
/*
@@ -369,61 +370,100 @@ ipsec_getpcbpolicy(struct inpcb *inp, u_
}
static void
-ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx)
+ipsec_setsockaddrs_inpcb(struct inpcb *inp, union sockaddr_union *src,
+ union sockaddr_union *dst, u_int dir)
{
#ifdef INET6
if (inp->inp_vflag & INP_IPV6) {
- bzero(&spidx->src.sin6, sizeof(spidx->src.sin6));
- spidx->src.sin6.sin6_family = AF_INET6;
- spidx->src.sin6.sin6_len = sizeof(struct sockaddr_in6);
- spidx->src.sin6.sin6_addr = inp->in6p_laddr;
- spidx->src.sin6.sin6_port = inp->inp_lport;
+ struct sockaddr_in6 *sin6;
+
+ bzero(&src->sin6, sizeof(src->sin6));
+ bzero(&dst->sin6, sizeof(dst->sin6));
+ src->sin6.sin6_family = AF_INET6;
+ src->sin6.sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6.sin6_family = AF_INET6;
+ dst->sin6.sin6_len = sizeof(struct sockaddr_in6);
+
+ if (dir == IPSEC_DIR_OUTBOUND)
+ sin6 = &src->sin6;
+ else
+ sin6 = &dst->sin6;
+ sin6->sin6_addr = inp->in6p_laddr;
+ sin6->sin6_port = inp->inp_lport;
if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_laddr)) {
/* XXXAE: use in6p_zoneid */
- spidx->src.sin6.sin6_addr.s6_addr16[1] = 0;
- spidx->src.sin6.sin6_scope_id = ntohs(
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ sin6->sin6_scope_id = ntohs(
inp->in6p_laddr.s6_addr16[1]);
}
- spidx->prefs = sizeof(struct in6_addr) << 3;
- bzero(&spidx->dst.sin6, sizeof(spidx->dst.sin6));
- spidx->dst.sin6.sin6_family = AF_INET6;
- spidx->dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
- spidx->dst.sin6.sin6_addr = inp->in6p_faddr;
- spidx->dst.sin6.sin6_port = inp->inp_fport;
+ if (dir == IPSEC_DIR_OUTBOUND)
+ sin6 = &dst->sin6;
+ else
+ sin6 = &src->sin6;
+ sin6->sin6_addr = inp->in6p_faddr;
+ sin6->sin6_port = inp->inp_fport;
if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_faddr)) {
/* XXXAE: use in6p_zoneid */
- spidx->dst.sin6.sin6_addr.s6_addr16[1] = 0;
- spidx->dst.sin6.sin6_scope_id = ntohs(
+ sin6->sin6_addr.s6_addr16[1] = 0;
+ sin6->sin6_scope_id = ntohs(
inp->in6p_faddr.s6_addr16[1]);
}
+ }
+#endif
+#ifdef INET
+ if (inp->inp_vflag & INP_IPV4) {
+ struct sockaddr_in *sin;
+
+ bzero(&src->sin, sizeof(src->sin));
+ bzero(&dst->sin, sizeof(dst->sin));
+ src->sin.sin_family = AF_INET;
+ src->sin.sin_len = sizeof(struct sockaddr_in);
+ dst->sin.sin_family = AF_INET;
+ dst->sin.sin_len = sizeof(struct sockaddr_in);
+
+ if (dir == IPSEC_DIR_OUTBOUND)
+ sin = &src->sin;
+ else
+ sin = &dst->sin;
+ sin->sin_addr = inp->inp_laddr;
+ sin->sin_port = inp->inp_lport;
+
+ if (dir == IPSEC_DIR_OUTBOUND)
+ sin = &dst->sin;
+ else
+ sin = &src->sin;
+ sin->sin_addr = inp->inp_faddr;
+ sin->sin_port = inp->inp_fport;
+ }
+#endif
+}
+
+static void
+ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx,
+ u_int dir)
+{
+
+ ipsec_setsockaddrs_inpcb(inp, &spidx->src, &spidx->dst, dir);
+#ifdef INET6
+ if (inp->inp_vflag & INP_IPV6) {
+ spidx->prefs = sizeof(struct in6_addr) << 3;
spidx->prefd = sizeof(struct in6_addr) << 3;
}
#endif
#ifdef INET
if (inp->inp_vflag & INP_IPV4) {
- bzero(&spidx->src.sin, sizeof(spidx->src.sin));
- spidx->src.sin.sin_family = AF_INET;
- spidx->src.sin.sin_len = sizeof(struct sockaddr_in);
- spidx->src.sin.sin_addr = inp->inp_laddr;
- spidx->src.sin.sin_port = inp->inp_lport;
spidx->prefs = sizeof(struct in_addr) << 3;
-
- bzero(&spidx->dst.sin, sizeof(spidx->dst.sin));
- spidx->dst.sin.sin_family = AF_INET;
- spidx->dst.sin.sin_len = sizeof(struct sockaddr_in);
- spidx->dst.sin.sin_addr = inp->inp_faddr;
- spidx->dst.sin.sin_port = inp->inp_fport;
spidx->prefd = sizeof(struct in_addr) << 3;
}
#endif
spidx->ul_proto = inp->inp_ip_p;
+ spidx->dir = dir;
KEYDBG(IPSEC_DUMP,
printf("%s: ", __func__); kdebug_secpolicyindex(spidx, NULL));
}
-
#ifdef INET
static void
ipsec4_get_ulp(const struct mbuf *m, struct secpolicyindex *spidx,
@@ -1408,8 +1448,7 @@ ipsec_hdrsiz_inpcb(struct inpcb *inp)
sp = ipsec_getpcbpolicy(inp, IPSEC_DIR_OUTBOUND);
if (sp == NULL && key_havesp(IPSEC_DIR_OUTBOUND)) {
- ipsec_setspidx_inpcb(inp, &spidx);
- spidx.dir = IPSEC_DIR_OUTBOUND;
+ ipsec_setspidx_inpcb(inp, &spidx, IPSEC_DIR_OUTBOUND);
sp = key_allocsp(&spidx, IPSEC_DIR_OUTBOUND);
}
if (sp == NULL)
More information about the svn-src-projects
mailing list