7151 lines
204 KiB
Diff
7151 lines
204 KiB
Diff
|
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 <net/bpf.h>
|
||
|
#include <net/if_types.h>
|
||
|
#include <net/if_dl.h>
|
||
|
+#include <net/if_gif.h>
|
||
|
#include <net/ethernet.h>
|
||
|
|
||
|
#include <netinet/tcp_fsm.h>
|
||
|
+#ifdef IPSEC
|
||
|
+#include <netkey/key.h>
|
||
|
+#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 <netipx/ipx_if.h>
|
||
|
#include <netipx/ipx_pcb.h>
|
||
|
|
||
|
+/* IPsec support */
|
||
|
+#include <netinet6/ipsec.h>
|
||
|
+#include <netkey/keydb.h>
|
||
|
+#include <netkey/key.h>
|
||
|
+#include <netkey/keysock.h>
|
||
|
+/* gif support */
|
||
|
+#include <machine/bus.h>
|
||
|
+#include <sys/rman.h>
|
||
|
+
|
||
|
#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 <sys/time.h>
|
||
|
#include <sys/syslog.h>
|
||
|
|
||
|
+#include <net/vnet.h>
|
||
|
#include <net/if.h>
|
||
|
#include <net/route.h>
|
||
|
|
||
|
@@ -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 <net/vnet.h>
|
||
|
+
|
||
|
#include <machine/stdarg.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
@@ -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 <netkey/keydb.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
#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 <machine/stdarg.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
#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 <netkey/keydb.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
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 <sys/time.h>
|
||
|
#include <sys/syslog.h>
|
||
|
|
||
|
+/*#include <net/vnet.h>*/
|
||
|
#include <net/if.h>
|
||
|
#include <net/route.h>
|
||
|
#include <net/netisr.h>
|
||
|
@@ -79,6 +80,7 @@
|
||
|
#include <machine/stdarg.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
#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 <machine/stdarg.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
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 <sys/sysctl.h>
|
||
|
#include <sys/proc.h>
|
||
|
|
||
|
+#include <net/vnet.h>
|
||
|
#include <net/if.h>
|
||
|
#include <net/route.h>
|
||
|
|
||
|
@@ -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 <sys/queue.h>
|
||
|
#include <sys/syslog.h>
|
||
|
|
||
|
+#include <net/vnet.h>
|
||
|
#include <net/if.h>
|
||
|
#include <net/route.h>
|
||
|
#include <net/raw_cb.h>
|
||
|
@@ -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 <sys/random.h>
|
||
|
|
||
|
#include <net/net_osdep.h>
|
||
|
+#include <sys/vimage.h>
|
||
|
+#include <net/vnet.h>
|
||
|
|
||
|
#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 <netinet6/in6_var.h>
|
||
|
|
||
|
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 *));
|