Date: Thu, 1 Dec 2016 11:57:16 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r309358 - projects/ipsec/sys/netipsec Message-ID: <201612011157.uB1BvGBg001782@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612011157.uB1BvGBg001782>