diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_init.c linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_init.c --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_init.c Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_init.c Sun May 9 23:59:44 2004 @@ -105,6 +105,10 @@ int debug_netlink = 0; #endif /* CONFIG_IPSEC_DEBUG */ +int ipsec_num_if; /* exported */ +static int num_if = IPSEC_NUM_IF; +MODULE_PARM(num_if, "i"); + int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr); /* * the following structure is required so that we receive @@ -133,6 +137,8 @@ /* turn off checking of keys */ des_check_key=0; #endif /* CONFIG_IPSEC_ENC_3DES */ + + ipsec_num_if = num_if; KLIPS_PRINT(1, "klips_info:ipsec_init: " "KLIPS startup, Openswan IPsec stack %s\n", diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_param.h linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_param.h --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_param.h Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_param.h Sun May 9 23:59:44 2004 @@ -46,10 +46,12 @@ #define device net_device #define ipsec_dev_get __dev_get_by_name +#define ipsec_dev_put dev_put #else #define ipsec_dev_get dev_get +#define ipsec_dev_put #endif /* NETDEV_23 */ diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_proc.c linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_proc.c --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_proc.c Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_proc.c Mon May 10 00:00:02 2004 @@ -470,7 +470,7 @@ (int)offset, length); - for(i = 0; i < IPSEC_NUM_IF; i++) { + for(i = 0; i < ipsec_num_if; i++) { /* minimum changes to remove sprintf, TIS */ snprintf(name, sizeof(name), "ipsec%u", i); dev = ipsec_dev_get(name); diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_rcv.c linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_rcv.c --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_rcv.c Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_rcv.c Sun May 9 23:59:44 2004 @@ -500,7 +500,7 @@ } if(skb->dev) { - for(i = 0; i < IPSEC_NUM_IF; i++) { + for(i = 0; i < ipsec_num_if; i++) { sprintf(name, "ipsec%d", i); if(!strcmp(name, skb->dev->name)) { prv = (struct ipsecpriv *)(skb->dev->priv); diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_tunnel.c linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_tunnel.c --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_tunnel.c Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_tunnel.c Sun May 9 23:59:44 2004 @@ -2841,7 +2841,7 @@ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_clear: .\n"); - for(i = 0; i < IPSEC_NUM_IF; i++) { + for(i = 0; i < ipsec_num_if; i++) { sprintf(name, "ipsec%d", i); if((ipsecdev = ipsec_dev_get(name)) != NULL) { if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { @@ -3012,7 +3012,7 @@ #endif /* NET_21 */ /* find the attached physical device and detach it. */ - for(i = 0; i < IPSEC_NUM_IF; i++) { + for(i = 0; i < ipsec_num_if; i++) { sprintf(name, "ipsec%d", i); ipsec_dev = ipsec_dev_get(name); if(ipsec_dev) { @@ -3186,97 +3186,80 @@ return 0; } -static struct device dev_ipsec3 = -{ - "ipsec3\0 ", /* name */ - 0, /* recv memory end */ - 0, /* recv memory start */ - 0, /* memory end */ - 0, /* memory start */ - 0x0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - ipsec_tunnel_probe /* setup */ -}; - -static struct device dev_ipsec2 = -{ - "ipsec2\0 ", /* name */ - 0, /* recv memory end */ - 0, /* recv memory start */ - 0, /* memory end */ - 0, /* memory start */ - 0x0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - ipsec_tunnel_probe /* setup */ -}; - -static struct device dev_ipsec1 = -{ - "ipsec1\0 ", /* name */ - 0, /* recv memory end */ - 0, /* recv memory start */ - 0, /* memory end */ - 0, /* memory start */ - 0x0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - ipsec_tunnel_probe /* setup */ -}; - -static struct device dev_ipsec0 = -{ - "ipsec0\0 ", /* name */ - 0, /* recv memory end */ - 0, /* recv memory start */ - 0, /* memory end */ - 0, /* memory start */ - 0x0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - ipsec_tunnel_probe /* setup */ -}; +struct device **ipsecdevices; int ipsec_tunnel_init_devices(void) { -#if 0 - KLIPS_PRINT(debug_tunnel & DB_TN_INIT, - "klips_debug:ipsec_tunnel_init_devices: " - "registering device %s\n", - dev_ipsec0.name); -#endif - if (register_netdev(&dev_ipsec0) != 0) - return -EIO; -#if 0 - KLIPS_PRINT(debug_tunnel & DB_TN_INIT, - "klips_debug:ipsec_tunnel_init_devices: " - "registering device %s\n", - dev_ipsec1.name); -#endif - if (register_netdev(&dev_ipsec1) != 0) - return -EIO; -#if 0 - KLIPS_PRINT(debug_tunnel & DB_TN_INIT, - "klips_debug:ipsec_tunnel_init_devices: " - "registering device %s\n", - dev_ipsec2.name); -#endif - if (register_netdev(&dev_ipsec2) != 0) - return -EIO; -#if 0 + int i; + char name[IFNAMSIZ]; + struct device *dev_ipsec; + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_init_devices: " - "registering device %s\n", - dev_ipsec3.name); -#endif - if (register_netdev(&dev_ipsec3) != 0) - return -EIO; + "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n", + ipsec_num_if, + (unsigned long) (sizeof(struct device) + IFNAMSIZ), + IFNAMSIZ); + + ipsecdevices = (struct device**)kmalloc(ipsec_num_if * sizeof(struct device *), GFP_KERNEL); + if (ipsecdevices == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "failed to allocate memory for devices table, quitting device init.\n"); + return -ENOMEM; + } + memset(ipsecdevices, 0, ipsec_num_if * sizeof(struct device **)); + + for(i = 0; i < ipsec_num_if; i++) { + sprintf(name, IPSEC_DEV_FORMAT, i); + dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL); + if (dev_ipsec == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "failed to allocate memory for device %s, quitting device init.\n", + name); + return -ENOMEM; + } + memset((caddr_t)dev_ipsec, 0, sizeof(struct device)); +#ifdef NETDEV_23 + strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name)); +#else /* NETDEV_23 */ + dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL); + if (dev_ipsec->name == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "failed to allocate memory for device %s name, quitting device init.\n", + name); + return -ENOMEM; + } + memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ); + strncpy(dev_ipsec->name, name, IFNAMSIZ); +#endif /* NETDEV_23 */ + dev_ipsec->next = NULL; + dev_ipsec->init = &ipsec_tunnel_probe; + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s\n", + dev_ipsec->name); + + /* reference and hold the device reference */ + dev_hold(dev_ipsec); + ipsecdevices[i]=dev_ipsec; + + if (register_netdev(dev_ipsec) != 0) { + KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s failed, quitting device init.\n", + dev_ipsec->name); + return -EIO; + } else { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s succeeded, continuing...\n", + dev_ipsec->name); + } + } return 0; } @@ -3285,20 +3268,33 @@ ipsec_tunnel_cleanup_devices(void) { int error = 0; + int i; + char name[32]; + struct device *dev_ipsec; + + for(i = ipsec_num_if; --i >= 0; ) { + dev_ipsec = ipsecdevices[i]; + if(dev_ipsec == NULL) { + continue; + } - unregister_netdev(&dev_ipsec0); - unregister_netdev(&dev_ipsec1); - unregister_netdev(&dev_ipsec2); - unregister_netdev(&dev_ipsec3); - kfree(dev_ipsec0.priv); - kfree(dev_ipsec1.priv); - kfree(dev_ipsec2.priv); - kfree(dev_ipsec3.priv); - dev_ipsec0.priv=NULL; - dev_ipsec1.priv=NULL; - dev_ipsec2.priv=NULL; - dev_ipsec3.priv=NULL; - + /* release reference */ + ipsecdevices[i]=NULL; + ipsec_dev_put(dev_ipsec); + + KLIPS_PRINT(debug_netlink, "Unregistering %s (refcnt=%d)\n", + name, + atomic_read(&dev_ipsec->refcnt)); + unregister_netdev(dev_ipsec); + KLIPS_PRINT(debug_netlink, "Unregisted %s\n", name); +#ifndef NETDEV_23 + kfree(dev_ipsec->name); + dev_ipsec->name=NULL; +#endif /* !NETDEV_23 */ + kfree(dev_ipsec->priv); + dev_ipsec->priv=NULL; + } + kfree(ipsecdevices); return error; } diff -urN linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_tunnel.h linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_tunnel.h --- linux-2.4.27-pre2-openswan-1.0.4rc1/net/ipsec/ipsec_tunnel.h Sun May 9 23:59:21 2004 +++ linux-2.4.27-pre2-openswan-1.0.4rc1-more-tun/net/ipsec/ipsec_tunnel.h Sun May 9 23:59:44 2004 @@ -98,8 +98,21 @@ int mtu; /* What is the desired MTU? */ }; +/* Set default number of ipsecX virtual devices here. */ +/* This must be < exp(field width of IPSEC_DEV_FORMAT) */ +/* It must also be reasonable so as not to overload the memory and CPU */ +/* constraints of the host. */ #define IPSEC_NUM_IF 4 +/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */ +/* With "ipsec" being 5 characters, that means 10 is the max field width */ +/* but machine memory and CPU constraints are not likely to tollerate */ +/* more than 3 digits. The default is one digit. */ +/* Update: userland scripts get upset if they can't find "ipsec0", so */ +/* for now, no "0"-padding should be used (which would have been helpful */ +/* to make text-searches work */ +#define IPSEC_DEV_FORMAT "ipsec%d" +extern int ipsec_num_if; extern char ipsec_tunnel_c_version[]; int ipsec_tunnel_init_devices(void);