diff options
-rw-r--r-- | sys/netinet/ip_ipsec.c | 4 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 2 | ||||
-rw-r--r-- | sys/netinet6/ip6_ipsec.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 4 | ||||
-rw-r--r-- | sys/netipsec/ipsec.c | 270 | ||||
-rw-r--r-- | sys/netipsec/ipsec.h | 6 | ||||
-rw-r--r-- | sys/netipsec/ipsec6.h | 8 |
9 files changed, 68 insertions, 238 deletions
diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 77e9aa7..4e23a2b 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -218,9 +218,7 @@ ip_ipsec_mtu(struct mbuf *m, int mtu) &ipsecerror); if (sp != NULL) { /* count IPsec header size */ - ipsechdr = ipsec4_hdrsiz(m, - IPSEC_DIR_OUTBOUND, - NULL); + ipsechdr = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL); /* * find the correct route for outer IPv4 diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index feacb51..7ea8d7d 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1050,7 +1050,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */ break; req = mtod(m, caddr_t); - error = ipsec4_set_policy(inp, sopt->sopt_name, req, + error = ipsec_set_policy(inp, sopt->sopt_name, req, m->m_len, (sopt->sopt_td != NULL) ? sopt->sopt_td->td_ucred : NULL); m_freem(m); @@ -1171,7 +1171,7 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) req = mtod(m, caddr_t); len = m->m_len; } - error = ipsec4_get_policy(sotoinpcb(so), req, len, &m); + error = ipsec_get_policy(sotoinpcb(so), req, len, &m); if (error == 0) error = soopt_mcopyout(sopt, m); /* XXX */ if (error == 0) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 53fc882..bba7be3 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1744,7 +1744,7 @@ ipsec_hdrsiz_tcp(struct tcpcb *tp) m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); tcpip_fillheaders(inp, ip6, th); - hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); + hdrsiz = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); } else #endif /* INET6 */ { @@ -1752,7 +1752,7 @@ ipsec_hdrsiz_tcp(struct tcpcb *tp) th = (struct tcphdr *)(ip + 1); m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr); tcpip_fillheaders(inp, ip, th); - hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); + hdrsiz = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); } m_free(m); diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index ca5101f..10a6c45 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -457,7 +457,7 @@ skip_routing: sp = ipsec_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND, IP_FORWARDING, &ipsecerror); if (sp) { - ipsechdrsiz = ipsec6_hdrsiz(mcopy, + ipsechdrsiz = ipsec_hdrsiz(mcopy, IPSEC_DIR_OUTBOUND, NULL); if (ipsechdrsiz < mtu) mtu -= ipsechdrsiz; diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index a6ac5c9..a0c1abc 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -341,9 +341,7 @@ ip6_ipsec_mtu(struct mbuf *m) &ipsecerror); if (sp != NULL) { /* count IPsec header size */ - ipsechdr = ipsec4_hdrsiz(m, - IPSEC_DIR_OUTBOUND, - NULL); + ipsechdr = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL); /* * find the correct route for outer IPv4 diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index ba40b68..2e2dc24 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1799,7 +1799,7 @@ do { \ if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */ break; req = mtod(m, caddr_t); - error = ipsec6_set_policy(in6p, optname, req, + error = ipsec_set_policy(in6p, optname, req, m->m_len, (sopt->sopt_td != NULL) ? sopt->sopt_td->td_ucred : NULL); m_freem(m); @@ -2024,7 +2024,7 @@ do { \ req = mtod(m, caddr_t); len = m->m_len; } - error = ipsec6_get_policy(in6p, req, len, mp); + error = ipsec_get_policy(in6p, req, len, mp); if (error == 0) error = soopt_mcopyout(sopt, m); /* XXX */ if (error == 0 && m) diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index c8d27d2..00ce8de 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -228,10 +228,7 @@ SYSCTL_V_STRUCT(V_NET, vnet_ipsec, _net_inet6_ipsec6, IPSECCTL_STATS, "IPsec IPv6 statistics."); #endif /* INET6 */ -static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *)); -#ifdef INET6 -static int ipsec6_setspidx_inpcb __P((struct mbuf *, struct inpcb *)); -#endif +static int ipsec_setspidx_inpcb __P((struct mbuf *, struct inpcb *)); static int ipsec_setspidx __P((struct mbuf *, struct secpolicyindex *, int)); static void ipsec4_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int)); static int ipsec4_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *)); @@ -241,11 +238,7 @@ static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *)); #endif static void ipsec_delpcbpolicy __P((struct inpcbpolicy *)); static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *src)); -static int ipsec_set_policy __P((struct secpolicy **pcb_sp, - int optname, caddr_t request, size_t len, struct ucred *cred)); -static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp)); static void vshiftl __P((unsigned char *, int, int)); -static size_t ipsec_hdrsiz __P((struct secpolicy *)); MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy"); @@ -358,7 +351,7 @@ static struct secpolicy * ipsec_getpolicybysock(struct mbuf *m, u_int dir, struct inpcb *inp, int *error) { INIT_VNET_IPSEC(curvnet); - struct inpcbpolicy *pcbsp = NULL; + struct inpcbpolicy *pcbsp; struct secpolicy *currsp = NULL; /* Policy on socket. */ struct secpolicy *sp; @@ -369,20 +362,11 @@ ipsec_getpolicybysock(struct mbuf *m, u_int dir, struct inpcb *inp, int *error) ("invalid direction %u", dir)); /* Set spidx in pcb. */ - if (inp->inp_vflag & INP_IPV6PROTO) { -#ifdef INET6 - *error = ipsec6_setspidx_inpcb(m, inp); - pcbsp = inp->inp_sp; -#else - *error = EINVAL; /* Should not happen. */ -#endif - } else { - *error = ipsec4_setspidx_inpcb(m, inp); - pcbsp = inp->inp_sp; - } + *error = ipsec_setspidx_inpcb(m, inp); if (*error) return (NULL); + pcbsp = inp->inp_sp; IPSEC_ASSERT(pcbsp != NULL, ("null pcbsp")); switch (dir) { case IPSEC_DIR_INBOUND: @@ -538,7 +522,7 @@ ipsec4_checkpolicy(struct mbuf *m, u_int dir, u_int flag, int *error, } static int -ipsec4_setspidx_inpcb(struct mbuf *m, struct inpcb *inp) +ipsec_setspidx_inpcb(struct mbuf *m, struct inpcb *inp) { int error; @@ -561,33 +545,6 @@ ipsec4_setspidx_inpcb(struct mbuf *m, struct inpcb *inp) return (error); } -#ifdef INET6 -static int -ipsec6_setspidx_inpcb(struct mbuf *m, struct inpcb *inp) -{ - int error; - - IPSEC_ASSERT(inp != NULL, ("null inp")); - IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp")); - IPSEC_ASSERT(inp->inp_sp->sp_out != NULL && inp->inp_sp->sp_in != NULL, - ("null sp_in || sp_out")); - - error = ipsec_setspidx(m, &inp->inp_sp->sp_in->spidx, 1); - if (error == 0) { - inp->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND; - inp->inp_sp->sp_out->spidx = inp->inp_sp->sp_in->spidx; - inp->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND; - } else { - bzero(&inp->inp_sp->sp_in->spidx, - sizeof(inp->inp_sp->sp_in->spidx)); - bzero(&inp->inp_sp->sp_out->spidx, - sizeof(inp->inp_sp->sp_in->spidx)); - } - - return (error); -} -#endif - /* * Configure security policy index (src/dst/proto/sport/dport) * by looking at the content of mbuf. @@ -1036,8 +993,8 @@ fail: /* Set policy and IPsec request if present. */ static int -ipsec_set_policy(struct secpolicy **pcb_sp, int optname, caddr_t request, - size_t len, struct ucred *cred) +ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname, + caddr_t request, size_t len, struct ucred *cred) { INIT_VNET_IPSEC(curvnet); struct sadb_x_policy *xpl; @@ -1056,7 +1013,7 @@ ipsec_set_policy(struct secpolicy **pcb_sp, int optname, caddr_t request, kdebug_sadb_x_policy((struct sadb_ext *)xpl)); /* Check policy type. */ - /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */ + /* ipsec_set_policy_internal() accepts IPSEC, ENTRUST and BYPASS. */ if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE) return (EINVAL); @@ -1084,30 +1041,8 @@ ipsec_set_policy(struct secpolicy **pcb_sp, int optname, caddr_t request, return (0); } -static int -ipsec_get_policy(struct secpolicy *pcb_sp, struct mbuf **mp) -{ - INIT_VNET_IPSEC(curvnet); - - /* Sanity check. */ - if (pcb_sp == NULL || mp == NULL) - return (EINVAL); - - *mp = key_sp2msg(pcb_sp); - if (!*mp) { - ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); - return (ENOBUFS); - } - - (*mp)->m_type = MT_DATA; - KEYDEBUG(KEYDEBUG_IPSEC_DUMP, - printf("%s:\n", __func__); kdebug_mbuf(*mp)); - - return (0); -} - int -ipsec4_set_policy(struct inpcb *inp, int optname, caddr_t request, +ipsec_set_policy(struct inpcb *inp, int optname, caddr_t request, size_t len, struct ucred *cred) { INIT_VNET_IPSEC(curvnet); @@ -1135,11 +1070,11 @@ ipsec4_set_policy(struct inpcb *inp, int optname, caddr_t request, return (EINVAL); } - return (ipsec_set_policy(pcb_sp, optname, request, len, cred)); + return (ipsec_set_policy_internal(pcb_sp, optname, request, len, cred)); } int -ipsec4_get_policy(struct inpcb *inp, caddr_t request, size_t len, +ipsec_get_policy(struct inpcb *inp, caddr_t request, size_t len, struct mbuf **mp) { INIT_VNET_IPSEC(curvnet); @@ -1168,7 +1103,21 @@ ipsec4_get_policy(struct inpcb *inp, caddr_t request, size_t len, return (EINVAL); } - return (ipsec_get_policy(pcb_sp, mp)); + /* Sanity check. Should be an IPSEC_ASSERT. */ + if (pcb_sp == NULL) + return (EINVAL); + + *mp = key_sp2msg(pcb_sp); + if (!*mp) { + ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); + return (ENOBUFS); + } + + (*mp)->m_type = MT_DATA; + KEYDEBUG(KEYDEBUG_IPSEC_DUMP, + printf("%s:\n", __func__); kdebug_mbuf(*mp)); + + return (0); } /* Delete policy in PCB. */ @@ -1192,73 +1141,6 @@ ipsec_delete_pcbpolicy(struct inpcb *inp) return (0); } -#ifdef INET6 -int -ipsec6_set_policy(struct inpcb *inp, int optname, caddr_t request, - size_t len, struct ucred *cred) -{ - INIT_VNET_IPSEC(curvnet); - struct sadb_x_policy *xpl; - struct secpolicy **pcb_sp; - - /* Sanity check. */ - if (inp == NULL || request == NULL) - return (EINVAL); - if (len < sizeof(*xpl)) - return (EINVAL); - xpl = (struct sadb_x_policy *)request; - - /* Select direction. */ - switch (xpl->sadb_x_policy_dir) { - case IPSEC_DIR_INBOUND: - pcb_sp = &inp->inp_sp->sp_in; - break; - case IPSEC_DIR_OUTBOUND: - pcb_sp = &inp->inp_sp->sp_out; - break; - default: - ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, - xpl->sadb_x_policy_dir)); - return (EINVAL); - } - - return (ipsec_set_policy(pcb_sp, optname, request, len, cred)); -} - -int -ipsec6_get_policy(struct inpcb *inp, caddr_t request, size_t len, - struct mbuf **mp) -{ - INIT_VNET_IPSEC(curvnet); - struct sadb_x_policy *xpl; - struct secpolicy *pcb_sp; - - /* Sanity check. */ - if (inp == NULL || request == NULL || mp == NULL) - return (EINVAL); - IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp")); - if (len < sizeof(*xpl)) - return (EINVAL); - xpl = (struct sadb_x_policy *)request; - - /* Select direction. */ - switch (xpl->sadb_x_policy_dir) { - case IPSEC_DIR_INBOUND: - pcb_sp = inp->inp_sp->sp_in; - break; - case IPSEC_DIR_OUTBOUND: - pcb_sp = inp->inp_sp->sp_out; - break; - default: - ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, - xpl->sadb_x_policy_dir)); - return (EINVAL); - } - - return (ipsec_get_policy(pcb_sp, mp)); -} -#endif - /* * Return current level. * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned. @@ -1437,15 +1319,9 @@ ipsec_in_reject(struct secpolicy *sp, struct mbuf *m) return (0); /* Valid. */ } -/* - * Check AH/ESP integrity. - * This function is called from tcp_input(), udp_input(), - * and {ah,esp}4_input for tunnel mode. - */ -int -ipsec4_in_reject(struct mbuf *m, struct inpcb *inp) +static int +ipsec46_in_reject(struct mbuf *m, struct inpcb *inp) { - INIT_VNET_IPSEC(curvnet); struct secpolicy *sp; int error; int result; @@ -1464,8 +1340,6 @@ ipsec4_in_reject(struct mbuf *m, struct inpcb *inp) if (sp != NULL) { result = ipsec_in_reject(sp, m); - if (result) - V_ipsec4stat.ips_in_polvio++; KEY_FREESP(&sp); } else { result = 0; /* XXX Should be panic? @@ -1474,6 +1348,24 @@ ipsec4_in_reject(struct mbuf *m, struct inpcb *inp) return (result); } +/* + * Check AH/ESP integrity. + * This function is called from tcp_input(), udp_input(), + * and {ah,esp}4_input for tunnel mode. + */ +int +ipsec4_in_reject(struct mbuf *m, struct inpcb *inp) +{ + INIT_VNET_IPSEC(curvnet); + int result; + + result = ipsec46_in_reject(m, inp); + if (result) + V_ipsec4stat.ips_in_polvio++; + + return (result); +} + #ifdef INET6 /* * Check AH/ESP integrity. @@ -1484,31 +1376,12 @@ int ipsec6_in_reject(struct mbuf *m, struct inpcb *inp) { INIT_VNET_IPSEC(curvnet); - struct secpolicy *sp = NULL; - int error; int result; - /* Sanity check. */ - if (m == NULL) - return (0); /* XXX Should be panic? */ - - /* Get SP for this packet. - * When we are called from ip_forward(), we call - * 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); + result = ipsec46_in_reject(m, inp); + if (result) + V_ipsec6stat.ips_in_polvio++; - if (sp != NULL) { - result = ipsec_in_reject(sp, m); - if (result) - V_ipsec6stat.ips_in_polvio++; - KEY_FREESP(&sp); - } else { - result = 0; - } return (result); } #endif @@ -1519,7 +1392,7 @@ ipsec6_in_reject(struct mbuf *m, struct inpcb *inp) * NOTE: SP passed is freed in this function. */ static size_t -ipsec_hdrsiz(struct secpolicy *sp) +ipsec_hdrsiz_internal(struct secpolicy *sp) { INIT_VNET_IPSEC(curvnet); struct ipsecrequest *isr; @@ -1577,9 +1450,12 @@ ipsec_hdrsiz(struct secpolicy *sp) return (size); } -/* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */ +/* + * This function is called from ipsec_hdrsiz_tcp(), ip_ipsec_mtu(), + * disabled ip6_ipsec_mtu() and ip6_forward(). + */ size_t -ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp) +ipsec_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp) { INIT_VNET_IPSEC(curvnet); struct secpolicy *sp; @@ -1598,7 +1474,7 @@ ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp) sp = ipsec_getpolicybysock(m, dir, inp, &error); if (sp != NULL) { - size = ipsec_hdrsiz(sp); + size = ipsec_hdrsiz_internal(sp); KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("%s: size:%lu.\n", __func__, (unsigned long)size)); @@ -1612,40 +1488,6 @@ ipsec4_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp) return (size); } -#ifdef INET6 -/* This function is called from ipsec6_hdrsize_tcp(), - * and maybe from ip6_forward(). - */ -size_t -ipsec6_hdrsiz(struct mbuf *m, u_int dir, struct inpcb *inp) -{ - INIT_VNET_IPSEC(curvnet); - struct secpolicy *sp; - int error; - size_t size; - - IPSEC_ASSERT(m != NULL, ("null mbuf")); - IPSEC_ASSERT(inp == NULL || inp->inp_socket != NULL, - ("socket w/o inpcb")); - - /* Get SP for this packet. */ - /* XXX Is it right to call with IP_FORWARDING. */ - if (inp == NULL) - sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error); - else - sp = ipsec_getpolicybysock(m, dir, inp, &error); - - if (sp == NULL) - return (0); - size = ipsec_hdrsiz(sp); - KEYDEBUG(KEYDEBUG_IPSEC_DATA, - printf("%s: size:%lu.\n", __func__, (unsigned long)size)); - KEY_FREESP(&sp); - - return (size); -} -#endif /*INET6*/ - /* * Check the variable replay window. * ipsec_chkreplay() performs replay check before ICV verification. diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index ccf4fd1..d5e7c157 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -374,9 +374,9 @@ extern int ipsec_copy_policy extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *)); extern int ipsec_in_reject __P((struct secpolicy *, struct mbuf *)); -extern int ipsec4_set_policy __P((struct inpcb *inp, int optname, +extern int ipsec_set_policy __P((struct inpcb *inp, int optname, caddr_t request, size_t len, struct ucred *cred)); -extern int ipsec4_get_policy __P((struct inpcb *inpcb, caddr_t request, +extern int ipsec_get_policy __P((struct inpcb *inpcb, caddr_t request, size_t len, struct mbuf **mp)); extern int ipsec_delete_pcbpolicy __P((struct inpcb *)); extern int ipsec4_in_reject __P((struct mbuf *, struct inpcb *)); @@ -386,7 +386,7 @@ struct tcpcb; extern int ipsec_chkreplay __P((u_int32_t, struct secasvar *)); extern int ipsec_updatereplay __P((u_int32_t, struct secasvar *)); -extern size_t ipsec4_hdrsiz __P((struct mbuf *, u_int, struct inpcb *)); +extern size_t ipsec_hdrsiz __P((struct mbuf *, u_int, struct inpcb *)); extern size_t ipsec_hdrsiz_tcp __P((struct tcpcb *)); union sockaddr_union; diff --git a/sys/netipsec/ipsec6.h b/sys/netipsec/ipsec6.h index f09ba18..6612407 100644 --- a/sys/netipsec/ipsec6.h +++ b/sys/netipsec/ipsec6.h @@ -50,16 +50,8 @@ extern int ip6_ipsec_ecn; struct inpcb; -extern int ipsec6_set_policy __P((struct inpcb *inp, int optname, - caddr_t request, size_t len, struct ucred *cred)); -extern int ipsec6_get_policy - __P((struct inpcb *inp, caddr_t request, size_t len, struct mbuf **mp)); extern int ipsec6_in_reject __P((struct mbuf *, struct inpcb *)); -struct tcp6cb; - -extern size_t ipsec6_hdrsiz __P((struct mbuf *, u_int, struct inpcb *)); - struct ip6_hdr; extern const char *ipsec6_logpacketstr __P((struct ip6_hdr *, u_int32_t)); |