diff -urN sys/i386/conf/CORE sys.CORE/i386/conf/CORE --- sys/i386/conf/CORE Wed Dec 31 16:00:00 1969 +++ sys.CORE/i386/conf/CORE Wed Jan 31 16:02:43 2007 @@ -0,0 +1,182 @@ +machine i386 +cpu I586_CPU +cpu I686_CPU +ident CORE +maxusers 0 + +makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols +options DDB + +options INET #InterNETworking +options INET6 #IPv6 communications protocols +options IPSEC +options IPSEC_ESP +#options IPSEC_DEBUG +options FFS #Berkeley Fast Filesystem +options FFS_ROOT #FFS usable as root device [keep this!] +options SOFTUPDATES #Enable FFS soft updates support +options UFS_DIRHASH #Improve performance on big directories +options MFS #Memory Filesystem +options MD_ROOT #MD is a potential root device +options MSDOSFS #MSDOS Filesystem +options CD9660 #ISO 9660 Filesystem +options CD9660_ROOT #CD-ROM usable as root, CD9660 required +options PROCFS #Process filesystem +options COMPAT_43 #Compatible with BSD 4.3 [KEEP THIS!] +options UCONSOLE #Allow users to grab the console +options USERCONFIG #boot -c editor +options VISUAL_USERCONFIG #visual boot -c editor +options KTRACE #ktrace(1) support +options SYSVSHM #SYSV-style shared memory +options SYSVMSG #SYSV-style message queues +options SYSVSEM #SYSV-style semaphores +options P1003_1B #Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING +options ICMP_BANDLIM #Rate limit bad replies +options KBD_INSTALL_CDEV # install a CDEV entry in /dev + +device isa +device pci + +# Floppy drives +device fdc0 at isa? port IO_FD1 irq 6 drq 2 +device fd0 at fdc0 drive 0 + +# ATA and ATAPI devices +device ata0 at isa? port IO_WD1 irq 14 +device ata1 at isa? port IO_WD2 irq 15 +device ata +device atadisk # ATA disk drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID #Static device numbering + +# SCSI peripherals +device scbus # SCSI bus (required) +device da # Direct Access (disks) +device sa # Sequential Access (tape etc) +device cd # CD +device pass # Passthrough device (direct SCSI access) + +# atkbdc0 controls both the keyboard and the PS/2 mouse +device atkbdc0 at isa? port IO_KBD +device atkbd0 at atkbdc? irq 1 flags 0x1 +device psm0 at atkbdc? irq 12 + +device vga0 at isa? + +# syscons is the default console driver, resembling an SCO console +device sc0 at isa? flags 0x100 + +device agp # support several AGP chipsets + +# Floating point support - do not disable. +device npx0 at nexus? port IO_NPX irq 13 + +# Power management support (see LINT for more options) +#device apm0 at nexus? #flags 0x20 # Advanced Power Management + +# PCCARD (PCMCIA) support +device card +device pcic0 at isa? irq 0 port 0x3e0 iomem 0xd0000 +device pcic1 at isa? irq 0 port 0x3e2 iomem 0xd4000 disable + +# Serial (COM) ports +# jeffa: added debug flag +device sio0 at isa? port IO_COM1 flags 0x80 irq 4 +#device sio0 at isa? port IO_COM1 flags 0x10 irq 4 +device sio1 at isa? port IO_COM2 irq 3 + +# PCI Ethernet NICs. +device de # DEC/Intel DC21x4x (``Tulip'') +device em # Intel PRO/1000 adapter Gigabit Ethernet Card (``Wiseman'') +device txp # 3Com 3cR990 (``Typhoon'') +device vx # 3Com 3c590, 3c595 (``Vortex'') + +# PCI Ethernet NICs that use the common MII bus controller code. +# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs! +device miibus # MII bus support +device dc # DEC/Intel 21143 and various workalikes +device fxp # Intel EtherExpress PRO/100B (82557, 82558) +device pcn # AMD Am79C97x PCI 10/100 NICs +device rl # RealTek 8129/8139 +device sf # Adaptec AIC-6915 (``Starfire'') +device sis # Silicon Integrated Systems SiS 900/SiS 7016 +device ste # Sundance ST201 (D-Link DFE-550TX) +device tl # Texas Instruments ThunderLAN +device tx # SMC EtherPower II (83c170 ``EPIC'') +device vr # VIA Rhine, Rhine II +device wb # Winbond W89C840F +device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'') +device bge # Broadcom BCM570x (``Tigon III'') + +# ISA Ethernet NICs. +# 'device ed' requires 'device miibus' +device ed0 at isa? disable port 0x280 irq 10 iomem 0xd8000 +device ex +device ep +device fe0 at isa? disable port 0x300 +# Xircom Ethernet +device xe + +# Wireless +#device awi +device wi +device an + +# The probe order of these is presently determined by i386/isa/isa_compat.c. +device ie0 at isa? disable port 0x300 irq 10 iomem 0xd0000 +#device le0 at isa? disable port 0x300 irq 5 iomem 0xd0000 +device lnc0 at isa? disable port 0x280 irq 10 drq 0 +device cs0 at isa? disable port 0x300 +device sn0 at isa? disable port 0x300 irq 10 + +# Pseudo devices - the number indicates how many units to allocate. +pseudo-device loop # Network loopback +pseudo-device ether # Ethernet support +pseudo-device tun # Packet tunnel. +pseudo-device pty # Pseudo-ttys (telnet etc) +pseudo-device md # Memory "disks" +pseudo-device gif +pseudo-device gre + +# The `bpf' pseudo-device enables the Berkeley Packet Filter. +# Be aware of the administrative consequences of enabling this! +pseudo-device bpf #Berkeley packet filter + +# USB support +device uhci # UHCI PCI->USB interface +device ohci # OHCI PCI->USB interface +device usb # USB Bus (required) +device ugen # Generic +device uhid # "Human Interface Devices" +device ukbd # Keyboard +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ums # Mouse +# USB Ethernet, requires mii +device aue # ADMtek USB ethernet +device cue # CATC USB ethernet +device kue # Kawasaki LSI USB ethernet +# USB com devices +device ucom +device uftdi + +# LIMUNES specific options +options ROOTDEVNAME=\"cd9660:acd0\" +options UNION # Is this really needed? +options EXT2FS # And this? +pseudo-device vn 15 # Vnode driver (turns a file into a device) + +options MROUTING # Multicast routing +options PIM # Protocol Independent Multicast +#options IPFIREWALL # firewall +#options IPFIREWALL_DEFAULT_TO_ACCEPT # allow everything by default +#options IPDIVERT # divert sockets + +options HZ=1000 +#options AUTO_EOI_1 +options CPU_ENABLE_SSE +options CPU_FASTER_5X86_FPU +makeoptions CONF_CFLAGS=-mpentiumpro diff -urN sys/kern/kern_vimage.c sys.CORE/kern/kern_vimage.c --- sys/kern/kern_vimage.c Wed Jan 31 15:57:04 2007 +++ sys.CORE/kern/kern_vimage.c Wed Jan 31 16:02:43 2007 @@ -52,9 +52,13 @@ #include #include #include +#include #include #include +#ifdef IPSEC +#include +#endif /* Arbitrary values */ #define TCP_SYNCACHE_HASHSIZE 512 @@ -107,6 +111,12 @@ { "mrt6stat", V_NET, v_mrt6stat, sizeof (x_vnet->mrt6stat) }, { "mf6ctable", V_NET, v_mf6ctable, sizeof (x_vnet->mf6ctable) }, { "mif6table", V_NET, v_mif6table, sizeof (x_vnet->mif6table) }, +#ifdef IPSEC + { "ipsecstat", V_NET, v_ipsecstat, sizeof (x_vnet->ipsecstat) }, +#ifdef INET6 + { "ipsec6stat", V_NET, v_ipsec6stat, sizeof (x_vnet->ipsec6stat) }, +#endif /* INET6 */ +#endif /* IPSEC */ { NULL, 0, 0 , 0 } }; @@ -742,7 +752,17 @@ } rtable_init((void **)vnet->rt_tables, vnet); +#ifdef IPSEC + if (vnet != vnet0) + key_init(vnet); +#endif vi_loopattach(vnet); + if (vnet != vnet0) + gif_init(vnet); + + /*Boeing IDC*/ + if (vnet != vnet0) + gre_init(vnet); if (IPFW_LOADED) ip_fw_init_ptr(vnet); @@ -796,6 +816,15 @@ free((caddr_t)vnet->ifnet_addrs, M_IFADDR); free((caddr_t)vnet->ifindex2ifnet, M_IFADDR); + + while (!LIST_EMPTY(&vnet->gif_softc_list)) + gif_clone_destroy(&LIST_FIRST(&vnet->gif_softc_list)->gif_if); + rman_fini(vnet->gifunits); + + /*Boeing IDC*/ + while (!LIST_EMPTY(&vnet->gre_softc_list)) + gre_clone_destroy(&LIST_FIRST(&vnet->gre_softc_list)->sc_if); + rman_fini(vnet->greunits); /* hopefully, we are finally clear to free the vnet container itself! */ LIST_REMOVE(vnet, vnet_le); diff -urN sys/net/if.c sys.CORE/net/if.c --- sys/net/if.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/if.c Wed Jan 31 16:19:58 2007 @@ -276,6 +276,11 @@ sdl->sdl_data[--namelen] = 0xff; TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); } +#ifdef MROUTING +#ifdef PIM + vnet->reg_vif_num = -1; /* XXX means VIFI_INVALID */ +#endif +#endif /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); diff -urN sys/net/if_gif.c sys.CORE/net/if_gif.c --- sys/net/if_gif.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/if_gif.c Wed Jan 31 16:02:43 2007 @@ -90,7 +90,9 @@ #define GIF_MAXUNIT 0x7fff /* ifp->if_unit is only 15 bits */ static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); +#ifdef MOVED_TO_VNET static struct rman gifunits[1]; +#endif /* MOVED_TO_VNET */ int gif_clone_create __P((struct if_clone *, int *, struct vnet *)); void gif_clone_destroy __P((struct ifnet *)); @@ -114,22 +116,26 @@ */ #define MAX_GIF_NEST 1 #endif +#ifdef MOVED_TO_VNET static int max_gif_nesting = MAX_GIF_NEST; -SYSCTL_INT(_net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW, - &max_gif_nesting, 0, "Max nested tunnels"); +#endif /* MOVED_TO_VNET */ +SYSCTL_V_INT(V_NET, _net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW, + v_max_gif_nesting, 0, "Max nested tunnels"); /* * By default, we disallow creation of multiple tunnels between the same * pair of addresses. Some applications require this functionality so * we allow control over this check here. */ +#ifdef MOVED_TO_VNET #ifdef XBONEHACK static int parallel_tunnels = 1; #else static int parallel_tunnels = 0; #endif -SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW, - ¶llel_tunnels, 0, "Allow parallel tunnels?"); +#endif /* MOVED_TO_VNET */ +SYSCTL_V_INT(V_NET, _net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW, + v_parallel_tunnels, 0, "Allow parallel tunnels?"); int gif_clone_create(ifc, unit, vnet) @@ -140,17 +146,19 @@ struct resource *r; struct gif_softc *sc; + if (vnet == NULL) + panic("gif_clone_create: NULL vnet was passed."); if (*unit > GIF_MAXUNIT) return (ENXIO); if (*unit < 0) { - r = rman_reserve_resource(gifunits, 0, GIF_MAXUNIT, 1, + r = rman_reserve_resource(vnet->gifunits, 0, GIF_MAXUNIT, 1, RF_ALLOCATED | RF_ACTIVE, NULL); if (r == NULL) return (ENOSPC); *unit = rman_get_start(r); } else { - r = rman_reserve_resource(gifunits, *unit, *unit, 1, + r = rman_reserve_resource(vnet->gifunits, *unit, *unit, 1, RF_ALLOCATED | RF_ACTIVE, NULL); if (r == NULL) return (EEXIST); @@ -202,6 +210,8 @@ struct gif_softc *sc = ifp->if_softc; struct vnet *vnet = ifp->if_vnet; + if (vnet == NULL) + panic("gif_clone_destroy: NULL vnet from ifp."); gif_delete_tunnel(&sc->gif_if); LIST_REMOVE(sc, gif_list); #ifdef INET6 @@ -226,31 +236,61 @@ free(sc, M_GIF); } +/* Initialize gif vars for a single vnet */ +int +gif_init(vnet) + struct vnet *vnet; +{ + int err=0; + + vnet->max_gif_nesting = MAX_GIF_NEST; + vnet->parallel_tunnels = 0; + vnet->gifunits->rm_type = RMAN_ARRAY; + vnet->gifunits->rm_descr = "configurable if_gif units"; + err = rman_init(vnet->gifunits); + if (err != 0) + return (err); + err = rman_manage_region(vnet->gifunits, 0, GIF_MAXUNIT); + if (err != 0) { + printf("%s: gifunits: rman_manage_region: Failed %d\n", + GIFNAME, err); + rman_fini(vnet->gifunits); + return (err); + } + LIST_INIT(&vnet->gif_softc_list); + + return 0; +} + static int gifmodevent(mod, type, data) module_t mod; int type; void *data; { - int err; + int err=0; struct vnet *vnet; switch (type) { case MOD_LOAD: - gifunits->rm_type = RMAN_ARRAY; - gifunits->rm_descr = "configurable if_gif units"; - err = rman_init(gifunits); + LIST_FOREACH(vnet, &vnet_head, vnet_le) + { + vnet->max_gif_nesting = MAX_GIF_NEST; + vnet->parallel_tunnels = 0; + vnet->gifunits->rm_type = RMAN_ARRAY; + vnet->gifunits->rm_descr = "configurable if_gif units"; + err = rman_init(vnet->gifunits); if (err != 0) return (err); - err = rman_manage_region(gifunits, 0, GIF_MAXUNIT); + err = rman_manage_region(vnet->gifunits, 0, GIF_MAXUNIT); if (err != 0) { printf("%s: gifunits: rman_manage_region: Failed %d\n", GIFNAME, err); - rman_fini(gifunits); + rman_fini(vnet->gifunits); return (err); } - LIST_FOREACH(vnet, &vnet_head, vnet_le) - LIST_INIT(&vnet->gif_softc_list); + LIST_INIT(&vnet->gif_softc_list); + } if_clone_attach(&gif_cloner); #ifdef INET6 @@ -261,11 +301,12 @@ case MOD_UNLOAD: if_clone_detach(&gif_cloner); - LIST_FOREACH(vnet, &vnet_head, vnet_le) + LIST_FOREACH(vnet, &vnet_head, vnet_le) { while (!LIST_EMPTY(&vnet->gif_softc_list)) gif_clone_destroy(&LIST_FIRST(&vnet->gif_softc_list)->gif_if); + err = rman_fini(vnet->gifunits); + } - err = rman_fini(gifunits); if (err != 0) return (err); #ifdef INET6 @@ -295,6 +336,8 @@ struct ip ip; struct gif_softc *sc; + if (vnet == NULL) + panic("gif_encapcheck: NULL vnet was passed."); sc = (struct gif_softc *)arg; if (sc == NULL) return 0; @@ -358,6 +401,11 @@ struct gif_softc *sc = (struct gif_softc*)ifp; int error = 0; static int called = 0; /* XXX: MUTEX */ + struct vnet *vnet; + + vnet = ifp->if_vnet; + /*if (vnet == NULL) + panic("gif_output: cannot find vnet.");*/ /* * gif may cause infinite recursion calls when misconfigured. @@ -366,7 +414,7 @@ * mutual exclusion of the variable CALLED, especially if we * use kernel thread. */ - if (++called > max_gif_nesting) { + if (++called > vnet->max_gif_nesting) { log(LOG_NOTICE, "gif_output: recursively called too many times(%d)\n", called); @@ -441,13 +489,16 @@ int s, isr; struct p_ifqueue *p_ifq = NULL; struct ifqueue *ifq; - struct vnet *vnet = m->m_pkthdr.rcvif->if_vnet; + struct vnet *vnet; if (ifp == NULL) { /* just in case */ m_freem(m); return; } + vnet = ifp->if_vnet; + if (vnet == NULL) + panic("gif_input: NULL vnet was passed."); m->m_pkthdr.rcvif = ifp; @@ -779,6 +830,8 @@ int error = 0; struct vnet *vnet = sc->gif_vnet; + if (vnet == NULL) + panic("gif_set_tunnel: NULL vnet from sc->gif_vnet"); s = splnet(); LIST_FOREACH(sc2, &vnet->gif_softc_list, gif_list) { @@ -796,7 +849,7 @@ * Disallow parallel tunnels unless instructed * otherwise. */ - if (!parallel_tunnels && + if (!vnet->parallel_tunnels && bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 && bcmp(sc2->gif_psrc, src, src->sa_len) == 0) { error = EADDRNOTAVAIL; diff -urN sys/net/if_gif.h sys.CORE/net/if_gif.h --- sys/net/if_gif.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/if_gif.h Wed Jan 31 16:02:43 2007 @@ -75,6 +75,7 @@ #define GIF_MTU_MAX (8192) /* Maximum MTU */ /* Prototypes */ +int gif_init(struct vnet *); void gifattach0 __P((struct gif_softc *)); void gif_input __P((struct mbuf *, int, struct ifnet *)); int gif_output __P((struct ifnet *, struct mbuf *, diff -urN sys/net/if_gre.c sys.CORE/net/if_gre.c --- sys/net/if_gre.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/if_gre.c Wed Jan 31 16:02:43 2007 @@ -97,10 +97,14 @@ #define GRE_MAXUNIT 0x7fff static MALLOC_DEFINE(M_GRE, GRENAME, "Generic Routing Encapsulation"); +#ifdef MOVED_TO_VNET static struct rman greunits[1]; +#endif /* MOVED_TO_VNET */ -static int gre_clone_create(struct if_clone *, int *, struct vnet *); -static void gre_clone_destroy(struct ifnet *); +/*Boeing IDC static int gre_clone_create(struct if_clone *, int *, struct vnet *);*/ +/*Boeing IDC static void gre_clone_destroy(struct ifnet *);*/ +int gre_clone_create __P((struct if_clone *, int *, struct vnet *)); +void gre_clone_destroy __P((struct ifnet *)); static int gre_ioctl(struct ifnet *, u_long, caddr_t); static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *rt); @@ -144,9 +148,11 @@ */ #define MAX_GRE_NEST 1 #endif +#ifdef MOVED_TO_VNET static int max_gre_nesting = MAX_GRE_NEST; -SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW, - &max_gre_nesting, 0, "Max nested tunnels"); +#endif /* MOVED_TO_VNET */ +SYSCTL_V_INT(V_NET, _net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW, + v_max_gre_nesting, 0, "Max nested tunnels"); /* ARGSUSED */ static void @@ -167,17 +173,20 @@ struct resource *r; struct gre_softc *sc; + if (vnet == NULL) + panic("gre_clone_create: NULL vnet was passed."); + if (*unit > GRE_MAXUNIT) return (ENXIO); if (*unit < 0) { - r = rman_reserve_resource(greunits, 0, GRE_MAXUNIT, 1, + r = rman_reserve_resource(vnet->greunits, 0, GRE_MAXUNIT, 1, RF_ALLOCATED | RF_ACTIVE, NULL); if (r == NULL) return (ENOSPC); *unit = rman_get_start(r); } else { - r = rman_reserve_resource(greunits, *unit, *unit, 1, + r = rman_reserve_resource(vnet->greunits, *unit, *unit, 1, RF_ALLOCATED | RF_ACTIVE, NULL); if (r == NULL) return (EEXIST); @@ -211,12 +220,16 @@ return (0); } -static void +/*static*/ +void gre_clone_destroy(ifp) struct ifnet *ifp; { int err; struct gre_softc *sc = ifp->if_softc; + /*Boeing IDC copied from if_gif.c*/ + if (sc->g_vnet == NULL) + panic("gre_clone_destroy: NULL vnet from ifp."); #ifdef INET if (sc->encap != NULL) @@ -232,6 +245,37 @@ free(sc, M_GRE); } + +/*Boeing IDC*/ + +/* Initialize gif vars for a single vnet */ +int +gre_init(vnet) + struct vnet *vnet; +{ + int err=0; + + vnet->max_gre_nesting = MAX_GRE_NEST; + vnet->parallel_tunnels = 0; + vnet->greunits->rm_type = RMAN_ARRAY; + vnet->gifunits->rm_descr = "configurable if_gre units"; + err = rman_init(vnet->greunits); + if (err != 0) + return (err); + err = rman_manage_region(vnet->greunits, 0, GRE_MAXUNIT); + if (err != 0) { + printf("%s: greunits: rman_manage_region: Failed %d\n", + GRENAME, err); + rman_fini(vnet->greunits); + return (err); + } + LIST_INIT(&vnet->gre_softc_list); + return 0; +} + + + + /* * The output routine. Takes a packet and encapsulates it in the protocol * given by sc->g_proto. See also RFC 1701 and RFC 2004 @@ -247,12 +291,14 @@ u_char osrc; u_short etype = 0; struct mobile_h mob_h; + struct vnet *vnet; + vnet = ifp->if_vnet; /* * gre may cause infinite recursion calls when misconfigured. * We'll prevent this by introducing upper limit. */ - if (++(sc->called) > max_gre_nesting) { + if (++(sc->called) > vnet->max_gre_nesting) { printf("%s: gre_output: recursively called too many " "times(%d)\n", if_name(&sc->sc_if), sc->called); m_freem(m); @@ -780,31 +826,33 @@ switch (type) { case MOD_LOAD: - greunits->rm_type = RMAN_ARRAY; - greunits->rm_descr = "configurable if_gre units"; - err = rman_init(greunits); + LIST_FOREACH(vnet, &vnet_head, vnet_le) + { + vnet->max_gre_nesting = MAX_GRE_NEST; + vnet->greunits->rm_type = RMAN_ARRAY; + vnet->greunits->rm_descr = "configurable if_gre units"; + err = rman_init(vnet->greunits); if (err != 0) return (err); - err = rman_manage_region(greunits, 0, GRE_MAXUNIT); + err = rman_manage_region(vnet->greunits, 0, GRE_MAXUNIT); if (err != 0) { - printf("%s: greunits: rman_manage_region: Failed %d\n", - GRENAME, err); - rman_fini(greunits); - return (err); + printf("%s: greunits: rman_manage_region: Failed %d\n", + GRENAME, err); + rman_fini(vnet->greunits); + return (err); + } + greattach(vnet); } - - LIST_FOREACH(vnet, &vnet_head, vnet_le) - greattach(vnet); - break; case MOD_UNLOAD: if_clone_detach(&gre_cloner); - LIST_FOREACH(vnet, &vnet_head, vnet_le) + err = 0; + LIST_FOREACH(vnet, &vnet_head, vnet_le) { while (!LIST_EMPTY(&vnet->gre_softc_list)) gre_clone_destroy(&LIST_FIRST(&vnet->gre_softc_list)->sc_if); - - err = rman_fini(greunits); + err += rman_fini(vnet->greunits); + } if (err != 0) return (err); diff -urN sys/net/if_gre.h sys.CORE/net/if_gre.h --- sys/net/if_gre.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/if_gre.h Wed Jan 31 16:02:43 2007 @@ -172,4 +172,7 @@ u_short gre_in_cksum(u_short *p, u_int len); #endif /* _KERNEL */ +/* Prototypes */ +int gre_init(struct vnet *); + #endif diff -urN sys/net/vnet.h sys.CORE/net/vnet.h --- sys/net/vnet.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/net/vnet.h Wed Jan 31 16:02:43 2007 @@ -83,6 +83,15 @@ #include #include +/* IPsec support */ +#include +#include +#include +#include +/* gif support */ +#include +#include + #ifdef _KERNEL int vi_if_move(struct vi_req *, struct ifnet *, struct vimage *); @@ -131,6 +140,7 @@ TAILQ_HEAD(dadq_head, dadq); +/**/ struct vnet { LIST_ENTRY(vnet) vnet_le; /* linked list of all vnets */ @@ -172,7 +182,8 @@ struct ifnet loif; /* from net/if_loop.c */ struct ifnet vipa; /* from net/if_loop.c */ - struct gre_softc_head gre_softc_list; + /*Boeing IDC struct gre_softc_head gre_softc_list;*/ + LIST_HEAD(, gre_softc) gre_softc_list; LIST_HEAD(, gif_softc) gif_softc_list; /* NETINET */ @@ -370,6 +381,8 @@ struct udpstat udpstat; /* from udp_usrreq.c */ struct icmpstat icmpstat; /* from ip_icmp.c */ struct igmpstat igmpstat; /* from igmp.c */ + struct pfkeystat pfkeystat; /* from keysock.c */ + struct _keystat { u_long getspi_count; } keystat; u_int rsvpdebug; /* from ip_mroute.c */ u_int mrtdebug; @@ -571,6 +584,67 @@ struct ip_fib_heap_entry ip_fib_heap[33]; int ip_fib_heap_index; + +/* gif tunneling interface stuff */ + /* + * from net/if_gif.c + */ + struct rman gifunits[1]; + int max_gif_nesting; + int parallel_tunnels; + /* + * from net/if_gre.c + */ + struct rman greunits[1]; + int max_gre_nesting; +/* IPsec stuff */ +/* Do not use #ifdef IPSEC here, or problems will occur! */ + /* + * from netkey/key.c + */ + u_int key_spi_trycnt; + u_int32_t key_spi_minval; + u_int32_t key_spi_maxval; + u_int32_t policy_id; + u_int key_int_random; /*interval to initialize randseed,1(m)*/ + u_int key_larval_lifetime; /* interval to expire acquiring, 30(s)*/ + int key_blockacq_count; /* counter for blocking SADB_ACQUIRE.*/ + int key_blockacq_lifetime; /* lifetime for blocking SADB_ACQUIRE.*/ + int key_preferred_oldsa; /* preferred old sa rather than new sa.*/ + u_int32_t acq_seq; + int key_tick_init_random; + LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX]; /* SPD */ + LIST_HEAD(_sahtree, secashead) sahtree; /* SAD */ + LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1]; /* regd list*/ + LIST_HEAD(_acqtree, secacq) acqtree; /* acquiring list */ + LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */ + struct key_cb key_cb; + + /* + * from netinet6/ipsec.c + */ + /* int ipsec_debug; stays in ipsec.c to avoid unnecessary passing + of vnet in simple functions that are printing */ + struct ipsecstat ipsecstat; + int ip4_ah_cleartos; + int ip4_ah_offsetmask; /* maybe IP_DF? */ + int ip4_ipsec_dfbit; /* DF bit on encap. 0: clear 1: set 2: copy */ + int ip4_esp_trans_deflev; + int ip4_esp_net_deflev; + int ip4_ah_trans_deflev; + int ip4_ah_net_deflev; + struct secpolicy ip4_def_policy; + int ip4_ipsec_ecn; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ + int ip4_esp_randpad; + struct ipsecstat ipsec6stat; + int ip6_esp_trans_deflev; + int ip6_esp_net_deflev; + int ip6_ah_trans_deflev; + int ip6_ah_net_deflev; + struct secpolicy ip6_def_policy; + int ip6_ipsec_ecn; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ + int ip6_esp_randpad; + }; /* @@ -827,7 +901,41 @@ #define v_rtq_reallyold6 offsetof(struct vnet, rtq_reallyold6) #define v_rtq_minreallyold6 offsetof(struct vnet, rtq_minreallyold6) #define v_rtq_toomany6 offsetof(struct vnet, rtq_toomany6) - +#define v_max_gif_nesting offsetof(struct vnet, max_gif_nesting) +#define v_parallel_tunnels offsetof(struct vnet, parallel_tunnels) +#define v_max_gre_nesting offsetof(struct vnet, max_gre_nesting) +#define v_key_debug_level offsetof(struct vnet, key_debug_level) +#define v_key_spi_trycnt offsetof(struct vnet, key_spi_trycnt) +#define v_key_spi_minval offsetof(struct vnet, key_spi_minval) +#define v_key_spi_maxval offsetof(struct vnet, key_spi_maxval) +#define v_policy_id offsetof(struct vnet, policy_id) +#define v_key_int_random offsetof(struct vnet, key_int_random) +#define v_key_larval_lifetime offsetof(struct vnet, key_larval_lifetime) +#define v_key_blockacq_count offsetof(struct vnet, key_blockacq_count) +#define v_key_blockacq_lifetime offsetof(struct vnet, key_blockacq_lifetime) +#define v_key_preferred_oldsa offsetof(struct vnet, key_preferred_oldsa) +#define v_acq_seq offsetof(struct vnet, acq_seq) +#define v_key_tick_init_random offsetof(struct vnet, key_tick_init_random) +#define v_key_cb offsetof(struct vnet, key_cb) +#define v_ipsecstat offsetof(struct vnet, ipsecstat) +#define v_ip4_ah_cleartos offsetof(struct vnet, ip4_ah_cleartos) +#define v_ip4_ah_offsetmask offsetof(struct vnet, ip4_ah_offsetmask) +#define v_ip4_ipsec_dfbit offsetof(struct vnet, ip4_ipsec_dfbit) +#define v_ip4_esp_trans_deflev offsetof(struct vnet, ip4_esp_trans_deflev) +#define v_ip4_esp_net_deflev offsetof(struct vnet, ip4_esp_net_deflev) +#define v_ip4_ah_trans_deflev offsetof(struct vnet, ip4_ah_trans_deflev) +#define v_ip4_ah_net_deflev offsetof(struct vnet, ip4_ah_net_deflev) +#define v_ip4_def_policy offsetof(struct vnet, ip4_def_policy) +#define v_ip4_ipsec_ecn offsetof(struct vnet, ip4_ipsec_ecn) +#define v_ip4_esp_randpad offsetof(struct vnet, ip4_esp_randpad) +#define v_ipsec6stat offsetof(struct vnet, ipsec6stat) +#define v_ip6_esp_trans_deflev offsetof(struct vnet, ip6_esp_trans_deflev) +#define v_ip6_esp_net_deflev offsetof(struct vnet, ip6_esp_net_deflev) +#define v_ip6_ah_trans_deflev offsetof(struct vnet, ip6_ah_trans_deflev) +#define v_ip6_ah_net_deflev offsetof(struct vnet, ip6_ah_net_deflev) +#define v_ip6_def_policy offsetof(struct vnet, ip6_def_policy) +#define v_ip6_ipsec_ecn offsetof(struct vnet, ip6_ipsec_ecn) +#define v_ip6_esp_randpad offsetof(struct vnet, ip6_esp_randpad) #endif _KERNEL diff -urN sys/netinet/ip_encap.c sys.CORE/netinet/ip_encap.c --- sys/netinet/ip_encap.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/ip_encap.c Wed Jan 31 16:02:43 2007 @@ -151,6 +151,7 @@ match = NULL; matchprio = 0; + for (ep = LIST_FIRST(&vnet->encaptab); ep; ep = LIST_NEXT(ep, chain)) { if (ep->af != AF_INET) continue; @@ -228,7 +229,7 @@ const struct ip6protosw *psw; struct encaptab *ep, *match; int prio, matchprio; - struct vnet *vnet = m->m_pkthdr.rcvif->if_vnet; + struct vnet *vnet = m->m_pkthdr.rcvif->if_vnet; ip6 = mtod(m, struct ip6_hdr *); @@ -378,7 +379,7 @@ encap_attach_func(af, proto, func, psw, arg, vnet) int af; int proto; - int (*func) __P((const struct mbuf *, int, int, void *)); + int (*func) __P((const struct mbuf *, int, int, void *, struct vnet *)); const struct protosw *psw; void *arg; struct vnet *vnet; @@ -450,6 +451,8 @@ u_int8_t *r; int matchlen; + char *inetadd; + if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d)) return 0; if (sp->sa_family != ep->af || dp->sa_family != ep->af) @@ -483,11 +486,24 @@ d.ss_len = dp->sa_len; d.ss_family = dp->sa_family; - if (bcmp(&s, &ep->src, ep->src.ss_len) == 0 && + if (bcmp(&s, &ep->src, ep->src.ss_len) == 0 && bcmp(&d, &ep->dst, ep->dst.ss_len) == 0) { return matchlen; - } else - return 0; + /*Boeing IDC MTUN IPv4 case*/ + } else if ((ep->src.ss_family == AF_INET) && + (IN_MULTICAST(ntohl(((struct sockaddr_in*)&ep->dst)->sin_addr.s_addr ))) && + (IN_MULTICAST(ntohl(((struct sockaddr_in*)sp)->sin_addr.s_addr ))) && + (bcmp(&s, &ep->dst, ep->src.ss_len) == 0)) { + return matchlen+1; + /*Boeing IDC MTUN IPv6 case*/ + } else if ((ep->src.ss_family == AF_INET6) && + (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6*)&ep->dst)->sin6_addr))) && + (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6*)sp)->sin6_addr))) && + (bcmp(&s, &ep->dst, ep->src.ss_len) == 0)) { + return matchlen+1; + } else { + return 0; + } } static void diff -urN sys/netinet/ip_encap.h sys.CORE/netinet/ip_encap.h --- sys/netinet/ip_encap.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/ip_encap.h Wed Jan 31 16:02:43 2007 @@ -57,7 +57,7 @@ const struct sockaddr *, const struct protosw *, void *, struct vnet *); const struct encaptab *encap_attach_func(int, int, - int (*)(const struct mbuf *, int, int, void *), + int (*)(const struct mbuf *, int, int, void *, struct vnet *), const struct protosw *, void *, struct vnet *); int encap_detach(const struct encaptab *, struct vnet *); void *encap_getarg(struct mbuf *); diff -urN sys/netinet/ip_icmp.c sys.CORE/netinet/ip_icmp.c --- sys/netinet/ip_icmp.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/ip_icmp.c Wed Jan 31 16:02:43 2007 @@ -600,7 +600,7 @@ (struct sockaddr *)&icmpgw, (struct rtentry **)0, vnet); pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc, vnet); #ifdef IPSEC - key_sa_routechange((struct sockaddr *)&icmpsrc); + key_sa_routechange((struct sockaddr *)&icmpsrc, vnet); #endif break; diff -urN sys/netinet/ip_input.c sys.CORE/netinet/ip_input.c --- sys/netinet/ip_input.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/ip_input.c Wed Jan 31 16:02:43 2007 @@ -694,8 +694,8 @@ /* * Enforce inbound IPsec SPD. */ - if (ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + if (ipsec4_in_reject(m, NULL, vnet)) { + vnet->ipsecstat.in_polvio++; goto bad; } #endif /* IPSEC */ @@ -903,8 +903,8 @@ * code - like udp/tcp/raw ip. */ if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0 && - ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + ipsec4_in_reject(m, NULL, vnet)) { + vnet->ipsecstat.in_polvio++; goto bad; } #endif @@ -1970,7 +1970,7 @@ sp = ipsec4_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND, IP_FORWARDING, - &ipsecerror); + &ipsecerror, vnet); if (sp == NULL) destifp = vnet->ipforward_rt.ro_rt->rt_ifp; @@ -1978,7 +1978,7 @@ /* count IPsec header size */ ipsechdr = ipsec4_hdrsiz(mcopy, IPSEC_DIR_OUTBOUND, - NULL); + NULL, vnet); /* * find the correct route for outer IPv4 @@ -2029,7 +2029,7 @@ /* count IPsec header size */ ipsechdr = ipsec4_hdrsiz(mcopy, IPSEC_DIR_OUTBOUND, - NULL); + NULL, vnet); /* * find the correct route for outer IPv4 diff -urN sys/netinet/ip_output.c sys.CORE/netinet/ip_output.c --- sys/netinet/ip_output.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/ip_output.c Wed Jan 31 16:02:43 2007 @@ -320,14 +320,22 @@ * See if the caller provided any multicast options */ if (imo != NULL) { - ip->ip_ttl = imo->imo_multicast_ttl; + /* Boeing IDC to handle divert re-injection + * If you don't want the TTL to be modified then + * set the multicast_ttl socket option to zero. + */ + if (imo->imo_multicast_ttl != 0){ + ip->ip_ttl = imo->imo_multicast_ttl; + } if (imo->imo_multicast_vif != -1) ip->ip_src.s_addr = ip_mcast_src ? ip_mcast_src(imo->imo_multicast_vif, vnet) : INADDR_ANY; - } else - ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; + } else { + ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; + } + /* * Confirm that the outgoing interface supports multicast. */ @@ -459,12 +467,12 @@ #ifdef IPSEC /* get SP for this packet */ if (so == NULL) - sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error); + sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error, vnet); else sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error); if (sp == NULL) { - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; goto bad; } @@ -476,7 +484,7 @@ /* * This packet is just discarded. */ - ipsecstat.out_polvio++; + vnet->ipsecstat.out_polvio++; goto bad; case IPSEC_POLICY_BYPASS: diff -urN sys/netinet/raw_ip.c sys.CORE/netinet/raw_ip.c --- sys/netinet/raw_ip.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/raw_ip.c Wed Jan 31 16:02:43 2007 @@ -184,9 +184,9 @@ #ifdef IPSEC /* check AH/ESP integrity. */ - if (n && ipsec4_in_reject_so(n, last->inp_socket)) { + if (n && ipsec4_in_reject_so(n, last->inp_socket, vnet)) { m_freem(n); - ipsecstat.in_polvio++; + vnet->ipsecstat.in_polvio++; /* do not inject data to pcb */ } else #endif /*IPSEC*/ @@ -217,9 +217,9 @@ } #ifdef IPSEC /* check AH/ESP integrity. */ - if (last && ipsec4_in_reject_so(m, last->inp_socket)) { + if (last && ipsec4_in_reject_so(m, last->inp_socket, vnet)) { m_freem(m); - ipsecstat.in_polvio++; + vnet->ipsecstat.in_polvio++; vnet->ipstat.ips_delivered--; /* do not inject data to pcb */ } else diff -urN sys/netinet/tcp_input.c sys.CORE/netinet/tcp_input.c --- sys/netinet/tcp_input.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/tcp_input.c Wed Jan 31 16:02:43 2007 @@ -580,13 +580,15 @@ #ifdef IPSEC if (isipv6) { - if (inp != NULL && ipsec6_in_reject_so(m, inp->inp_socket)) { - ipsec6stat.in_polvio++; +#ifdef INET6 + if (inp != NULL && ipsec6_in_reject_so(m, inp->inp_socket, vnet)) { + vnet->ipsec6stat.in_polvio++; goto drop; } +#endif } else { - if (inp != NULL && ipsec4_in_reject_so(m, inp->inp_socket)) { - ipsecstat.in_polvio++; + if (inp != NULL && ipsec4_in_reject_so(m, inp->inp_socket, vnet)) { + vnet->ipsecstat.in_polvio++; goto drop; } } diff -urN sys/netinet/tcp_subr.c sys.CORE/netinet/tcp_subr.c --- sys/netinet/tcp_subr.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/tcp_subr.c Wed Jan 31 16:02:43 2007 @@ -1468,9 +1468,13 @@ struct ip6_hdr *ip6; #endif /* INET6 */ struct tcphdr *th; + struct vnet *vnet; if ((tp == NULL) || ((inp = tp->t_inpcb) == NULL)) return 0; + vnet = tp->t_vnet; + if (vnet == NULL) + panic("ipsec_hdrsiz_tcp: NULL vnet was passed."); MGETHDR(m, M_DONTWAIT, MT_DATA); if (!m) return 0; @@ -1482,7 +1486,7 @@ m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr); tcp_fillheaders(tp, ip6, th); - hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); + hdrsiz = ipsec6_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp, vnet); } else #endif /* INET6 */ { @@ -1490,7 +1494,7 @@ th = (struct tcphdr *)(ip + 1); m->m_pkthdr.len = m->m_len = sizeof(struct tcpiphdr); tcp_fillheaders(tp, ip, th); - hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp); + hdrsiz = ipsec4_hdrsiz(m, IPSEC_DIR_OUTBOUND, inp, vnet); } m_free(m); diff -urN sys/netinet/udp_usrreq.c sys.CORE/netinet/udp_usrreq.c --- sys/netinet/udp_usrreq.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet/udp_usrreq.c Wed Jan 31 16:02:43 2007 @@ -325,8 +325,8 @@ #ifdef IPSEC /* check AH/ESP integrity. */ - if (ipsec4_in_reject_so(m, last->inp_socket)) - ipsecstat.in_polvio++; + if (ipsec4_in_reject_so(m, last->inp_socket, vnet)) + vnet->ipsecstat.in_polvio++; /* do not inject data to pcb */ else #endif /*IPSEC*/ @@ -365,8 +365,8 @@ } #ifdef IPSEC /* check AH/ESP integrity. */ - if (ipsec4_in_reject_so(m, last->inp_socket)) { - ipsecstat.in_polvio++; + if (ipsec4_in_reject_so(m, last->inp_socket, vnet)) { + vnet->ipsecstat.in_polvio++; goto bad; } #endif /*IPSEC*/ @@ -410,8 +410,8 @@ return; } #ifdef IPSEC - if (ipsec4_in_reject_so(m, inp->inp_socket)) { - ipsecstat.in_polvio++; + if (ipsec4_in_reject_so(m, inp->inp_socket, vnet)) { + vnet->ipsecstat.in_polvio++; goto bad; } #endif /*IPSEC*/ diff -urN sys/netinet6/ah.h sys.CORE/netinet6/ah.h --- sys/netinet6/ah.h Sat Apr 27 22:40:26 2002 +++ sys.CORE/netinet6/ah.h Wed Jan 31 16:02:43 2007 @@ -86,9 +86,9 @@ extern size_t ah_hdrsiz __P((struct ipsecrequest *)); extern void ah4_input __P((struct mbuf *, ...)); -extern int ah4_output __P((struct mbuf *, struct ipsecrequest *)); +extern int ah4_output __P((struct mbuf *, struct ipsecrequest *, struct vnet*)); extern int ah4_calccksum __P((struct mbuf *, caddr_t, size_t, - const struct ah_algorithm *, struct secasvar *)); + const struct ah_algorithm *, struct secasvar *, struct vnet *)); #endif /* _KERNEL */ #endif /* _NETINET6_AH_H_ */ diff -urN sys/netinet6/ah_core.c sys.CORE/netinet6/ah_core.c --- sys/netinet6/ah_core.c Sat Apr 27 22:40:26 2002 +++ sys.CORE/netinet6/ah_core.c Wed Jan 31 16:02:43 2007 @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -1181,12 +1182,13 @@ * Don't use m_copy(), it will try to share cluster mbuf by using refcnt. */ int -ah4_calccksum(m, ahdat, len, algo, sav) +ah4_calccksum(m, ahdat, len, algo, sav, vnet) struct mbuf *m; caddr_t ahdat; size_t len; const struct ah_algorithm *algo; struct secasvar *sav; + struct vnet *vnet; { int off; int hdrtype; @@ -1200,6 +1202,9 @@ if ((m->m_flags & M_PKTHDR) == 0) return EINVAL; + if (vnet == NULL) + panic("ah4_calccksum: NULL vnet was passed."); + ahseen = 0; hdrtype = -1; /* dummy, it is called IPPROTO_IP */ @@ -1231,9 +1236,9 @@ #endif iphdr.ip_ttl = 0; iphdr.ip_sum = htons(0); - if (ip4_ah_cleartos) + if (vnet->ip4_ah_cleartos) iphdr.ip_tos = 0; - iphdr.ip_off = htons(ntohs(iphdr.ip_off) & ip4_ah_offsetmask); + iphdr.ip_off = htons(ntohs(iphdr.ip_off) & vnet->ip4_ah_offsetmask); (algo->update)(&algos, (caddr_t)&iphdr, sizeof(struct ip)); if (hlen != sizeof(struct ip)) { diff -urN sys/netinet6/ah_input.c sys.CORE/netinet6/ah_input.c --- sys/netinet6/ah_input.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ah_input.c Wed Jan 31 16:02:43 2007 @@ -87,6 +87,8 @@ #define KEYDEBUG(lev,arg) #endif +#include + #include #include @@ -120,19 +122,25 @@ int off, proto; va_list ap; size_t stripsiz = 0; + struct vnet *vnet; va_start(ap, m); off = va_arg(ap, int); proto = va_arg(ap, int); va_end(ap); + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ah4_input: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; + if (vnet == NULL) + panic("ah4_input: NULL vnet passed."); #ifndef PULLDOWN_TEST if (m->m_len < off + sizeof(struct newah)) { m = m_pullup(m, off + sizeof(struct newah)); if (!m) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup;" "dropping the packet for simplicity\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } } @@ -145,7 +153,7 @@ if (ah == NULL) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup;" "dropping the packet for simplicity\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } #endif @@ -161,11 +169,11 @@ if ((sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst, - IPPROTO_AH, spi)) == 0) { + IPPROTO_AH, spi, vnet)) == 0) { ipseclog((LOG_WARNING, "IPv4 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_nosa++; + vnet->ipsecstat.in_nosa++; goto fail; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -175,7 +183,7 @@ ipseclog((LOG_DEBUG, "IPv4 AH input: non-mature/dying SA found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + vnet->ipsecstat.in_badspi++; goto fail; } @@ -184,7 +192,7 @@ ipseclog((LOG_DEBUG, "IPv4 AH input: " "unsupported authentication algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + vnet->ipsecstat.in_badspi++; goto fail; } @@ -225,7 +233,7 @@ "(%lu, should be at least %lu): %s\n", (u_long)siz1, (u_long)siz, ipsec4_logpacketstr(ip, spi))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } if ((ah->ah_len << 2) - sizoff != siz1) { @@ -233,7 +241,7 @@ "(%d should be %lu): %s\n", (ah->ah_len << 2) - sizoff, (u_long)siz1, ipsec4_logpacketstr(ip, spi))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } @@ -242,7 +250,7 @@ m = m_pullup(m, off + sizeof(struct ah) + sizoff + siz1); if (!m) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } @@ -254,7 +262,7 @@ sizeof(struct ah) + sizoff + siz1); if (ah == NULL) { ipseclog((LOG_DEBUG, "IPv4 AH input: can't pullup\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } #endif @@ -267,7 +275,7 @@ if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav)) ; /* okey */ else { - ipsecstat.in_ahreplay++; + vnet->ipsecstat.in_ahreplay++; ipseclog((LOG_WARNING, "replay packet in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); @@ -283,7 +291,7 @@ if (!cksum) { ipseclog((LOG_DEBUG, "IPv4 AH input: " "couldn't alloc temporary region for cksum\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } @@ -293,12 +301,12 @@ */ ip->ip_len = htons(ip->ip_len + hlen); ip->ip_off = htons(ip->ip_off); - if (ah4_calccksum(m, (caddr_t)cksum, siz1, algo, sav)) { + if (ah4_calccksum(m, (caddr_t)cksum, siz1, algo, sav, vnet)) { free(cksum, M_TEMP); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } - ipsecstat.in_ahhist[sav->alg_auth]++; + vnet->ipsecstat.in_ahhist[sav->alg_auth]++; /* * flip them back. */ @@ -321,7 +329,7 @@ "checksum mismatch in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); free(cksum, M_TEMP); - ipsecstat.in_ahauthfail++; + vnet->ipsecstat.in_ahauthfail++; goto fail; } } @@ -374,12 +382,12 @@ ipseclog((LOG_DEBUG, "IPv4 AH input: authentication succeess\n")); #endif - ipsecstat.in_ahauthsucc++; + vnet->ipsecstat.in_ahauthsucc++; } else { ipseclog((LOG_WARNING, "authentication failed in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_ahauthfail++; + vnet->ipsecstat.in_ahauthfail++; goto fail; } @@ -388,7 +396,7 @@ */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav)) { - ipsecstat.in_ahreplay++; + vnet->ipsecstat.in_ahreplay++; goto fail; } } @@ -416,19 +424,19 @@ if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (!m) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } } ip = mtod(m, struct ip *); /* ECN consideration. */ - ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos); + ip_ecn_egress(vnet->ip4_ipsec_ecn, &tos, &ip->ip_tos); if (!key_checktunnelsanity(sav, AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) { ipseclog((LOG_NOTICE, "ipsec tunnel address mismatch " "in IPv4 AH input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } @@ -459,13 +467,13 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) { - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; goto fail; } s = splimp(); if (IF_QFULL(&g_ipintrq)) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; splx(s); goto fail; } @@ -521,7 +529,7 @@ if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (m == NULL) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } } @@ -536,14 +544,14 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0) { - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; goto fail; } if (nxt != IPPROTO_DONE) { if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && - ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + ipsec4_in_reject(m, NULL, vnet)) { + vnet->ipsecstat.in_polvio++; goto fail; } (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt); @@ -557,7 +565,7 @@ printf("DP ah4_input call free SA:%p\n", sav)); key_freesav(sav); } - ipsecstat.in_success++; + vnet->ipsecstat.in_success++; return; fail: @@ -591,7 +599,12 @@ u_int16_t nxt; int s; size_t stripsiz = 0; + struct vnet *vnet; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ah6_input: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; + if (vnet == NULL) #ifndef PULLDOWN_TEST IP6_EXTHDR_CHECK(m, off, sizeof(struct ah), IPPROTO_DONE); ah = (struct ah *)(mtod(m, caddr_t) + off); @@ -599,7 +612,7 @@ IP6_EXTHDR_GET(ah, struct ah *, m, off, sizeof(struct newah)); if (ah == NULL) { ipseclog((LOG_DEBUG, "IPv6 AH input: can't pullup\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; return IPPROTO_DONE; } #endif @@ -612,17 +625,17 @@ if (ntohs(ip6->ip6_plen) == 0) { ipseclog((LOG_ERR, "IPv6 AH input: " "AH with IPv6 jumbogram is not supported.\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } if ((sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst, - IPPROTO_AH, spi)) == 0) { + IPPROTO_AH, spi, vnet)) == 0) { ipseclog((LOG_WARNING, "IPv6 AH input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_nosa++; + vnet->ipsec6stat.in_nosa++; goto fail; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -632,7 +645,7 @@ ipseclog((LOG_DEBUG, "IPv6 AH input: non-mature/dying SA found for spi %u; ", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + vnet->ipsec6stat.in_badspi++; goto fail; } @@ -641,7 +654,7 @@ ipseclog((LOG_DEBUG, "IPv6 AH input: " "unsupported authentication algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + vnet->ipsec6stat.in_badspi++; goto fail; } @@ -665,7 +678,7 @@ "(%lu, should be at least %lu): %s\n", (u_long)siz1, (u_long)siz, ipsec6_logpacketstr(ip6, spi))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } if ((ah->ah_len << 2) - sizoff != siz1) { @@ -673,7 +686,7 @@ "(%d should be %lu): %s\n", (ah->ah_len << 2) - sizoff, (u_long)siz1, ipsec6_logpacketstr(ip6, spi))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } #ifndef PULLDOWN_TEST @@ -683,7 +696,7 @@ sizeof(struct ah) + sizoff + siz1); if (ah == NULL) { ipseclog((LOG_NOTICE, "couldn't pullup gather IPv6 AH checksum part")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; m = NULL; goto fail; } @@ -697,7 +710,7 @@ if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav)) ; /* okey */ else { - ipsec6stat.in_ahreplay++; + vnet->ipsec6stat.in_ahreplay++; ipseclog((LOG_WARNING, "replay packet in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), @@ -714,16 +727,16 @@ if (!cksum) { ipseclog((LOG_DEBUG, "IPv6 AH input: " "couldn't alloc temporary region for cksum\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } if (ah6_calccksum(m, (caddr_t)cksum, siz1, algo, sav)) { free(cksum, M_TEMP); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } - ipsec6stat.in_ahhist[sav->alg_auth]++; + vnet->ipsec6stat.in_ahhist[sav->alg_auth]++; { caddr_t sumpos = NULL; @@ -741,7 +754,7 @@ "checksum mismatch in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); free(cksum, M_TEMP); - ipsec6stat.in_ahauthfail++; + vnet->ipsec6stat.in_ahauthfail++; goto fail; } } @@ -786,12 +799,12 @@ ipseclog((LOG_DEBUG, "IPv6 AH input: authentication succeess\n")); #endif - ipsec6stat.in_ahauthsucc++; + vnet->ipsec6stat.in_ahauthsucc++; } else { ipseclog((LOG_WARNING, "authentication failed in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_ahauthfail++; + vnet->ipsec6stat.in_ahauthfail++; goto fail; } @@ -800,7 +813,7 @@ */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav)) { - ipsec6stat.in_ahreplay++; + vnet->ipsec6stat.in_ahreplay++; goto fail; } } @@ -832,20 +845,20 @@ */ m = m_pullup(m, sizeof(*ip6)); if (!m) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } } ip6 = mtod(m, struct ip6_hdr *); /* ECN consideration. */ - ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow); + ip6_ecn_egress(vnet->ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow); if (!key_checktunnelsanity(sav, AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) { ipseclog((LOG_NOTICE, "ipsec tunnel address mismatch " "in IPv6 AH input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } @@ -861,17 +874,17 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) { - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; goto fail; } s = splimp(); - if (IF_QFULL(&ip6intrq)) { - ipsec6stat.in_inval++; + if (IF_QFULL(&g_ip6intrq)) { + vnet->ipsec6stat.in_inval++; splx(s); goto fail; } - IF_ENQUEUE(&ip6intrq, m); + IF_ENQUEUE(&g_ip6intrq, m); m = NULL; schednetisr(NETISR_IPV6); /* can be skipped but to make sure */ splx(s); @@ -934,7 +947,7 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_AH, spi) != 0) { - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; goto fail; } } @@ -947,7 +960,7 @@ printf("DP ah6_input call free SA:%p\n", sav)); key_freesav(sav); } - ipsec6stat.in_success++; + vnet->ipsec6stat.in_success++; return nxt; fail: @@ -972,6 +985,7 @@ struct secasvar *sav; struct ip6_hdr *ip6; struct mbuf *m; + struct vnet *vnet = NULL; struct ip6ctlparam *ip6cp = NULL; int off; struct sockaddr_in6 *sa6_src, *sa6_dst; @@ -986,11 +1000,15 @@ if (d != NULL) { ip6cp = (struct ip6ctlparam *)d; m = ip6cp->ip6c_m; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ah6_ctlinput: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; ip6 = ip6cp->ip6c_ip6; off = ip6cp->ip6c_off; } else { m = NULL; ip6 = NULL; + off = 0; } if (ip6) { @@ -1025,7 +1043,7 @@ sav = key_allocsa(AF_INET6, (caddr_t)&sa6_src->sin6_addr, (caddr_t)&sa6_dst->sin6_addr, - IPPROTO_AH, ahp->ah_spi); + IPPROTO_AH, ahp->ah_spi, vnet); if (sav) { if (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING) @@ -1042,7 +1060,7 @@ * corresponding routing entry, or * - ignore the MTU change notification. */ - icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); + icmp6_mtudisc_update((struct ip6ctlparam *)d, valid, vnet); } /* we normally notify single pcb here */ diff -urN sys/netinet6/ah_output.c sys.CORE/netinet6/ah_output.c --- sys/netinet6/ah_output.c Mon May 5 23:46:58 2003 +++ sys.CORE/netinet6/ah_output.c Wed Jan 31 16:02:43 2007 @@ -75,6 +75,7 @@ #include #include +#include #ifdef INET static struct in_addr *ah4_finaldst __P((struct mbuf *)); @@ -142,9 +143,10 @@ * the function does not modify m. */ int -ah4_output(m, isr) +ah4_output(m, isr, vnet) struct mbuf *m; struct ipsecrequest *isr; + struct vnet *vnet; { struct secasvar *sav = isr->sav; const struct ah_algorithm *algo; @@ -159,6 +161,8 @@ struct in_addr *finaldst; int error; + if (vnet == NULL) + panic("ah4_output: NULL vnet was passed."); /* sanity checks */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) { struct ip *ip; @@ -169,7 +173,7 @@ (u_int32_t)ntohl(ip->ip_src.s_addr), (u_int32_t)ntohl(ip->ip_dst.s_addr), (u_int32_t)ntohl(sav->spi))); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); return EINVAL; } @@ -178,7 +182,7 @@ if (!algo) { ipseclog((LOG_ERR, "ah4_output: unsupported algorithm: " "SPI=%u\n", (u_int32_t)ntohl(sav->spi))); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); return EINVAL; } @@ -260,7 +264,7 @@ ipseclog((LOG_WARNING, "replay counter overflowed. %s\n", ipsec_logsastr(sav))); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); return EINVAL; } @@ -282,7 +286,7 @@ ip->ip_len = htons(ntohs(ip->ip_len) + ahlen); else { ipseclog((LOG_ERR, "IPv4 AH output: size exceeds limit\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); return EMSGSIZE; } @@ -304,13 +308,13 @@ * calcurate the checksum, based on security association * and the algorithm specified. */ - error = ah4_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav); + error = ah4_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav, vnet); if (error) { ipseclog((LOG_ERR, "error after ah4_calccksum, called from ah4_output")); m_freem(m); m = NULL; - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; return error; } @@ -318,8 +322,8 @@ ip = mtod(m, struct ip *); /* just to make sure */ ip->ip_dst.s_addr = dst.s_addr; } - ipsecstat.out_success++; - ipsecstat.out_ahhist[sav->alg_auth]++; + vnet->ipsecstat.out_success++; + vnet->ipsecstat.out_ahhist[sav->alg_auth]++; key_sa_recordxfer(sav, m); return 0; @@ -371,6 +375,11 @@ int error = 0; int ahlen; struct ip6_hdr *ip6; + struct vnet *vnet; + + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ah6_output: unable to find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; if (m->m_len < sizeof(struct ip6_hdr)) { ipseclog((LOG_DEBUG, "ah6_output: first mbuf too short\n")); @@ -422,7 +431,7 @@ ipseclog((LOG_DEBUG, "ah6_output: internal error: " "sav->replay is null: SPI=%u\n", (u_int32_t)ntohl(sav->spi))); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; m_freem(m); return EINVAL; } @@ -431,7 +440,7 @@ if (!algo) { ipseclog((LOG_ERR, "ah6_output: unsupported algorithm: " "SPI=%u\n", (u_int32_t)ntohl(sav->spi))); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; m_freem(m); return EINVAL; } @@ -467,7 +476,7 @@ ipseclog((LOG_WARNING, "replay counter overflowed. %s\n", ipsec_logsastr(sav))); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; m_freem(m); return EINVAL; } @@ -487,13 +496,13 @@ */ error = ah6_calccksum(m, (caddr_t)ahsumpos, plen, algo, sav); if (error) { - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; m_freem(m); } else { - ipsec6stat.out_success++; + vnet->ipsec6stat.out_success++; key_sa_recordxfer(sav, m); } - ipsec6stat.out_ahhist[sav->alg_auth]++; + vnet->ipsec6stat.out_ahhist[sav->alg_auth]++; return(error); } diff -urN sys/netinet6/esp.h sys.CORE/netinet6/esp.h --- sys/netinet6/esp.h Sat Apr 27 22:40:26 2002 +++ sys.CORE/netinet6/esp.h Wed Jan 31 16:02:43 2007 @@ -97,7 +97,8 @@ extern int esp_max_ivlen __P((void)); /* crypt routines */ -extern int esp4_output __P((struct mbuf *, struct ipsecrequest *)); +extern int esp4_output __P((struct mbuf *, struct ipsecrequest *, + struct vnet *vnet)); extern void esp4_input __P((struct mbuf *, ...)); extern size_t esp_hdrsiz __P((struct ipsecrequest *)); diff -urN sys/netinet6/esp6.h sys.CORE/netinet6/esp6.h --- sys/netinet6/esp6.h Tue Jul 3 04:01:49 2001 +++ sys.CORE/netinet6/esp6.h Wed Jan 31 16:02:43 2007 @@ -39,10 +39,10 @@ #ifdef _KERNEL extern int esp6_output __P((struct mbuf *, u_char *, struct mbuf *, - struct ipsecrequest *)); + struct ipsecrequest *, struct vnet *)); extern int esp6_input __P((struct mbuf **, int *, int)); -extern void esp6_ctlinput __P((int, struct sockaddr *, void *)); +extern void esp6_ctlinput __P((int, struct sockaddr *, void *, struct vnet *)); #endif /*_KERNEL*/ #endif /*_NETINET6_ESP6_H_*/ diff -urN sys/netinet6/esp_input.c sys.CORE/netinet6/esp_input.c --- sys/netinet6/esp_input.c Fri Nov 28 06:52:52 2003 +++ sys.CORE/netinet6/esp_input.c Wed Jan 31 16:02:43 2007 @@ -89,6 +89,7 @@ #include #include +#include #define IPLEN_FLIPPED @@ -123,17 +124,21 @@ int s; va_list ap; int off, proto; + struct vnet *vnet; va_start(ap, m); off = va_arg(ap, int); proto = va_arg(ap, int); va_end(ap); + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("esp4_input: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; /* sanity check for alignment. */ if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) { ipseclog((LOG_ERR, "IPv4 ESP input: packet alignment problem " "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len)); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -142,7 +147,7 @@ if (!m) { ipseclog((LOG_DEBUG, "IPv4 ESP input: can't pullup in esp4_input\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } } @@ -160,11 +165,11 @@ if ((sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst, - IPPROTO_ESP, spi)) == 0) { + IPPROTO_ESP, spi, vnet)) == 0) { ipseclog((LOG_WARNING, "IPv4 ESP input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_nosa++; + vnet->ipsecstat.in_nosa++; goto bad; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -174,7 +179,7 @@ ipseclog((LOG_DEBUG, "IPv4 ESP input: non-mature/dying SA found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + vnet->ipsecstat.in_badspi++; goto bad; } algo = esp_algorithm_lookup(sav->alg_enc); @@ -182,7 +187,7 @@ ipseclog((LOG_DEBUG, "IPv4 ESP input: " "unsupported encryption algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsecstat.in_badspi++; + vnet->ipsecstat.in_badspi++; goto bad; } @@ -191,7 +196,7 @@ if (ivlen < 0) { ipseclog((LOG_ERR, "inproper ivlen in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -209,7 +214,7 @@ if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) ; /* okey */ else { - ipsecstat.in_espreplay++; + vnet->ipsecstat.in_espreplay++; ipseclog((LOG_WARNING, "replay packet in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); @@ -228,14 +233,14 @@ goto noreplaycheck; siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1)); if (m->m_pkthdr.len < off + ESPMAXLEN + siz) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } if (AH_MAXSUMSIZE < siz) { ipseclog((LOG_DEBUG, "internal error: AH_MAXSUMSIZE must be larger than %lu\n", (u_long)siz)); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -244,14 +249,14 @@ if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) { ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_espauthfail++; + vnet->ipsecstat.in_espauthfail++; goto bad; } if (bcmp(sum0, sum, siz) != 0) { ipseclog((LOG_WARNING, "auth fail in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_espauthfail++; + vnet->ipsecstat.in_espauthfail++; goto bad; } @@ -264,7 +269,7 @@ ip->ip_len = htons(ntohs(ip->ip_len) - siz); #endif m->m_flags |= M_AUTHIPDGM; - ipsecstat.in_espauthsucc++; + vnet->ipsecstat.in_espauthsucc++; } /* @@ -272,7 +277,7 @@ */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) { - ipsecstat.in_espreplay++; + vnet->ipsecstat.in_espreplay++; goto bad; } } @@ -294,7 +299,7 @@ if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) { ipseclog((LOG_WARNING, "IPv4 ESP input: packet too short\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -303,7 +308,7 @@ if (!m) { ipseclog((LOG_DEBUG, "IPv4 ESP input: can't pullup in esp4_input\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } } @@ -312,7 +317,7 @@ * pre-compute and cache intermediate key */ if (esp_schedule(algo, sav) != 0) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -326,10 +331,10 @@ m = NULL; ipseclog((LOG_ERR, "decrypt fail in IPv4 ESP input: %s\n", ipsec_logsastr(sav))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } - ipsecstat.in_esphist[sav->alg_enc]++; + vnet->ipsecstat.in_esphist[sav->alg_enc]++; m->m_flags |= M_DECRYPTED; @@ -346,7 +351,7 @@ ipseclog((LOG_WARNING, "bad pad length in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } @@ -375,36 +380,36 @@ if (m->m_len < sizeof(*ip)) { m = m_pullup(m, sizeof(*ip)); if (!m) { - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } } ip = mtod(m, struct ip *); /* ECN consideration. */ - ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos); + ip_ecn_egress(vnet->ip4_ipsec_ecn, &tos, &ip->ip_tos); if (!key_checktunnelsanity(sav, AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) { ipseclog((LOG_ERR, "ipsec tunnel address mismatch " "in IPv4 ESP input: %s %s\n", ipsec4_logpacketstr(ip, spi), ipsec_logsastr(sav))); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto bad; } key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV4, 0) != 0) { - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; goto bad; } s = splimp(); - if (IF_QFULL(&ipintrq)) { - ipsecstat.in_inval++; + if (IF_QFULL(&g_ipintrq)) { + vnet->ipsecstat.in_inval++; splx(s); goto bad; } - IF_ENQUEUE(&ipintrq, m); + IF_ENQUEUE(&g_ipintrq, m); m = NULL; schednetisr(NETISR_IP); /* can be skipped but to make sure */ splx(s); @@ -435,14 +440,14 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) { - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; goto bad; } if (nxt != IPPROTO_DONE) { if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && - ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + ipsec4_in_reject(m, NULL, vnet)) { + vnet->ipsecstat.in_polvio++; goto bad; } (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt); @@ -456,7 +461,7 @@ printf("DP esp4_input call free SA:%p\n", sav)); key_freesav(sav); } - ipsecstat.in_success++; + vnet->ipsecstat.in_success++; return; bad: @@ -478,6 +483,7 @@ int *offp, proto; { struct mbuf *m = *mp; + struct vnet *vnet; int off = *offp; struct ip6_hdr *ip6; struct esp *esp; @@ -491,11 +497,14 @@ size_t esplen; int s; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("esp6_input: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; /* sanity check for alignment. */ if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) { ipseclog((LOG_ERR, "IPv6 ESP input: packet alignment problem " "(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len)); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -505,7 +514,7 @@ #else IP6_EXTHDR_GET(esp, struct esp *, m, off, ESPMAXLEN); if (esp == NULL) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; return IPPROTO_DONE; } #endif @@ -514,7 +523,7 @@ if (ntohs(ip6->ip6_plen) == 0) { ipseclog((LOG_ERR, "IPv6 ESP input: " "ESP with IPv6 jumbogram is not supported.\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -523,11 +532,11 @@ if ((sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst, - IPPROTO_ESP, spi)) == 0) { + IPPROTO_ESP, spi, vnet)) == 0) { ipseclog((LOG_WARNING, "IPv6 ESP input: no key association found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_nosa++; + vnet->ipsec6stat.in_nosa++; goto bad; } KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -537,7 +546,7 @@ ipseclog((LOG_DEBUG, "IPv6 ESP input: non-mature/dying SA found for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + vnet->ipsec6stat.in_badspi++; goto bad; } algo = esp_algorithm_lookup(sav->alg_enc); @@ -545,7 +554,7 @@ ipseclog((LOG_DEBUG, "IPv6 ESP input: " "unsupported encryption algorithm for spi %u\n", (u_int32_t)ntohl(spi))); - ipsec6stat.in_badspi++; + vnet->ipsec6stat.in_badspi++; goto bad; } @@ -554,7 +563,7 @@ if (ivlen < 0) { ipseclog((LOG_ERR, "inproper ivlen in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_badspi++; + vnet->ipsec6stat.in_badspi++; goto bad; } @@ -572,7 +581,7 @@ if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) ; /* okey */ else { - ipsec6stat.in_espreplay++; + vnet->ipsec6stat.in_espreplay++; ipseclog((LOG_WARNING, "replay packet in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); @@ -591,14 +600,14 @@ goto noreplaycheck; siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1)); if (m->m_pkthdr.len < off + ESPMAXLEN + siz) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } if (AH_MAXSUMSIZE < siz) { ipseclog((LOG_DEBUG, "internal error: AH_MAXSUMSIZE must be larger than %lu\n", (u_long)siz)); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -607,14 +616,14 @@ if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) { ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_espauthfail++; + vnet->ipsec6stat.in_espauthfail++; goto bad; } if (bcmp(sum0, sum, siz) != 0) { ipseclog((LOG_WARNING, "auth fail in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_espauthfail++; + vnet->ipsec6stat.in_espauthfail++; goto bad; } @@ -624,7 +633,7 @@ ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - siz); m->m_flags |= M_AUTHIPDGM; - ipsec6stat.in_espauthsucc++; + vnet->ipsec6stat.in_espauthsucc++; } /* @@ -632,7 +641,7 @@ */ if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) { if (ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav)) { - ipsec6stat.in_espreplay++; + vnet->ipsec6stat.in_espreplay++; goto bad; } } @@ -654,7 +663,7 @@ if (m->m_pkthdr.len < off + esplen + ivlen + sizeof(esptail)) { ipseclog((LOG_WARNING, "IPv6 ESP input: packet too short\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -663,7 +672,7 @@ #else IP6_EXTHDR_GET(esp, struct esp *, m, off, esplen + ivlen); if (esp == NULL) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; m = NULL; goto bad; } @@ -674,7 +683,7 @@ * pre-compute and cache intermediate key */ if (esp_schedule(algo, sav) != 0) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -688,10 +697,10 @@ m = NULL; ipseclog((LOG_ERR, "decrypt fail in IPv6 ESP input: %s\n", ipsec_logsastr(sav))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } - ipsec6stat.in_esphist[sav->alg_enc]++; + vnet->ipsec6stat.in_esphist[sav->alg_enc]++; m->m_flags |= M_DECRYPTED; @@ -708,7 +717,7 @@ ipseclog((LOG_WARNING, "bad pad length in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } @@ -740,37 +749,37 @@ #endif m = m_pullup(m, sizeof(*ip6)); if (!m) { - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } } ip6 = mtod(m, struct ip6_hdr *); /* ECN consideration. */ - ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow); + ip6_ecn_egress(vnet->ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow); if (!key_checktunnelsanity(sav, AF_INET6, (caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) { ipseclog((LOG_ERR, "ipsec tunnel address mismatch " "in IPv6 ESP input: %s %s\n", ipsec6_logpacketstr(ip6, spi), ipsec_logsastr(sav))); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto bad; } key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0 || ipsec_addhist(m, IPPROTO_IPV6, 0) != 0) { - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; goto bad; } s = splimp(); - if (IF_QFULL(&ip6intrq)) { - ipsec6stat.in_inval++; + if (IF_QFULL(&g_ip6intrq)) { + vnet->ipsec6stat.in_inval++; splx(s); goto bad; } - IF_ENQUEUE(&ip6intrq, m); + IF_ENQUEUE(&g_ip6intrq, m); m = NULL; schednetisr(NETISR_IPV6); /* can be skipped but to make sure */ splx(s); @@ -864,7 +873,7 @@ key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_ESP, spi) != 0) { - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; goto bad; } } @@ -877,7 +886,7 @@ printf("DP esp6_input call free SA:%p\n", sav)); key_freesav(sav); } - ipsec6stat.in_success++; + vnet->ipsec6stat.in_success++; return nxt; bad: @@ -892,10 +901,11 @@ } void -esp6_ctlinput(cmd, sa, d) +esp6_ctlinput(cmd, sa, d, vnet) int cmd; struct sockaddr *sa; void *d; + struct vnet *vnet; { const struct newesp *espp; struct newesp esp; @@ -906,6 +916,8 @@ int off; struct sockaddr_in6 *sa6_src, *sa6_dst; + if (vnet == NULL) + panic("esp6_ctlinput: NULL vnet was passed."); if (sa->sa_family != AF_INET6 || sa->sa_len != sizeof(struct sockaddr_in6)) return; @@ -921,6 +933,7 @@ } else { m = NULL; ip6 = NULL; + off = 0; } if (ip6) { @@ -939,7 +952,7 @@ */ bzero(&ip6cp1, sizeof(ip6cp1)); ip6cp1.ip6c_src = ip6cp->ip6c_src; - pfctlinput2(cmd, sa, (void *)&ip6cp1); + pfctlinput2(cmd, sa, (void *)&ip6cp1, vnet); /* * Then go to special cases that need ESP header information. @@ -973,7 +986,7 @@ sav = key_allocsa(AF_INET6, (caddr_t)&sa6_src->sin6_addr, (caddr_t)&sa6_dst->sin6_addr, - IPPROTO_ESP, espp->esp_spi); + IPPROTO_ESP, espp->esp_spi, vnet); if (sav) { if (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING) @@ -990,7 +1003,7 @@ * corresponding routing entry, or * - ignore the MTU change notification. */ - icmp6_mtudisc_update((struct ip6ctlparam *)d, valid); + icmp6_mtudisc_update((struct ip6ctlparam *)d, valid, vnet); } } else { /* we normally notify any pcb here */ diff -urN sys/netinet6/esp_output.c sys.CORE/netinet6/esp_output.c --- sys/netinet6/esp_output.c Fri Nov 28 06:54:26 2003 +++ sys.CORE/netinet6/esp_output.c Wed Jan 31 16:02:43 2007 @@ -78,9 +78,10 @@ #include #include +#include static int esp_output __P((struct mbuf *, u_char *, struct mbuf *, - struct ipsecrequest *, int)); + struct ipsecrequest *, int, struct vnet *)); /* * compute ESP header size. @@ -174,12 +175,13 @@ * <-----------------> espoff */ static int -esp_output(m, nexthdrp, md, isr, af) +esp_output(m, nexthdrp, md, isr, af, vnet) struct mbuf *m; u_char *nexthdrp; struct mbuf *md; struct ipsecrequest *isr; int af; + struct vnet *vnet; { struct mbuf *n; struct mbuf *mprev; @@ -197,17 +199,19 @@ int error = 0; struct ipsecstat *stat; + if (vnet == NULL) + panic("esp6_output: NULL vnet was passed."); switch (af) { #ifdef INET case AF_INET: afnumber = 4; - stat = &ipsecstat; + stat = &vnet->ipsecstat; break; #endif #ifdef INET6 case AF_INET6: afnumber = 6; - stat = &ipsec6stat; + stat = &vnet->ipsec6stat; break; #endif default: @@ -229,7 +233,7 @@ (u_int32_t)ntohl(ip->ip_src.s_addr), (u_int32_t)ntohl(ip->ip_dst.s_addr), (u_int32_t)ntohl(sav->spi))); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; break; } #endif /* INET */ @@ -238,7 +242,7 @@ ipseclog((LOG_DEBUG, "esp6_output: internal error: " "sav->replay is null: SPI=%u\n", (u_int32_t)ntohl(sav->spi))); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; break; #endif /* INET6 */ default: @@ -368,7 +372,7 @@ else { ipseclog((LOG_ERR, "IPv4 ESP output: size exceeds limit\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); error = EMSGSIZE; goto fail; @@ -435,12 +439,12 @@ switch (af) { #ifdef INET case AF_INET: - randpadmax = ip4_esp_randpad; + randpadmax = vnet->ip4_esp_randpad; break; #endif #ifdef INET6 case AF_INET6: - randpadmax = ip6_esp_randpad; + randpadmax = vnet->ip6_esp_randpad; break; #endif default: @@ -539,7 +543,7 @@ else { ipseclog((LOG_ERR, "IPv4 ESP output: size exceeds limit\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); error = EMSGSIZE; goto fail; @@ -651,7 +655,7 @@ else { ipseclog((LOG_ERR, "IPv4 ESP output: size exceeds limit\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); error = EMSGSIZE; goto fail; @@ -686,9 +690,10 @@ #ifdef INET int -esp4_output(m, isr) +esp4_output(m, isr, vnet) struct mbuf *m; struct ipsecrequest *isr; + struct vnet *vnet; { struct ip *ip; if (m->m_len < sizeof(struct ip)) { @@ -698,23 +703,24 @@ } ip = mtod(m, struct ip *); /* XXX assumes that m->m_next points to payload */ - return esp_output(m, &ip->ip_p, m->m_next, isr, AF_INET); + return esp_output(m, &ip->ip_p, m->m_next, isr, AF_INET, vnet); } #endif /* INET */ #ifdef INET6 int -esp6_output(m, nexthdrp, md, isr) +esp6_output(m, nexthdrp, md, isr, vnet) struct mbuf *m; u_char *nexthdrp; struct mbuf *md; struct ipsecrequest *isr; + struct vnet *vnet; { if (m->m_len < sizeof(struct ip6_hdr)) { ipseclog((LOG_DEBUG, "esp6_output: first mbuf too short\n")); m_freem(m); return 0; } - return esp_output(m, nexthdrp, md, isr, AF_INET6); + return esp_output(m, nexthdrp, md, isr, AF_INET6, vnet); } #endif /* INET6 */ diff -urN sys/netinet6/icmp6.c sys.CORE/netinet6/icmp6.c --- sys/netinet6/icmp6.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/icmp6.c Wed Jan 31 16:02:43 2007 @@ -2416,7 +2416,7 @@ bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr)); pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&sdst, vnet); #ifdef IPSEC - key_sa_routechange((struct sockaddr *)&sdst); + key_sa_routechange((struct sockaddr *)&sdst, vnet); #endif } diff -urN sys/netinet6/in6_ifattach.c sys.CORE/netinet6/in6_ifattach.c --- sys/netinet6/in6_ifattach.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/in6_ifattach.c Wed Jan 31 16:02:43 2007 @@ -1032,6 +1032,8 @@ bzero(nullbuf, sizeof(nullbuf)); for (i = 1; i < vnet->if_index + 1; i++) { + if (vnet->nd_ifinfo == NULL) /* nd6 not initialized yet! */ + continue; ndi = &vnet->nd_ifinfo[i]; if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) { /* diff -urN sys/netinet6/in6_proto.c sys.CORE/netinet6/in6_proto.c --- sys/netinet6/in6_proto.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/in6_proto.c Wed Jan 31 16:02:43 2007 @@ -209,7 +209,7 @@ #ifdef IPSEC { SOCK_RAW, &inet6domain, IPPROTO_AH, PR_ATOMIC|PR_ADDR, ah6_input, 0, 0, 0, - 0, + 0, 0, 0, 0, 0, 0, &nousrreqs, }, @@ -218,14 +218,14 @@ esp6_input, 0, esp6_ctlinput, 0, - 0, + 0, 0, 0, 0, 0, 0, &nousrreqs, }, #endif { SOCK_RAW, &inet6domain, IPPROTO_IPCOMP, PR_ATOMIC|PR_ADDR, ipcomp6_input, 0, 0, 0, - 0, + 0, 0, 0, 0, 0, 0, &nousrreqs, }, diff -urN sys/netinet6/ip6_forward.c sys.CORE/netinet6/ip6_forward.c --- sys/netinet6/ip6_forward.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ip6_forward.c Wed Jan 31 16:02:43 2007 @@ -122,9 +122,9 @@ * Don't increment ip6s_cantforward because this is the check * before forwarding packet actually. */ - if (ipsec6_in_reject(m, NULL)) { + if (ipsec6_in_reject(m, NULL, vnet)) { #if !defined(FAST_IPSEC) - ipsec6stat.in_polvio++; + vnet->ipsec6stat.in_polvio++; #endif m_freem(m); return; @@ -178,9 +178,9 @@ #ifdef IPSEC /* get a security policy for this packet */ sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, IP_FORWARDING, - &error); + &error, vnet); if (sp == NULL) { - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; vnet->ip6stat.ip6s_cantforward++; if (mcopy) { #if 0 @@ -201,7 +201,7 @@ /* * This packet is just discarded. */ - ipsec6stat.out_polvio++; + vnet->ipsec6stat.out_polvio++; vnet->ip6stat.ip6s_cantforward++; key_freesp(sp); if (mcopy) { @@ -263,7 +263,7 @@ state.ro = NULL; /* update at ipsec6_output_tunnel() */ state.dst = NULL; /* update at ipsec6_output_tunnel() */ - error = ipsec6_output_tunnel(&state, sp, 0); + error = ipsec6_output_tunnel(&state, sp, 0, vnet); m = state.m; key_freesp(sp); @@ -401,10 +401,10 @@ * encapsulated packet as "rt->rt_ifp". */ sp = ipsec6_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND, - IP_FORWARDING, &ipsecerror); + IP_FORWARDING, &ipsecerror, vnet); if (sp) { ipsechdrsiz = ipsec6_hdrsiz(mcopy, - IPSEC_DIR_OUTBOUND, NULL); + IPSEC_DIR_OUTBOUND, NULL, vnet); if (ipsechdrsiz < mtu) mtu -= ipsechdrsiz; } diff -urN sys/netinet6/ip6_input.c sys.CORE/netinet6/ip6_input.c --- sys/netinet6/ip6_input.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ip6_input.c Wed Jan 31 16:02:43 2007 @@ -928,8 +928,8 @@ * code - like udp/tcp/raw ip. */ if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && - ipsec6_in_reject(m, NULL)) { - ipsec6stat.in_polvio++; + ipsec6_in_reject(m, NULL, vnet)) { + vnet->ipsec6stat.in_polvio++; goto bad; } #endif diff -urN sys/netinet6/ip6_output.c sys.CORE/netinet6/ip6_output.c --- sys/netinet6/ip6_output.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ip6_output.c Wed Jan 31 16:02:43 2007 @@ -193,6 +193,8 @@ ip6 = mtod(m, struct ip6_hdr *); #endif /* FAST_IPSEC */ + if (vnet == NULL) + panic("ip6_output: NULL vnet was passed."); #define MAKE_EXTHDR(hp, mp) \ do { \ if (hp) { \ @@ -221,12 +223,12 @@ #ifdef IPSEC /* get a security policy for this packet */ if (so == NULL) - sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error); + sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, 0, &error, vnet); else sp = ipsec6_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error); if (sp == NULL) { - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; goto freehdrs; } @@ -238,7 +240,7 @@ /* * This packet is just discarded. */ - ipsec6stat.out_polvio++; + vnet->ipsec6stat.out_polvio++; goto freehdrs; case IPSEC_POLICY_BYPASS: @@ -250,7 +252,7 @@ case IPSEC_POLICY_IPSEC: if (sp->req == NULL) { /* acquire a policy */ - error = key_spdacquire(sp); + error = key_spdacquire(sp, vnet); goto freehdrs; } needipsec = 1; @@ -436,7 +438,7 @@ bzero(&state, sizeof(state)); state.m = m; error = ipsec6_output_trans(&state, nexthdrp, mprev, sp, flags, - &needipsectun); + &needipsectun, vnet); m = state.m; if (error) { /* mbuf is already reclaimed in ipsec6_output_trans. */ @@ -562,7 +564,7 @@ state.ro = (struct route *)ro; state.dst = (struct sockaddr *)dst; - error = ipsec6_output_tunnel(&state, sp, flags); + error = ipsec6_output_tunnel(&state, sp, flags, vnet); m = state.m; ro = (struct route_in6 *)state.ro; @@ -1337,6 +1339,8 @@ int alwaysfrag = 0; int error = 0; + if (vnet == NULL) + panic("ip6_getpmtu: NULL vnet was passed."); if (ro_pmtu != ro) { /* The first hop and the final destination may differ. */ struct sockaddr_in6 *sa6_dst = @@ -1416,6 +1420,8 @@ int optlen; struct proc *p; + if (vnet == NULL) + panic("ip6_ctloutput: NULL vnet from socket."); if (sopt) { level = sopt->sopt_level; op = sopt->sopt_dir; @@ -1853,6 +1859,8 @@ struct proc *p = sopt->sopt_p; int priv = 0; + if (vnet == NULL) + panic("ip6_pcbopts: NULL vnet from socket."); /* turn off any old options. */ if (opt) { #ifdef DIAGNOSTIC @@ -2042,6 +2050,8 @@ struct in6_multi_mship *imm; struct proc *p = curproc; /* XXX */ + if (vnet == NULL) + panic("ip6_setmoptions: NULL vnet passed."); if (im6o == NULL) { /* * No multicast option buffer attached to the pcb; @@ -2326,6 +2336,8 @@ *mp = m_get(M_WAIT, MT_HEADER); /* XXX */ + if (vnet == NULL) + panic("ip6_getmoptions: NULL vnet was passed."); switch (optname) { case IPV6_MULTICAST_IF: diff -urN sys/netinet6/ipcomp_input.c sys.CORE/netinet6/ipcomp_input.c --- sys/netinet6/ipcomp_input.c Sat Apr 27 22:40:27 2002 +++ sys.CORE/netinet6/ipcomp_input.c Wed Jan 31 16:02:43 2007 @@ -47,6 +47,7 @@ #include #include +/*#include */ #include #include #include @@ -79,6 +80,7 @@ #include #include +#include #define IPLEN_FLIPPED @@ -106,6 +108,7 @@ size_t newlen, olen; struct secasvar *sav = NULL; int off, proto; + struct vnet *vnet; va_list ap; va_start(ap, m); @@ -113,10 +116,14 @@ proto = va_arg(ap, int); va_end(ap); + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipcomp_input: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; + if (m->m_pkthdr.len < off + sizeof(struct ipcomp)) { ipseclog((LOG_DEBUG, "IPv4 IPComp input: assumption failed " "(packet too short)\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } @@ -125,7 +132,7 @@ m = NULL; /* already freed */ ipseclog((LOG_DEBUG, "IPv4 IPComp input: assumption failed " "(pulldown failure)\n")); - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } ipcomp = mtod(md, struct ipcomp *); @@ -141,7 +148,7 @@ if (cpi >= IPCOMP_CPI_NEGOTIATE_MIN) { sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, - (caddr_t)&ip->ip_dst, IPPROTO_IPCOMP, htonl(cpi)); + (caddr_t)&ip->ip_dst, IPPROTO_IPCOMP, htonl(cpi), vnet); if (sav != NULL && (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING)) { @@ -153,7 +160,7 @@ if (!algo) { ipseclog((LOG_WARNING, "IPv4 IPComp input: unknown cpi %u\n", cpi)); - ipsecstat.in_nosa++; + vnet->ipsecstat.in_nosa++; goto fail; } @@ -173,13 +180,13 @@ error = (*algo->decompress)(m, m->m_next, &newlen); if (error != 0) { if (error == EINVAL) - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; else if (error == ENOBUFS) - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; m = NULL; goto fail; } - ipsecstat.in_comphist[cpi]++; + vnet->ipsecstat.in_comphist[cpi]++; /* * returning decompressed packet onto icmp is meaningless. @@ -204,7 +211,7 @@ len -= olen; if (len & ~0xffff) { /* packet too big after decompress */ - ipsecstat.in_inval++; + vnet->ipsecstat.in_inval++; goto fail; } #ifdef IPLEN_FLIPPED @@ -218,7 +225,7 @@ if (sav) { key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_IPCOMP, (u_int32_t)cpi) != 0) { - ipsecstat.in_nomem++; + vnet->ipsecstat.in_nomem++; goto fail; } key_freesav(sav); @@ -227,8 +234,8 @@ if (nxt != IPPROTO_DONE) { if ((inetsw[ip_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && - ipsec4_in_reject(m, NULL)) { - ipsecstat.in_polvio++; + ipsec4_in_reject(m, NULL, vnet)) { + vnet->ipsecstat.in_polvio++; goto fail; } (*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt); @@ -236,7 +243,7 @@ m_freem(m); m = NULL; - ipsecstat.in_success++; + vnet->ipsecstat.in_success++; return; fail: @@ -265,16 +272,20 @@ size_t newlen; struct secasvar *sav = NULL; char *prvnxtp; + struct vnet *vnet = NULL; m = *mp; off = *offp; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipcomp6_input: unable to find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; md = m_pulldown(m, off, sizeof(*ipcomp), NULL); if (!m) { m = NULL; /* already freed */ ipseclog((LOG_DEBUG, "IPv6 IPComp input: assumption failed " "(pulldown failure)\n")); - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; goto fail; } ipcomp = mtod(md, struct ipcomp *); @@ -285,7 +296,8 @@ if (cpi >= IPCOMP_CPI_NEGOTIATE_MIN) { sav = key_allocsa(AF_INET6, (caddr_t)&ip6->ip6_src, - (caddr_t)&ip6->ip6_dst, IPPROTO_IPCOMP, htonl(cpi)); + (caddr_t)&ip6->ip6_dst, IPPROTO_IPCOMP, htonl(cpi), + vnet); if (sav != NULL && (sav->state == SADB_SASTATE_MATURE || sav->state == SADB_SASTATE_DYING)) { @@ -297,7 +309,7 @@ if (!algo) { ipseclog((LOG_WARNING, "IPv6 IPComp input: unknown cpi %u; " "dropping the packet for simplicity\n", cpi)); - ipsec6stat.in_nosa++; + vnet->ipsec6stat.in_nosa++; goto fail; } @@ -311,13 +323,13 @@ error = (*algo->decompress)(m, md, &newlen); if (error != 0) { if (error == EINVAL) - ipsec6stat.in_inval++; + vnet->ipsec6stat.in_inval++; else if (error == ENOBUFS) - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; m = NULL; goto fail; } - ipsec6stat.in_comphist[cpi]++; + vnet->ipsec6stat.in_comphist[cpi]++; m->m_pkthdr.len = off + newlen; /* @@ -338,7 +350,7 @@ if (sav) { key_sa_recordxfer(sav, m); if (ipsec_addhist(m, IPPROTO_IPCOMP, (u_int32_t)cpi) != 0) { - ipsec6stat.in_nomem++; + vnet->ipsec6stat.in_nomem++; goto fail; } key_freesav(sav); @@ -346,7 +358,7 @@ } *offp = off; *mp = m; - ipsec6stat.in_success++; + vnet->ipsec6stat.in_success++; return nxt; fail: diff -urN sys/netinet6/ipcomp_output.c sys.CORE/netinet6/ipcomp_output.c --- sys/netinet6/ipcomp_output.c Tue Apr 29 01:33:50 2003 +++ sys.CORE/netinet6/ipcomp_output.c Wed Jan 31 16:02:43 2007 @@ -80,6 +80,7 @@ #include #include +#include static int ipcomp_output __P((struct mbuf *, u_char *, struct mbuf *, struct ipsecrequest *, int)); @@ -123,18 +124,23 @@ int afnumber; int error = 0; struct ipsecstat *stat; + struct vnet *vnet; + + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipcomp_output: unable to get vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; switch (af) { #ifdef INET case AF_INET: afnumber = 4; - stat = &ipsecstat; + stat = &vnet->ipsecstat; break; #endif #ifdef INET6 case AF_INET6: afnumber = 6; - stat = &ipsec6stat; + stat = &vnet->ipsec6stat; break; #endif default: @@ -309,7 +315,7 @@ else { ipseclog((LOG_ERR, "IPv4 ESP output: size exceeds limit\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); error = EMSGSIZE; goto fail; @@ -353,9 +359,14 @@ struct ipsecrequest *isr; { struct ip *ip; + struct vnet *vnet; + + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipcomp4_output: unable to get vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; if (m->m_len < sizeof(struct ip)) { ipseclog((LOG_DEBUG, "ipcomp4_output: first mbuf too short\n")); - ipsecstat.out_inval++; + vnet->ipsecstat.out_inval++; m_freem(m); return 0; } @@ -373,9 +384,13 @@ struct mbuf *md; struct ipsecrequest *isr; { + struct vnet *vnet; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipcomp6_output: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; if (m->m_len < sizeof(struct ip6_hdr)) { ipseclog((LOG_DEBUG, "ipcomp6_output: first mbuf too short\n")); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; m_freem(m); return 0; } diff -urN sys/netinet6/ipsec.c sys.CORE/netinet6/ipsec.c --- sys/netinet6/ipsec.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ipsec.c Wed Jan 31 16:02:43 2007 @@ -112,6 +112,7 @@ int ipsec_debug = 0; #endif +#ifdef MOVED_TO_VNET struct ipsecstat ipsecstat; int ip4_ah_cleartos = 1; int ip4_ah_offsetmask = 0; /* maybe IP_DF? */ @@ -123,6 +124,7 @@ struct secpolicy ip4_def_policy; int ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ int ip4_esp_randpad = -1; +#endif #ifdef SYSCTL_DECL SYSCTL_DECL(_net_inet_ipsec); @@ -132,32 +134,33 @@ #endif /* net.inet.ipsec */ -SYSCTL_STRUCT(_net_inet_ipsec, IPSECCTL_STATS, - stats, CTLFLAG_RD, &ipsecstat, ipsecstat, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, - def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, - CTLFLAG_RW, &ip4_esp_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, - CTLFLAG_RW, &ip4_esp_net_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, - CTLFLAG_RW, &ip4_ah_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, - CTLFLAG_RW, &ip4_ah_net_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS, - ah_cleartos, CTLFLAG_RW, &ip4_ah_cleartos, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK, - ah_offsetmask, CTLFLAG_RW, &ip4_ah_offsetmask, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT, - dfbit, CTLFLAG_RW, &ip4_ipsec_dfbit, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, - ecn, CTLFLAG_RW, &ip4_ipsec_ecn, 0, ""); +SYSCTL_V_STRUCT(V_NET, _net_inet_ipsec, IPSECCTL_STATS, + stats, CTLFLAG_RD, v_ipsecstat, ipsecstat, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_POLICY, + def_policy, CTLFLAG_RW, &((struct secpolicy*)v_ip4_def_policy)->policy, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, + esp_trans_deflev, CTLFLAG_RW, v_ip4_esp_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, + CTLFLAG_RW, v_ip4_esp_net_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, + CTLFLAG_RW, v_ip4_ah_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, + CTLFLAG_RW, v_ip4_ah_net_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_AH_CLEARTOS, + ah_cleartos, CTLFLAG_RW, v_ip4_ah_cleartos, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_AH_OFFSETMASK, + ah_offsetmask, CTLFLAG_RW, v_ip4_ah_offsetmask, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DFBIT, + dfbit, CTLFLAG_RW, v_ip4_ipsec_dfbit, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_ECN, + ecn, CTLFLAG_RW, v_ip4_ipsec_ecn, 0, ""); SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG, debug, CTLFLAG_RW, &ipsec_debug, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD, - esp_randpad, CTLFLAG_RW, &ip4_esp_randpad, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_ESP_RANDPAD, + esp_randpad, CTLFLAG_RW, v_ip4_esp_randpad, 0, ""); #ifdef INET6 +#ifdef MOVED_TO_VNET struct ipsecstat ipsec6stat; int ip6_esp_trans_deflev = IPSEC_LEVEL_USE; int ip6_esp_net_deflev = IPSEC_LEVEL_USE; @@ -166,26 +169,27 @@ struct secpolicy ip6_def_policy; int ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ int ip6_esp_randpad = -1; +#endif /* MOVED_TO_VNET */ /* net.inet6.ipsec6 */ -SYSCTL_STRUCT(_net_inet6_ipsec6, IPSECCTL_STATS, - stats, CTLFLAG_RD, &ipsec6stat, ipsecstat, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, - def_policy, CTLFLAG_RW, &ip6_def_policy.policy, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, - CTLFLAG_RW, &ip6_esp_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, - CTLFLAG_RW, &ip6_esp_net_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, - CTLFLAG_RW, &ip6_ah_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, - CTLFLAG_RW, &ip6_ah_net_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN, - ecn, CTLFLAG_RW, &ip6_ipsec_ecn, 0, ""); +SYSCTL_V_STRUCT(V_NET, _net_inet6_ipsec6, IPSECCTL_STATS, + stats, CTLFLAG_RD, v_ipsec6stat, ipsecstat, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_POLICY, + def_policy, CTLFLAG_RW, &((struct secpolicy *)v_ip6_def_policy)->policy, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, + esp_trans_deflev, CTLFLAG_RW, v_ip6_esp_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, + CTLFLAG_RW, v_ip6_esp_net_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, + ah_trans_deflev, CTLFLAG_RW, v_ip6_ah_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, + CTLFLAG_RW, v_ip6_ah_net_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_ECN, + ecn, CTLFLAG_RW, v_ip6_ipsec_ecn, 0, ""); 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, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD, + esp_randpad, CTLFLAG_RW, v_ip6_esp_randpad, 0, ""); #endif /* INET6 */ static int ipsec_setspidx_mbuf @@ -217,10 +221,10 @@ static struct mbuf *ipsec6_splithdr __P((struct mbuf *)); #endif #ifdef INET -static int ipsec4_encapsulate __P((struct mbuf *, struct secasvar *)); +static int ipsec4_encapsulate __P((struct mbuf *, struct secasvar *, struct vnet *)); #endif #ifdef INET6 -static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *)); +static int ipsec6_encapsulate __P((struct mbuf *, struct secasvar *, struct vnet *)); #endif /* @@ -245,11 +249,15 @@ struct inpcbpolicy *pcbsp = NULL; struct secpolicy *currsp = NULL; /* policy on socket */ struct secpolicy *kernsp = NULL; /* policy on kernel */ + struct vnet *vnet; /* sanity check */ if (m == NULL || so == NULL || error == NULL) panic("ipsec4_getpolicybysock: NULL pointer was passed."); - + vnet = so->so_vnet; + if (vnet == NULL) + panic("ipsec4_getpolicybysock: NULL vnet pointer."); + switch (so->so_proto->pr_domain->dom_family) { case AF_INET: /* set spidx in pcb */ @@ -306,7 +314,7 @@ case IPSEC_POLICY_ENTRUST: /* look for a policy in SPD */ - kernsp = key_allocsp(&currsp->spidx, dir); + kernsp = key_allocsp(&currsp->spidx, dir, vnet); /* SP found */ if (kernsp != NULL) { @@ -318,16 +326,16 @@ } /* no SP found */ - if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD - && ip4_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip4_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip4_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - ip4_def_policy.policy, IPSEC_POLICY_NONE)); - ip4_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip4_def_policy.policy, IPSEC_POLICY_NONE)); + vnet->ip4_def_policy.policy = IPSEC_POLICY_NONE; } - ip4_def_policy.refcnt++; + vnet->ip4_def_policy.refcnt++; *error = 0; - return &ip4_def_policy; + return &vnet->ip4_def_policy; case IPSEC_POLICY_IPSEC: currsp->refcnt++; @@ -345,7 +353,7 @@ /* when non-privilieged socket */ /* look for a policy in SPD */ - kernsp = key_allocsp(&currsp->spidx, dir); + kernsp = key_allocsp(&currsp->spidx, dir, vnet); /* SP found */ if (kernsp != NULL) { @@ -366,16 +374,16 @@ return NULL; case IPSEC_POLICY_ENTRUST: - if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD - && ip4_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip4_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip4_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - ip4_def_policy.policy, IPSEC_POLICY_NONE)); - ip4_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip4_def_policy.policy, IPSEC_POLICY_NONE)); + vnet->ip4_def_policy.policy = IPSEC_POLICY_NONE; } - ip4_def_policy.refcnt++; + vnet->ip4_def_policy.refcnt++; *error = 0; - return &ip4_def_policy; + return &vnet->ip4_def_policy; case IPSEC_POLICY_IPSEC: currsp->refcnt++; @@ -402,17 +410,20 @@ * others : error occured. */ struct secpolicy * -ipsec4_getpolicybyaddr(m, dir, flag, error) +ipsec4_getpolicybyaddr(m, dir, flag, error, vnet) struct mbuf *m; u_int dir; int flag; int *error; + struct vnet *vnet; { struct secpolicy *sp = NULL; /* sanity check */ if (m == NULL || error == NULL) panic("ipsec4_getpolicybyaddr: NULL pointer was passed."); + if (vnet == NULL) + panic("ipsec4_getpolicybyaddr: NULL vnet pointer was passed."); { struct secpolicyindex spidx; @@ -426,7 +437,7 @@ if (*error != 0) return NULL; - sp = key_allocsp(&spidx, dir); + sp = key_allocsp(&spidx, dir, vnet); } /* SP found */ @@ -439,16 +450,16 @@ } /* no SP found */ - if (ip4_def_policy.policy != IPSEC_POLICY_DISCARD - && ip4_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip4_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip4_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy:%d->%d\n", - ip4_def_policy.policy, + vnet->ip4_def_policy.policy, IPSEC_POLICY_NONE)); - ip4_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip4_def_policy.policy = IPSEC_POLICY_NONE; } - ip4_def_policy.refcnt++; + vnet->ip4_def_policy.refcnt++; *error = 0; - return &ip4_def_policy; + return &vnet->ip4_def_policy; } #ifdef INET6 @@ -472,10 +483,15 @@ struct inpcbpolicy *pcbsp = NULL; struct secpolicy *currsp = NULL; /* policy on socket */ struct secpolicy *kernsp = NULL; /* policy on kernel */ + struct vnet *vnet; /* sanity check */ if (m == NULL || so == NULL || error == NULL) panic("ipsec6_getpolicybysock: NULL pointer was passed."); + vnet = so->so_vnet; + if (vnet == NULL) + panic("ipsec6_getpolicybysock: NULL vnet pointer was passed."); + #ifdef DIAGNOSTIC if (so->so_proto->pr_domain->dom_family != AF_INET6) @@ -516,7 +532,7 @@ case IPSEC_POLICY_ENTRUST: /* look for a policy in SPD */ - kernsp = key_allocsp(&currsp->spidx, dir); + kernsp = key_allocsp(&currsp->spidx, dir, vnet); /* SP found */ if (kernsp != NULL) { @@ -528,16 +544,16 @@ } /* no SP found */ - if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD - && ip6_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip6_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip6_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - ip6_def_policy.policy, IPSEC_POLICY_NONE)); - ip6_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip6_def_policy.policy, IPSEC_POLICY_NONE)); + vnet->ip6_def_policy.policy = IPSEC_POLICY_NONE; } - ip6_def_policy.refcnt++; + vnet->ip6_def_policy.refcnt++; *error = 0; - return &ip6_def_policy; + return &vnet->ip6_def_policy; case IPSEC_POLICY_IPSEC: currsp->refcnt++; @@ -555,7 +571,7 @@ /* when non-privilieged socket */ /* look for a policy in SPD */ - kernsp = key_allocsp(&currsp->spidx, dir); + kernsp = key_allocsp(&currsp->spidx, dir, vnet); /* SP found */ if (kernsp != NULL) { @@ -576,16 +592,16 @@ return NULL; case IPSEC_POLICY_ENTRUST: - if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD - && ip6_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip6_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip6_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - ip6_def_policy.policy, IPSEC_POLICY_NONE)); - ip6_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip6_def_policy.policy, IPSEC_POLICY_NONE)); + vnet->ip6_def_policy.policy = IPSEC_POLICY_NONE; } - ip6_def_policy.refcnt++; + vnet->ip6_def_policy.refcnt++; *error = 0; - return &ip6_def_policy; + return &vnet->ip6_def_policy; case IPSEC_POLICY_IPSEC: currsp->refcnt++; @@ -619,17 +635,20 @@ #endif struct secpolicy * -ipsec6_getpolicybyaddr(m, dir, flag, error) +ipsec6_getpolicybyaddr(m, dir, flag, error, vnet) struct mbuf *m; u_int dir; int flag; int *error; + struct vnet *vnet; { struct secpolicy *sp = NULL; /* sanity check */ if (m == NULL || error == NULL) panic("ipsec6_getpolicybyaddr: NULL pointer was passed."); + if (vnet == NULL) + panic("ipsec6_getpolicybyaddr: NULL vnet pointer was passed."); { struct secpolicyindex spidx; @@ -643,7 +662,7 @@ if (*error != 0) return NULL; - sp = key_allocsp(&spidx, dir); + sp = key_allocsp(&spidx, dir, vnet); } /* SP found */ @@ -656,15 +675,15 @@ } /* no SP found */ - if (ip6_def_policy.policy != IPSEC_POLICY_DISCARD - && ip6_def_policy.policy != IPSEC_POLICY_NONE) { + if (vnet->ip6_def_policy.policy != IPSEC_POLICY_DISCARD + && vnet->ip6_def_policy.policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", - ip6_def_policy.policy, IPSEC_POLICY_NONE)); - ip6_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip6_def_policy.policy, IPSEC_POLICY_NONE)); + vnet->ip6_def_policy.policy = IPSEC_POLICY_NONE; } - ip6_def_policy.refcnt++; + vnet->ip6_def_policy.refcnt++; *error = 0; - return &ip6_def_policy; + return &vnet->ip6_def_policy; } #endif /* INET6 */ @@ -1505,8 +1524,9 @@ * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned. */ u_int -ipsec_get_reqlevel(isr) +ipsec_get_reqlevel(isr, vnet) struct ipsecrequest *isr; + struct vnet *vnet; { u_int level = 0; u_int esp_trans_deflev, esp_net_deflev, ah_trans_deflev, ah_net_deflev; @@ -1514,6 +1534,8 @@ /* sanity check */ if (isr == NULL || isr->sp == NULL) panic("ipsec_get_reqlevel: NULL pointer is passed."); + if (vnet == NULL) + panic("ipsec_get_reqlevel: NULL vnet is passed."); if (((struct sockaddr *)&isr->sp->spidx.src)->sa_family != ((struct sockaddr *)&isr->sp->spidx.dst)->sa_family) panic("ipsec_get_reqlevel: family mismatched."); @@ -1534,18 +1556,18 @@ switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) { #ifdef INET case AF_INET: - esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev); - esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev); - ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev); - ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev); + esp_trans_deflev = IPSEC_CHECK_DEFAULT(vnet->ip4_esp_trans_deflev); + esp_net_deflev = IPSEC_CHECK_DEFAULT(vnet->ip4_esp_net_deflev); + ah_trans_deflev = IPSEC_CHECK_DEFAULT(vnet->ip4_ah_trans_deflev); + ah_net_deflev = IPSEC_CHECK_DEFAULT(vnet->ip4_ah_net_deflev); break; #endif #ifdef INET6 case AF_INET6: - esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev); - esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev); - ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev); - ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev); + esp_trans_deflev = IPSEC_CHECK_DEFAULT(vnet->ip6_esp_trans_deflev); + esp_net_deflev = IPSEC_CHECK_DEFAULT(vnet->ip6_esp_net_deflev); + ah_trans_deflev = IPSEC_CHECK_DEFAULT(vnet->ip6_ah_trans_deflev); + ah_net_deflev = IPSEC_CHECK_DEFAULT(vnet->ip6_ah_net_deflev); break; #endif /* INET6 */ default: @@ -1614,10 +1636,16 @@ struct ipsecrequest *isr; u_int level; int need_auth, need_conf, need_icv; + struct vnet *vnet; KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("ipsec_in_reject: using SP\n"); kdebug_secpolicy(sp)); + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipsec_in_reject(): unable to get vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; + if (vnet == NULL) + panic("ipsec_in_reject(): NULL vnet was passed."); /* check policy */ switch (sp->policy) { @@ -1644,7 +1672,7 @@ for (isr = sp->req; isr != NULL; isr = isr->next) { /* get current level */ - level = ipsec_get_reqlevel(isr); + level = ipsec_get_reqlevel(isr, vnet); switch (isr->saidx.proto) { case IPPROTO_ESP: @@ -1691,9 +1719,10 @@ * and {ah,esp}4_input for tunnel mode */ int -ipsec4_in_reject_so(m, so) +ipsec4_in_reject_so(m, so, vnet) struct mbuf *m; struct socket *so; + struct vnet *vnet; { struct secpolicy *sp = NULL; int error; @@ -1708,7 +1737,7 @@ * ipsec4_getpolicybyaddr() with IP_FORWARDING flag. */ if (so == NULL) - sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error); + sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error, vnet); else sp = ipsec4_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error); @@ -1725,14 +1754,15 @@ } int -ipsec4_in_reject(m, inp) +ipsec4_in_reject(m, inp, vnet) struct mbuf *m; struct inpcb *inp; + struct vnet *vnet; { if (inp == NULL) - return ipsec4_in_reject_so(m, NULL); + return ipsec4_in_reject_so(m, NULL, vnet); if (inp->inp_socket) - return ipsec4_in_reject_so(m, inp->inp_socket); + return ipsec4_in_reject_so(m, inp->inp_socket, vnet); else panic("ipsec4_in_reject: invalid inpcb/socket"); } @@ -1744,9 +1774,10 @@ * and {ah,esp}6_input for tunnel mode */ int -ipsec6_in_reject_so(m, so) +ipsec6_in_reject_so(m, so, vnet) struct mbuf *m; struct socket *so; + struct vnet *vnet; { struct secpolicy *sp = NULL; int error; @@ -1761,7 +1792,7 @@ * ipsec6_getpolicybyaddr() with IP_FORWARDING flag. */ if (so == NULL) - sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error); + sp = ipsec6_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error, vnet); else sp = ipsec6_getpolicybysock(m, IPSEC_DIR_INBOUND, so, &error); @@ -1777,14 +1808,15 @@ } int -ipsec6_in_reject(m, in6p) +ipsec6_in_reject(m, in6p, vnet) struct mbuf *m; struct in6pcb *in6p; + struct vnet *vnet; { if (in6p == NULL) - return ipsec6_in_reject_so(m, NULL); + return ipsec6_in_reject_so(m, NULL, vnet); if (in6p->in6p_socket) - return ipsec6_in_reject_so(m, in6p->in6p_socket); + return ipsec6_in_reject_so(m, in6p->in6p_socket, vnet); else panic("ipsec6_in_reject: invalid in6p/socket"); } @@ -1868,10 +1900,11 @@ /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */ size_t -ipsec4_hdrsiz(m, dir, inp) +ipsec4_hdrsiz(m, dir, inp, vnet) struct mbuf *m; u_int dir; struct inpcb *inp; + struct vnet *vnet; { struct secpolicy *sp = NULL; int error; @@ -1888,7 +1921,7 @@ * ipsec4_getpolicybyaddr() with IP_FORWARDING flag. */ if (inp == NULL) - sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error); + sp = ipsec4_getpolicybyaddr(m, dir, IP_FORWARDING, &error,vnet); else sp = ipsec4_getpolicybysock(m, dir, inp->inp_socket, &error); @@ -1910,10 +1943,11 @@ * and maybe from ip6_forward.() */ size_t -ipsec6_hdrsiz(m, dir, in6p) +ipsec6_hdrsiz(m, dir, in6p, vnet) struct mbuf *m; u_int dir; struct in6pcb *in6p; + struct vnet *vnet; { struct secpolicy *sp = NULL; int error; @@ -1928,7 +1962,7 @@ /* get SP for this packet */ /* XXX Is it right to call with IP_FORWARDING. */ if (in6p == NULL) - sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error); + sp = ipsec6_getpolicybyaddr(m, dir, IP_FORWARDING, &error, vnet); else sp = ipsec6_getpolicybysock(m, dir, in6p->in6p_socket, &error); @@ -1951,9 +1985,10 @@ * ip->ip_src must be fixed later on. */ static int -ipsec4_encapsulate(m, sav) +ipsec4_encapsulate(m, sav, vnet) struct mbuf *m; struct secasvar *sav; + struct vnet *vnet; { struct ip *oip; struct ip *ip; @@ -1967,6 +2002,8 @@ m_freem(m); return EINVAL; } + if (vnet == NULL) + panic("ipsec4_encapsulate(): vnet is NULL."); #if 0 /* XXX if the dst is myself, perform nothing. */ if (key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst)) { @@ -2030,7 +2067,7 @@ /* construct new IPv4 header. see RFC 2401 5.1.2.1 */ /* ECN consideration. */ - ip_ecn_ingress(ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos); + ip_ecn_ingress(vnet->ip4_ipsec_ecn, &ip->ip_tos, &oip->ip_tos); #ifdef _IP_VHL ip->ip_vhl = IP_MAKE_VHL(IPVERSION, sizeof(struct ip) >> 2); #else @@ -2038,7 +2075,7 @@ #endif ip->ip_off &= htons(~IP_OFFMASK); ip->ip_off &= htons(~IP_MF); - switch (ip4_ipsec_dfbit) { + switch (vnet->ip4_ipsec_dfbit) { case 0: /* clear DF bit */ ip->ip_off &= htons(~IP_DF); break; @@ -2058,7 +2095,7 @@ #ifdef RANDOM_IP_ID ip->ip_id = ip_randomid(); #else - ip->ip_id = htons(ip_id++); + ip->ip_id = htons(vnet->ip_id++); #endif bcopy(&((struct sockaddr_in *)&sav->sah->saidx.src)->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); @@ -2074,14 +2111,18 @@ #ifdef INET6 static int -ipsec6_encapsulate(m, sav) +ipsec6_encapsulate(m, sav, vnet) struct mbuf *m; struct secasvar *sav; + struct vnet *vnet; { struct ip6_hdr *oip6; struct ip6_hdr *ip6; size_t plen; + if (vnet == NULL) + panic("ipsec6_encapsulate(): vnet is NULL."); + /* can't tunnel between different AFs */ if (((struct sockaddr *)&sav->sah->saidx.src)->sa_family != ((struct sockaddr *)&sav->sah->saidx.dst)->sa_family @@ -2133,7 +2174,7 @@ /* construct new IPv6 header. see RFC 2401 5.1.2.2 */ /* ECN consideration. */ - ip6_ecn_ingress(ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow); + ip6_ecn_ingress(vnet->ip6_ipsec_ecn, &ip6->ip6_flow, &oip6->ip6_flow); if (plen < IPV6_MAXPACKET - sizeof(struct ip6_hdr)) ip6->ip6_plen = htons(plen); else { @@ -2493,6 +2534,8 @@ panic("state->ro == NULL in ipsec4_output"); if (!state->dst) panic("state->dst == NULL in ipsec4_output"); + if (vnet == NULL) + panic("ipsec4_output: vnet is NULL."); KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("ipsec4_output: applyed SP\n"); @@ -2541,13 +2584,13 @@ * this packet because it is responsibility for * upper layer to retransmit the packet. */ - ipsecstat.out_nosa++; + vnet->ipsecstat.out_nosa++; goto bad; } /* validity check */ if (isr->sav == NULL) { - switch (ipsec_get_reqlevel(isr)) { + switch (ipsec_get_reqlevel(isr, vnet)) { case IPSEC_LEVEL_USE: continue; case IPSEC_LEVEL_REQUIRE: @@ -2565,7 +2608,7 @@ */ if (isr->sav->state != SADB_SASTATE_MATURE && isr->sav->state != SADB_SASTATE_DYING) { - ipsecstat.out_nosa++; + vnet->ipsecstat.out_nosa++; error = EINVAL; goto bad; } @@ -2596,7 +2639,7 @@ error = ENOMEM; goto bad; } - error = ipsec4_encapsulate(state->m, isr->sav); + error = ipsec4_encapsulate(state->m, isr->sav, vnet); splx(s); if (error) { state->m = NULL; @@ -2641,7 +2684,7 @@ switch (isr->saidx.proto) { case IPPROTO_ESP: #ifdef IPSEC_ESP - if ((error = esp4_output(state->m, isr)) != 0) { + if ((error = esp4_output(state->m, isr, vnet)) != 0) { state->m = NULL; goto bad; } @@ -2653,7 +2696,7 @@ goto bad; #endif case IPPROTO_AH: - if ((error = ah4_output(state->m, isr)) != 0) { + if ((error = ah4_output(state->m, isr, vnet)) != 0) { state->m = NULL; goto bad; } @@ -2695,13 +2738,14 @@ * IPsec output logic for IPv6, transport mode. */ int -ipsec6_output_trans(state, nexthdrp, mprev, sp, flags, tun) +ipsec6_output_trans(state, nexthdrp, mprev, sp, flags, tun, vnet) struct ipsec_output_state *state; u_char *nexthdrp; struct mbuf *mprev; struct secpolicy *sp; int flags; int *tun; + struct vnet *vnet; { struct ip6_hdr *ip6; struct ipsecrequest *isr = NULL; @@ -2722,6 +2766,8 @@ panic("sp == NULL in ipsec6_output_trans"); if (!tun) panic("tun == NULL in ipsec6_output_trans"); + if (!vnet) + panic("vnet == NULL in ipsec6_output_trans"); KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("ipsec6_output_trans: applyed SP\n"); @@ -2766,7 +2812,7 @@ } } - if (key_checkrequest(isr, &saidx) == ENOENT) { + if (key_checkrequest(isr, &saidx, vnet) == ENOENT) { /* * IPsec processing is required, but no SA found. * I assume that key_acquire() had been called @@ -2774,7 +2820,7 @@ * this packet because it is responsibility for * upper layer to retransmit the packet. */ - ipsec6stat.out_nosa++; + vnet->ipsec6stat.out_nosa++; error = ENOENT; /* @@ -2793,7 +2839,7 @@ /* validity check */ if (isr->sav == NULL) { - switch (ipsec_get_reqlevel(isr)) { + switch (ipsec_get_reqlevel(isr, vnet)) { case IPSEC_LEVEL_USE: continue; case IPSEC_LEVEL_REQUIRE: @@ -2808,7 +2854,7 @@ */ if (isr->sav->state != SADB_SASTATE_MATURE && isr->sav->state != SADB_SASTATE_DYING) { - ipsec6stat.out_nosa++; + vnet->ipsec6stat.out_nosa++; error = EINVAL; goto bad; } @@ -2816,7 +2862,7 @@ switch (isr->saidx.proto) { case IPPROTO_ESP: #ifdef IPSEC_ESP - error = esp6_output(state->m, nexthdrp, mprev->m_next, isr); + error = esp6_output(state->m, nexthdrp, mprev->m_next, isr, vnet); #else m_freem(state->m); error = EINVAL; @@ -2832,7 +2878,7 @@ ipseclog((LOG_ERR, "ipsec6_output_trans: " "unknown ipsec protocol %d\n", isr->saidx.proto)); m_freem(state->m); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; error = EINVAL; break; } @@ -2844,7 +2890,7 @@ if (plen > IPV6_MAXPACKET) { ipseclog((LOG_ERR, "ipsec6_output_trans: " "IPsec with IPv6 jumbogram is not supported\n")); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; error = EINVAL; /* XXX */ goto bad; } @@ -2868,10 +2914,11 @@ * IPsec output logic for IPv6, tunnel mode. */ int -ipsec6_output_tunnel(state, sp, flags) +ipsec6_output_tunnel(state, sp, flags, vnet) struct ipsec_output_state *state; struct secpolicy *sp; int flags; + struct vnet *vnet; { struct ip6_hdr *ip6; struct ipsecrequest *isr = NULL; @@ -2887,6 +2934,8 @@ panic("state->m == NULL in ipsec6_output_tunnel"); if (!sp) panic("sp == NULL in ipsec6_output_tunnel"); + if (!vnet) + panic("vnet == NULL in ipsec6_output_tunnel"); KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("ipsec6_output_tunnel: applyed SP\n"); @@ -2943,7 +2992,7 @@ } } - if (key_checkrequest(isr, &saidx) == ENOENT) { + if (key_checkrequest(isr, &saidx, vnet) == ENOENT) { /* * IPsec processing is required, but no SA found. * I assume that key_acquire() had been called @@ -2951,14 +3000,14 @@ * this packet because it is responsibility for * upper layer to retransmit the packet. */ - ipsec6stat.out_nosa++; + vnet->ipsec6stat.out_nosa++; error = ENOENT; goto bad; } /* validity check */ if (isr->sav == NULL) { - switch (ipsec_get_reqlevel(isr)) { + switch (ipsec_get_reqlevel(isr, vnet)) { case IPSEC_LEVEL_USE: continue; case IPSEC_LEVEL_REQUIRE: @@ -2973,7 +3022,7 @@ */ if (isr->sav->state != SADB_SASTATE_MATURE && isr->sav->state != SADB_SASTATE_DYING) { - ipsec6stat.out_nosa++; + vnet->ipsec6stat.out_nosa++; error = EINVAL; goto bad; } @@ -2994,7 +3043,7 @@ "family mismatched between inner and outer, spi=%u\n", (u_int32_t)ntohl(isr->sav->spi))); splx(s); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; error = EAFNOSUPPORT; goto bad; } @@ -3002,11 +3051,11 @@ state->m = ipsec6_splithdr(state->m); if (!state->m) { splx(s); - ipsec6stat.out_nomem++; + vnet->ipsec6stat.out_nomem++; error = ENOMEM; goto bad; } - error = ipsec6_encapsulate(state->m, isr->sav); + error = ipsec6_encapsulate(state->m, isr->sav, vnet); splx(s); if (error) { state->m = 0; @@ -3028,11 +3077,11 @@ dst6->sin6_family = AF_INET6; dst6->sin6_len = sizeof(*dst6); dst6->sin6_addr = ip6->ip6_dst; - rtalloc(state->ro); + rtalloc(state->ro, vnet); } if (state->ro->ro_rt == 0) { - ip6stat.ip6s_noroute++; - ipsec6stat.out_noroute++; + vnet->ip6stat.ip6s_noroute++; + vnet->ipsec6stat.out_noroute++; error = EHOSTUNREACH; goto bad; } @@ -3047,7 +3096,7 @@ state->m = ipsec6_splithdr(state->m); if (!state->m) { - ipsec6stat.out_nomem++; + vnet->ipsec6stat.out_nomem++; error = ENOMEM; goto bad; } @@ -3055,7 +3104,7 @@ switch (isr->saidx.proto) { case IPPROTO_ESP: #ifdef IPSEC_ESP - error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, isr); + error = esp6_output(state->m, &ip6->ip6_nxt, state->m->m_next, isr, vnet); #else m_freem(state->m); error = EINVAL; @@ -3071,7 +3120,7 @@ ipseclog((LOG_ERR, "ipsec6_output_tunnel: " "unknown ipsec protocol %d\n", isr->saidx.proto)); m_freem(state->m); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; error = EINVAL; break; } @@ -3083,7 +3132,7 @@ if (plen > IPV6_MAXPACKET) { ipseclog((LOG_ERR, "ipsec6_output_tunnel: " "IPsec with IPv6 jumbogram is not supported\n")); - ipsec6stat.out_inval++; + vnet->ipsec6stat.out_inval++; error = EINVAL; /* XXX */ goto bad; } @@ -3193,7 +3242,11 @@ int hlen; struct secpolicy *sp; struct ip *oip; + struct vnet *vnet; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipsec4_tunnel_validate: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; #ifdef DIAGNOSTIC if (m->m_len < sizeof(struct ip)) panic("too short mbuf on ipsec4_tunnel_validate"); @@ -3260,7 +3313,7 @@ */ sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst, - (struct sockaddr *)&isrc, (struct sockaddr *)&idst); + (struct sockaddr *)&isrc, (struct sockaddr *)&idst, vnet); if (!sp) return 0; key_freesp(sp); @@ -3282,7 +3335,12 @@ struct sockaddr_in6 osrc, odst, isrc, idst; struct secpolicy *sp; struct ip6_hdr *oip6; + struct vnet *vnet; + if (m == NULL || m->m_pkthdr.rcvif == NULL) + panic("ipsec6_tunnel_validate: cannot find vnet."); + vnet = m->m_pkthdr.rcvif->if_vnet; + #ifdef DIAGNOSTIC if (m->m_len < sizeof(struct ip6_hdr)) panic("too short mbuf on ipsec6_tunnel_validate"); @@ -3325,7 +3383,7 @@ */ sp = key_gettunnel((struct sockaddr *)&osrc, (struct sockaddr *)&odst, - (struct sockaddr *)&isrc, (struct sockaddr *)&idst); + (struct sockaddr *)&isrc, (struct sockaddr *)&idst, vnet); /* * when there is no suitable inbound policy for the packet of the ipsec * tunnel mode, the kernel never decapsulate the tunneled packet diff -urN sys/netinet6/ipsec.h sys.CORE/netinet6/ipsec.h --- sys/netinet6/ipsec.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/ipsec.h Wed Jan 31 16:02:43 2007 @@ -285,6 +285,7 @@ extern int ipsec_debug; +#ifdef MOVED_TO_VNET extern struct ipsecstat ipsecstat; extern struct secpolicy ip4_def_policy; extern int ip4_esp_trans_deflev; @@ -296,34 +297,36 @@ extern int ip4_ipsec_dfbit; extern int ip4_ipsec_ecn; extern int ip4_esp_randpad; +#endif #define ipseclog(x) do { if (ipsec_debug) log x; } while (0) extern struct secpolicy *ipsec4_getpolicybysock __P((struct mbuf *, u_int, struct socket *, int *)); extern struct secpolicy *ipsec4_getpolicybyaddr - __P((struct mbuf *, u_int, int, int *)); + __P((struct mbuf *, u_int, int, int *, struct vnet *)); struct inpcb; extern int ipsec_init_policy __P((struct socket *so, struct inpcbpolicy **)); extern int ipsec_copy_policy __P((struct inpcbpolicy *, struct inpcbpolicy *)); -extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *)); +extern u_int ipsec_get_reqlevel __P((struct ipsecrequest *, struct vnet *)); extern int ipsec4_set_policy __P((struct inpcb *inp, int optname, caddr_t request, size_t len, int priv)); extern int ipsec4_get_policy __P((struct inpcb *inpcb, caddr_t request, size_t len, struct mbuf **mp)); extern int ipsec4_delete_pcbpolicy __P((struct inpcb *)); -extern int ipsec4_in_reject_so __P((struct mbuf *, struct socket *)); -extern int ipsec4_in_reject __P((struct mbuf *, struct inpcb *)); +extern int ipsec4_in_reject_so __P((struct mbuf *, struct socket *, struct vnet *)); +extern int ipsec4_in_reject __P((struct mbuf *, struct inpcb *, struct vnet *)); struct secas; 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 ipsec4_hdrsiz __P((struct mbuf *, u_int, struct inpcb *, + struct vnet *)); extern size_t ipsec_hdrsiz_tcp __P((struct tcpcb *)); struct ip; diff -urN sys/netinet6/ipsec6.h sys.CORE/netinet6/ipsec6.h --- sys/netinet6/ipsec6.h Tue Jul 3 04:01:54 2001 +++ sys.CORE/netinet6/ipsec6.h Wed Jan 31 16:02:43 2007 @@ -53,29 +53,29 @@ extern struct secpolicy *ipsec6_getpolicybysock __P((struct mbuf *, u_int, struct socket *, int *)); extern struct secpolicy *ipsec6_getpolicybyaddr - __P((struct mbuf *, u_int, int, int *)); + __P((struct mbuf *, u_int, int, int *, struct vnet *)); struct inpcb; -extern int ipsec6_in_reject_so __P((struct mbuf *, struct socket *)); +extern int ipsec6_in_reject_so __P((struct mbuf *, struct socket *, struct vnet *)); extern int ipsec6_delete_pcbpolicy __P((struct inpcb *)); extern int ipsec6_set_policy __P((struct inpcb *inp, int optname, caddr_t request, size_t len, int priv)); 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 *)); +extern int ipsec6_in_reject __P((struct mbuf *, struct inpcb *, struct vnet *)); struct tcp6cb; -extern size_t ipsec6_hdrsiz __P((struct mbuf *, u_int, struct inpcb *)); +extern size_t ipsec6_hdrsiz __P((struct mbuf *, u_int, struct inpcb *, struct vnet *vnet)); struct ip6_hdr; extern const char *ipsec6_logpacketstr __P((struct ip6_hdr *, u_int32_t)); extern int ipsec6_output_trans __P((struct ipsec_output_state *, u_char *, - struct mbuf *, struct secpolicy *, int, int *)); + struct mbuf *, struct secpolicy *, int, int *, struct vnet *)); extern int ipsec6_output_tunnel __P((struct ipsec_output_state *, - struct secpolicy *, int)); + struct secpolicy *, int, struct vnet *)); extern int ipsec6_tunnel_validate __P((struct mbuf *, int, u_int, struct secasvar *)); #endif /*_KERNEL*/ diff -urN sys/netinet6/raw_ip6.c sys.CORE/netinet6/raw_ip6.c --- sys/netinet6/raw_ip6.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/raw_ip6.c Wed Jan 31 16:02:43 2007 @@ -168,9 +168,9 @@ /* * Check AH/ESP integrity. */ - if (n && ipsec6_in_reject_so(n, last->inp_socket)) { + if (n && ipsec6_in_reject_so(n, last->inp_socket, vnet)) { m_freem(n); - ipsec6stat.in_polvio++; + vnet->ipsec6stat.in_polvio++; /* do not inject data into pcb */ } else #endif /*IPSEC*/ @@ -207,10 +207,10 @@ /* * Check AH/ESP integrity. */ - if (last && ipsec6_in_reject_so(m, last->inp_socket)) { + if (last && ipsec6_in_reject_so(m, last->inp_socket, vnet)) { m_freem(m); - ipsec6stat.in_polvio++; - ip6stat.ip6s_delivered--; + vnet->ipsec6stat.in_polvio++; + vnet->ip6stat.ip6s_delivered--; /* do not inject data into pcb */ } else #endif /*IPSEC*/ @@ -220,7 +220,7 @@ */ if (last && ipsec6_in_reject(m, last)) { m_freem(m); - ip6stat.ip6s_delivered--; + vnet->ip6stat.ip6s_delivered--; /* do not inject data into pcb */ } else #endif /*FAST_IPSEC*/ diff -urN sys/netinet6/udp6_usrreq.c sys.CORE/netinet6/udp6_usrreq.c --- sys/netinet6/udp6_usrreq.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netinet6/udp6_usrreq.c Wed Jan 31 16:02:43 2007 @@ -260,8 +260,8 @@ /* * Check AH/ESP integrity. */ - if (ipsec6_in_reject_so(m, last->inp_socket)) - ipsec6stat.in_polvio++; + if (ipsec6_in_reject_so(m, last->inp_socket, vnet)) + vnet->ipsec6stat.in_polvio++; /* do not inject data into pcb */ else #endif /* IPSEC */ @@ -327,8 +327,8 @@ /* * Check AH/ESP integrity. */ - if (ipsec6_in_reject_so(m, last->inp_socket)) { - ipsec6stat.in_polvio++; + if (ipsec6_in_reject_so(m, last->inp_socket, vnet)) { + vnet->ipsec6stat.in_polvio++; goto bad; } #endif /* IPSEC */ @@ -383,8 +383,8 @@ /* * Check AH/ESP integrity. */ - if (ipsec6_in_reject_so(m, in6p->in6p_socket)) { - ipsec6stat.in_polvio++; + if (ipsec6_in_reject_so(m, in6p->in6p_socket, vnet)) { + vnet->ipsec6stat.in_polvio++; goto bad; } #endif /* IPSEC */ diff -urN sys/netipsec/ipsec.c sys.CORE/netipsec/ipsec.c --- sys/netipsec/ipsec.c Mon Jun 30 18:38:13 2003 +++ sys.CORE/netipsec/ipsec.c Wed Jan 31 16:02:43 2007 @@ -53,6 +53,7 @@ #include #include +#include #include #include @@ -123,31 +124,31 @@ SYSCTL_DECL(_net_inet_ipsec); /* net.inet.ipsec */ -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV,esp_trans_deflev, CTLFLAG_RW, &ip4_esp_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, CTLFLAG_RW, &ip4_esp_net_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, CTLFLAG_RW, &ip4_ah_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, CTLFLAG_RW, &ip4_ah_net_deflev, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_AH_CLEARTOS, ah_cleartos, CTLFLAG_RW, &ah_cleartos, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_AH_OFFSETMASK, ah_offsetmask, CTLFLAG_RW, &ip4_ah_offsetmask, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DFBIT, dfbit, CTLFLAG_RW, &ip4_ipsec_dfbit, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_ECN, ecn, CTLFLAG_RW, &ip4_ipsec_ecn, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_DEBUG, debug, CTLFLAG_RW, &ipsec_debug, 0, ""); -SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, IPSECCTL_ESP_RANDPAD, esp_randpad, CTLFLAG_RW, &ip4_esp_randpad, 0, ""); -SYSCTL_INT(_net_inet_ipsec, OID_AUTO, +SYSCTL_V_INT(V_NET, _net_inet_ipsec, OID_AUTO, crypto_support, CTLFLAG_RW, &crypto_support,0, ""); -SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO, +SYSCTL_V_STRUCT(V_NET, _net_inet_ipsec, OID_AUTO, ipsecstats, CTLFLAG_RD, &newipsecstat, newipsecstat, ""); #ifdef INET6 @@ -165,21 +166,21 @@ SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD, 0,0, compat_ipsecstats_sysctl, "S", ""); #endif /* COMPAT_KAME */ -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, - CTLFLAG_RW, &ip6_esp_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, + esp_trans_deflev, CTLFLAG_RW, &ip6_esp_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev, CTLFLAG_RW, &ip6_esp_net_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev, - CTLFLAG_RW, &ip6_ah_trans_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, + ah_trans_deflev, CTLFLAG_RW, &ip6_ah_trans_deflev, 0, ""); +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev, CTLFLAG_RW, &ip6_ah_net_deflev, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_ECN, ecn, CTLFLAG_RW, &ip6_ipsec_ecn, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_DEBUG, debug, CTLFLAG_RW, &ipsec_debug, 0, ""); -SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD, +SYSCTL_V_INT(V_NET, _net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD, esp_randpad, CTLFLAG_RW, &ip6_esp_randpad, 0, ""); #endif /* INET6 */ diff -urN sys/netipsec/key.c sys.CORE/netipsec/key.c --- sys/netipsec/key.c Sat Feb 14 14:23:23 2004 +++ sys.CORE/netipsec/key.c Wed Jan 31 16:02:43 2007 @@ -54,6 +54,7 @@ #include #include +#include #include #include #include @@ -203,51 +204,51 @@ SYSCTL_DECL(_net_key); #endif -SYSCTL_INT(_net_key, KEYCTL_DEBUG_LEVEL, debug, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_DEBUG_LEVEL, debug, CTLFLAG_RW, \ &key_debug_level, 0, ""); /* max count of trial for the decision of spi value */ -SYSCTL_INT(_net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ &key_spi_trycnt, 0, ""); /* minimum spi value to allocate automatically. */ -SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ &key_spi_minval, 0, ""); /* maximun spi value to allocate automatically. */ -SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ &key_spi_maxval, 0, ""); /* interval to initialize randseed */ -SYSCTL_INT(_net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW, \ &key_int_random, 0, ""); /* lifetime for larval SA */ -SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ &key_larval_lifetime, 0, ""); /* counter for blocking to send SADB_ACQUIRE to IKEd */ -SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_BLOCKACQ_COUNT,blockacq_count,CTLFLAG_RW, \ &key_blockacq_count, 0, ""); /* lifetime for blocking to send SADB_ACQUIRE to IKEd */ -SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ &key_blockacq_lifetime, 0, ""); /* ESP auth */ -SYSCTL_INT(_net_key, KEYCTL_ESP_AUTH, esp_auth, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_ESP_AUTH, esp_auth, CTLFLAG_RW, \ &ipsec_esp_auth, 0, ""); /* minimum ESP key length */ -SYSCTL_INT(_net_key, KEYCTL_ESP_KEYMIN, esp_keymin, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_ESP_KEYMIN, esp_keymin, CTLFLAG_RW, \ &ipsec_esp_keymin, 0, ""); /* minimum AH key length */ -SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW, \ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_AH_KEYMIN, ah_keymin, CTLFLAG_RW, \ &ipsec_ah_keymin, 0, ""); /* perfered old SA rather than new SA */ -SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW,\ +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_PREFERED_OLDSA,prefered_oldsa, CTLFLAG_RW,\ &key_prefered_oldsa, 0, ""); #ifndef LIST_FOREACH @@ -349,12 +350,13 @@ int extlen[SADB_EXT_MAX + 1]; }; -static struct secasvar *key_allocsa_policy __P((const struct secasindex *)); +static struct secasvar *key_allocsa_policy __P((const struct secasindex *, + struct vnet *)); static void key_freesp_so __P((struct secpolicy **)); static struct secasvar *key_do_allocsa_policy __P((struct secashead *, u_int)); static void key_delsp __P((struct secpolicy *)); -static struct secpolicy *key_getsp __P((struct secpolicyindex *)); -static struct secpolicy *key_getspbyid __P((u_int32_t)); +static struct secpolicy *key_getsp __P((struct secpolicyindex *, struct vnet*)); +static struct secpolicy *key_getspbyid __P((u_int32_t, struct vnet *)); static u_int32_t key_newreqid __P((void)); static struct mbuf *key_gather_mbuf __P((struct mbuf *, const struct sadb_msghdr *, int, int, ...)); @@ -523,7 +525,7 @@ * others: found and return the pointer. */ struct secpolicy * -key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, int tag) +key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, int tag, struct vnet *vnet) { struct secpolicy *sp; int s; @@ -541,7 +543,7 @@ printf("*** objects\n"); kdebug_secpolicyindex(spidx)); - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(&sp->spidx)); @@ -580,7 +582,7 @@ union sockaddr_union *dst, u_int8_t proto, u_int dir, - const char* where, int tag) + const char* where, int tag, struct vnet *vnet) { struct secpolicy *sp; int s; @@ -599,7 +601,7 @@ printf("spi %u proto %u dir %u\n", spi, proto, dir); kdebug_sockaddr(&dst->sa)); - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(&sp->spidx)); @@ -642,7 +644,7 @@ const struct sockaddr *odst, const struct sockaddr *isrc, const struct sockaddr *idst, - const char* where, int tag) + const char* where, int tag, struct vnet *vnet) { struct secpolicy *sp; const int dir = IPSEC_DIR_INBOUND; @@ -661,7 +663,7 @@ } s = splnet(); /*called from softclock()*/ - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; @@ -817,7 +819,7 @@ struct secasvar *sav; u_int stateidx, state; - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) @@ -991,7 +993,7 @@ union sockaddr_union *dst, u_int proto, u_int32_t spi, - const char* where, int tag) + const char* where, int tag, struct vnet *vnet) { struct secashead *sah; struct secasvar *sav; @@ -1010,7 +1012,7 @@ * encrypted so we can't check internal IP header. */ s = splnet(); /*called from softclock()*/ - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { /* search valid state */ for (stateidx = 0; stateidx < _ARRAYLEN(saorder_state_valid); @@ -1213,13 +1215,13 @@ * others : found, pointer to a SP. */ static struct secpolicy * -key_getsp(struct secpolicyindex *spidx) +key_getsp(struct secpolicyindex *spidx, struct vnet *vnet) { struct secpolicy *sp; KASSERT(spidx != NULL, ("key_getsp: null spidx")); - LIST_FOREACH(sp, &sptree[spidx->dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[spidx->dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (key_cmpspidx_exactly(spidx, &sp->spidx)) { @@ -1237,11 +1239,11 @@ * others : found, pointer to a SP. */ static struct secpolicy * -key_getspbyid(u_int32_t id) +key_getspbyid(u_int32_t id, struct vnet *vnet) { struct secpolicy *sp; - LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) { + LIST_FOREACH(sp, &vnet->sptree[IPSEC_DIR_INBOUND], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (sp->id == id) { @@ -1250,7 +1252,7 @@ } } - LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) { + LIST_FOREACH(sp, &vnet->sptree[IPSEC_DIR_OUTBOUND], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (sp->id == id) { @@ -7060,37 +7062,59 @@ } void -key_init() +key_init(vnet) + struct vnet *vnet; { int i; for (i = 0; i < IPSEC_DIR_MAX; i++) { - LIST_INIT(&sptree[i]); + LIST_INIT(&vnet->sptree[i]); } - LIST_INIT(&sahtree); + LIST_INIT(&vnet->sahtree); for (i = 0; i <= SADB_SATYPE_MAX; i++) { - LIST_INIT(®tree[i]); + LIST_INIT(&vnet->regtree[i]); } #ifndef IPSEC_NONBLOCK_ACQUIRE - LIST_INIT(&acqtree); + LIST_INIT(&vnet->acqtree); #endif - LIST_INIT(&spacqtree); + LIST_INIT(&vnet->spacqtree); /* system default */ - ip4_def_policy.policy = IPSEC_POLICY_NONE; - ip4_def_policy.refcnt++; /*never reclaim this*/ + vnet->ip4_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip4_def_policy.refcnt++; /*never reclaim this*/ #ifndef IPSEC_DEBUG2 timeout((void *)key_timehandler, (void *)0, hz); #endif /*IPSEC_DEBUG2*/ /* initialize key statistics */ - keystat.getspi_count = 1; + vnet->keystat.getspi_count = 1; + + /* initialize vars in struct vnet */ + vnet->acq_seq = 0; + vnet->ip4_ah_offsetmask = 0; + vnet->ip4_ipsec_dfbit = 0; + vnet->ip4_esp_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip4_esp_net_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ah_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ah_net_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ipsec_ecn = 0; + vnet->ip4_esp_randpad = -1; + vnet->crypto_support = 0; +#ifdef INET6 + vnet->ip6_esp_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip6_esp_net_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ah_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ah_net_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ipsec_ecn = 0; + vnet->ip6_esp_randpad = -1; +#endif - printf("IPsec: Initialized Security Association Processing.\n"); + if (vnet == vnet0) + printf("IPsec: Initialized Security Association Processing.\n"); return; } diff -urN sys/netipsec/keysock.c sys.CORE/netipsec/keysock.c --- sys/netipsec/keysock.c Thu Jan 23 21:11:36 2003 +++ sys.CORE/netipsec/keysock.c Wed Jan 31 16:02:43 2007 @@ -592,10 +592,11 @@ }; static void -key_init0(void) +key_init0(vnet) + struct vnet *vnet; { - bzero((caddr_t)&key_cb, sizeof(key_cb)); - key_init(); + bzero((caddr_t)&vnet->key_cb, sizeof(key_cb)); + key_init(vnet); } struct domain keydomain = diff -urN sys/netkey/key.c sys.CORE/netkey/key.c --- sys/netkey/key.c Thu Jan 13 14:47:18 2005 +++ sys.CORE/netkey/key.c Wed Jan 31 16:02:43 2007 @@ -107,6 +107,8 @@ #include #include +#include +#include #ifndef satosin #define satosin(s) ((struct sockaddr_in *)s) @@ -126,6 +128,7 @@ */ u_int32_t key_debug_level = 0; +#ifdef MOVED_TO_VNET static u_int key_spi_trycnt = 1000; static u_int32_t key_spi_minval = 0x100; static u_int32_t key_spi_maxval = 0x0fffffff; /* XXX */ @@ -149,6 +152,7 @@ static LIST_HEAD(_spacqtree, secspacq) spacqtree; /* SP acquiring list */ struct key_cb key_cb; +#endif /* MOVED_TO_VNET */ /* search order for SAs */ static const u_int saorder_state_valid_prefer_old[] = { @@ -223,32 +227,32 @@ &key_debug_level, 0, ""); /* max count of trial for the decision of spi value */ -SYSCTL_INT(_net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ - &key_spi_trycnt, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_TRY, spi_trycnt, CTLFLAG_RW, \ + v_key_spi_trycnt, 0, ""); /* minimum spi value to allocate automatically. */ -SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ - &key_spi_minval, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_MIN_VALUE, spi_minval, CTLFLAG_RW, \ + v_key_spi_minval, 0, ""); /* maximun spi value to allocate automatically. */ -SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ - &key_spi_maxval, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_SPI_MAX_VALUE, spi_maxval, CTLFLAG_RW, \ + v_key_spi_maxval, 0, ""); /* interval to initialize randseed */ -SYSCTL_INT(_net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW, \ - &key_int_random, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_RANDOM_INT, int_random, CTLFLAG_RW, \ + v_key_int_random, 0, ""); /* lifetime for larval SA */ -SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ - &key_larval_lifetime, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_LARVAL_LIFETIME, larval_lifetime, CTLFLAG_RW, \ + v_key_larval_lifetime, 0, ""); /* counter for blocking to send SADB_ACQUIRE to IKEd */ -SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW, \ - &key_blockacq_count, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_BLOCKACQ_COUNT, blockacq_count, CTLFLAG_RW, \ + v_key_blockacq_count, 0, ""); /* lifetime for blocking to send SADB_ACQUIRE to IKEd */ -SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ - &key_blockacq_lifetime, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_BLOCKACQ_LIFETIME, blockacq_lifetime, CTLFLAG_RW, \ + v_key_blockacq_lifetime, 0, ""); /* ESP auth */ SYSCTL_INT(_net_key, KEYCTL_ESP_AUTH, esp_auth, CTLFLAG_RW, \ @@ -263,8 +267,8 @@ &ipsec_ah_keymin, 0, ""); /* perfered old SA rather than new SA */ -SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW,\ - &key_preferred_oldsa, 0, ""); +SYSCTL_V_INT(V_NET, _net_key, KEYCTL_PREFERED_OLDSA, prefered_oldsa, CTLFLAG_RW,\ + v_key_preferred_oldsa, 0, ""); #ifndef LIST_FOREACH #define LIST_FOREACH(elm, head, field) \ @@ -352,9 +356,11 @@ } while (0) /* key statistics */ +#ifdef MOVED_TO_VNET struct _keystat { u_long getspi_count; /* the avarage of count to try to get new SPI */ } keystat; +#endif struct sadb_msghdr { struct sadb_msg *msg; @@ -363,18 +369,20 @@ int extlen[SADB_EXT_MAX + 1]; }; -static struct secasvar *key_allocsa_policy __P((struct secasindex *)); +static struct secasvar *key_allocsa_policy __P((struct secasindex *, + struct vnet *)); static void key_freesp_so __P((struct secpolicy **)); -static struct secasvar *key_do_allocsa_policy __P((struct secashead *, u_int)); +static struct secasvar *key_do_allocsa_policy __P((struct secashead *, u_int, + struct vnet *)); static void key_delsp __P((struct secpolicy *)); -static struct secpolicy *key_getsp __P((struct secpolicyindex *)); -static struct secpolicy *key_getspbyid __P((u_int32_t)); +static struct secpolicy *key_getsp __P((struct secpolicyindex *, struct vnet*)); +static struct secpolicy *key_getspbyid __P((u_int32_t, struct vnet*)); static u_int32_t key_newreqid __P((void)); static struct mbuf *key_gather_mbuf __P((struct mbuf *, const struct sadb_msghdr *, int, int, ...)); static int key_spdadd __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); -static u_int32_t key_getnewspid __P((void)); +static u_int32_t key_getnewspid __P((struct vnet *)); static int key_spddelete __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); static int key_spddelete2 __P((struct socket *, struct mbuf *, @@ -388,14 +396,15 @@ static struct mbuf *key_setdumpsp __P((struct secpolicy *, u_int8_t, u_int32_t, u_int32_t)); static u_int key_getspreqmsglen __P((struct secpolicy *)); -static int key_spdexpire __P((struct secpolicy *)); -static struct secashead *key_newsah __P((struct secasindex *)); +static int key_spdexpire __P((struct secpolicy *, struct vnet *)); +static struct secashead *key_newsah __P((struct secasindex *, struct vnet *)); static void key_delsah __P((struct secashead *)); static struct secasvar *key_newsav __P((struct mbuf *, const struct sadb_msghdr *, struct secashead *, int *)); static void key_delsav __P((struct secasvar *)); -static struct secashead *key_getsah __P((struct secasindex *)); -static struct secasvar *key_checkspidup __P((struct secasindex *, u_int32_t)); +static struct secashead *key_getsah __P((struct secasindex *, struct vnet *)); +static struct secasvar *key_checkspidup __P((struct secasindex *, u_int32_t, + struct vnet *)); static struct secasvar *key_getsavbyspi __P((struct secashead *, u_int32_t)); static int key_setsaval __P((struct secasvar *, struct mbuf *, const struct sadb_msghdr *)); @@ -416,7 +425,7 @@ u_int32_t)); static void *key_newbuf __P((const void *, u_int)); #ifdef INET6 -static int key_ismyaddr6 __P((struct sockaddr_in6 *)); +static int key_ismyaddr6 __P((struct sockaddr_in6 *, struct vnet *)); #endif /* flags for key_cmpsaidx() */ @@ -440,7 +449,8 @@ static int key_getspi __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); static u_int32_t key_do_getnewspi __P((struct sadb_spirange *, - struct secasindex *)); + struct secasindex *, + struct vnet *)); static int key_update __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); #ifdef IPSEC_DOSEQCHECK @@ -465,19 +475,20 @@ static struct mbuf *key_getcomb_ipcomp __P((void)); static struct mbuf *key_getprop __P((const struct secasindex *)); -static int key_acquire __P((struct secasindex *, struct secpolicy *)); +static int key_acquire __P((struct secasindex *, struct secpolicy *, + struct vnet *)); #ifndef IPSEC_NONBLOCK_ACQUIRE -static struct secacq *key_newacq __P((struct secasindex *)); -static struct secacq *key_getacq __P((struct secasindex *)); -static struct secacq *key_getacqbyseq __P((u_int32_t)); +static struct secacq *key_newacq __P((struct secasindex *, struct vnet *)); +static struct secacq *key_getacq __P((struct secasindex *, struct vnet *)); +static struct secacq *key_getacqbyseq __P((u_int32_t, struct vnet *)); #endif static struct secspacq *key_newspacq __P((struct secpolicyindex *)); -static struct secspacq *key_getspacq __P((struct secpolicyindex *)); +static struct secspacq *key_getspacq __P((struct secpolicyindex *, struct vnet *)); static int key_acquire2 __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); static int key_register __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); -static int key_expire __P((struct secasvar *)); +static int key_expire __P((struct secasvar *, struct vnet *vnet)); static int key_flush __P((struct socket *, struct mbuf *, const struct sadb_msghdr *)); static int key_dump __P((struct socket *, struct mbuf *, @@ -486,7 +497,7 @@ const struct sadb_msghdr *)); static int key_senderror __P((struct socket *, struct mbuf *, int)); static int key_validate_ext __P((const struct sadb_ext *, int)); -static int key_align __P((struct mbuf *, struct sadb_msghdr *)); +static int key_align __P((struct mbuf *, struct sadb_msghdr *, struct vnet *)); #if 0 static const char *key_getfqdn __P((void)); static const char *key_getuserfqdn __P((void)); @@ -502,9 +513,10 @@ * others: found and return the pointer. */ struct secpolicy * -key_allocsp(spidx, dir) +key_allocsp(spidx, dir, vnet) struct secpolicyindex *spidx; u_int dir; + struct vnet *vnet; { struct secpolicy *sp; struct timeval tv; @@ -513,6 +525,8 @@ /* sanity check */ if (spidx == NULL) panic("key_allocsp: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_allocsp: NULL vnet is passed.\n"); /* check direction */ switch (dir) { @@ -529,7 +543,7 @@ printf("*** objects\n"); kdebug_secpolicyindex(spidx)); - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(&sp->spidx)); @@ -564,8 +578,9 @@ * XXX slow */ struct secpolicy * -key_gettunnel(osrc, odst, isrc, idst) +key_gettunnel(osrc, odst, isrc, idst, vnet) struct sockaddr *osrc, *odst, *isrc, *idst; + struct vnet *vnet; { struct secpolicy *sp; const int dir = IPSEC_DIR_INBOUND; @@ -580,9 +595,11 @@ isrc->sa_family, idst->sa_family)); return NULL; } + if (vnet == NULL) + panic("key_gettunnel: NULL vnet is passed.\n"); s = splnet(); /*called from softclock()*/ - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; @@ -639,9 +656,10 @@ * ENOENT: policy may be valid, but SA with REQUIRE is on acquiring. */ int -key_checkrequest(isr, saidx) +key_checkrequest(isr, saidx, vnet) struct ipsecrequest *isr; struct secasindex *saidx; + struct vnet *vnet; { u_int level; int error; @@ -649,6 +667,8 @@ /* sanity check */ if (isr == NULL || saidx == NULL) panic("key_checkrequest: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_checkrequest: NULL vnet is passed.\n"); /* check mode */ switch (saidx->mode) { @@ -661,7 +681,7 @@ } /* get current level */ - level = ipsec_get_reqlevel(isr); + level = ipsec_get_reqlevel(isr, vnet); #if 0 /* @@ -704,14 +724,14 @@ * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt. */ if (isr->sav == NULL) - isr->sav = key_allocsa_policy(saidx); + isr->sav = key_allocsa_policy(saidx, vnet); /* When there is SA. */ if (isr->sav != NULL) return 0; /* there is no SA */ - if ((error = key_acquire(saidx, isr->sp)) != 0) { + if ((error = key_acquire(saidx, isr->sp, vnet)) != 0) { /* XXX What should I do ? */ ipseclog((LOG_DEBUG, "key_checkrequest: error %d returned " "from key_acquire.\n", error)); @@ -728,8 +748,9 @@ * others: found and return the pointer. */ static struct secasvar * -key_allocsa_policy(saidx) +key_allocsa_policy(saidx, vnet) struct secasindex *saidx; + struct vnet *vnet; { struct secashead *sah; struct secasvar *sav; @@ -737,7 +758,9 @@ const u_int *saorder_state_valid; int arraysize; - LIST_FOREACH(sah, &sahtree, chain) { + if (vnet == NULL) + panic("key_allocsa_policy: NULL vnet is passed.\n"); + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID)) @@ -752,7 +775,7 @@ * search a valid state list for outbound packet. * This search order is important. */ - if (key_preferred_oldsa) { + if (vnet->key_preferred_oldsa) { saorder_state_valid = saorder_state_valid_prefer_old; arraysize = _ARRAYLEN(saorder_state_valid_prefer_old); } else { @@ -764,7 +787,7 @@ state = saorder_state_valid[stateidx]; - sav = key_do_allocsa_policy(sah, state); + sav = key_do_allocsa_policy(sah, state, vnet); if (sav != NULL) return sav; } @@ -780,12 +803,15 @@ * others : found, pointer to a SA. */ static struct secasvar * -key_do_allocsa_policy(sah, state) +key_do_allocsa_policy(sah, state, vnet) struct secashead *sah; u_int state; + struct vnet *vnet; { struct secasvar *sav, *nextsav, *candidate, *d; + if (vnet == NULL) + panic("key_do_allocsa_policy: NULL vnet is passed.\n"); /* initilize */ candidate = NULL; @@ -812,7 +838,7 @@ "lifetime_current is NULL.\n"); /* What the best method is to compare ? */ - if (key_preferred_oldsa) { + if (vnet->key_preferred_oldsa) { if (candidate->lft_c->sadb_lifetime_addtime > sav->lft_c->sadb_lifetime_addtime) { candidate = sav; @@ -883,7 +909,7 @@ PFKEY_UNIT64(result->m_pkthdr.len); if (key_sendup_mbuf(NULL, result, - KEY_SENDUP_REGISTERED)) + KEY_SENDUP_REGISTERED, vnet)) goto msgfail; msgfail: key_freesav(d); @@ -916,10 +942,11 @@ * keep source address in IPsec SA. We see a tricky situation here. */ struct secasvar * -key_allocsa(family, src, dst, proto, spi) +key_allocsa(family, src, dst, proto, spi, vnet) u_int family, proto; caddr_t src, dst; u_int32_t spi; + struct vnet *vnet; { struct secashead *sah; struct secasvar *sav; @@ -933,12 +960,14 @@ /* sanity check */ if (src == NULL || dst == NULL) panic("key_allocsa: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_allocsa: NULL vnet is passed.\n"); /* * when both systems employ similar strategy to use a SA. * the search order is important even in the inbound case. */ - if (key_preferred_oldsa) { + if (vnet->key_preferred_oldsa) { saorder_state_valid = saorder_state_valid_prefer_old; arraysize = _ARRAYLEN(saorder_state_valid_prefer_old); } else { @@ -953,7 +982,7 @@ * encrypted so we can't check internal IP header. */ s = splnet(); /*called from softclock()*/ - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { /* * search a valid state list for inbound packet. * the search order is not important. @@ -1248,16 +1277,19 @@ * others : found, pointer to a SP. */ static struct secpolicy * -key_getsp(spidx) +key_getsp(spidx, vnet) struct secpolicyindex *spidx; + struct vnet *vnet; { struct secpolicy *sp; /* sanity check */ if (spidx == NULL) panic("key_getsp: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_getsp: NULL vnet is passed.\n"); - LIST_FOREACH(sp, &sptree[spidx->dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[spidx->dir], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (key_cmpspidx_exactly(spidx, &sp->spidx)) { @@ -1275,12 +1307,15 @@ * others : found, pointer to a SP. */ static struct secpolicy * -key_getspbyid(id) +key_getspbyid(id, vnet) u_int32_t id; + struct vnet *vnet; { struct secpolicy *sp; - LIST_FOREACH(sp, &sptree[IPSEC_DIR_INBOUND], chain) { + if (vnet == NULL) + panic("key_getspbyid: NULL vnet is passed.\n"); + LIST_FOREACH(sp, &vnet->sptree[IPSEC_DIR_INBOUND], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (sp->id == id) { @@ -1289,7 +1324,7 @@ } } - LIST_FOREACH(sp, &sptree[IPSEC_DIR_OUTBOUND], chain) { + LIST_FOREACH(sp, &vnet->sptree[IPSEC_DIR_OUTBOUND], chain) { if (sp->state == IPSEC_SPSTATE_DEAD) continue; if (sp->id == id) { @@ -1735,10 +1770,14 @@ struct secpolicy *newsp; struct timeval tv; int error; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdadd: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spdadd: NULL vnet pointer.\n"); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || @@ -1808,7 +1847,7 @@ * If the type is either SPDADD or SPDSETIDX AND a SP is found, * then error. */ - newsp = key_getsp(&spidx); + newsp = key_getsp(&spidx, vnet); if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { if (newsp) { newsp->state = IPSEC_SPSTATE_DEAD; @@ -1827,7 +1866,7 @@ return key_senderror(so, m, error); } - if ((newsp->id = key_getnewspid()) == 0) { + if ((newsp->id = key_getnewspid(vnet)) == 0) { keydb_delsecpolicy(newsp); return key_senderror(so, m, ENOBUFS); } @@ -1879,12 +1918,13 @@ newsp->refcnt = 1; /* do not reclaim until I say I do */ newsp->state = IPSEC_SPSTATE_ALIVE; - LIST_INSERT_TAIL(&sptree[newsp->spidx.dir], newsp, secpolicy, chain); + LIST_INSERT_TAIL(&vnet->sptree[newsp->spidx.dir], newsp, + secpolicy, chain); /* delete the entry in spacqtree */ if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { struct secspacq *spacq; - if ((spacq = key_getspacq(&spidx)) != NULL) { + if ((spacq = key_getspacq(&spidx, vnet)) != NULL) { /* reset counter in order to deletion by timehandler. */ microtime(&tv); spacq->created = tv.tv_sec; @@ -1934,7 +1974,7 @@ xpl->sadb_x_policy_id = newsp->id; m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -1945,17 +1985,22 @@ * others: success. */ static u_int32_t -key_getnewspid() +key_getnewspid(vnet) + struct vnet *vnet; { u_int32_t newid = 0; - int count = key_spi_trycnt; /* XXX */ + int count; struct secpolicy *sp; + if (vnet == NULL) + panic("key_getnewspid: NULL vnet was passed."); + count = vnet->key_spi_trycnt; /* XXX */ /* when requesting to allocate spi ranged */ while (count--) { - newid = (policy_id = (policy_id == ~0 ? 1 : policy_id + 1)); + newid = (vnet->policy_id = (vnet->policy_id == ~0 ? + 1 : vnet->policy_id+1)); - if ((sp = key_getspbyid(newid)) == NULL) + if ((sp = key_getspbyid(newid, vnet)) == NULL) break; key_freesp(sp); @@ -1991,10 +2036,14 @@ struct sadb_x_policy *xpl0; struct secpolicyindex spidx; struct secpolicy *sp; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddelete: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spddelete: NULL vnet pointer.\n"); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || @@ -2034,7 +2083,7 @@ } /* Is there SP in SPD ? */ - if ((sp = key_getsp(&spidx)) == NULL) { + if ((sp = key_getsp(&spidx, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_spddelete: no SP found.\n")); return key_senderror(so, m, EINVAL); } @@ -2060,7 +2109,7 @@ newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -2084,10 +2133,14 @@ { u_int32_t id; struct secpolicy *sp; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddelete2: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spddelete2: NULL vnet pointer.\n"); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { @@ -2099,7 +2152,7 @@ id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id; /* Is there SP in SPD ? */ - if ((sp = key_getspbyid(id)) == NULL) { + if ((sp = key_getspbyid(id, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_spddelete2: no SP found id:%u.\n", id)); key_senderror(so, m, EINVAL); } @@ -2156,7 +2209,7 @@ newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -2181,10 +2234,14 @@ u_int32_t id; struct secpolicy *sp; struct mbuf *n; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdget: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spdget: NULL vnet pointer.\n"); if (mhp->ext[SADB_X_EXT_POLICY] == NULL || mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { @@ -2195,7 +2252,7 @@ id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id; /* Is there SP in SPD ? */ - if ((sp = key_getspbyid(id)) == NULL) { + if ((sp = key_getspbyid(id, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_spdget: no SP found id:%u.\n", id)); return key_senderror(so, m, ENOENT); } @@ -2203,7 +2260,7 @@ n = key_setdumpsp(sp, SADB_X_SPDGET, 0, mhp->msg->sadb_msg_pid); if (n != NULL) { m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + return key_sendup_mbuf(so, n, KEY_SENDUP_ONE, vnet); } else return key_senderror(so, m, ENOBUFS); } @@ -2224,8 +2281,9 @@ * others: error number */ int -key_spdacquire(sp) +key_spdacquire(sp, vnet) struct secpolicy *sp; + struct vnet *vnet; { struct mbuf *result = NULL, *m; struct secspacq *newspacq; @@ -2238,10 +2296,12 @@ panic("key_spdacquire: called but there is request.\n"); if (sp->policy != IPSEC_POLICY_IPSEC) panic("key_spdacquire: policy mismathed. IPsec is expected.\n"); + if (vnet == NULL) + panic("key_spdacquire: NULL vnet is passed.\n"); /* get a entry to check whether sent message or not. */ - if ((newspacq = key_getspacq(&sp->spidx)) != NULL) { - if (key_blockacq_count < newspacq->count) { + if ((newspacq = key_getspacq(&sp->spidx, vnet)) != NULL) { + if (vnet->key_blockacq_count < newspacq->count) { /* reset counter and do send message. */ newspacq->count = 0; } else { @@ -2255,7 +2315,7 @@ return ENOBUFS; /* add to acqtree */ - LIST_INSERT_HEAD(&spacqtree, newspacq, chain); + LIST_INSERT_HEAD(&vnet->spacqtree, newspacq, chain); } /* create new sadb_msg to reply. */ @@ -2273,7 +2333,7 @@ mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); - return key_sendup_mbuf(NULL, m, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(NULL, m, KEY_SENDUP_REGISTERED, vnet); fail: if (result) @@ -2302,16 +2362,20 @@ struct sadb_msg *newmsg; struct secpolicy *sp; u_int dir; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spdflush: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spdflush: NULL vnet pointer.\n"); if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) return key_senderror(so, m, EINVAL); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { sp->state = IPSEC_SPSTATE_DEAD; } } @@ -2329,7 +2393,7 @@ newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); - return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, m, KEY_SENDUP_ALL, vnet); } /* @@ -2353,15 +2417,19 @@ int cnt; u_int dir; struct mbuf *n; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_spddump: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_spddump: NULL vnet pointer.\n"); /* search SPD entry and get buffer size. */ cnt = 0; for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { cnt++; } } @@ -2370,13 +2438,13 @@ return key_senderror(so, m, ENOENT); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &sptree[dir], chain) { + LIST_FOREACH(sp, &vnet->sptree[dir], chain) { --cnt; n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt, mhp->msg->sadb_msg_pid); if (n) - key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + key_sendup_mbuf(so, n, KEY_SENDUP_ONE, vnet); } } @@ -2481,8 +2549,9 @@ * others : error number */ static int -key_spdexpire(sp) +key_spdexpire(sp, vnet) struct secpolicy *sp; + struct vnet *vnet; { int s; struct mbuf *result = NULL, *m; @@ -2496,6 +2565,8 @@ /* sanity check */ if (sp == NULL) panic("key_spdexpire: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_spdexpire: NULL vnet is passed.\n"); /* set msg header */ m = key_setsadbmsg(SADB_X_SPDEXPIRE, 0, 0, 0, 0, 0); @@ -2580,7 +2651,7 @@ PFKEY_UNIT64(result->m_pkthdr.len); splx(s); - return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED, vnet); fail: if (result) @@ -2596,14 +2667,17 @@ * others : pointer to new SA head. */ static struct secashead * -key_newsah(saidx) +key_newsah(saidx, vnet) struct secasindex *saidx; + struct vnet *vnet; { struct secashead *newsah; /* sanity check */ if (saidx == NULL) panic("key_newsaidx: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_newsaidx: NULL vnet is passed.\n"); newsah = keydb_newsecashead(); if (newsah == NULL) @@ -2613,7 +2687,7 @@ /* add to saidxtree */ newsah->state = SADB_SASTATE_MATURE; - LIST_INSERT_HEAD(&sahtree, newsah, chain); + LIST_INSERT_HEAD(&vnet->sahtree, newsah, chain); return(newsah); } @@ -2846,12 +2920,15 @@ * others : found, pointer to a SA. */ static struct secashead * -key_getsah(saidx) +key_getsah(saidx, vnet) struct secasindex *saidx; + struct vnet *vnet; { struct secashead *sah; - LIST_FOREACH(sah, &sahtree, chain) { + if (vnet == NULL) + panic("key_getsah: NULL vnet was passed."); + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, saidx, CMP_REQID)) @@ -2869,13 +2946,16 @@ * others : found, pointer to a SA. */ static struct secasvar * -key_checkspidup(saidx, spi) +key_checkspidup(saidx, spi, vnet) struct secasindex *saidx; u_int32_t spi; + struct vnet *vnet; { struct secashead *sah; struct secasvar *sav; + if (vnet == NULL) + panic("key_checkspidup: NULL vnet was passed."); /* check address family */ if (saidx->src.ss_family != saidx->dst.ss_family) { ipseclog((LOG_DEBUG, "key_checkspidup: address family mismatched.\n")); @@ -2883,8 +2963,8 @@ } /* check all SAD */ - LIST_FOREACH(sah, &sahtree, chain) { - if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst)) + LIST_FOREACH(sah, &vnet->sahtree, chain) { + if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst, vnet)) continue; sav = key_getsavbyspi(sah, spi); if (sav != NULL) @@ -3794,8 +3874,9 @@ * 0: false */ int -key_ismyaddr(sa) +key_ismyaddr(sa, vnet) struct sockaddr *sa; + struct vnet *vnet; { #ifdef INET struct sockaddr_in *sin; @@ -3805,12 +3886,14 @@ /* sanity check */ if (sa == NULL) panic("key_ismyaddr: NULL pointer is passed.\n"); + if (vnet == NULL) + panic("key_ismyaddr: NULL vnet was passed."); switch (sa->sa_family) { #ifdef INET case AF_INET: sin = (struct sockaddr_in *)sa; - for (ia = in_ifaddrhead.tqh_first; ia; + for (ia = vnet->in_ifaddrhead.tqh_first; ia; ia = ia->ia_link.tqe_next) { if (sin->sin_family == ia->ia_addr.sin_family && @@ -3824,7 +3907,7 @@ #endif #ifdef INET6 case AF_INET6: - return key_ismyaddr6((struct sockaddr_in6 *)sa); + return key_ismyaddr6((struct sockaddr_in6 *)sa, vnet); #endif } @@ -3841,13 +3924,16 @@ #include static int -key_ismyaddr6(sin6) +key_ismyaddr6(sin6, vnet) struct sockaddr_in6 *sin6; + struct vnet *vnet; { struct in6_ifaddr *ia; struct in6_multi *in6m; - for (ia = in6_ifaddr; ia; ia = ia->ia_next) { + if (vnet == NULL) + panic("key_ismyaddr6: NULL vnet was passed."); + for (ia = vnet->in6_ifaddr; ia; ia = ia->ia_next) { if (key_sockaddrcmp((struct sockaddr *)&sin6, (struct sockaddr *)&ia->ia_addr, 0) == 0) return 1; @@ -4178,17 +4264,22 @@ u_int dir; int s; struct timeval tv; + struct vnet *vnet; microtime(&tv); s = splnet(); /*called from softclock()*/ + /* This timer function is called once to step through every vnet. */ + LIST_FOREACH(vnet, &vnet_head, vnet_le) + { + /* SPD */ { struct secpolicy *sp, *nextsp; for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - for (sp = LIST_FIRST(&sptree[dir]); + for (sp = LIST_FIRST(&vnet->sptree[dir]); sp != NULL; sp = nextsp) { @@ -4208,7 +4299,7 @@ || (sp->validtime && tv.tv_sec - sp->lastused > sp->validtime)) { sp->state = IPSEC_SPSTATE_DEAD; - key_spdexpire(sp); + key_spdexpire(sp, vnet); continue; } } @@ -4220,7 +4311,7 @@ struct secashead *sah, *nextsah; struct secasvar *sav, *nextsav; - for (sah = LIST_FIRST(&sahtree); + for (sah = LIST_FIRST(&vnet->sahtree); sah != NULL; sah = nextsah) { @@ -4239,7 +4330,7 @@ nextsav = LIST_NEXT(sav, chain); - if (tv.tv_sec - sav->created > key_larval_lifetime) { + if (tv.tv_sec - sav->created > vnet->key_larval_lifetime) { key_freesav(sav); } } @@ -4284,7 +4375,7 @@ * message in the status of * DYING. Do remove below code. */ - key_expire(sav); + key_expire(sav, vnet); } } @@ -4303,7 +4394,7 @@ * message in the status of * DYING. Do remove below code. */ - key_expire(sav); + key_expire(sav, vnet); } } @@ -4387,13 +4478,13 @@ { struct secacq *acq, *nextacq; - for (acq = LIST_FIRST(&acqtree); + for (acq = LIST_FIRST(&vnet->acqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); - if (tv.tv_sec - acq->created > key_blockacq_lifetime + if (tv.tv_sec - acq->created > vnet->key_blockacq_lifetime && __LIST_CHAINED(acq)) { LIST_REMOVE(acq, chain); KFREE(acq); @@ -4406,13 +4497,13 @@ { struct secspacq *acq, *nextacq; - for (acq = LIST_FIRST(&spacqtree); + for (acq = LIST_FIRST(&vnet->spacqtree); acq != NULL; acq = nextacq) { nextacq = LIST_NEXT(acq, chain); - if (tv.tv_sec - acq->created > key_blockacq_lifetime + if (tv.tv_sec - acq->created > vnet->key_blockacq_lifetime && __LIST_CHAINED(acq)) { LIST_REMOVE(acq, chain); KFREE(acq); @@ -4421,11 +4512,13 @@ } /* initialize random seed */ - if (key_tick_init_random++ > key_int_random) { - key_tick_init_random = 0; + if (vnet->key_tick_init_random++ > vnet->key_int_random) { + vnet->key_tick_init_random = 0; key_srandom(); } + /* end LIST_FOREACH(vnet, ...) */ + } #ifndef IPSEC_DEBUG2 /* do exchange to tick time !! */ (void)timeout((void *)key_timehandler, (void *)0, hz); @@ -4562,10 +4655,14 @@ u_int8_t mode; u_int32_t reqid; int error; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_getspi: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_getspi: cannot find vnet.\n"); if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) { @@ -4633,14 +4730,14 @@ /* SPI allocation */ spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE], - &saidx); + &saidx, vnet); if (spi == 0) return key_senderror(so, m, EINVAL); /* get a SA index */ - if ((newsah = key_getsah(&saidx)) == NULL) { + if ((newsah = key_getsah(&saidx, vnet)) == NULL) { /* create a new SA index */ - if ((newsah = key_newsah(&saidx)) == NULL) { + if ((newsah = key_newsah(&saidx, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_getspi: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } @@ -4661,7 +4758,7 @@ /* delete the entry in acqtree */ if (mhp->msg->sadb_msg_seq != 0) { struct secacq *acq; - if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) != NULL) { + if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq, vnet)) != NULL) { /* reset counter in order to deletion by timehandler. */ struct timeval tv; microtime(&tv); @@ -4722,7 +4819,7 @@ if (n->m_len < sizeof(struct sadb_msg)) { n = m_pullup(n, sizeof(struct sadb_msg)); if (n == NULL) - return key_sendup_mbuf(so, m, KEY_SENDUP_ONE); + return key_sendup_mbuf(so, m, KEY_SENDUP_ONE, vnet); } n->m_pkthdr.len = 0; @@ -4735,7 +4832,7 @@ newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + return key_sendup_mbuf(so, n, KEY_SENDUP_ONE, vnet); } } @@ -4747,21 +4844,26 @@ * others: success. */ static u_int32_t -key_do_getnewspi(spirange, saidx) +key_do_getnewspi(spirange, saidx, vnet) struct sadb_spirange *spirange; struct secasindex *saidx; + struct vnet *vnet; { u_int32_t newspi; u_int32_t min, max; - int count = key_spi_trycnt; + int count; + + if (vnet == NULL) + panic("key_do_getnewspi: NULL vnet was passed."); + count = vnet->key_spi_trycnt; /* set spi range to allocate */ if (spirange != NULL) { min = spirange->sadb_spirange_min; max = spirange->sadb_spirange_max; } else { - min = key_spi_minval; - max = key_spi_maxval; + min = vnet->key_spi_minval; + max = vnet->key_spi_maxval; } /* IPCOMP needs 2-byte SPI */ if (saidx->proto == IPPROTO_IPCOMP) { @@ -4776,7 +4878,7 @@ } if (min == max) { - if (key_checkspidup(saidx, min) != NULL) { + if (key_checkspidup(saidx, min, vnet) != NULL) { ipseclog((LOG_DEBUG, "key_do_getnewspi: SPI %u exists already.\n", min)); return 0; } @@ -4794,7 +4896,7 @@ /* generate pseudo-random SPI value ranged. */ newspi = min + (key_random() % (max - min + 1)); - if (key_checkspidup(saidx, newspi) == NULL) + if (key_checkspidup(saidx, newspi, vnet) == NULL) break; } @@ -4805,8 +4907,8 @@ } /* statistics */ - keystat.getspi_count = - (keystat.getspi_count + key_spi_trycnt - count) / 2; + vnet->keystat.getspi_count = + (vnet->keystat.getspi_count + vnet->key_spi_trycnt - count)/2; return newspi; } @@ -4839,10 +4941,14 @@ u_int8_t mode; u_int32_t reqid; int error; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_update: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_update: cannot find vnet.\n"); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -4887,7 +4993,7 @@ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - if ((sah = key_getsah(&saidx)) == NULL) { + if ((sah = key_getsah(&saidx, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_update: no SA index found.\n")); return key_senderror(so, m, ENOENT); } @@ -4963,7 +5069,7 @@ } m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -5034,10 +5140,14 @@ u_int8_t mode; u_int32_t reqid; int error; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_add: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_add: NULL vnet pointer is passed.\n"); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -5082,9 +5192,9 @@ KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - if ((newsah = key_getsah(&saidx)) == NULL) { + if ((newsah = key_getsah(&saidx, vnet)) == NULL) { /* create a new SA header */ - if ((newsah = key_newsah(&saidx)) == NULL) { + if ((newsah = key_newsah(&saidx, vnet)) == NULL) { ipseclog((LOG_DEBUG, "key_add: No more memory.\n")); return key_senderror(so, m, ENOBUFS); } @@ -5130,7 +5240,7 @@ } m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -5265,10 +5375,14 @@ struct secashead *sah; struct secasvar *sav = NULL; u_int16_t proto; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_delete: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_delete: NULL vnet pointer is passed.\n"); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -5309,7 +5423,7 @@ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) @@ -5349,7 +5463,7 @@ newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -5368,6 +5482,11 @@ struct secashead *sah; struct secasvar *sav, *nextsav; u_int stateidx, state; + struct vnet *vnet; + + if (so == NULL || so->so_vnet == NULL) + panic("key_delete_all: cannot find vnet.\n"); + vnet = so->so_vnet; src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]); dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]); @@ -5375,7 +5494,7 @@ /* XXX boundary check against sa_len */ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) @@ -5425,7 +5544,7 @@ newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, n, KEY_SENDUP_ALL, vnet); } } @@ -5453,10 +5572,14 @@ struct secashead *sah; struct secasvar *sav = NULL; u_int16_t proto; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_get: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_get: NULL vnet pointer is passed.\n"); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -5485,7 +5608,7 @@ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA header */ - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0) @@ -5518,7 +5641,7 @@ return key_senderror(so, m, ENOBUFS); m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + return key_sendup_mbuf(so, n, KEY_SENDUP_ONE, vnet); } } @@ -5795,9 +5918,10 @@ * others: error number */ static int -key_acquire(saidx, sp) +key_acquire(saidx, sp, vnet) struct secasindex *saidx; struct secpolicy *sp; + struct vnet *vnet; { struct mbuf *result = NULL, *m; #ifndef IPSEC_NONBLOCK_ACQUIRE @@ -5812,6 +5936,8 @@ panic("key_acquire: NULL pointer is passed.\n"); if ((satype = key_proto2satype(saidx->proto)) == 0) panic("key_acquire: invalid proto is passed.\n"); + if (vnet == NULL) + panic("key_acquire: NULL vnet is passed.\n"); #ifndef IPSEC_NONBLOCK_ACQUIRE /* @@ -5821,8 +5947,8 @@ * managed with ACQUIRING list. */ /* get a entry to check whether sending message or not. */ - if ((newacq = key_getacq(saidx)) != NULL) { - if (key_blockacq_count < newacq->count) { + if ((newacq = key_getacq(saidx, vnet)) != NULL) { + if (vnet->key_blockacq_count < newacq->count) { /* reset counter and do send message. */ newacq->count = 0; } else { @@ -5832,11 +5958,11 @@ } } else { /* make new entry for blocking to send SADB_ACQUIRE. */ - if ((newacq = key_newacq(saidx)) == NULL) + if ((newacq = key_newacq(saidx, vnet)) == NULL) return ENOBUFS; /* add to acqtree */ - LIST_INSERT_HEAD(&acqtree, newacq, chain); + LIST_INSERT_HEAD(&vnet->acqtree, newacq, chain); } #endif @@ -5966,7 +6092,7 @@ mtod(result, struct sadb_msg *)->sadb_msg_len = PFKEY_UNIT64(result->m_pkthdr.len); - return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED, vnet); fail: if (result) @@ -5976,12 +6102,15 @@ #ifndef IPSEC_NONBLOCK_ACQUIRE static struct secacq * -key_newacq(saidx) +key_newacq(saidx, vnet) struct secasindex *saidx; + struct vnet *vnet; { struct secacq *newacq; struct timeval tv; + if (vnet == NULL) + panic("key_newacq: NULL vnet was passed."); /* get new entry */ KMALLOC(newacq, struct secacq *, sizeof(struct secacq)); if (newacq == NULL) { @@ -5992,7 +6121,7 @@ /* copy secindex */ bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx)); - newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq); + newacq->seq = (vnet->acq_seq == ~0 ? 1 : ++vnet->acq_seq); microtime(&tv); newacq->created = tv.tv_sec; newacq->count = 0; @@ -6001,12 +6130,15 @@ } static struct secacq * -key_getacq(saidx) +key_getacq(saidx, vnet) struct secasindex *saidx; + struct vnet *vnet; { struct secacq *acq; - LIST_FOREACH(acq, &acqtree, chain) { + if (vnet == NULL) + panic("key_getacq: NULL vnet was passed."); + LIST_FOREACH(acq, &vnet->acqtree, chain) { if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY)) return acq; } @@ -6015,12 +6147,15 @@ } static struct secacq * -key_getacqbyseq(seq) +key_getacqbyseq(seq, vnet) u_int32_t seq; + struct vnet *vnet; { struct secacq *acq; - LIST_FOREACH(acq, &acqtree, chain) { + if (vnet == NULL) + panic("key_getacqbyseq: NULL vnet was passed."); + LIST_FOREACH(acq, &vnet->acqtree, chain) { if (acq->seq == seq) return acq; } @@ -6054,12 +6189,15 @@ } static struct secspacq * -key_getspacq(spidx) +key_getspacq(spidx, vnet) struct secpolicyindex *spidx; + struct vnet *vnet; { struct secspacq *acq; - LIST_FOREACH(acq, &spacqtree, chain) { + if (vnet == NULL) + panic("key_getspacq: NULL vnet was passed."); + LIST_FOREACH(acq, &vnet->spacqtree, chain) { if (key_cmpspidx_exactly(spidx, &acq->spidx)) return acq; } @@ -6092,10 +6230,14 @@ struct secashead *sah; u_int16_t proto; int error; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_acquire2: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_acquire2: NULL vnet pointer is passed.\n"); /* * Error message from KMd. @@ -6115,7 +6257,7 @@ return 0; } - if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) == NULL) { + if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq, vnet)) == NULL) { /* * the specified larval SA is already gone, or we got * a bogus sequence number. we can silently ignore it. @@ -6165,7 +6307,7 @@ KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx); /* get a SA index */ - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (sah->state == SADB_SASTATE_DEAD) continue; if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID)) @@ -6176,14 +6318,14 @@ return key_senderror(so, m, EEXIST); } - error = key_acquire(&saidx, NULL); + error = key_acquire(&saidx, NULL, vnet); if (error != 0) { ipseclog((LOG_DEBUG, "key_acquire2: error %d returned " "from key_acquire.\n", mhp->msg->sadb_msg_errno)); return key_senderror(so, m, error); } - return key_sendup_mbuf(so, m, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(so, m, KEY_SENDUP_REGISTERED, vnet); } /* @@ -6206,13 +6348,17 @@ const struct sadb_msghdr *mhp; { struct secreg *reg, *newreg = 0; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_register: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_register: NULL vnet is passed.\n"); /* check for invalid register message */ - if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0])) + if (mhp->msg->sadb_msg_satype >= sizeof(vnet->regtree)/sizeof(vnet->regtree[0])) return key_senderror(so, m, EINVAL); /* When SATYPE_UNSPEC is specified, only return sabd_supported. */ @@ -6220,7 +6366,7 @@ goto setmsg; /* check whether existing or not */ - LIST_FOREACH(reg, ®tree[mhp->msg->sadb_msg_satype], chain) { + LIST_FOREACH(reg, &vnet->regtree[mhp->msg->sadb_msg_satype], chain) { if (reg->so == so) { ipseclog((LOG_DEBUG, "key_register: socket exists already.\n")); return key_senderror(so, m, EEXIST); @@ -6239,7 +6385,8 @@ ((struct keycb *)sotorawcb(so))->kp_registered++; /* add regnode to regtree. */ - LIST_INSERT_HEAD(®tree[mhp->msg->sadb_msg_satype], newreg, chain); + LIST_INSERT_HEAD(&vnet->regtree[mhp->msg->sadb_msg_satype], + newreg, chain); setmsg: { @@ -6355,7 +6502,7 @@ #endif m_freem(m); - return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED, vnet); } } @@ -6369,10 +6516,14 @@ { struct secreg *reg; int i; + struct vnet *vnet; /* sanity check */ if (so == NULL) panic("key_freereg: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_freereg: NULL vnet pointer is passed.\n"); /* * check whether existing or not. @@ -6380,7 +6531,7 @@ * one socket is registered to multiple type of SA. */ for (i = 0; i <= SADB_SATYPE_MAX; i++) { - LIST_FOREACH(reg, ®tree[i], chain) { + LIST_FOREACH(reg, &vnet->regtree[i], chain) { if (reg->so == so && __LIST_CHAINED(reg)) { LIST_REMOVE(reg, chain); @@ -6404,8 +6555,9 @@ * others : error number */ static int -key_expire(sav) +key_expire(sav, vnet) struct secasvar *sav; + struct vnet *vnet; { int s; int satype; @@ -6414,6 +6566,8 @@ int error = -1; struct sadb_lifetime *lt; + if (vnet == NULL) + panic("key_expire: NULL vnet was passed."); /* XXX: Why do we lock ? */ s = splnet(); /*called from softclock()*/ @@ -6513,7 +6667,7 @@ PFKEY_UNIT64(result->m_pkthdr.len); splx(s); - return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED); + return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED, vnet); fail: if (result) @@ -6546,10 +6700,14 @@ u_int16_t proto; u_int8_t state; u_int stateidx; + struct vnet *vnet; /* sanity check */ if (so == NULL || mhp == NULL || mhp->msg == NULL) panic("key_flush: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_flush: NULL vnet pointer is passed.\n"); /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -6558,7 +6716,7 @@ } /* no SATYPE specified, i.e. flushing all SA. */ - for (sah = LIST_FIRST(&sahtree); + for (sah = LIST_FIRST(&vnet->sahtree); sah != NULL; sah = nextsah) { nextsah = LIST_NEXT(sah, chain); @@ -6599,7 +6757,7 @@ newmsg->sadb_msg_errno = 0; newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); - return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, m, KEY_SENDUP_ALL, vnet); } /* @@ -6629,10 +6787,12 @@ int cnt; struct sadb_msg *newmsg; struct mbuf *n; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_dump: NULL pointer is passed.\n"); + vnet = so->so_vnet; /* map satype to proto */ if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) { @@ -6642,7 +6802,7 @@ /* count sav entries to be sent to the userland. */ cnt = 0; - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) continue; @@ -6662,7 +6822,7 @@ /* send this to the userland, one at a time. */ newmsg = NULL; - LIST_FOREACH(sah, &sahtree, chain) { + LIST_FOREACH(sah, &vnet->sahtree, chain) { if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC && proto != sah->saidx.proto) continue; @@ -6683,7 +6843,7 @@ if (!n) return key_senderror(so, m, ENOBUFS); - key_sendup_mbuf(so, n, KEY_SENDUP_ONE); + key_sendup_mbuf(so, n, KEY_SENDUP_ONE, vnet); } } } @@ -6704,10 +6864,14 @@ const struct sadb_msghdr *mhp; { int olen; + struct vnet *vnet; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) panic("key_promisc: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL); + panic("key_promisc: NULL vnet pointer is passed.\n"); olen = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len); @@ -6736,14 +6900,14 @@ /* send the original message back to everyone */ mhp->msg->sadb_msg_errno = 0; - return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, m, KEY_SENDUP_ALL, vnet); } else { /* send packet as is */ m_adj(m, PFKEY_ALIGN8(sizeof(struct sadb_msg))); /* TODO: if sadb_msg_seq is specified, send to specific pid */ - return key_sendup_mbuf(so, m, KEY_SENDUP_ALL); + return key_sendup_mbuf(so, m, KEY_SENDUP_ALL, vnet); } } @@ -6790,6 +6954,7 @@ struct mbuf *m; struct socket *so; { + struct vnet *vnet; struct sadb_msg *msg; struct sadb_msghdr mh; u_int orglen; @@ -6799,6 +6964,9 @@ /* sanity check */ if (m == NULL || so == NULL) panic("key_parse: NULL pointer is passed.\n"); + vnet = so->so_vnet; + if (vnet == NULL) + panic("key_parse: NULL vnet is passed.\n"); #if 0 /*kdebug_sadb assumes msg in linear buffer*/ KEYDEBUG(KEYDEBUG_KEY_DUMP, @@ -6818,7 +6986,7 @@ if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len != m->m_pkthdr.len) { ipseclog((LOG_DEBUG, "key_parse: invalid message length.\n")); - pfkeystat.out_invlen++; + vnet->pfkeystat.out_invlen++; error = EINVAL; goto senderror; } @@ -6827,7 +6995,7 @@ ipseclog((LOG_DEBUG, "key_parse: PF_KEY version %u is mismatched.\n", msg->sadb_msg_version)); - pfkeystat.out_invver++; + vnet->pfkeystat.out_invver++; error = EINVAL; goto senderror; } @@ -6835,7 +7003,7 @@ if (msg->sadb_msg_type > SADB_MAX) { ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", msg->sadb_msg_type)); - pfkeystat.out_invmsgtype++; + vnet->pfkeystat.out_invmsgtype++; error = EINVAL; goto senderror; } @@ -6868,7 +7036,7 @@ } /* align the mbuf chain so that extensions are in contiguous region. */ - error = key_align(m, &mh); + error = key_align(m, &mh, vnet); if (error) return error; @@ -6892,7 +7060,7 @@ case SADB_EXPIRE: ipseclog((LOG_DEBUG, "key_parse: must specify satype " "when msg type=%u.\n", msg->sadb_msg_type)); - pfkeystat.out_invsatype++; + vnet->pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } @@ -6911,7 +7079,7 @@ case SADB_X_SPDDELETE2: ipseclog((LOG_DEBUG, "key_parse: illegal satype=%u\n", msg->sadb_msg_type)); - pfkeystat.out_invsatype++; + vnet->pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } @@ -6922,7 +7090,7 @@ case SADB_SATYPE_MIP: ipseclog((LOG_DEBUG, "key_parse: type %u isn't supported.\n", msg->sadb_msg_satype)); - pfkeystat.out_invsatype++; + vnet->pfkeystat.out_invsatype++; error = EOPNOTSUPP; goto senderror; case 1: /* XXX: What does it do? */ @@ -6932,7 +7100,7 @@ default: ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n", msg->sadb_msg_satype)); - pfkeystat.out_invsatype++; + vnet->pfkeystat.out_invsatype++; error = EINVAL; goto senderror; } @@ -6949,7 +7117,7 @@ /* check upper layer protocol */ if (src0->sadb_address_proto != dst0->sadb_address_proto) { ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n")); - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -6958,7 +7126,7 @@ if (PFKEY_ADDR_SADDR(src0)->sa_family != PFKEY_ADDR_SADDR(dst0)->sa_family) { ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n")); - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -6966,7 +7134,7 @@ PFKEY_ADDR_SADDR(dst0)->sa_len) { ipseclog((LOG_DEBUG, "key_parse: address struct size mismatched.\n")); - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -6975,7 +7143,7 @@ case AF_INET: if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in)) { - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -6983,7 +7151,7 @@ case AF_INET6: if (PFKEY_ADDR_SADDR(src0)->sa_len != sizeof(struct sockaddr_in6)) { - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -6991,7 +7159,7 @@ default: ipseclog((LOG_DEBUG, "key_parse: unsupported address family.\n")); - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EAFNOSUPPORT; goto senderror; } @@ -7013,7 +7181,7 @@ dst0->sadb_address_prefixlen > plen) { ipseclog((LOG_DEBUG, "key_parse: illegal prefixlen.\n")); - pfkeystat.out_invaddr++; + vnet->pfkeystat.out_invaddr++; error = EINVAL; goto senderror; } @@ -7026,7 +7194,7 @@ if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) || key_typesw[msg->sadb_msg_type] == NULL) { - pfkeystat.out_invmsgtype++; + vnet->pfkeystat.out_invmsgtype++; error = EINVAL; goto senderror; } @@ -7035,7 +7203,7 @@ senderror: msg->sadb_msg_errno = error; - return key_sendup_mbuf(so, m, target); + return key_sendup_mbuf(so, m, target, vnet); } static int @@ -7044,14 +7212,18 @@ struct mbuf *m; int code; { + struct vnet *vnet; struct sadb_msg *msg; + if (so == NULL || so->so_vnet == NULL) + panic("key_senderror: cannot find vnet"); + vnet = so->so_vnet; if (m->m_len < sizeof(struct sadb_msg)) panic("invalid mbuf passed to key_senderror"); msg = mtod(m, struct sadb_msg *); msg->sadb_msg_errno = code; - return key_sendup_mbuf(so, m, KEY_SENDUP_ONE); + return key_sendup_mbuf(so, m, KEY_SENDUP_ONE, vnet); } /* @@ -7060,9 +7232,10 @@ * XXX larger-than-MCLBYTES extension? */ static int -key_align(m, mhp) +key_align(m, mhp, vnet) struct mbuf *m; struct sadb_msghdr *mhp; + struct vnet *vnet; { struct mbuf *n; struct sadb_ext *ext; @@ -7075,6 +7248,8 @@ panic("key_align: NULL pointer is passed.\n"); if (m->m_len < sizeof(struct sadb_msg)) panic("invalid mbuf passed to key_align"); + if (vnet == NULL) + panic("key_align: NULL vnet is passed.\n"); /* initialize */ bzero(mhp, sizeof(*mhp)); @@ -7122,7 +7297,7 @@ "key_align: duplicate ext_type %u " "is passed.\n", ext->sadb_ext_type)); m_freem(m); - pfkeystat.out_dupext++; + vnet->pfkeystat.out_dupext++; return EINVAL; } break; @@ -7131,7 +7306,7 @@ "key_align: invalid ext_type %u is passed.\n", ext->sadb_ext_type)); m_freem(m); - pfkeystat.out_invexttype++; + vnet->pfkeystat.out_invexttype++; return EINVAL; } @@ -7139,7 +7314,7 @@ if (key_validate_ext(ext, extlen)) { m_freem(m); - pfkeystat.out_invlen++; + vnet->pfkeystat.out_invlen++; return EINVAL; } @@ -7157,7 +7332,7 @@ if (off != end) { m_freem(m); - pfkeystat.out_invlen++; + vnet->pfkeystat.out_invlen++; return EINVAL; } @@ -7224,49 +7399,97 @@ } void -key_init() +key_init(vnet) + struct vnet *vnet; { int i; - bzero((caddr_t)&key_cb, sizeof(key_cb)); + if (vnet == NULL) + panic("key_init: NULL vnet was passed."); + bzero((caddr_t)&vnet->key_cb, sizeof(vnet->key_cb)); for (i = 0; i < IPSEC_DIR_MAX; i++) { - LIST_INIT(&sptree[i]); + LIST_INIT(&vnet->sptree[i]); } - LIST_INIT(&sahtree); + LIST_INIT(&vnet->sahtree); for (i = 0; i <= SADB_SATYPE_MAX; i++) { - LIST_INIT(®tree[i]); + LIST_INIT(&vnet->regtree[i]); } #ifndef IPSEC_NONBLOCK_ACQUIRE - LIST_INIT(&acqtree); + LIST_INIT(&vnet->acqtree); #endif - LIST_INIT(&spacqtree); + LIST_INIT(&vnet->spacqtree); /* system default */ #ifdef INET - ip4_def_policy.policy = IPSEC_POLICY_NONE; - ip4_def_policy.refcnt++; /*never reclaim this*/ + vnet->ip4_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip4_def_policy.refcnt++; /*never reclaim this*/ #endif #ifdef INET6 - ip6_def_policy.policy = IPSEC_POLICY_NONE; - ip6_def_policy.refcnt++; /*never reclaim this*/ + vnet->ip6_def_policy.policy = IPSEC_POLICY_NONE; + vnet->ip6_def_policy.refcnt++; /*never reclaim this*/ #endif -#ifndef IPSEC_DEBUG2 - timeout((void *)key_timehandler, (void *)0, hz); -#endif /*IPSEC_DEBUG2*/ - /* initialize key statistics */ - keystat.getspi_count = 1; + vnet->keystat.getspi_count = 1; - printf("IPsec: Initialized Security Association Processing.\n"); + /* initalize vnet variables (normally static) */ + /* from netkey/key.c */ + vnet->key_spi_trycnt = 1000; + vnet->key_spi_minval = 0x100; + vnet->key_spi_maxval = 0x0fffffff; /* XXX */ + vnet->policy_id = 0; + vnet->key_int_random = 60; /*interval to initialize randseed,1(m)*/ + vnet->key_larval_lifetime = 30; /* interval to expire acquiring, 30(s)*/ + vnet->key_blockacq_count = 10; /* counter for blocking SADB_ACQUIRE.*/ + vnet->key_blockacq_lifetime = 20;/* lifetime f/ blocking SADB_ACQUIRE.*/ + vnet->key_preferred_oldsa = 1; /* preferred old sa rather than new sa.*/ + vnet->acq_seq = 0; + vnet->key_tick_init_random = 0; + + /* from netinet6/ipsec.c */ + vnet->ip4_ah_cleartos = 1; + vnet->ip4_ah_offsetmask = 0; /* maybe IP_DF? */ + vnet->ip4_ipsec_dfbit = 0;/* DF bit on encap. 0: clear 1: set 2: copy */ + vnet->ip4_esp_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip4_esp_net_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ah_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ah_net_deflev = IPSEC_LEVEL_USE; + vnet->ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ + vnet->ip4_esp_randpad = -1; +#ifdef INET6 + /* what about ipsec6stat? */ + vnet->ip6_esp_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip6_esp_net_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ah_trans_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ah_net_deflev = IPSEC_LEVEL_USE; + vnet->ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ + vnet->ip6_esp_randpad = -1; +#endif + +/* net.inet6.ipsec6 */ + +#ifndef IPSEC_DEBUG2 + if (vnet == vnet0) /* one timehandler iterates for all vnets */ + timeout((void *)key_timehandler, (void *)0, hz); +#endif /*IPSEC_DEBUG2*/ + + if (vnet == vnet0) + printf("IPsec: Initialized Security Association Processing.\n"); return; } +void +key_destroy(vnet) +struct vnet *vnet; +{ + /* XXX do nothing */ +} + /* * XXX: maybe This function is called after INBOUND IPsec processing. * @@ -7406,13 +7629,16 @@ /* dumb version */ void -key_sa_routechange(dst) +key_sa_routechange(dst, vnet) struct sockaddr *dst; + struct vnet *vnet; { struct secashead *sah; struct route *ro; - LIST_FOREACH(sah, &sahtree, chain) { + if (vnet == NULL) + panic("key_sa_routechange: NULL vnet was passed."); + LIST_FOREACH(sah, &vnet->sahtree, chain) { ro = &sah->sa_route; if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len && bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) { diff -urN sys/netkey/key.h sys.CORE/netkey/key.h --- sys/netkey/key.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/netkey/key.h Wed Jan 31 16:02:43 2007 @@ -35,7 +35,7 @@ #ifdef _KERNEL -extern struct key_cb key_cb; +/*extern struct key_cb key_cb;*/ struct secpolicy; struct secpolicyindex; @@ -46,14 +46,15 @@ struct sadb_msg; struct sadb_x_policy; -extern struct secpolicy *key_allocsp __P((struct secpolicyindex *, u_int)); +extern struct secpolicy *key_allocsp __P((struct secpolicyindex *, u_int, + struct vnet*)); extern struct secpolicy *key_gettunnel __P((struct sockaddr *, - struct sockaddr *, struct sockaddr *, struct sockaddr *)); + struct sockaddr *, struct sockaddr *, struct sockaddr *, struct vnet*)); extern int key_checkrequest __P((struct ipsecrequest *isr, struct secasindex *, struct vnet *)); extern struct secasvar *key_allocsa __P((u_int, caddr_t, caddr_t, - u_int, u_int32_t)); + u_int, u_int32_t, struct vnet *)); extern void key_freesp __P((struct secpolicy *)); extern void key_freeso __P((struct socket *)); extern void key_freesav __P((struct secasvar *)); @@ -68,11 +69,12 @@ extern void key_randomfill __P((void *, size_t)); extern void key_freereg __P((struct socket *)); extern int key_parse __P((struct mbuf *, struct socket *)); -extern void key_init __P((void)); +extern void key_init __P((struct vnet *)); +extern void key_destroy __P((struct vnet *)); extern int key_checktunnelsanity __P((struct secasvar *, u_int, caddr_t, caddr_t)); extern void key_sa_recordxfer __P((struct secasvar *, struct mbuf *)); -extern void key_sa_routechange __P((struct sockaddr *)); +extern void key_sa_routechange __P((struct sockaddr *, struct vnet *)); extern void key_sa_stir_iv __P((struct secasvar *)); #ifdef MALLOC_DECLARE diff -urN sys/netkey/keysock.c sys.CORE/netkey/keysock.c --- sys/netkey/keysock.c Wed Jan 31 15:57:05 2007 +++ sys.CORE/netkey/keysock.c Wed Jan 31 16:02:43 2007 @@ -65,9 +65,7 @@ struct sockaddr key_dst = { 2, PF_KEY, }; struct sockaddr key_src = { 2, PF_KEY, }; -static int key_sendup0 __P((struct rawcb *, struct mbuf *, int)); - -struct pfkeystat pfkeystat; +static int key_sendup0 __P((struct rawcb *, struct mbuf *, int, struct vnet*)); /* * key_output() @@ -86,27 +84,31 @@ int s; struct socket *so; va_list ap; + struct vnet *vnet; va_start(ap, m); so = va_arg(ap, struct socket *); + vnet = va_arg(ap, struct vnet *); va_end(ap); if (m == 0) panic("key_output: NULL pointer was passed.\n"); + if (vnet == NULL) + panic("key_output: NULL vnet was passed.\n"); - pfkeystat.out_total++; - pfkeystat.out_bytes += m->m_pkthdr.len; + vnet->pfkeystat.out_total++; + vnet->pfkeystat.out_bytes += m->m_pkthdr.len; len = m->m_pkthdr.len; if (len < sizeof(struct sadb_msg)) { - pfkeystat.out_tooshort++; + vnet->pfkeystat.out_tooshort++; error = EINVAL; goto end; } if (m->m_len < sizeof(struct sadb_msg)) { if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) { - pfkeystat.out_nomem++; + vnet->pfkeystat.out_nomem++; error = ENOBUFS; goto end; } @@ -118,9 +120,9 @@ KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m)); msg = mtod(m, struct sadb_msg *); - pfkeystat.out_msgtype[msg->sadb_msg_type]++; + vnet->pfkeystat.out_msgtype[msg->sadb_msg_type]++; if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) { - pfkeystat.out_invlen++; + vnet->pfkeystat.out_invlen++; error = EINVAL; goto end; } @@ -140,13 +142,17 @@ * send message to the socket. */ static int -key_sendup0(rp, m, promisc) +key_sendup0(rp, m, promisc, vnet) struct rawcb *rp; struct mbuf *m; int promisc; + struct vnet *vnet; { int error; + if (vnet == NULL) + panic("key_sendup0: NULL vnet was passed.\n"); + if (promisc) { struct sadb_msg *pmsg; @@ -154,7 +160,7 @@ if (m && m->m_len < sizeof(struct sadb_msg)) m = m_pullup(m, sizeof(struct sadb_msg)); if (!m) { - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; m_freem(m); return ENOBUFS; } @@ -167,12 +173,12 @@ pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len); /* pid and seq? */ - pfkeystat.in_msgtype[pmsg->sadb_msg_type]++; + vnet->pfkeystat.in_msgtype[pmsg->sadb_msg_type]++; } if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, m, NULL)) { - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; m_freem(m); error = ENOBUFS; } else @@ -196,6 +202,8 @@ /* sanity check */ if (so == 0 || msg == 0) panic("key_sendup: NULL pointer was passed.\n"); + if (vnet == NULL) + panic("key_sendup: NULL vnet was passed.\n"); KEYDEBUG(KEYDEBUG_KEY_DUMP, printf("key_sendup: \n"); @@ -205,9 +213,9 @@ * we increment statistics here, just in case we have ENOBUFS * in this function. */ - pfkeystat.in_total++; - pfkeystat.in_bytes += len; - pfkeystat.in_msgtype[msg->sadb_msg_type]++; + vnet->pfkeystat.in_total++; + vnet->pfkeystat.in_bytes += len; + vnet->pfkeystat.in_msgtype[msg->sadb_msg_type]++; /* * Get mbuf chain whenever possible (not clusters), @@ -229,7 +237,7 @@ n->m_len = MLEN; } if (!n) { - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; return ENOBUFS; } if (tlen >= MCLBYTES) { /*XXX better threshold? */ @@ -237,7 +245,7 @@ if ((n->m_flags & M_EXT) == 0) { m_free(n); m_freem(m); - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; return ENOBUFS; } n->m_len = MCLBYTES; @@ -260,9 +268,9 @@ m_copyback(m, 0, len, (caddr_t)msg); /* avoid duplicated statistics */ - pfkeystat.in_total--; - pfkeystat.in_bytes -= len; - pfkeystat.in_msgtype[msg->sadb_msg_type]--; + vnet->pfkeystat.in_total--; + vnet->pfkeystat.in_bytes -= len; + vnet->pfkeystat.in_msgtype[msg->sadb_msg_type]--; return key_sendup_mbuf(so, m, target, vnet); } @@ -285,14 +293,16 @@ panic("key_sendup_mbuf: NULL pointer was passed.\n"); if (so == NULL && target == KEY_SENDUP_ONE) panic("key_sendup_mbuf: NULL pointer was passed.\n"); + if (vnet == NULL) + panic("key_sendup_mbuf: NULL vnet pointer was passed.\n"); - pfkeystat.in_total++; - pfkeystat.in_bytes += m->m_pkthdr.len; + vnet->pfkeystat.in_total++; + vnet->pfkeystat.in_bytes += m->m_pkthdr.len; if (m->m_len < sizeof(struct sadb_msg)) { #if 1 m = m_pullup(m, sizeof(struct sadb_msg)); if (m == NULL) { - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; return ENOBUFS; } #else @@ -302,7 +312,7 @@ if (m->m_len >= sizeof(struct sadb_msg)) { struct sadb_msg *msg; msg = mtod(m, struct sadb_msg *); - pfkeystat.in_msgtype[msg->sadb_msg_type]++; + vnet->pfkeystat.in_msgtype[msg->sadb_msg_type]++; } LIST_FOREACH(rp, &vnet->rawcb_list, list) @@ -323,7 +333,7 @@ */ if (((struct keycb *)rp)->kp_promisc) { if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { - (void)key_sendup0(rp, n, 1); + (void)key_sendup0(rp, n, 1, vnet); n = NULL; } } @@ -347,18 +357,18 @@ sendup++; break; } - pfkeystat.in_msgtarget[target]++; + vnet->pfkeystat.in_msgtarget[target]++; if (!sendup) continue; if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) { m_freem(m); - pfkeystat.in_nomem++; + vnet->pfkeystat.in_nomem++; return ENOBUFS; } - if ((error = key_sendup0(rp, n, 0)) != 0) { + if ((error = key_sendup0(rp, n, 0, vnet)) != 0) { m_freem(m); return error; } @@ -367,7 +377,7 @@ } if (so) { - error = key_sendup0(sotorawcb(so), m, 0); + error = key_sendup0(sotorawcb(so), m, 0, vnet); m = NULL; } else { error = 0; @@ -397,9 +407,12 @@ static int key_attach(struct socket *so, int proto, struct proc *p) { + struct vnet *vnet = so->so_vnet; struct keycb *kp; int s, error; + if (vnet == NULL) + panic("key_attach: NULL vnet was passed.\n"); if (sotorawcb(so) != 0) return EISCONN; /* XXX panic? */ kp = (struct keycb *)malloc(sizeof *kp, M_PCB, M_WAITOK); /* XXX */ @@ -428,8 +441,8 @@ kp->kp_promisc = kp->kp_registered = 0; if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ - key_cb.key_count++; - key_cb.any_count++; + vnet->key_cb.key_count++; + vnet->key_cb.any_count++; kp->kp_raw.rcb_laddr = &key_src; kp->kp_raw.rcb_faddr = &key_dst; soisconnected(so); @@ -474,15 +487,18 @@ static int key_detach(struct socket *so) { + struct vnet *vnet = so->so_vnet; struct keycb *kp = (struct keycb *)sotorawcb(so); int s, error; + if (vnet == NULL) + panic("key_detach: NULL vnet from sock."); s = splnet(); if (kp != 0) { if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */ - key_cb.key_count--; - key_cb.any_count--; + vnet->key_cb.key_count--; + vnet->key_cb.any_count--; key_freereg(so); } @@ -585,13 +601,13 @@ { SOCK_RAW, &keydomain, PF_KEY_V2, PR_ATOMIC|PR_ADDR, 0, key_output, raw_ctlinput, 0, 0, - raw_init, 0, 0, 0, + raw_init, raw_destroy, 0, 0, 0, &key_usrreqs } }; struct domain keydomain = - { PF_KEY, "key", key_init, 0, 0, + { PF_KEY, "key", key_init, key_destroy, 0, 0, keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] }; DOMAIN_SET(key); diff -urN sys/netkey/keysock.h sys.CORE/netkey/keysock.h --- sys/netkey/keysock.h Wed Jan 31 15:57:05 2007 +++ sys.CORE/netkey/keysock.h Wed Jan 31 16:02:43 2007 @@ -69,8 +69,6 @@ int kp_registered; /* registered socket */ }; -extern struct pfkeystat pfkeystat; - extern int key_output __P((struct mbuf *, ...)); extern int key_usrreq __P((struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *));