Module Name: src Committed By: tls Date: Sun Aug 10 06:56:34 UTC 2014
Modified Files: src/sys/netipsec [tls-earlyentropy]: ipsec.c ipsec.h ipsec_netbsd.c key.c key.h keysock.c keysock.h xform_ipip.c Log Message: Rebase. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.62.2.1 src/sys/netipsec/ipsec.c cvs rdiff -u -r1.34 -r1.34.6.1 src/sys/netipsec/ipsec.h cvs rdiff -u -r1.36 -r1.36.2.1 src/sys/netipsec/ipsec_netbsd.c cvs rdiff -u -r1.86 -r1.86.2.1 src/sys/netipsec/key.c cvs rdiff -u -r1.12 -r1.12.6.1 src/sys/netipsec/key.h cvs rdiff -u -r1.21 -r1.21.26.1 src/sys/netipsec/keysock.c cvs rdiff -u -r1.6 -r1.6.62.1 src/sys/netipsec/keysock.h cvs rdiff -u -r1.29 -r1.29.6.1 src/sys/netipsec/xform_ipip.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netipsec/ipsec.c diff -u src/sys/netipsec/ipsec.c:1.62 src/sys/netipsec/ipsec.c:1.62.2.1 --- src/sys/netipsec/ipsec.c:1.62 Tue Dec 24 15:48:53 2013 +++ src/sys/netipsec/ipsec.c Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsec.c,v 1.62 2013/12/24 15:48:53 christos Exp $ */ +/* $NetBSD: ipsec.c,v 1.62.2.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.c,v 1.2.2.2 2003/07/01 01:38:13 sam Exp $ */ /* $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.62 2013/12/24 15:48:53 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1.62.2.1 2014/08/10 06:56:34 tls Exp $"); /* * IPsec controller part. @@ -106,6 +106,9 @@ __KERNEL_RCSID(0, "$NetBSD: ipsec.c,v 1. #include <net/net_osdep.h> +int ipsec_used = 0; +int ipsec_enabled = 1; + #ifdef IPSEC_DEBUG int ipsec_debug = 1; Index: src/sys/netipsec/ipsec.h diff -u src/sys/netipsec/ipsec.h:1.34 src/sys/netipsec/ipsec.h:1.34.6.1 --- src/sys/netipsec/ipsec.h:1.34 Sat Jun 8 13:50:22 2013 +++ src/sys/netipsec/ipsec.h Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsec.h,v 1.34 2013/06/08 13:50:22 rmind Exp $ */ +/* $NetBSD: ipsec.h,v 1.34.6.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netipsec/ipsec.h,v 1.2.4.2 2004/02/14 22:23:23 bms Exp $ */ /* $KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $ */ @@ -354,6 +354,7 @@ int ipsec_clear_socket_cache(struct mbuf void nat_t_ports_get(struct mbuf *, u_int16_t *, u_int16_t *); +extern int ipsec_used __read_mostly, ipsec_enabled __read_mostly; #endif /* _KERNEL */ Index: src/sys/netipsec/ipsec_netbsd.c diff -u src/sys/netipsec/ipsec_netbsd.c:1.36 src/sys/netipsec/ipsec_netbsd.c:1.36.2.1 --- src/sys/netipsec/ipsec_netbsd.c:1.36 Tue Feb 25 18:30:12 2014 +++ src/sys/netipsec/ipsec_netbsd.c Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsec_netbsd.c,v 1.36 2014/02/25 18:30:12 pooka Exp $ */ +/* $NetBSD: ipsec_netbsd.c,v 1.36.2.1 2014/08/10 06:56:34 tls Exp $ */ /* $KAME: esp_input.c,v 1.60 2001/09/04 08:43:19 itojun Exp $ */ /* $KAME: ah_input.c,v 1.64 2001/09/04 08:43:19 itojun Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.36 2014/02/25 18:30:12 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipsec_netbsd.c,v 1.36.2.1 2014/08/10 06:56:34 tls Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -473,6 +473,34 @@ sysctl_net_inet_ipip_stats(SYSCTLFN_ARGS return (NETSTAT_SYSCTL(ipipstat_percpu, IPIP_NSTATS)); } +static int +sysctl_net_ipsec_enabled(SYSCTLFN_ARGS) +{ + int newenabled, error; + struct sysctlnode node; + node = *rnode; + node.sysctl_data = &newenabled; + + newenabled = ipsec_enabled; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL) + return error; + + switch (newenabled) { + case 0: + if (key_get_used()) + return EBUSY; + /*FALLTHROUGH*/ + case 1: + case 2: + ipsec_enabled = newenabled; + key_update_used(); + return 0; + default: + return EINVAL; + } +} + /* XXX will need a different oid at parent */ SYSCTL_SETUP(sysctl_net_inet_ipsec_setup, "sysctl net.inet.ipsec subtree setup") { @@ -660,6 +688,20 @@ SYSCTL_SETUP(sysctl_net_inet_ipsec_setup sysctl_net_inet_ipsec_stats, 0, NULL, 0, CTL_NET, PF_INET, ipproto_ipsec, CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "enabled", + SYSCTL_DESCR("Enable IPSec processing"), + sysctl_net_ipsec_enabled, 0, NULL, 0, + CTL_NET, PF_INET, ipproto_ipsec, + CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY, + CTLTYPE_INT, "used", + SYSCTL_DESCR("Is IPSec active?"), + NULL, 0, &ipsec_used, 0, + CTL_NET, PF_INET, ipproto_ipsec, + CTL_CREATE, CTL_EOL); #ifdef IPSEC_DEBUG sysctl_createv(clog, 0, NULL, NULL, CTLFLAG_PERMANENT|CTLFLAG_READWRITE, @@ -755,7 +797,20 @@ SYSCTL_SETUP(sysctl_net_inet6_ipsec6_set NULL, 0, &ipsec_debug, 0, CTL_NET, PF_INET6, IPPROTO_AH, IPSECCTL_DEBUG, CTL_EOL); - + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, + CTLTYPE_INT, "enabled", + SYSCTL_DESCR("Enable IPSec processing"), + sysctl_net_ipsec_enabled, 0, NULL, 0, + CTL_NET, PF_INET6, IPPROTO_AH, + CTL_CREATE, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT|CTLFLAG_READONLY, + CTLTYPE_INT, "used", + SYSCTL_DESCR("Is IPSec active?"), + NULL, 0, &ipsec_used, 0, + CTL_NET, PF_INET6, IPPROTO_AH, + CTL_CREATE, CTL_EOL); /* * "aliases" for the ipsec6 subtree */ Index: src/sys/netipsec/key.c diff -u src/sys/netipsec/key.c:1.86 src/sys/netipsec/key.c:1.86.2.1 --- src/sys/netipsec/key.c:1.86 Sat Mar 1 12:55:23 2014 +++ src/sys/netipsec/key.c Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.86 2014/03/01 12:55:23 joerg Exp $ */ +/* $NetBSD: key.c,v 1.86.2.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ /* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.86 2014/03/01 12:55:23 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.86.2.1 2014/08/10 06:56:34 tls Exp $"); /* * This code is referd to RFC 2367 @@ -1224,8 +1224,10 @@ key_freeso(struct socket *so) /* Does it have a PCB ? */ if (pcb == NULL) return; - key_freesp_so(&pcb->inp_sp->sp_in); - key_freesp_so(&pcb->inp_sp->sp_out); + + struct inpcbpolicy *sp = pcb->inp_sp; + key_freesp_so(&sp->sp_in); + key_freesp_so(&sp->sp_out); } break; #endif @@ -1234,12 +1236,13 @@ key_freeso(struct socket *so) { #ifdef HAVE_NRL_INPCB struct inpcb *pcb = sotoinpcb(so); + struct inpcbpolicy *sp = pcb->inp_sp; /* Does it have a PCB ? */ if (pcb == NULL) return; - key_freesp_so(&pcb->inp_sp->sp_in); - key_freesp_so(&pcb->inp_sp->sp_out); + key_freesp_so(&sp->sp_in); + key_freesp_so(&sp->sp_out); #else struct in6pcb *pcb = sotoin6pcb(so); @@ -1770,7 +1773,7 @@ key_gather_mbuf(struct mbuf *m, const st } va_end(ap); - if ((result->m_flags & M_PKTHDR) != 0) { + if (result && (result->m_flags & M_PKTHDR) != 0) { result->m_pkthdr.len = 0; for (n = result; n; n = n->m_next) result->m_pkthdr.len += n->m_len; @@ -2005,6 +2008,7 @@ key_spdadd(struct socket *so, struct mbu xpl->sadb_x_policy_id = newsp->id; m_freem(m); + key_update_used(); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } @@ -2137,6 +2141,7 @@ key_spddelete(struct socket *so, struct newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); + key_update_used(); return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); } } @@ -5077,81 +5082,82 @@ static int key_handle_natt_info(struct secasvar *sav, const struct sadb_msghdr *mhp) { + const char *msg = "?" ; + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *sport, *dport; + struct sadb_address *iaddr, *raddr; + struct sadb_x_nat_t_frag *frag; - if (mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL) - ipseclog((LOG_DEBUG,"update: NAT-T OAi present\n")); - if (mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL) - ipseclog((LOG_DEBUG,"update: NAT-T OAr present\n")); + if (mhp->ext[SADB_X_EXT_NAT_T_TYPE] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_SPORT] == NULL || + mhp->ext[SADB_X_EXT_NAT_T_DPORT] == NULL) + return 0; - if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && - (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && - (mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL)) { - struct sadb_x_nat_t_type *type; - struct sadb_x_nat_t_port *sport; - struct sadb_x_nat_t_port *dport; - struct sadb_address *iaddr, *raddr; - struct sadb_x_nat_t_frag *frag; + if (mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) { + msg = "TYPE"; + goto bad; + } - if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || - (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || - (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { - ipseclog((LOG_DEBUG, "key_update: " - "invalid message.\n")); - return -1; - } + if (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) { + msg = "SPORT"; + goto bad; + } - if ((mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL) && - (mhp->extlen[SADB_X_EXT_NAT_T_OAI] < sizeof(*iaddr))) { - ipseclog((LOG_DEBUG, "key_update: invalid message\n")); - return -1; - } + if (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport)) { + msg = "DPORT"; + goto bad; + } - if ((mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL) && - (mhp->extlen[SADB_X_EXT_NAT_T_OAR] < sizeof(*raddr))) { - ipseclog((LOG_DEBUG, "key_update: invalid message\n")); - return -1; + if (mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL) { + ipseclog((LOG_DEBUG,"%s: NAT-T OAi present\n", __func__)); + if (mhp->extlen[SADB_X_EXT_NAT_T_OAI] < sizeof(*iaddr)) { + msg = "OAI"; + goto bad; } + } - if ((mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) && - (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag))) { - ipseclog((LOG_DEBUG, "key_update: invalid message\n")); - return -1; + if (mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL) { + ipseclog((LOG_DEBUG,"%s: NAT-T OAr present\n", __func__)); + if (mhp->extlen[SADB_X_EXT_NAT_T_OAR] < sizeof(*raddr)) { + msg = "OAR"; + goto bad; } + } - type = (struct sadb_x_nat_t_type *) - mhp->ext[SADB_X_EXT_NAT_T_TYPE]; - sport = (struct sadb_x_nat_t_port *) - mhp->ext[SADB_X_EXT_NAT_T_SPORT]; - dport = (struct sadb_x_nat_t_port *) - mhp->ext[SADB_X_EXT_NAT_T_DPORT]; - iaddr = (struct sadb_address *) - mhp->ext[SADB_X_EXT_NAT_T_OAI]; - raddr = (struct sadb_address *) - mhp->ext[SADB_X_EXT_NAT_T_OAR]; - frag = (struct sadb_x_nat_t_frag *) - mhp->ext[SADB_X_EXT_NAT_T_FRAG]; - - ipseclog((LOG_DEBUG, - "key_update: type %d, sport = %d, dport = %d\n", - type->sadb_x_nat_t_type_type, - sport->sadb_x_nat_t_port_port, - dport->sadb_x_nat_t_port_port)); - - if (type) - sav->natt_type = type->sadb_x_nat_t_type_type; - if (sport) - key_porttosaddr(&sav->sah->saidx.src, - sport->sadb_x_nat_t_port_port); - if (dport) - key_porttosaddr(&sav->sah->saidx.dst, - dport->sadb_x_nat_t_port_port); - if (frag) - sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; - else - sav->esp_frag = IP_MAXPACKET; + if (mhp->ext[SADB_X_EXT_NAT_T_FRAG] != NULL) { + if (mhp->extlen[SADB_X_EXT_NAT_T_FRAG] < sizeof(*frag)) { + msg = "FRAG"; + goto bad; + } } + type = (struct sadb_x_nat_t_type *)mhp->ext[SADB_X_EXT_NAT_T_TYPE]; + sport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_SPORT]; + dport = (struct sadb_x_nat_t_port *)mhp->ext[SADB_X_EXT_NAT_T_DPORT]; + iaddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAI]; + raddr = (struct sadb_address *)mhp->ext[SADB_X_EXT_NAT_T_OAR]; + frag = (struct sadb_x_nat_t_frag *)mhp->ext[SADB_X_EXT_NAT_T_FRAG]; + + ipseclog((LOG_DEBUG, "%s: type %d, sport = %d, dport = %d\n", + __func__, type->sadb_x_nat_t_type_type, + ntohs(sport->sadb_x_nat_t_port_port), + ntohs(dport->sadb_x_nat_t_port_port))); + + sav->natt_type = type->sadb_x_nat_t_type_type; + key_porttosaddr(&sav->sah->saidx.src, + sport->sadb_x_nat_t_port_port); + key_porttosaddr(&sav->sah->saidx.dst, + dport->sadb_x_nat_t_port_port); + if (frag) + sav->esp_frag = frag->sadb_x_nat_t_frag_fraglen; + else + sav->esp_frag = IP_MAXPACKET; + return 0; +bad: + ipseclog((LOG_DEBUG, "%s: invalid message %s\n", __func__, msg)); + __USE(msg); + return -1; } /* Just update the IPSEC_NAT_T ports if present */ @@ -5159,11 +5165,10 @@ static int key_set_natt_ports(union sockaddr_union *src, union sockaddr_union *dst, const struct sadb_msghdr *mhp) { - if (mhp->ext[SADB_X_EXT_NAT_T_OAI] != NULL) - ipseclog((LOG_DEBUG,"update: NAT-T OAi present\n")); + ipseclog((LOG_DEBUG,"%s: NAT-T OAi present\n", __func__)); if (mhp->ext[SADB_X_EXT_NAT_T_OAR] != NULL) - ipseclog((LOG_DEBUG,"update: NAT-T OAr present\n")); + ipseclog((LOG_DEBUG,"%s: NAT-T OAr present\n", __func__)); if ((mhp->ext[SADB_X_EXT_NAT_T_TYPE] != NULL) && (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL) && @@ -5175,22 +5180,25 @@ key_set_natt_ports(union sockaddr_union if ((mhp->extlen[SADB_X_EXT_NAT_T_TYPE] < sizeof(*type)) || (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport)) || (mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport))) { - ipseclog((LOG_DEBUG, "key_update: " - "invalid message.\n")); + ipseclog((LOG_DEBUG, "%s: invalid message\n", + __func__)); return -1; } + type = (struct sadb_x_nat_t_type *) + mhp->ext[SADB_X_EXT_NAT_T_TYPE]; sport = (struct sadb_x_nat_t_port *) mhp->ext[SADB_X_EXT_NAT_T_SPORT]; dport = (struct sadb_x_nat_t_port *) mhp->ext[SADB_X_EXT_NAT_T_DPORT]; - if (sport) - key_porttosaddr(src, - sport->sadb_x_nat_t_port_port); - if (dport) - key_porttosaddr(dst, - dport->sadb_x_nat_t_port_port); + key_porttosaddr(src, sport->sadb_x_nat_t_port_port); + key_porttosaddr(dst, dport->sadb_x_nat_t_port_port); + + ipseclog((LOG_DEBUG, "%s: type %d, sport = %d, dport = %d\n", + __func__, type->sadb_x_nat_t_type_type, + ntohs(sport->sadb_x_nat_t_port_port), + ntohs(dport->sadb_x_nat_t_port_port))); } return 0; @@ -8080,6 +8088,36 @@ key_setspddump(int *errorp, pid_t pid) return (m); } +int +key_get_used(void) { + return !LIST_EMPTY(&sptree[IPSEC_DIR_INBOUND]) || + !LIST_EMPTY(&sptree[IPSEC_DIR_OUTBOUND]); +} + +void +key_update_used(void) +{ + switch (ipsec_enabled) { + default: + case 0: +#ifdef notyet + /* XXX: racy */ + ipsec_used = 0; +#endif + break; + case 1: +#ifndef notyet + /* XXX: racy */ + if (!ipsec_used) +#endif + ipsec_used = key_get_used(); + break; + case 2: + ipsec_used = 1; + break; + } +} + static int sysctl_net_key_dumpsa(SYSCTLFN_ARGS) { Index: src/sys/netipsec/key.h diff -u src/sys/netipsec/key.h:1.12 src/sys/netipsec/key.h:1.12.6.1 --- src/sys/netipsec/key.h:1.12 Tue Jun 4 22:47:37 2013 +++ src/sys/netipsec/key.h Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.12 2013/06/04 22:47:37 christos Exp $ */ +/* $NetBSD: key.h,v 1.12.6.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: src/sys/netipsec/key.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: key.h,v 1.21 2001/07/27 03:51:30 itojun Exp $ */ @@ -106,6 +106,8 @@ int key_parse (struct mbuf *, struct soc void key_init (void); void key_sa_recordxfer (struct secasvar *, struct mbuf *); void key_sa_routechange (struct sockaddr *); +void key_update_used(void); +int key_get_used(void); u_int16_t key_portfromsaddr (const union sockaddr_union *); Index: src/sys/netipsec/keysock.c diff -u src/sys/netipsec/keysock.c:1.21 src/sys/netipsec/keysock.c:1.21.26.1 --- src/sys/netipsec/keysock.c:1.21 Sun Jul 17 20:54:54 2011 +++ src/sys/netipsec/keysock.c Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: keysock.c,v 1.21 2011/07/17 20:54:54 joerg Exp $ */ +/* $NetBSD: keysock.c,v 1.21.26.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.21 2011/07/17 20:54:54 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.21.26.1 2014/08/10 06:56:34 tls Exp $"); #include "opt_ipsec.h" @@ -43,7 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: keysock.c,v #include <sys/domain.h> #include <sys/errno.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/mbuf.h> #include <sys/protosw.h> #include <sys/signalvar.h> @@ -85,12 +85,6 @@ static int key_sendup0(struct rawcb *, s int key_registered_sb_max = (2048 * MHLEN); /* XXX arbitrary */ -/* XXX sysctl */ -#ifdef __FreeBSD__ -SYSCTL_INT(_net_key, OID_AUTO, registered_sbmax, CTLFLAG_RD, - &key_registered_sb_max , 0, "Maximum kernel-to-user PFKEY datagram size"); -#endif - /* * key_output() */ @@ -249,17 +243,19 @@ key_sendup(struct socket *so, struct sad tlen = len; m = mprev = NULL; while (tlen > 0) { + int mlen; if (tlen == len) { MGETHDR(n, M_DONTWAIT, MT_DATA); - n->m_len = MHLEN; + mlen = MHLEN; } else { MGET(n, M_DONTWAIT, MT_DATA); - n->m_len = MLEN; + mlen = MLEN; } if (!n) { PFKEY_STATINC(PFKEY_STAT_IN_NOMEM); return ENOBUFS; } + n->m_len = mlen; if (tlen >= MCLBYTES) { /*XXX better threshold? */ MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { @@ -435,54 +431,24 @@ key_sendup_mbuf(struct socket *so, struc return error; } -#ifdef __FreeBSD__ - -/* - * key_abort() - * derived from net/rtsock.c:rts_abort() - */ static int -key_abort(struct socket *so) -{ - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_abort(so); - splx(s); - return error; -} - -/* - * key_attach() - * derived from net/rtsock.c:rts_attach() - */ -static int -key_attach(struct socket *so, int proto, struct proc *td) +key_attach(struct socket *so, int proto) { struct keycb *kp; int s, error; - if (sotorawcb(so) != 0) - return EISCONN; /* XXX panic? */ - kp = (struct keycb *)malloc(sizeof *kp, M_PCB, M_WAITOK|M_ZERO); /* XXX */ - if (kp == 0) - return ENOBUFS; - - /* - * The spl[soft]net() is necessary to block protocols from sending - * error notifications (like RTM_REDIRECT or RTM_LOSING) while - * this PCB is extant but incompletely initialized. - * Probably we should try to do more of this work beforehand and - * eliminate the spl. - */ - s = splnet(); /* FreeBSD */ + KASSERT(sotorawcb(so) == NULL); + kp = kmem_zalloc(sizeof(*kp), KM_SLEEP); + kp->kp_raw.rcb_len = sizeof(*kp); so->so_pcb = kp; - error = raw_usrreqs.pru_attach(so, proto, td); - kp = (struct keycb *)sotorawcb(so); + + s = splsoftnet(); + error = raw_attach(so, proto); if (error) { - free(kp, M_PCB); + PFKEY_STATINC(PFKEY_STAT_SOCKERR); + kmem_free(kp, sizeof(*kp)); so->so_pcb = NULL; - splx(s); - return error; + goto out; } kp->kp_promisc = kp->kp_registered = 0; @@ -494,240 +460,303 @@ key_attach(struct socket *so, int proto, kp->kp_raw.rcb_faddr = &key_dst; soisconnected(so); so->so_options |= SO_USELOOPBACK; +out: + KASSERT(solocked(so)); + splx(s); + return error; +} +static void +key_detach(struct socket *so) +{ + struct keycb *kp = (struct keycb *)sotorawcb(so); + int s; + + KASSERT(solocked(so)); + KASSERT(kp != NULL); + + s = splsoftnet(); + if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ + key_cb.key_count--; + key_cb.any_count--; + key_freereg(so); + raw_detach(so); splx(s); - return 0; } -/* - * key_bind() - * derived from net/rtsock.c:rts_bind() - */ static int -key_bind(struct socket *so, struct sockaddr *nam, struct proc *td) +key_accept(struct socket *so, struct mbuf *nam) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_bind(so, nam, td); /* xxx just EINVAL */ - splx(s); - return error; + KASSERT(solocked(so)); + + panic("key_accept"); + + return EOPNOTSUPP; } -/* - * key_connect() - * derived from net/rtsock.c:rts_connect() - */ static int -key_connect(struct socket *so, struct sockaddr *nam, struct proc *td) +key_bind(struct socket *so, struct mbuf *nam, struct lwp *l) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_connect(so, nam, td); /* XXX just EINVAL */ - splx(s); - return error; + KASSERT(solocked(so)); + + return EOPNOTSUPP; } -/* - * key_detach() - * derived from net/rtsock.c:rts_detach() - */ static int -key_detach(struct socket *so) +key_listen(struct socket *so, struct lwp *l) { - struct keycb *kp = (struct keycb *)sotorawcb(so); - int s, error; + KASSERT(solocked(so)); - s = splnet(); /* FreeBSD */ - if (kp != 0) { - if (kp->kp_raw.rcb_proto.sp_protocol - == PF_KEY) /* XXX: AF_KEY */ - key_cb.key_count--; - key_cb.any_count--; + return EOPNOTSUPP; +} - key_freereg(so); - } - error = raw_usrreqs.pru_detach(so); - splx(s); - return error; +static int +key_connect(struct socket *so, struct mbuf *nam, struct lwp *l) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; +} + +static int +key_connect2(struct socket *so, struct socket *so2) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; } -/* - * key_disconnect() - * derived from net/rtsock.c:key_disconnect() - */ static int key_disconnect(struct socket *so) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_disconnect(so); + struct rawcb *rp = sotorawcb(so); + int s; + + KASSERT(solocked(so)); + KASSERT(rp != NULL); + + s = splsoftnet(); + soisdisconnected(so); + raw_disconnect(rp); splx(s); - return error; + + return 0; } -/* - * key_peeraddr() - * derived from net/rtsock.c:rts_peeraddr() - */ static int -key_peeraddr(struct socket *so, struct sockaddr **nam) +key_shutdown(struct socket *so) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_peeraddr(so, nam); + int s; + + KASSERT(solocked(so)); + + /* + * Mark the connection as being incapable of further input. + */ + s = splsoftnet(); + socantsendmore(so); splx(s); - return error; + + return 0; } -/* - * key_send() - * derived from net/rtsock.c:rts_send() - */ static int -key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, - struct mbuf *control, struct proc *td) +key_abort(struct socket *so) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_send(so, flags, m, nam, control, td); - splx(s); - return error; + KASSERT(solocked(so)); + + panic("key_abort"); + + return EOPNOTSUPP; } -/* - * key_shutdown() - * derived from net/rtsock.c:rts_shutdown() - */ static int -key_shutdown(struct socket *so) +key_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_shutdown(so); - splx(s); - return error; + return EOPNOTSUPP; } -/* - * key_sockaddr() - * derived from net/rtsock.c:rts_sockaddr() - */ static int -key_sockaddr(struct socket *so, struct sockaddr **nam) +key_stat(struct socket *so, struct stat *ub) { - int s, error; - s = splnet(); /* FreeBSD */ - error = raw_usrreqs.pru_sockaddr(so, nam); - splx(s); - return error; + KASSERT(solocked(so)); + + return 0; } -#else /*!__FreeBSD__ -- traditional proto_usrreq() switch */ -/* - * key_usrreq() - * derived from net/rtsock.c:route_usrreq() - */ -int -key_usrreq(struct socket *so, int req,struct mbuf *m, struct mbuf *nam, - struct mbuf *control, struct lwp *l) +static int +key_peeraddr(struct socket *so, struct mbuf *nam) +{ + struct rawcb *rp = sotorawcb(so); + + KASSERT(solocked(so)); + KASSERT(rp != NULL); + KASSERT(nam != NULL); + + if (rp->rcb_faddr == NULL) + return ENOTCONN; + + raw_setpeeraddr(rp, nam); + return 0; +} + +static int +key_sockaddr(struct socket *so, struct mbuf *nam) +{ + struct rawcb *rp = sotorawcb(so); + + KASSERT(solocked(so)); + KASSERT(rp != NULL); + KASSERT(nam != NULL); + + if (rp->rcb_faddr == NULL) + return ENOTCONN; + + raw_setsockaddr(rp, nam); + return 0; +} + +static int +key_rcvd(struct socket *so, int flags, struct lwp *l) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; +} + +static int +key_recvoob(struct socket *so, struct mbuf *m, int flags) +{ + KASSERT(solocked(so)); + + return EOPNOTSUPP; +} + +static int +key_send(struct socket *so, struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) { int error = 0; - struct keycb *kp = (struct keycb *)sotorawcb(so); int s; - s = splsoftnet(); - if (req == PRU_ATTACH) { - kp = (struct keycb *)malloc(sizeof(*kp), M_PCB, M_WAITOK); - sosetlock(so); - so->so_pcb = kp; - if (so->so_pcb) - memset(so->so_pcb, 0, sizeof(*kp)); - } - if (req == PRU_DETACH && kp) { - int af = kp->kp_raw.rcb_proto.sp_protocol; - if (af == PF_KEY) /* XXX: AF_KEY */ - key_cb.key_count--; - key_cb.any_count--; - - key_freereg(so); - } + KASSERT(solocked(so)); - error = raw_usrreq(so, req, m, nam, control, l); - m = control = NULL; /* reclaimed in raw_usrreq */ - kp = (struct keycb *)sotorawcb(so); - if (req == PRU_ATTACH && kp) { - int af = kp->kp_raw.rcb_proto.sp_protocol; - if (error) { - PFKEY_STATINC(PFKEY_STAT_SOCKERR); - free(kp, M_PCB); - so->so_pcb = NULL; - splx(s); - return (error); - } - - kp->kp_promisc = kp->kp_registered = 0; - - if (af == PF_KEY) /* XXX: AF_KEY */ - key_cb.key_count++; - key_cb.any_count++; - kp->kp_raw.rcb_laddr = &key_src; - kp->kp_raw.rcb_faddr = &key_dst; - soisconnected(so); - so->so_options |= SO_USELOOPBACK; - } + s = splsoftnet(); + error = raw_send(so, m, nam, control, l); splx(s); - return (error); + + return error; } -#endif /*!__FreeBSD__*/ -/* sysctl */ -#ifdef SYSCTL_NODE -SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family"); -#endif /* SYSCTL_NODE */ +static int +key_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) +{ + KASSERT(solocked(so)); -/* - * Definitions of protocols supported in the KEY domain. - */ + m_freem(m); + m_freem(control); -#ifdef __FreeBSD__ -extern struct domain keydomain; + return EOPNOTSUPP; +} -struct pr_usrreqs key_usrreqs = { - key_abort, pru_accept_notsupp, key_attach, key_bind, - key_connect, - pru_connect2_notsupp, pru_control_notsupp, key_detach, - key_disconnect, pru_listen_notsupp, key_peeraddr, - pru_rcvd_notsupp, - pru_rcvoob_notsupp, key_send, pru_sense_null, key_shutdown, - key_sockaddr, sosend, soreceive, sopoll -}; +static int +key_purgeif(struct socket *so, struct ifnet *ifa) +{ + + panic("key_purgeif"); -struct protosw keysw[] = { -{ SOCK_RAW, &keydomain, PF_KEY_V2, PR_ATOMIC|PR_ADDR, - 0, (pr_output_t *)key_output, raw_ctlinput, 0, - 0, - raw_init, 0, 0, 0, - &key_usrreqs + return EOPNOTSUPP; } -}; -static void -key_init0(void) +/* + * key_usrreq() + * derived from net/rtsock.c:route_usrreq() + */ +static int +key_usrreq(struct socket *so, int req,struct mbuf *m, struct mbuf *nam, + struct mbuf *control, struct lwp *l) { - memset(&key_cb, 0, sizeof(key_cb)); - key_init(); -} + int s, error = 0; + + KASSERT(req != PRU_ATTACH); + KASSERT(req != PRU_DETACH); + KASSERT(req != PRU_ACCEPT); + KASSERT(req != PRU_BIND); + KASSERT(req != PRU_LISTEN); + KASSERT(req != PRU_CONNECT); + KASSERT(req != PRU_CONNECT2); + KASSERT(req != PRU_DISCONNECT); + KASSERT(req != PRU_SHUTDOWN); + KASSERT(req != PRU_ABORT); + KASSERT(req != PRU_CONTROL); + KASSERT(req != PRU_SENSE); + KASSERT(req != PRU_PEERADDR); + KASSERT(req != PRU_SOCKADDR); + KASSERT(req != PRU_RCVD); + KASSERT(req != PRU_RCVOOB); + KASSERT(req != PRU_SEND); + KASSERT(req != PRU_SENDOOB); + KASSERT(req != PRU_PURGEIF); -struct domain keydomain = - { PF_KEY, "key", key_init0, 0, 0, - keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] }; + s = splsoftnet(); + error = raw_usrreq(so, req, m, nam, control, l); + m = control = NULL; /* reclaimed in raw_usrreq */ + splx(s); -DOMAIN_SET(key); + return error; +} -#else /* !__FreeBSD__ */ +/* + * Definitions of protocols supported in the KEY domain. + */ DOMAIN_DEFINE(keydomain); +PR_WRAP_USRREQS(key) +#define key_attach key_attach_wrapper +#define key_detach key_detach_wrapper +#define key_accept key_accept_wrapper +#define key_bind key_bind_wrapper +#define key_listen key_listen_wrapper +#define key_connect key_connect_wrapper +#define key_connect2 key_connect2_wrapper +#define key_disconnect key_disconnect_wrapper +#define key_shutdown key_shutdown_wrapper +#define key_abort key_abort_wrapper +#define key_ioctl key_ioctl_wrapper +#define key_stat key_stat_wrapper +#define key_peeraddr key_peeraddr_wrapper +#define key_sockaddr key_sockaddr_wrapper +#define key_rcvd key_rcvd_wrapper +#define key_recvoob key_recvoob_wrapper +#define key_send key_send_wrapper +#define key_sendoob key_sendoob_wrapper +#define key_purgeif key_purgeif_wrapper +#define key_usrreq key_usrreq_wrapper + +const struct pr_usrreqs key_usrreqs = { + .pr_attach = key_attach, + .pr_detach = key_detach, + .pr_accept = key_accept, + .pr_bind = key_bind, + .pr_listen = key_listen, + .pr_connect = key_connect, + .pr_connect2 = key_connect2, + .pr_disconnect = key_disconnect, + .pr_shutdown = key_shutdown, + .pr_abort = key_abort, + .pr_ioctl = key_ioctl, + .pr_stat = key_stat, + .pr_peeraddr = key_peeraddr, + .pr_sockaddr = key_sockaddr, + .pr_rcvd = key_rcvd, + .pr_recvoob = key_recvoob, + .pr_send = key_send, + .pr_sendoob = key_sendoob, + .pr_purgeif = key_purgeif, + .pr_generic = key_usrreq, +}; + const struct protosw keysw[] = { { .pr_type = SOCK_RAW, @@ -736,7 +765,7 @@ const struct protosw keysw[] = { .pr_flags = PR_ATOMIC|PR_ADDR, .pr_output = key_output, .pr_ctlinput = raw_ctlinput, - .pr_usrreq = key_usrreq, + .pr_usrreqs = &key_usrreqs, .pr_init = raw_init, } }; @@ -748,5 +777,3 @@ struct domain keydomain = { .dom_protosw = keysw, .dom_protoswNPROTOSW = &keysw[__arraycount(keysw)], }; - -#endif Index: src/sys/netipsec/keysock.h diff -u src/sys/netipsec/keysock.h:1.6 src/sys/netipsec/keysock.h:1.6.62.1 --- src/sys/netipsec/keysock.h:1.6 Wed Apr 23 07:29:47 2008 +++ src/sys/netipsec/keysock.h Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: keysock.h,v 1.6 2008/04/23 07:29:47 thorpej Exp $ */ +/* $NetBSD: keysock.h,v 1.6.62.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: src/sys/netipsec/keysock.h,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: keysock.h,v 1.8 2000/03/27 05:11:06 sumikawa Exp $ */ @@ -71,14 +71,6 @@ struct keycb { }; int key_output (struct mbuf *, ...); -#ifndef __NetBSD__ -int key_usrreq (struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *); -#else -int key_usrreq (struct socket *, - int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *); -#endif - int key_sendup (struct socket *, struct sadb_msg *, u_int, int); int key_sendup_mbuf (struct socket *, struct mbuf *, int); #endif /* _KERNEL */ Index: src/sys/netipsec/xform_ipip.c diff -u src/sys/netipsec/xform_ipip.c:1.29 src/sys/netipsec/xform_ipip.c:1.29.6.1 --- src/sys/netipsec/xform_ipip.c:1.29 Wed Jun 5 19:01:26 2013 +++ src/sys/netipsec/xform_ipip.c Sun Aug 10 06:56:34 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: xform_ipip.c,v 1.29 2013/06/05 19:01:26 christos Exp $ */ +/* $NetBSD: xform_ipip.c,v 1.29.6.1 2014/08/10 06:56:34 tls Exp $ */ /* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */ @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.29 2013/06/05 19:01:26 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.29.6.1 2014/08/10 06:56:34 tls Exp $"); /* * IP-inside-IP processing @@ -194,14 +194,13 @@ _ipip_input(struct mbuf *m, int iphlen, register struct sockaddr_in *sin; register struct ifnet *ifp; register struct ifaddr *ifa; - struct ifqueue *ifq = NULL; + pktqueue_t *pktq = NULL; struct ip *ipo; #ifdef INET6 register struct sockaddr_in6 *sin6; struct ip6_hdr *ip6 = NULL; u_int8_t itos; #endif - int isr; u_int8_t otos; u_int8_t v; int hlen; @@ -392,27 +391,24 @@ _ipip_input(struct mbuf *m, int iphlen, switch (v >> 4) { #ifdef INET case 4: - ifq = &ipintrq; - isr = NETISR_IP; + pktq = ip_pktq; break; #endif #ifdef INET6 case 6: - ifq = &ip6intrq; - isr = NETISR_IPV6; + pktq = ip6_pktq; break; #endif default: panic("ipip_input: should never reach here"); } - if (!IF_HANDOFF(ifq, m, NULL)) { + int s = splnet(); + if (__predict_false(!pktq_enqueue(pktq, m, 0))) { IPIP_STATINC(IPIP_STAT_QFULL); - - DPRINTF(("ipip_input: packet dropped because of full queue\n")); - } else { - schednetisr(isr); + m_freem(m); } + splx(s); } int @@ -688,9 +684,7 @@ static struct xformsw ipe4_xformsw = { #ifdef INET PR_WRAP_CTLOUTPUT(rip_ctloutput) -PR_WRAP_USRREQ(rip_usrreq) #define rip_ctloutput rip_ctloutput_wrapper -#define rip_usrreq rip_usrreq_wrapper extern struct domain inetdomain; static struct ipprotosw ipe4_protosw = { @@ -702,7 +696,7 @@ static struct ipprotosw ipe4_protosw = { .pr_output = 0, .pr_ctlinput = 0, .pr_ctloutput = rip_ctloutput, - .pr_usrreq = rip_usrreq, + .pr_usrreqs = &rip_usrreqs, .pr_init = 0, .pr_fasttimo = 0, .pr_slowtimo = 0, @@ -711,9 +705,7 @@ static struct ipprotosw ipe4_protosw = { #endif #ifdef INET6 PR_WRAP_CTLOUTPUT(rip6_ctloutput) -PR_WRAP_USRREQ(rip6_usrreq) #define rip6_ctloutput rip6_ctloutput_wrapper -#define rip6_usrreq rip6_usrreq_wrapper extern struct domain inet6domain; static struct ip6protosw ipe4_protosw6 = { @@ -725,7 +717,7 @@ static struct ip6protosw ipe4_protosw6 = .pr_output = 0, .pr_ctlinput = 0, .pr_ctloutput = rip6_ctloutput, - .pr_usrreq = rip6_usrreq, + .pr_usrreqs = &rip6_usrreqs, .pr_init = 0, .pr_fasttimo = 0, .pr_slowtimo = 0,