diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index ca9725d50bf..fba8ed21f51 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -121,6 +121,8 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; +import com.cloud.agent.api.Start2Answer; +import com.cloud.agent.api.Start2Command; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartConsoleProxyAnswer; @@ -134,6 +136,8 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; @@ -145,28 +149,34 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.api.to.VirtualMachineTO.Monitor; +import com.cloud.agent.api.to.VirtualMachineTO.SshMonitor; import com.cloud.agent.resource.computing.KVMHABase.NfsStoragePool; import com.cloud.agent.resource.computing.KVMHABase.PoolType; import com.cloud.agent.resource.computing.LibvirtStoragePoolDef.poolType; import com.cloud.agent.resource.computing.LibvirtStorageVolumeDef.volFormat; -import com.cloud.agent.resource.computing.LibvirtVMDef.consoleDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.devicesDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.diskDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.featuresDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.graphicDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.guestDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.guestResourceDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.inputDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.interfaceDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.interfaceDef.hostNicType; -import com.cloud.agent.resource.computing.LibvirtVMDef.serialDef; -import com.cloud.agent.resource.computing.LibvirtVMDef.termPolicy; +import com.cloud.agent.resource.computing.LibvirtVMDef.ConsoleDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.DevicesDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.DiskDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.FeaturesDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.GraphicDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.GuestDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.GuestResourceDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.InputDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.InterfaceDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.InterfaceDef.hostNicType; +import com.cloud.agent.resource.computing.LibvirtVMDef.SerialDef; +import com.cloud.agent.resource.computing.LibvirtVMDef.TermPolicy; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Network.BroadcastDomainType; +import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkEnums.RouterPrivateIpStrategy; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; @@ -196,6 +206,7 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.DomainRouter; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.State; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineName; @@ -871,14 +882,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected synchronized String startDomainRouter(StartRouterCommand cmd) { DomainRouter router = cmd.getRouter(); - List nics = null; + List nics = null; try { nics = createRouterVMNetworks(cmd); - List disks = createSystemVMDisk(cmd.getVolumes()); + List disks = createSystemVMDisk(cmd.getVolumes()); String dataDiskPath = null; - for (diskDef disk : disks) { + for (DiskDef disk : disks) { if (disk.getDiskLabel().equalsIgnoreCase("vdb")) { dataDiskPath = disk.getDiskPath(); } @@ -894,7 +905,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv startDomain(vmName, domXML); - for (interfaceDef nic : nics) { + for (InterfaceDef nic : nics) { if (nic.getHostNetType() == hostNicType.VNET) { disableBridgeForwardding(nic.getBrName()); } @@ -920,14 +931,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected synchronized String startConsoleProxy(StartConsoleProxyCommand cmd) { ConsoleProxyVO console = cmd.getProxy(); - List nics = null; + List nics = null; try { nics = createSysVMNetworks(console.getGuestMacAddress(), console.getPrivateMacAddress(), console.getPublicMacAddress(), console.getVlanId()); - List disks = createSystemVMDisk(cmd.getVolumes()); + List disks = createSystemVMDisk(cmd.getVolumes()); String dataDiskPath = null; - for (diskDef disk : disks) { + for (DiskDef disk : disks) { if (disk.getDiskLabel().equalsIgnoreCase("vdb")) { dataDiskPath = disk.getDiskPath(); } @@ -959,14 +970,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected String startSecStorageVM(StartSecStorageVmCommand cmd) { SecondaryStorageVmVO secVm = cmd.getSecondaryStorageVmVO(); - List nics = null; + List nics = null; try { nics = createSysVMNetworks(secVm.getGuestMacAddress(), secVm.getPrivateMacAddress(), secVm.getPublicMacAddress(), secVm.getVlanId()); - List disks = createSystemVMDisk(cmd.getVolumes()); + List disks = createSystemVMDisk(cmd.getVolumes()); String dataDiskPath = null; - for (diskDef disk : disks) { + for (DiskDef disk : disks) { if (disk.getDiskLabel().equalsIgnoreCase("vdb")) { dataDiskPath = disk.getDiskPath(); } @@ -995,61 +1006,61 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return null; } - private String defineVMXML(String vmName, String uuid, int memSize, int cpus, String arch, List nics, List disks, String vncPaswd, String guestOSType) { + private String defineVMXML(String vmName, String uuid, int memSize, int cpus, String arch, List nics, List disks, String vncPaswd, String guestOSType) { LibvirtVMDef vm = new LibvirtVMDef(); vm.setHvsType(_hypervisorType); vm.setDomainName(vmName); vm.setDomUUID(uuid); vm.setDomDescription(KVMGuestOsMapper.getGuestOsName(guestOSType)); - guestDef guest = new guestDef(); - guest.setGuestType(guestDef.guestType.KVM); + GuestDef guest = new GuestDef(); + guest.setGuestType(GuestDef.guestType.KVM); guest.setGuestArch(arch); guest.setMachineType("pc"); - guest.setBootOrder(guestDef.bootOrder.CDROM); - guest.setBootOrder(guestDef.bootOrder.HARDISK); + guest.setBootOrder(GuestDef.bootOrder.CDROM); + guest.setBootOrder(GuestDef.bootOrder.HARDISK); vm.addComp(guest); - guestResourceDef grd = new guestResourceDef(); + GuestResourceDef grd = new GuestResourceDef(); grd.setMemorySize(memSize*1024); grd.setVcpuNum(cpus); vm.addComp(grd); - featuresDef features = new featuresDef(); + FeaturesDef features = new FeaturesDef(); features.addFeatures("pae"); features.addFeatures("apic"); features.addFeatures("acpi"); vm.addComp(features); - termPolicy term = new termPolicy(); + TermPolicy term = new TermPolicy(); term.setCrashPolicy("destroy"); term.setPowerOffPolicy("destroy"); term.setRebootPolicy("restart"); vm.addComp(term); - devicesDef devices = new devicesDef(); + DevicesDef devices = new DevicesDef(); devices.setEmulatorPath(_hypervisorPath); - for (interfaceDef nic : nics) { + for (InterfaceDef nic : nics) { devices.addDevice(nic); } - for (diskDef disk : disks) { + for (DiskDef disk : disks) { if (!disk.isAttachDeferred()) devices.addDevice(disk); } - serialDef serial = new serialDef("pty", null, (short)0); + SerialDef serial = new SerialDef("pty", null, (short)0); devices.addDevice(serial); - consoleDef console = new consoleDef("pty", null, null, (short)0); + ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); devices.addDevice(console); - graphicDef grap = new graphicDef("vnc", (short)0, true, null, null, null); + GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null); devices.addDevice(grap); - inputDef input = new inputDef("tablet", "usb"); + InputDef input = new InputDef("tablet", "usb"); devices.addDevice(input); vm.addComp(devices); @@ -1234,8 +1245,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((DeleteStoragePoolCommand) cmd); } else if (cmd instanceof FenceCommand ) { return execute((FenceCommand) cmd); + } else if (cmd instanceof Start2Command ) { + return execute((Start2Command) cmd); } else if (cmd instanceof RoutingCommand) { return _virtRouterResource.executeRequest(cmd); + } else if (cmd instanceof CheckSshCommand) { + return execute((CheckSshCommand) cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -2553,14 +2568,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } protected synchronized String startVM(StartCommand cmd) { - List nics = null; + List nics = null; try { String uuid = UUID.nameUUIDFromBytes(cmd.getVmName().getBytes()).toString(); nics = createUserVMNetworks(cmd); - List disks = createVMDisk(cmd.getVolumes(), cmd.getGuestOSDescription(), cmd.getISOPath()); + List disks = createVMDisk(cmd.getVolumes(), cmd.getGuestOSDescription(), cmd.getISOPath()); @@ -2574,7 +2589,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv startDomain(cmd.getVmName(), vmDomainXML); // Attach each data volume to the VM, if there is a deferred attached disk - for (diskDef disk : disks) { + for (DiskDef disk : disks) { if (disk.isAttachDeferred()) { attachOrDetachDisk(true, cmd.getVmName(), disk.getDiskPath()); } @@ -2602,6 +2617,282 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } + + private void handleVmStartFailure(String vmName, LibvirtVMDef vm) { + if (vm != null && vm.getDevices() != null) + cleanupVMNetworks(vm.getDevices().getInterfaces()); + } + + private LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) { + LibvirtVMDef vm = new LibvirtVMDef(); + vm.setHvsType(_hypervisorType); + vm.setDomainName(vmTO.getName()); + vm.setDomUUID(UUID.nameUUIDFromBytes(vmTO.getName().getBytes()).toString()); + vm.setDomDescription(KVMGuestOsMapper.getGuestOsName(vmTO.getOs())); + + GuestDef guest = new GuestDef(); + guest.setGuestType(GuestDef.guestType.KVM); + guest.setGuestArch(vmTO.getArch()); + guest.setMachineType("pc"); + guest.setBootOrder(GuestDef.bootOrder.CDROM); + guest.setBootOrder(GuestDef.bootOrder.HARDISK); + + vm.addComp(guest); + + GuestResourceDef grd = new GuestResourceDef(); + grd.setMemorySize(vmTO.getMinRam()/1024); + grd.setVcpuNum(vmTO.getCpus()); + vm.addComp(grd); + + FeaturesDef features = new FeaturesDef(); + features.addFeatures("pae"); + features.addFeatures("apic"); + features.addFeatures("acpi"); + vm.addComp(features); + + TermPolicy term = new TermPolicy(); + term.setCrashPolicy("destroy"); + term.setPowerOffPolicy("destroy"); + term.setRebootPolicy("restart"); + vm.addComp(term); + + DevicesDef devices = new DevicesDef(); + devices.setEmulatorPath(_hypervisorPath); + + + SerialDef serial = new SerialDef("pty", null, (short)0); + devices.addDevice(serial); + + ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); + devices.addDevice(console); + + GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null); + devices.addDevice(grap); + + InputDef input = new InputDef("tablet", "usb"); + devices.addDevice(input); + + vm.addComp(devices); + + return vm; + } + + private void createVifs(VirtualMachineTO vmSpec, LibvirtVMDef vm) throws InternalErrorException { + NicTO[] nics = vmSpec.getNics(); + for (int i = 0; i < nics.length; i++) { + for (NicTO nic : vmSpec.getNics()) { + if (nic.getDeviceId() == i) + createVif(vm, nic); + } + } + } + + + protected Start2Answer execute(Start2Command cmd) { + VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + String vmName = vmSpec.getName(); + LibvirtVMDef vm = null; + + State state = State.Stopped; + + try { + + synchronized (_vms) { + _vms.put(vmName, State.Starting); + } + + vm = createVMFromSpec(vmSpec); + + createVbd(vmSpec, vmName, vm); + + createVifs(vmSpec, vm); + + s_logger.debug("starting " + vmName + ": " + vm.toString()); + startDomain(vmName, vm.toString()); + + Monitor monitor = vmSpec.getMonitor(); + if (monitor != null && monitor instanceof SshMonitor) { + SshMonitor sshMon = (SshMonitor)monitor; + String privateIp = sshMon.getIp(); + int cmdPort = sshMon.getPort(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); + } + + String result = _virtRouterResource.connect(privateIp, cmdPort); + if (result != null) { + throw new CloudRuntimeException("Can not ping System vm " + vmName + "due to:" + result); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port succeeded for vm " + vmName); + } + } + + // Attach each data volume to the VM, if there is a deferred attached disk + for (DiskDef disk : vm.getDevices().getDisks()) { + if (disk.isAttachDeferred()) { + attachOrDetachDisk(true, vmName, disk.getDiskPath()); + } + } + state = State.Running; + return new Start2Answer(cmd); + } catch (Exception e) { + s_logger.warn("Exception ", e); + handleVmStartFailure(vmName, vm); + return new Start2Answer(cmd, e.getMessage()); + } finally { + synchronized (_vms) { + if (state != State.Stopped) { + _vms.put(vmName, state); + } else { + _vms.remove(vmName); + } + } + } + } + + private String getVolumePath(VolumeTO volume) throws LibvirtException, URISyntaxException { + if (volume.getType() == Volume.VolumeType.ISO) { + StorageVol vol = getVolume(_conn, volume.getPath()); + return vol.getPath(); + } else { + return volume.getPath(); + } + } + + private void createVbd(VirtualMachineTO vmSpec, String vmName, LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException{ + boolean foundISO = false; + for (VolumeTO volume : vmSpec.getDisks()) { + String volPath = getVolumePath(volume); + + DiskDef.diskBus diskBusType = getGuestDiskModel(vmSpec.getOs()); + DiskDef disk = new DiskDef(); + if (volume.getType() == VolumeType.ISO) { + foundISO = true; + disk.defISODisk(volPath); + } else { + int devId = 0; + if (volume.getType() == VolumeType.ROOT) { + devId = 0; + } else { + devId = 1; + } + disk.defFileBasedDisk(volume.getPath(), devId, diskBusType, DiskDef.diskFmtType.QCOW2); + } + + //Centos doesn't support scsi hotplug. For other host OSes, we attach the disk after the vm is running, so that we can hotplug it. + if (volume.getType() == VolumeType.DATADISK && diskBusType != DiskDef.diskBus.VIRTIO) { + disk.setAttachDeferred(true); + } + + if (!disk.isAttachDeferred()) { + vm.getDevices().addDevice(disk); + } + } + + if (vmSpec.getType() == VirtualMachine.Type.User) { + if (!foundISO) { + /*Add iso as placeholder*/ + DiskDef iso = new DiskDef(); + iso.defISODisk(null); + vm.getDevices().addDevice(iso); + } + } else { + DiskDef iso = new DiskDef(); + iso.defISODisk(_sysvmISOPath); + vm.getDevices().addDevice(iso); + + createPatchVbd(vmName, vm, vmSpec); + } + } + + private void createPatchVbd(String vmName, LibvirtVMDef vm, VirtualMachineTO vmSpec) throws LibvirtException, InternalErrorException { + + List disks = vm.getDevices().getDisks(); + DiskDef rootDisk = disks.get(0); + + StorageVol tmplVol = createTmplDataDisk(rootDisk.getDiskPath(), 10L * 1024 * 1024); + String datadiskPath = tmplVol.getKey(); + + /*add patch disk*/ + DiskDef patchDisk = new DiskDef(); + patchDisk.defFileBasedDisk(rootDisk.getDiskPath(), 1, rootDisk.getBusType(), DiskDef.diskFmtType.RAW); + disks.add(patchDisk); + patchDisk.setDiskPath(datadiskPath); + + String bootArgs = vmSpec.getBootArgs(); + + patchSystemVm(bootArgs, datadiskPath, vmName); + + } + + private String createVlanBr(String vlanId, String nic) throws InternalErrorException{ + String brName = setVnetBrName(vlanId); + createVnet(vlanId, nic); + return brName; + } + + private InterfaceDef createVif(LibvirtVMDef vm, NicTO nic) throws InternalErrorException { + InterfaceDef intf = new InterfaceDef(); + + String vlanId = null; + if (nic.getBroadcastType() == BroadcastDomainType.Vlan) { + URI broadcastUri = nic.getBroadcastUri(); + vlanId = broadcastUri.getHost(); + s_logger.debug("vlanId: " + vlanId); + } + + if (nic.getType() == TrafficType.Guest) { + if (nic.getBroadcastType() == BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")){ + String brName = createVlanBr(vlanId, _pifs.first()); + intf.defBridgeNet(brName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } else { + intf.defBridgeNet(_privBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } + } else if (nic.getType() == TrafficType.Control) { + intf.defPrivateNet(_privNwName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } else if (nic.getType() == TrafficType.Public) { + if (nic.getBroadcastType() == BroadcastDomainType.Vlan && !vlanId.equalsIgnoreCase("untagged")) { + String brName = createVlanBr(vlanId, _pifs.second()); + intf.defBridgeNet(brName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } else { + intf.defBridgeNet(_publicBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } + } else if (nic.getType() == TrafficType.Management) { + intf.defBridgeNet(_privBridgeName, null, nic.getMac(), InterfaceDef.nicModel.VIRTIO); + } + + vm.getDevices().addDevice(intf); + return intf; + } + + + protected CheckSshAnswer execute(CheckSshCommand cmd) { + String vmName = cmd.getName(); + String privateIp = cmd.getIp(); + int cmdPort = cmd.getPort(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); + } + + try { + String result = _virtRouterResource.connect(privateIp, cmdPort); + if (result != null) { + return new CheckSshAnswer(cmd, "Can not ping System vm " + vmName + "due to:" + result); + } + } catch (Exception e) { + return new CheckSshAnswer(cmd, e); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Ping command port succeeded for vm " + vmName); + } + + return new CheckSshAnswer(cmd); + } + protected synchronized String attachOrDetachISO(String vmName, String isoPath, boolean isAttach) throws LibvirtException, URISyntaxException { String isoXml = null; if (isoPath != null && isAttach) { @@ -2609,14 +2900,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv isoPath = isoVol.getPath(); - diskDef iso = new diskDef(); - iso.defFileBasedDisk(isoPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW); - iso.setDeviceType(diskDef.deviceType.CDROM); + DiskDef iso = new DiskDef(); + iso.defFileBasedDisk(isoPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW); + iso.setDeviceType(DiskDef.deviceType.CDROM); isoXml = iso.toString(); } else { - diskDef iso = new diskDef(); - iso.defFileBasedDisk(null, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW); - iso.setDeviceType(diskDef.deviceType.CDROM); + DiskDef iso = new DiskDef(); + iso.defFileBasedDisk(null, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW); + iso.setDeviceType(DiskDef.deviceType.CDROM); isoXml = iso.toString(); } @@ -2664,12 +2955,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv s_logger.warn("Can't get disk dev"); return "Can't get disk dev"; } - diskDef disk = new diskDef(); + DiskDef disk = new DiskDef(); String guestOSType = getGuestType(vmName); if (isGuestPVEnabled(guestOSType)) { - disk.defFileBasedDisk(sourceFile, diskDev, diskDef.diskBus.VIRTIO, diskDef.diskFmtType.QCOW2); + disk.defFileBasedDisk(sourceFile, diskDev, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); } else { - disk.defFileBasedDisk(sourceFile, diskDev, diskDef.diskBus.SCSI, diskDef.diskFmtType.QCOW2); + disk.defFileBasedDisk(sourceFile, diskDev, DiskDef.diskBus.SCSI, DiskDef.diskFmtType.QCOW2); } String xml = disk.toString(); return attachOrDetachDevice(attach, vmName, xml); @@ -3320,19 +3611,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return dataVol; } - private interfaceDef.nicModel getGuestNicModel(String guestOSType) { + private InterfaceDef.nicModel getGuestNicModel(String guestOSType) { if (isGuestPVEnabled(guestOSType) && !isCentosHost()) { - return interfaceDef.nicModel.VIRTIO; + return InterfaceDef.nicModel.VIRTIO; } else { - return interfaceDef.nicModel.E1000; + return InterfaceDef.nicModel.E1000; } } - private diskDef.diskBus getGuestDiskModel(String guestOSType) { + private DiskDef.diskBus getGuestDiskModel(String guestOSType) { if (isGuestPVEnabled(guestOSType) && !isCentosHost()) { - return diskDef.diskBus.VIRTIO; + return DiskDef.diskBus.VIRTIO; } else { - return diskDef.diskBus.IDE; + return DiskDef.diskBus.IDE; } } @@ -3342,12 +3633,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String getVnetIdFromBrName(String vnetBrName) { return vnetBrName.replaceAll("cloudVirBr", ""); } - private List createUserVMNetworks(StartCommand cmd) throws InternalErrorException { - List nics = new ArrayList(); - interfaceDef.nicModel nicModel = getGuestNicModel(cmd.getGuestOSDescription()); + private List createUserVMNetworks(StartCommand cmd) throws InternalErrorException { + List nics = new ArrayList(); + InterfaceDef.nicModel nicModel = getGuestNicModel(cmd.getGuestOSDescription()); String guestMac = cmd.getGuestMacAddress(); String brName; - interfaceDef pubNic = new interfaceDef(); + InterfaceDef pubNic = new InterfaceDef(); if (cmd.getGuestIpAddress() == null) { /*guest network is direct attached without external DHCP server*/ brName = _privBridgeName; @@ -3368,89 +3659,89 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return nics; } - private List createRouterVMNetworks(StartRouterCommand cmd) throws InternalErrorException { - List nics = new ArrayList(); + private List createRouterVMNetworks(StartRouterCommand cmd) throws InternalErrorException { + List nics = new ArrayList(); DomainRouter router = cmd.getRouter(); String guestMac = router.getGuestMacAddress(); String privateMac = router.getPrivateMacAddress(); String pubMac = router.getPublicMacAddress(); String brName; - interfaceDef pubNic = new interfaceDef(); - interfaceDef privNic = new interfaceDef(); - interfaceDef vnetNic = new interfaceDef(); + InterfaceDef pubNic = new InterfaceDef(); + InterfaceDef privNic = new InterfaceDef(); + InterfaceDef vnetNic = new InterfaceDef(); /*nic 0, guest network*/ if ("untagged".equalsIgnoreCase(router.getVnet())){ - vnetNic.defBridgeNet(_privBridgeName, null, guestMac, interfaceDef.nicModel.VIRTIO); + vnetNic.defBridgeNet(_privBridgeName, null, guestMac, InterfaceDef.nicModel.VIRTIO); } else { String vnetId = getVnetId(router.getVnet()); brName = setVnetBrName(vnetId); String vnetDev = "vtap" + vnetId; createVnet(vnetId, _pifs.first()); - vnetNic.defBridgeNet(brName, null, guestMac, interfaceDef.nicModel.VIRTIO); + vnetNic.defBridgeNet(brName, null, guestMac, InterfaceDef.nicModel.VIRTIO); } nics.add(vnetNic); /*nic 1: link local*/ - privNic.defPrivateNet(_privNwName, null, privateMac, interfaceDef.nicModel.VIRTIO); + privNic.defPrivateNet(_privNwName, null, privateMac, InterfaceDef.nicModel.VIRTIO); nics.add(privNic); /*nic 2: public */ if ("untagged".equalsIgnoreCase(router.getVlanId())) { - pubNic.defBridgeNet(_publicBridgeName, null, pubMac, interfaceDef.nicModel.VIRTIO); + pubNic.defBridgeNet(_publicBridgeName, null, pubMac, InterfaceDef.nicModel.VIRTIO); } else { String vnetId = getVnetId(router.getVlanId()); brName = setVnetBrName(vnetId); String vnetDev = "vtap" + vnetId; createVnet(vnetId, _pifs.second()); - pubNic.defBridgeNet(brName, null, pubMac, interfaceDef.nicModel.VIRTIO); + pubNic.defBridgeNet(brName, null, pubMac, InterfaceDef.nicModel.VIRTIO); } nics.add(pubNic); return nics; } - private List createSysVMNetworks(String guestMac, String privMac, String pubMac, String vlanId) throws InternalErrorException { - List nics = new ArrayList(); + private List createSysVMNetworks(String guestMac, String privMac, String pubMac, String vlanId) throws InternalErrorException { + List nics = new ArrayList(); String brName; - interfaceDef pubNic = new interfaceDef(); - interfaceDef privNic = new interfaceDef(); - interfaceDef vnetNic = new interfaceDef(); + InterfaceDef pubNic = new InterfaceDef(); + InterfaceDef privNic = new InterfaceDef(); + InterfaceDef vnetNic = new InterfaceDef(); /*nic 0: link local*/ - privNic.defPrivateNet(_privNwName, null, guestMac, interfaceDef.nicModel.VIRTIO); + privNic.defPrivateNet(_privNwName, null, guestMac, InterfaceDef.nicModel.VIRTIO); nics.add(privNic); /*nic 1, priv network*/ - vnetNic.defBridgeNet(_privBridgeName, null, privMac, interfaceDef.nicModel.VIRTIO); + vnetNic.defBridgeNet(_privBridgeName, null, privMac, InterfaceDef.nicModel.VIRTIO); nics.add(vnetNic); /*nic 2: public */ if ("untagged".equalsIgnoreCase(vlanId)) { - pubNic.defBridgeNet(_publicBridgeName, null, pubMac, interfaceDef.nicModel.VIRTIO); + pubNic.defBridgeNet(_publicBridgeName, null, pubMac, InterfaceDef.nicModel.VIRTIO); } else { String vnetId = getVnetId(vlanId); brName = setVnetBrName(vnetId); String vnetDev = "vtap" + vnetId; createVnet(vnetId, _pifs.second()); - pubNic.defBridgeNet(brName, null, pubMac, interfaceDef.nicModel.VIRTIO); + pubNic.defBridgeNet(brName, null, pubMac, InterfaceDef.nicModel.VIRTIO); } nics.add(pubNic); return nics; } - private void cleanupVMNetworks(List nics) { - for (interfaceDef nic : nics) { + private void cleanupVMNetworks(List nics) { + for (InterfaceDef nic : nics) { if (nic.getHostNetType() == hostNicType.VNET) { cleanupVnet(getVnetIdFromBrName(nic.getBrName())); } } } - private List createSystemVMDisk(List vols) throws InternalErrorException, LibvirtException{ - List disks = new ArrayList(); + private List createSystemVMDisk(List vols) throws InternalErrorException, LibvirtException{ + List disks = new ArrayList(); // Get the root volume List rootVolumes = findVolumes(vols, VolumeType.ROOT, true); @@ -3464,24 +3755,24 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv StorageVol tmplVol = createTmplDataDisk(rootkPath, 10L * 1024 * 1024); String datadiskPath = tmplVol.getKey(); - diskDef hda = new diskDef(); - hda.defFileBasedDisk(rootkPath, "vda", diskDef.diskBus.VIRTIO, diskDef.diskFmtType.QCOW2); + DiskDef hda = new DiskDef(); + hda.defFileBasedDisk(rootkPath, "vda", DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); disks.add(hda); - diskDef hdb = new diskDef(); - hdb.defFileBasedDisk(datadiskPath, "vdb", diskDef.diskBus.VIRTIO, diskDef.diskFmtType.RAW); + DiskDef hdb = new DiskDef(); + hdb.defFileBasedDisk(datadiskPath, "vdb", DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.RAW); disks.add(hdb); - diskDef hdc = new diskDef(); - hdc.defFileBasedDisk(_sysvmISOPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW); - hdc.setDeviceType(diskDef.deviceType.CDROM); + DiskDef hdc = new DiskDef(); + hdc.defFileBasedDisk(_sysvmISOPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW); + hdc.setDeviceType(DiskDef.deviceType.CDROM); disks.add(hdc); return disks; } - private List createVMDisk(List vols, String guestOSType, String isoURI) throws InternalErrorException, LibvirtException, URISyntaxException{ - List disks = new ArrayList(); + private List createVMDisk(List vols, String guestOSType, String isoURI) throws InternalErrorException, LibvirtException, URISyntaxException{ + List disks = new ArrayList(); // Get the root volume List rootVolumes = findVolumes(vols, VolumeType.ROOT, true); @@ -3505,17 +3796,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv if (dataVolumes.size() > 0) dataVolume = dataVolumes.get(0); - diskDef.diskBus diskBusType = getGuestDiskModel(guestOSType); + DiskDef.diskBus diskBusType = getGuestDiskModel(guestOSType); - diskDef hda = new diskDef(); - hda.defFileBasedDisk(rootVolume.getPath(), "vda", diskBusType, diskDef.diskFmtType.QCOW2); + DiskDef hda = new DiskDef(); + hda.defFileBasedDisk(rootVolume.getPath(), "vda", diskBusType, DiskDef.diskFmtType.QCOW2); disks.add(hda); /*Centos doesn't support scsi hotplug. For other host OSes, we attach the disk after the vm is running, so that we can hotplug it.*/ if (dataVolume != null) { - diskDef hdb = new diskDef(); - hdb.defFileBasedDisk(dataVolume.getPath(), "vdb", diskBusType, diskDef.diskFmtType.QCOW2); + DiskDef hdb = new DiskDef(); + hdb.defFileBasedDisk(dataVolume.getPath(), "vdb", diskBusType, DiskDef.diskFmtType.QCOW2); if (!isCentosHost()) { hdb.setAttachDeferred(true); } @@ -3523,9 +3814,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } /*Add a placeholder for iso, even if there is no iso attached*/ - diskDef hdc = new diskDef(); - hdc.defFileBasedDisk(isoPath, "hdc", diskDef.diskBus.IDE, diskDef.diskFmtType.RAW); - hdc.setDeviceType(diskDef.deviceType.CDROM); + DiskDef hdc = new DiskDef(); + hdc.defFileBasedDisk(isoPath, "hdc", DiskDef.diskBus.IDE, DiskDef.diskFmtType.RAW); + hdc.setDeviceType(DiskDef.deviceType.CDROM); disks.add(hdc); return disks; diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtVMDef.java b/agent/src/com/cloud/agent/resource/computing/LibvirtVMDef.java index 4d0ab0ccbcc..f6c78e9155d 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtVMDef.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtVMDef.java @@ -19,7 +19,10 @@ package com.cloud.agent.resource.computing; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; public class LibvirtVMDef { @@ -27,9 +30,9 @@ public class LibvirtVMDef { private String _domName; private String _domUUID; private String _desc; - private final List components = new ArrayList(); + private final Map components = new HashMap(); - public static class guestDef { + public static class GuestDef { enum guestType { KVM, XEN, @@ -104,12 +107,12 @@ public class LibvirtVMDef { } } - public static class guestResourceDef { - private int _mem; + public static class GuestResourceDef { + private long _mem; private int _currentMem = -1; private String _memBacking; private int _vcpu = -1; - public void setMemorySize(int mem) { + public void setMemorySize(long mem) { _mem = mem; } public void setCurrentMem(int currMem) { @@ -138,7 +141,7 @@ public class LibvirtVMDef { } } - public static class featuresDef { + public static class FeaturesDef { private final List _features = new ArrayList(); public void addFeatures(String feature) { _features.add(feature); @@ -154,11 +157,11 @@ public class LibvirtVMDef { return feaBuilder.toString(); } } - public static class termPolicy { + public static class TermPolicy { private String _reboot; private String _powerOff; private String _crash; - public termPolicy() { + public TermPolicy() { _reboot = _powerOff = _crash = "destroy"; } public void setRebootPolicy(String rbPolicy) { @@ -180,11 +183,20 @@ public class LibvirtVMDef { } } - public static class devicesDef { + public static class DevicesDef { private String _emulator; - private final List devices = new ArrayList(); + private final Map> devices = new HashMap>(); public boolean addDevice(Object device) { - return devices.add(device); + Object dev = devices.get(device.getClass().toString()); + if (dev == null) { + List devs = new ArrayList(); + devs.add(device); + devices.put(device.getClass().toString(), devs); + } else { + List devs = (List)dev; + devs.add(device); + } + return true; } public void setEmulatorPath(String emulator) { _emulator = emulator; @@ -196,15 +208,24 @@ public class LibvirtVMDef { if (_emulator != null) { devicesBuilder.append("" + _emulator + "\n"); } - for (Object o : devices) { - devicesBuilder.append(o.toString()); + + for (List devs : devices.values()) { + for (Object dev : devs) { + devicesBuilder.append(dev.toString()); + } } devicesBuilder.append("\n"); return devicesBuilder.toString(); } + public List getDisks() { + return (List)devices.get(DiskDef.class.toString()); + } + public List getInterfaces() { + return (List)devices.get(InterfaceDef.class.toString()); + } } - public static class diskDef { + public static class DiskDef { enum deviceType { FLOOPY("floopy"), DISK("disk"), @@ -282,6 +303,33 @@ public class LibvirtVMDef { _bus = bus; } + private String getDevLabel(int devId, diskBus bus) { + char suffix = (char)('a' + devId); + if (bus == diskBus.SCSI) { + return "sd" + suffix; + } else if (bus == diskBus.VIRTIO) { + return "vd" + suffix; + } + return "hd" + suffix; + } + public void defFileBasedDisk(String filePath, int devId, diskBus bus, diskFmtType diskFmtType) { + + _diskType = diskType.FILE; + _deviceType = deviceType.DISK; + _sourcePath = filePath; + _diskLabel = getDevLabel(devId, bus); + _diskFmtType = diskFmtType; + _bus = bus; + + } + public void defISODisk(String volPath) { + _diskType = diskType.FILE; + _deviceType = deviceType.CDROM; + _sourcePath = volPath; + _diskLabel = "hdc"; + _diskFmtType = diskFmtType.RAW; + _bus = diskBus.IDE; + } public void defBlockBasedDisk(String diskName, String diskLabel, diskBus bus) { _diskType = diskType.BLOCK; _deviceType = deviceType.DISK; @@ -307,6 +355,19 @@ public class LibvirtVMDef { public String getDiskLabel() { return _diskLabel; } + public deviceType getDeviceType() { + return _deviceType; + } + public void setDiskPath(String volPath) { + this._sourcePath = volPath; + } + public diskBus getBusType() { + return _bus; + } + public int getDiskSeq() { + char suffix = this._diskLabel.charAt(this._diskLabel.length() - 1); + return suffix - 'a'; + } @Override public String toString() { StringBuilder diskBuilder = new StringBuilder(); @@ -342,7 +403,7 @@ public class LibvirtVMDef { } } - public static class interfaceDef { + public static class InterfaceDef { enum guestNetType { BRIDGE("bridge"), NETWORK("network"), @@ -415,6 +476,7 @@ public class LibvirtVMDef { public guestNetType getNetType() { return _netType; } + @Override public String toString() { StringBuilder netBuilder = new StringBuilder(); @@ -437,12 +499,12 @@ public class LibvirtVMDef { return netBuilder.toString(); } } - public static class consoleDef { + public static class ConsoleDef { private final String _ttyPath; private final String _type; private final String _source; private short _port = -1; - public consoleDef(String type, String path, String source, short port) { + public ConsoleDef(String type, String path, String source, short port) { _type = type; _ttyPath = path; _source = source; @@ -467,11 +529,11 @@ public class LibvirtVMDef { return consoleBuilder.toString(); } } - public static class serialDef { + public static class SerialDef { private final String _type; private final String _source; private short _port = -1; - public serialDef(String type, String source, short port) { + public SerialDef(String type, String source, short port) { _type = type; _source = source; _port = port; @@ -490,14 +552,14 @@ public class LibvirtVMDef { return serialBuidler.toString(); } } - public static class graphicDef { + public static class GraphicDef { private final String _type; private short _port = -2; private boolean _autoPort = false; private final String _listenAddr; private final String _passwd; private final String _keyMap; - public graphicDef(String type, short port, boolean auotPort, String listenAddr, String passwd, String keyMap) { + public GraphicDef(String type, short port, boolean auotPort, String listenAddr, String passwd, String keyMap) { _type = type; _port = port; _autoPort = auotPort; @@ -528,10 +590,10 @@ public class LibvirtVMDef { return graphicBuilder.toString(); } } - public static class inputDef { + public static class InputDef { private final String _type; /*tablet, mouse*/ private final String _bus; /*ps2, usb, xen*/ - public inputDef(String type, String bus) { + public InputDef(String type, String bus) { _type = type; _bus = bus; } @@ -558,8 +620,18 @@ public class LibvirtVMDef { public void setDomDescription(String desc) { _desc = desc; } - public boolean addComp(Object comp) { - return components.add(comp); + public String getGuestOSType() { + return _desc; + } + public void addComp(Object comp) { + components.put(comp.getClass().toString(), comp); + } + public DevicesDef getDevices() { + Object o = components.get(DevicesDef.class.toString()); + if (o != null) { + return (DevicesDef)o; + } + return null; } @Override public String toString() { @@ -572,7 +644,7 @@ public class LibvirtVMDef { if (_desc != null ) { vmBuilder.append("" + _desc + "\n"); } - for (Object o : components) { + for (Object o : components.values()) { vmBuilder.append(o.toString()); } vmBuilder.append("\n"); @@ -586,63 +658,63 @@ public class LibvirtVMDef { vm.setDomainName("testing"); vm.setDomUUID(UUID.randomUUID().toString()); - guestDef guest = new guestDef(); - guest.setGuestType(guestDef.guestType.KVM); + GuestDef guest = new GuestDef(); + guest.setGuestType(GuestDef.guestType.KVM); guest.setGuestArch("x86_64"); guest.setMachineType("pc-0.11"); - guest.setBootOrder(guestDef.bootOrder.HARDISK); + guest.setBootOrder(GuestDef.bootOrder.HARDISK); vm.addComp(guest); - guestResourceDef grd = new guestResourceDef(); + GuestResourceDef grd = new GuestResourceDef(); grd.setMemorySize(512*1024); grd.setVcpuNum(1); vm.addComp(grd); - featuresDef features = new featuresDef(); + FeaturesDef features = new FeaturesDef(); features.addFeatures("pae"); features.addFeatures("apic"); features.addFeatures("acpi"); vm.addComp(features); - termPolicy term = new termPolicy(); + TermPolicy term = new TermPolicy(); term.setCrashPolicy("destroy"); term.setPowerOffPolicy("destroy"); term.setRebootPolicy("destroy"); vm.addComp(term); - devicesDef devices = new devicesDef(); + DevicesDef devices = new DevicesDef(); devices.setEmulatorPath("/usr/bin/cloud-qemu-system-x86_64"); - diskDef hda = new diskDef(); - hda.defFileBasedDisk("/path/to/hda1", "hda", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2); + DiskDef hda = new DiskDef(); + hda.defFileBasedDisk("/path/to/hda1", 0, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); devices.addDevice(hda); - diskDef hdb = new diskDef(); - hdb.defFileBasedDisk("/path/to/hda2", "hdb", diskDef.diskBus.IDE, diskDef.diskFmtType.QCOW2); + DiskDef hdb = new DiskDef(); + hdb.defFileBasedDisk("/path/to/hda2", 1, DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); devices.addDevice(hdb); - interfaceDef pubNic = new interfaceDef(); - pubNic.defBridgeNet("cloudbr0", "vnet1", "00:16:3e:77:e2:a1", interfaceDef.nicModel.VIRTIO); + InterfaceDef pubNic = new InterfaceDef(); + pubNic.defBridgeNet("cloudbr0", "vnet1", "00:16:3e:77:e2:a1", InterfaceDef.nicModel.VIRTIO); devices.addDevice(pubNic); - interfaceDef privNic = new interfaceDef(); - privNic.defPrivateNet("cloud-private", null, "00:16:3e:77:e2:a2", interfaceDef.nicModel.VIRTIO); + InterfaceDef privNic = new InterfaceDef(); + privNic.defPrivateNet("cloud-private", null, "00:16:3e:77:e2:a2", InterfaceDef.nicModel.VIRTIO); devices.addDevice(privNic); - interfaceDef vlanNic = new interfaceDef(); - vlanNic.defBridgeNet("vnbr1000", "tap1", "00:16:3e:77:e2:a2", interfaceDef.nicModel.VIRTIO); + InterfaceDef vlanNic = new InterfaceDef(); + vlanNic.defBridgeNet("vnbr1000", "tap1", "00:16:3e:77:e2:a2", InterfaceDef.nicModel.VIRTIO); devices.addDevice(vlanNic); - serialDef serial = new serialDef("pty", null, (short)0); + SerialDef serial = new SerialDef("pty", null, (short)0); devices.addDevice(serial); - consoleDef console = new consoleDef("pty", null, null, (short)0); + ConsoleDef console = new ConsoleDef("pty", null, null, (short)0); devices.addDevice(console); - graphicDef grap = new graphicDef("vnc", (short)0, true, null, null, null); + GraphicDef grap = new GraphicDef("vnc", (short)0, true, null, null, null); devices.addDevice(grap); - inputDef input = new inputDef("tablet", "usb"); + InputDef input = new InputDef("tablet", "usb"); devices.addDevice(input); vm.addComp(devices); diff --git a/api/src/com/cloud/dc/DataCenter.java b/api/src/com/cloud/dc/DataCenter.java index f1013b1e880..57facf1a5f8 100644 --- a/api/src/com/cloud/dc/DataCenter.java +++ b/api/src/com/cloud/dc/DataCenter.java @@ -13,5 +13,6 @@ public interface DataCenter extends Grouping { String getDns1(); String getDns2(); String getGuestNetworkCidr(); + String getName(); Long getDomainId(); } diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/com/cloud/deploy/DeploymentPlanner.java index 83c8c76ed5d..915e56b97f1 100644 --- a/api/src/com/cloud/deploy/DeploymentPlanner.java +++ b/api/src/com/cloud/deploy/DeploymentPlanner.java @@ -6,9 +6,15 @@ package com.cloud.deploy; import java.util.HashSet; import java.util.Set; +import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; +import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.host.Host; +import com.cloud.org.Cluster; +import com.cloud.storage.StoragePool; import com.cloud.utils.component.Adapter; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -23,7 +29,7 @@ public interface DeploymentPlanner extends Adapter { * @param avoid avoid these data centers, pods, clusters, or hosts. * @return DeployDestination for that virtual machine. */ - DeployDestination plan(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException; + DeployDestination plan(VirtualMachineProfile vm, DeploymentPlan plan, ExcludeList avoid) throws InsufficientServerCapacityException; /** * check() is called right before the virtual machine starts to make sure @@ -35,15 +41,40 @@ public interface DeploymentPlanner extends Adapter { * @param avoid what to avoid. * @return true if it's okay to start; false if not. If false, the exclude list will include what should be excluded. */ - boolean check(VirtualMachineProfile vm, DeploymentPlan plan, DeployDestination dest, ExcludeList exclude); + boolean check(VirtualMachineProfile vm, DeploymentPlan plan, DeployDestination dest, ExcludeList exclude); public static class ExcludeList { Set _dcIds; Set _podIds; Set _clusterIds; Set _hostIds; + Set _poolIds; - public void adddDataCenter(long dataCenterId) { + public void add(InsufficientCapacityException e) { + Class scope = e.getScope(); + + if (scope == null) { + return; + } + + if (Host.class.isAssignableFrom(scope)) { + addHost(e.getId()); + } else if (Pod.class.isAssignableFrom(scope)) { + addPod(e.getId()); + } else if (DataCenter.class.isAssignableFrom(scope)) { + addDataCenter(e.getId()); + } else if (Cluster.class.isAssignableFrom(scope)) { + addCluster(e.getId()); + } else if (StoragePool.class.isAssignableFrom(scope)) { + addPool(e.getId()); + } + } + + public void addPool(long poolId) { + _poolIds.add(poolId); + } + + public void addDataCenter(long dataCenterId) { if (_dcIds == null) { _dcIds = new HashSet(); } diff --git a/api/src/com/cloud/exception/InsufficientAddressCapacityException.java b/api/src/com/cloud/exception/InsufficientAddressCapacityException.java index de4d98a1e21..de2beecd832 100644 --- a/api/src/com/cloud/exception/InsufficientAddressCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientAddressCapacityException.java @@ -27,8 +27,8 @@ public class InsufficientAddressCapacityException extends InsufficientNetworkCap private static final long serialVersionUID = SerialVersionUID.InsufficientAddressCapacityException; - public InsufficientAddressCapacityException(String msg) { - super(msg); + public InsufficientAddressCapacityException(String msg, Class scope, Long id) { + super(msg, scope, id); } protected InsufficientAddressCapacityException() { diff --git a/api/src/com/cloud/exception/InsufficientCapacityException.java b/api/src/com/cloud/exception/InsufficientCapacityException.java index 233306b6000..ea059530091 100755 --- a/api/src/com/cloud/exception/InsufficientCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientCapacityException.java @@ -26,10 +26,32 @@ import com.cloud.utils.SerialVersionUID; public abstract class InsufficientCapacityException extends Exception { private static final long serialVersionUID = SerialVersionUID.InsufficientCapacityException; + Long id; + Class scope; + protected InsufficientCapacityException() { + super(); } - public InsufficientCapacityException(String msg) { + public InsufficientCapacityException(String msg, Class type, Long id) { super(msg); } + + /** + * @return scope where we are insufficient. The possible classes are + * Host, StoragePool, Cluster, Pod, DataCenter, NetworkConfiguration. + */ + public Class getScope() { + return scope; + } + + /** + * @return the id of the object that it is insufficient in. Note that this method is + * marked such that if the id is not set, then it will throw NullPointerException. + * This is intended as you should check to see if the Scope is present before + * accessing this method. + */ + public long getId() { + return id; + } } diff --git a/api/src/com/cloud/exception/InsufficientNetworkCapacityException.java b/api/src/com/cloud/exception/InsufficientNetworkCapacityException.java index bec23a42b87..ebbcc572121 100644 --- a/api/src/com/cloud/exception/InsufficientNetworkCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientNetworkCapacityException.java @@ -26,7 +26,7 @@ public class InsufficientNetworkCapacityException extends InsufficientCapacityEx super(); } - public InsufficientNetworkCapacityException(String msg) { - super(msg); + public InsufficientNetworkCapacityException(String msg, Class scope, Long id) { + super(msg, scope, id); } } diff --git a/api/src/com/cloud/exception/InsufficientServerCapacityException.java b/api/src/com/cloud/exception/InsufficientServerCapacityException.java index b20424a537f..588bac8d132 100755 --- a/api/src/com/cloud/exception/InsufficientServerCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientServerCapacityException.java @@ -17,6 +17,7 @@ */ package com.cloud.exception; +import com.cloud.org.Cluster; import com.cloud.utils.SerialVersionUID; /** @@ -28,7 +29,11 @@ public class InsufficientServerCapacityException extends InsufficientCapacityExc private static final long serialVersionUID = SerialVersionUID.InsufficientServerCapacityException; - public InsufficientServerCapacityException(String msg) { - super(msg); + public InsufficientServerCapacityException(String msg, Long clusterId) { + this(msg, Cluster.class, clusterId); + } + + public InsufficientServerCapacityException(String msg, Class scope, Long id) { + super(msg, scope, id); } } diff --git a/api/src/com/cloud/exception/InsufficientStorageCapacityException.java b/api/src/com/cloud/exception/InsufficientStorageCapacityException.java index 1f2b9c94977..8abaa14b018 100755 --- a/api/src/com/cloud/exception/InsufficientStorageCapacityException.java +++ b/api/src/com/cloud/exception/InsufficientStorageCapacityException.java @@ -17,6 +17,7 @@ */ package com.cloud.exception; +import com.cloud.storage.StoragePool; import com.cloud.utils.SerialVersionUID; /** @@ -27,7 +28,11 @@ public class InsufficientStorageCapacityException extends InsufficientCapacityEx private static final long serialVersionUID = SerialVersionUID.InsufficientStorageCapacityException; - public InsufficientStorageCapacityException(String msg) { - super(msg); + public InsufficientStorageCapacityException(String msg, long id) { + this(msg, StoragePool.class, id); + } + + public InsufficientStorageCapacityException(String msg, Class scope, Long id) { + super(msg, scope, id); } } diff --git a/api/src/com/cloud/exception/InsufficientVirtualNetworkCapcityException.java b/api/src/com/cloud/exception/InsufficientVirtualNetworkCapcityException.java index 4d3b00256df..70e90e47170 100644 --- a/api/src/com/cloud/exception/InsufficientVirtualNetworkCapcityException.java +++ b/api/src/com/cloud/exception/InsufficientVirtualNetworkCapcityException.java @@ -17,12 +17,17 @@ */ package com.cloud.exception; +import com.cloud.dc.Pod; import com.cloud.utils.SerialVersionUID; public class InsufficientVirtualNetworkCapcityException extends InsufficientNetworkCapacityException { private static final long serialVersionUID = SerialVersionUID.InsufficientVirtualNetworkCapacityException; - public InsufficientVirtualNetworkCapcityException(String msg) { - super(msg); + public InsufficientVirtualNetworkCapcityException(String msg, Class scope, Long id) { + super(msg, scope, id); + } + + public InsufficientVirtualNetworkCapcityException(String msg, long id) { + this(msg, Pod.class, id); } } diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index cf393f10fb8..22e822097fe 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -92,9 +92,9 @@ public class Network { Public, Guest, Storage, + Management, Control, - Vpn, - Management + Vpn }; public enum IsolationType { diff --git a/api/src/com/cloud/network/configuration/NetworkGuru.java b/api/src/com/cloud/network/configuration/NetworkGuru.java index 107e6a5f618..ac2c19b8c7a 100644 --- a/api/src/com/cloud/network/configuration/NetworkGuru.java +++ b/api/src/com/cloud/network/configuration/NetworkGuru.java @@ -18,7 +18,7 @@ import com.cloud.vm.VirtualMachineProfile; /** * NetworkGuru takes a network offering requested and figures - * out what is the correct network configuration that are needed to add + * out the correct network configuration needed to add * to the account in order to support this network. * */ @@ -71,4 +71,13 @@ public interface NetworkGuru extends Adapter { void deallocate(NetworkConfiguration config, NicProfile nic, VirtualMachineProfile vm); void destroy(NetworkConfiguration config, NetworkOffering offering); + + /** + * Throw away the design. + * @param config + * @param offering + * @param owner + * @return + */ + boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner); } diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index 7cfbedb1118..d17f06a5878 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -37,8 +37,8 @@ public class DiskProfile { private long diskOfferingId; private Long templateId; private long volumeId; - private Volume vol; - private DiskOffering offering; + + private HypervisorType hyperType; protected DiskProfile() { @@ -58,8 +58,6 @@ public class DiskProfile { public DiskProfile(Volume vol, DiskOffering offering, HypervisorType hyperType) { this(vol.getId(), vol.getVolumeType(), vol.getName(), offering.getId(), vol.getSize(), offering.getTagsArray(), offering.getUseLocalStorage(), offering.getUseLocalStorage(), vol.getSize()); - this.vol = vol; - this.offering = offering; this.hyperType = hyperType; } diff --git a/api/src/com/cloud/vm/Nic.java b/api/src/com/cloud/vm/Nic.java index 54d93d00221..8e7fdfed336 100644 --- a/api/src/com/cloud/vm/Nic.java +++ b/api/src/com/cloud/vm/Nic.java @@ -31,6 +31,10 @@ public interface Nic extends Resource { String getMacAddress(); + String getNetmask(); + + String getGateway(); + /** * @return network profile id that this */ diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index f2eb4b68d13..7d90f6da4e2 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -103,9 +103,13 @@ listPublicIpAddresses=com.cloud.api.commands.ListPublicIpAddressesCmd;15 #### firewall commands listPortForwardingRules=com.cloud.api.commands.ListPortForwardingRulesCmd;15 -createPortForwardingRule=com.cloud.api.commands.CreateIPForwardingRuleCmd;15 -deletePortForwardingRule=com.cloud.api.commands.DeleteIPForwardingRuleCmd;15 -updatePortForwardingRule=com.cloud.api.commands.UpdateIPForwardingRuleCmd;15 +createPortForwardingRule=com.cloud.api.commands.CreatePortForwardingRuleCmd;15 +deletePortForwardingRule=com.cloud.api.commands.DeletePortForwardingRuleCmd;15 +updatePortForwardingRule=com.cloud.api.commands.UpdatePortForwardingRuleCmd;15 + +#### NAT commands +createIpForwardingRule=com.cloud.api.commands.CreateIpForwardingRuleCmd;15 +deleteIpForwardingRule=com.cloud.api.commands.DeleteIpForwardingRuleCmd;15 #### load balancer commands createLoadBalancerRule=com.cloud.api.commands.CreateLoadBalancerRuleCmd;15 diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 3119a71cda9..87f9dcaf4f4 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -123,8 +123,8 @@ - - + < adapter name="Storage" class="com.cloud.storage.allocator.FirstFitStoragePoolAllocator"/ > + diff --git a/cloud.spec b/cloud.spec index f15b8f58529..21af8d57832 100644 --- a/cloud.spec +++ b/cloud.spec @@ -74,19 +74,6 @@ Group: System Environment/Libraries The Cloud.com server libraries provide a set of Java classes used in the Cloud.com Stack. -%package vnet -Summary: Cloud.com-specific virtual network daemon -Requires: python -Requires: %{name}-daemonize = %{version}-%{release} -Requires: %{name}-python = %{version}-%{release} -Requires: net-tools -Requires: bridge-utils -Obsoletes: vmops-vnet < %{version}-%{release} -Group: System Environment/Daemons -%description vnet -The Cloud.com virtual network daemon manages virtual networks used in the -Cloud.com Stack. - %package agent-scripts Summary: Cloud.com agent scripts # FIXME nuke the archdependency @@ -217,7 +204,6 @@ Requires: java >= 1.6.0 Requires: %{name}-utils = %{version}-%{release}, %{name}-core = %{version}-%{release}, %{name}-deps = %{version}-%{release} Requires: %{name}-agent-libs = %{version}-%{release} Requires: %{name}-agent-scripts = %{version}-%{release} -Requires: %{name}-vnet = %{version}-%{release} Requires: python Requires: %{name}-python = %{version}-%{release} Requires: commons-httpclient @@ -439,21 +425,6 @@ else /sbin/service %{name}-console-proxy condrestart >/dev/null 2>&1 || true fi -%preun vnet -if [ "$1" == "0" ] ; then - /sbin/chkconfig --del %{name}-vnetd > /dev/null 2>&1 || true - /sbin/service %{name}-vnetd stop > /dev/null 2>&1 || true -fi - -%post vnet -if [ "$1" == "1" ] ; then - /sbin/chkconfig --add %{name}-vnetd > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 %{name}-vnetd on > /dev/null 2>&1 || true -else - /sbin/service %{name}-vnetd condrestart >/dev/null 2>&1 || true -fi - - %files utils %defattr(0644,root,root,0755) %{_javadir}/%{name}-utils.jar @@ -520,12 +491,6 @@ fi %defattr(0644,root,root,0755) %{_javadir}/%{name}-core.jar -%files vnet -%defattr(0644,root,root,0755) -%attr(0755,root,root) %{_sbindir}/%{name}-vnetd -%attr(0755,root,root) %{_sbindir}/%{name}-vn -%attr(0755,root,root) %{_initrddir}/%{name}-vnetd - %files python %defattr(0644,root,root,0755) %{_prefix}/lib*/python*/site-packages/%{name}* diff --git a/core/src/com/cloud/agent/api/routing/SetFirewallRuleCommand.java b/core/src/com/cloud/agent/api/routing/SetFirewallRuleCommand.java index c46d78d8138..92ebcdd8195 100755 --- a/core/src/com/cloud/agent/api/routing/SetFirewallRuleCommand.java +++ b/core/src/com/cloud/agent/api/routing/SetFirewallRuleCommand.java @@ -25,6 +25,8 @@ public class SetFirewallRuleCommand extends RoutingCommand { String routerIpAddress; String oldPrivateIP = null; String oldPrivatePort = null; + boolean nat = false; + boolean create = false; protected SetFirewallRuleCommand() { } @@ -37,10 +39,12 @@ public class SetFirewallRuleCommand extends RoutingCommand { this.oldPrivatePort = oldPrivatePort; } - public SetFirewallRuleCommand(String routerName, String routerIpAddress, FirewallRuleVO rule) { + public SetFirewallRuleCommand(String routerName, String routerIpAddress, boolean nat, FirewallRuleVO rule, boolean create) { this.routerName = routerName; this.routerIpAddress = routerIpAddress; + this.nat = nat; this.rule = rule; + this.create = create; } @Override @@ -96,4 +100,12 @@ public class SetFirewallRuleCommand extends RoutingCommand { return this.oldPrivatePort; } + public boolean isNat(){ + return this.nat; + } + + public boolean isCreate() { + return create; + } + } diff --git a/core/src/com/cloud/dc/dao/DataCenterIpAddressDao.java b/core/src/com/cloud/dc/dao/DataCenterIpAddressDao.java index 73b0952941a..c30d7386ae9 100644 --- a/core/src/com/cloud/dc/dao/DataCenterIpAddressDao.java +++ b/core/src/com/cloud/dc/dao/DataCenterIpAddressDao.java @@ -26,6 +26,7 @@ public interface DataCenterIpAddressDao extends GenericDao listByPodIdDcIdIpAddress(long podId, long dcId, String ipAddress); + List listByPodIdDcId(long podId, long dcId); int countIPs(long podId, long dcId, boolean onlyCountAllocated); boolean deleteIpAddressByPod(long podId); diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 72e3761c766..114de0e504a 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1115,32 +1115,44 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected Answer execute(final SetFirewallRuleCommand cmd) { String args; - if (cmd.isEnable()) { - args = "-A"; - } else { - args = "-D"; + if(cmd.isNat()){ + //1:1 NAT needs instanceip;publicip;domrip;op + if(cmd.isCreate()) + args = "-A"; + else + args = "-D"; + + args += " -l " + cmd.getPublicIpAddress(); + args += " -i " + cmd.getRouterIpAddress(); + args += " -r " + cmd.getPrivateIpAddress(); + args += " -G " + cmd.getProtocol(); + }else{ + if (cmd.isEnable()) { + args = "-A"; + } else { + args = "-D"; + } + + args += " -P " + cmd.getProtocol().toLowerCase(); + args += " -l " + cmd.getPublicIpAddress(); + args += " -p " + cmd.getPublicPort(); + args += " -n " + cmd.getRouterName(); + args += " -i " + cmd.getRouterIpAddress(); + args += " -r " + cmd.getPrivateIpAddress(); + args += " -d " + cmd.getPrivatePort(); + args += " -N " + cmd.getVlanNetmask(); + + String oldPrivateIP = cmd.getOldPrivateIP(); + String oldPrivatePort = cmd.getOldPrivatePort(); + + if (oldPrivateIP != null) { + args += " -w " + oldPrivateIP; + } + + if (oldPrivatePort != null) { + args += " -x " + oldPrivatePort; + } } - - args += " -P " + cmd.getProtocol().toLowerCase(); - args += " -l " + cmd.getPublicIpAddress(); - args += " -p " + cmd.getPublicPort(); - args += " -n " + cmd.getRouterName(); - args += " -i " + cmd.getRouterIpAddress(); - args += " -r " + cmd.getPrivateIpAddress(); - args += " -d " + cmd.getPrivatePort(); - args += " -N " + cmd.getVlanNetmask(); - - String oldPrivateIP = cmd.getOldPrivateIP(); - String oldPrivatePort = cmd.getOldPrivatePort(); - - if (oldPrivateIP != null) { - args += " -w " + oldPrivateIP; - } - - if (oldPrivatePort != null) { - args += " -x " + oldPrivatePort; - } - String result = callHostPlugin("vmops", "setFirewallRule", "args", args); if (result == null || result.isEmpty()) { @@ -4680,7 +4692,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR vdir.type = Types.VdiType.USER; if(cmd.getSize()!=0) - vdir.virtualSize = cmd.getSize(); + vdir.virtualSize = (cmd.getSize()*1024*1024*1L); else vdir.virtualSize = dskch.getSize(); vdi = VDI.create(conn, vdir); diff --git a/core/src/com/cloud/network/dao/FirewallRulesDao.java b/core/src/com/cloud/network/dao/FirewallRulesDao.java index 7db42df3bf6..ef2bd4f0ed4 100644 --- a/core/src/com/cloud/network/dao/FirewallRulesDao.java +++ b/core/src/com/cloud/network/dao/FirewallRulesDao.java @@ -44,5 +44,6 @@ public interface FirewallRulesDao extends GenericDao { public List listBySecurityGroupId(long securityGroupId); public List listByLoadBalancerId(long loadBalancerId); public List listForwardingByPubAndPrivIp(boolean forwarding, String publicIPAddress, String privateIp); - public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding); + public FirewallRuleVO findByGroupAndPrivateIp(long groupId, String privateIp, boolean forwarding); + List findByPublicIpPrivateIpForNatRule(String publicIp,String privateIp); } diff --git a/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java index 55bce08b553..be3dee36020 100644 --- a/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java +++ b/core/src/com/cloud/network/dao/FirewallRulesDaoImpl.java @@ -55,7 +55,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i protected SearchBuilder FWByPrivateIPSearch; protected SearchBuilder RulesExcludingPubIpPort; protected SearchBuilder FWByGroupId; - protected SearchBuilder FWByGroupAndPrivateIp; + protected SearchBuilder FWByGroupAndPrivateIp; + protected SearchBuilder FWByPrivateIpPrivatePortPublicIpPublicPortSearch; protected FirewallRulesDaoImpl() { } @@ -124,6 +125,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i FWByGroupAndPrivateIp.and("forwarding", FWByGroupAndPrivateIp.entity().isForwarding(), SearchCriteria.Op.EQ); FWByGroupAndPrivateIp.done(); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch = createSearchBuilder(); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicIpAddress(), SearchCriteria.Op.EQ); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privateIpAddress", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("privatePort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPrivatePort(), SearchCriteria.Op.NULL); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch.and("publicPort", FWByPrivateIpPrivatePortPublicIpPublicPortSearch.entity().getPublicPort(), SearchCriteria.Op.NULL); + FWByPrivateIpPrivatePortPublicIpPublicPortSearch.done(); + return true; } @@ -306,5 +314,13 @@ public class FirewallRulesDaoImpl extends GenericDaoBase i sc.setParameters("forwarding", forwarding); return findOneBy(sc); + } + + @Override + public List findByPublicIpPrivateIpForNatRule(String publicIp, String privateIp){ + SearchCriteria sc = FWByPrivateIpPrivatePortPublicIpPublicPortSearch.create(); + sc.setParameters("publicIpAddress", publicIp); + sc.setParameters("privateIpAddress", privateIp); + return listBy(sc); } } diff --git a/core/src/com/cloud/storage/VolumeVO.java b/core/src/com/cloud/storage/VolumeVO.java index b755376c3cd..d3b02e0f95e 100755 --- a/core/src/com/cloud/storage/VolumeVO.java +++ b/core/src/com/cloud/storage/VolumeVO.java @@ -238,7 +238,6 @@ public class VolumeVO implements Volume { } - public boolean isRecreatable() { return recreatable; } diff --git a/core/src/com/cloud/vm/SecondaryStorageVmVO.java b/core/src/com/cloud/vm/SecondaryStorageVmVO.java index cb00d26350c..a97f690638e 100644 --- a/core/src/com/cloud/vm/SecondaryStorageVmVO.java +++ b/core/src/com/cloud/vm/SecondaryStorageVmVO.java @@ -26,6 +26,8 @@ import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; + +import com.cloud.vm.VirtualMachine.Type; /** * SecondaryStorageVmVO domain object @@ -86,7 +88,11 @@ public class SecondaryStorageVmVO extends VMInstanceVO implements SecondaryStora @Temporal(TemporalType.TIMESTAMP) @Column(name="last_update", updatable=true, nullable=true) private Date lastUpdateTime; - + + public SecondaryStorageVmVO(long id, long serviceOfferingId, String name, long templateId, long guestOSId, long dataCenterId, + long domainId, long accountId) { + super(id, serviceOfferingId, name, name, Type.SecondaryStorageVm, templateId, guestOSId, domainId, accountId, true); + } public SecondaryStorageVmVO( long id, diff --git a/debian/cloud-vnet.install b/debian/cloud-vnet.install deleted file mode 100644 index 8a894c7d4c8..00000000000 --- a/debian/cloud-vnet.install +++ /dev/null @@ -1,3 +0,0 @@ -/usr/sbin/cloud-vn -/usr/sbin/cloud-vnetd -/etc/init.d/cloud-vnetd diff --git a/debian/cloud-vnet.postinst b/debian/cloud-vnet.postinst deleted file mode 100644 index 02c33c835aa..00000000000 --- a/debian/cloud-vnet.postinst +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -e - -case "$1" in - configure) - - if [ "$2" = "" ] ; then # no recently configured version, this is a first install - /usr/sbin/update-rc.d cloud-vnet defaults || true - fi - - ;; -esac - -#DEBHELPER# \ No newline at end of file diff --git a/debian/control b/debian/control index 91a8186c662..acbef6ad45d 100644 --- a/debian/control +++ b/debian/control @@ -49,16 +49,6 @@ Description: Cloud.com server library The Cloud.com server libraries provide a set of Java classes used in the Cloud.com Cloud Stack. -Package: cloud-vnet -Provides: vmops-vnet -Conflicts: vmops-vnet -Replaces: vmops-vnet -Architecture: any -Depends: cloud-daemonize (= ${source:Version}), cloud-python (= ${source:Version}), python, bridge-utils, net-tools -Description: Cloud.com-specific virtual network daemon - The Cloud.com virtual network daemon manages virtual networks used in the - Cloud.com Cloud Stack. - Package: cloud-agent-scripts Provides: vmops-agent-scripts, vmops-console, cloud-console, vmops-console-proxy Conflicts: vmops-agent-scripts, vmops-console, cloud-console, vmops-console-proxy @@ -151,7 +141,7 @@ Provides: vmops-agent Conflicts: vmops-agent Replaces: vmops-agent Architecture: any -Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), cloud-vnet (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, cloud-daemonize, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, cgroup-bin, augeas-tools, uuid-runtime, rsync, grep, iproute +Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, cloud-daemonize, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, cgroup-bin, augeas-tools, uuid-runtime, rsync, grep, iproute Description: Cloud.com agent The Cloud.com agent is in charge of managing shared computing resources in a Cloud.com Cloud Stack-powered cloud. Install this package if this computer diff --git a/patches/systemvm/debian/config/root/firewall.sh b/patches/systemvm/debian/config/root/firewall.sh index 89cd0d4a95e..d8f698b2ba3 100755 --- a/patches/systemvm/debian/config/root/firewall.sh +++ b/patches/systemvm/debian/config/root/firewall.sh @@ -9,7 +9,7 @@ usage() { printf "Usage: %s: (-A|-D) -i -r -P protocol (-p port_range | -t icmp_type_code) -l -d [-f -u -y -z ] \n" $(basename $0) >&2 } -set -x +# set -x get_dom0_ip () { eval "$1=$(ifconfig eth0 | awk '/inet addr/ {split ($2,A,":"); print A[2]}')" @@ -71,6 +71,36 @@ icmp_entry() { return $? } +#Add 1:1 NAT entry +add_one_to_one_nat_entry() { + local guestIp=$1 + local publicIp=$2 + local dIp=$3 + local op=$4 + if [ "$op" == "-D" ] + then + iptables -t nat $op PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp + if [ $? -gt 0 ] + then + return 0 + fi + else + iptables -t nat $op PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp + fi + iptables -t nat $op POSTROUTING -o eth2 -s $guestIp -j SNAT --to-source $publicIp + if [ "$op" == "-A" ] + then + iptables -P FORWARD DROP + else + iptables -P FORWARD ACCEPT + fi + iptables $op FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables $op FORWARD -i eth2 -o eth0 -d $guestIp -m state --state NEW -j ACCEPT + iptables $op FORWARD -i eth0 -o eth2 -s $guestIp -m state --state NEW -j ACCEPT + + return $? +} + get_vif_list() { local vif_list="" for i in /sys/class/net/eth*; do @@ -107,11 +137,12 @@ wflag= xflag= nflag= Nflag= +Gflag= op="" oldPrivateIP="" oldPrivatePort="" -while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:' OPTION +while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:G:' OPTION do case $OPTION in A) Aflag=1 @@ -153,12 +184,23 @@ do N) Nflag=1 netmask="$OPTARG" ;; + G) Gflag=1 + nat="$OPTARG" + ;; ?) usage exit 2 ;; esac done +#1:1 NAT +if [ "$Gflag" == "1" ] + then + add_one_to_one_nat_entry $instanceIp $publicIp $domRIp $op + fi + exit $? +fi + reverseOp=$(reverse_op $op) VIF_LIST=$(get_vif_list) diff --git a/scripts/network/domr/call_firewall.sh b/scripts/network/domr/call_firewall.sh index 287efa21f5d..8c84a121829 100755 --- a/scripts/network/domr/call_firewall.sh +++ b/scripts/network/domr/call_firewall.sh @@ -33,11 +33,12 @@ wflag= xflag= nflag= Nflag= +Gflag= op="" oldPrivateIP="" oldPrivatePort="" -while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:' OPTION +while getopts 'ADr:i:P:p:t:l:d:w:x:n:N:G:' OPTION do case $OPTION in A) Aflag=1 @@ -79,6 +80,9 @@ do N) Nflag=1 netmask="$OPTARG" ;; + G) Gflag=1 + nat="OPTARG" + ;; ?) usage exit 2 ;; @@ -101,12 +105,6 @@ then exit 2 fi -if [ "$rflag$iflag$Pflag$pflag$tflag$lflag" != "11111" ] -then - usage - exit 2 -fi - #Require -d with -p if [ "$pflag$dflag" != 11 -a "$pflag$dflag" != "" ] then diff --git a/scripts/network/domr/firewall.sh b/scripts/network/domr/firewall.sh index 56ee70facbc..91cf622c051 100755 --- a/scripts/network/domr/firewall.sh +++ b/scripts/network/domr/firewall.sh @@ -231,4 +231,4 @@ case $protocol in ;; esac -exit 0 +exit 0 \ No newline at end of file diff --git a/server/.classpath b/server/.classpath index 9546c1c9646..6d7912d4ca3 100644 --- a/server/.classpath +++ b/server/.classpath @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 07efe960554..2906583cee0 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -54,6 +54,7 @@ import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.ResourceLimit; import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.Vlan.VlanType; @@ -67,6 +68,8 @@ import com.cloud.host.Status.Event; import com.cloud.network.FirewallRuleVO; import com.cloud.network.IPAddressVO; import com.cloud.network.LoadBalancerVO; +import com.cloud.network.Network.TrafficType; +import com.cloud.network.NetworkConfiguration; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; import com.cloud.server.Criteria; @@ -91,6 +94,7 @@ import com.cloud.uservm.UserVm; import com.cloud.vm.ConsoleProxyVO; import com.cloud.vm.DomainRouter; import com.cloud.vm.InstanceGroupVO; +import com.cloud.vm.Nic; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.State; import com.cloud.vm.SystemVm; @@ -351,6 +355,9 @@ public class ApiResponseHelper { } public static UserVmResponse createUserVmResponse (UserVm userVm) { + if (userVm.getPrivateIpAddress() == null) { + return createUserVm2Response(userVm); + } UserVmResponse userVmResponse = new UserVmResponse(); Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId())); //FIXME - this check should be done in searchForUserVm method in ManagementServerImpl; @@ -377,7 +384,6 @@ public class ApiResponseHelper { userVmResponse.setState(userVm.getState().toString()); } - userVmResponse.setHaEnable(userVm.isHaEnabled()); if (userVm.getDisplayName() != null) { @@ -473,6 +479,9 @@ public class ApiResponseHelper { } public static SystemVmResponse createSystemVmResponse (VMInstanceVO systemVM) { + if (systemVM.getPrivateIpAddress() == null) { + return createSystemVm2Response(systemVM); + } SystemVmResponse vmResponse = new SystemVmResponse(); if (systemVM instanceof SystemVm) { SystemVm vm = (SystemVm)systemVM; @@ -528,6 +537,9 @@ public class ApiResponseHelper { public static DomainRouterResponse createDomainRouterResponse (DomainRouter router) { + if (router.getPrivateIpAddress() == null) { + return createDomainRouter2Response(router); + } DomainRouterResponse routerResponse = new DomainRouterResponse(); routerResponse.setId(router.getId()); @@ -985,4 +997,276 @@ public class ApiResponseHelper { return response; } + + + public static UserVmResponse createUserVm2Response (UserVm userVm) { + UserVmResponse userVmResponse = new UserVmResponse(); + Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId())); + //FIXME - this check should be done in searchForUserVm method in ManagementServerImpl; + //otherwise the number of vms returned is not going to match pageSize request parameter + if ((acct != null) && (acct.getRemoved() == null)) { + userVmResponse.setAccountName(acct.getAccountName()); + userVmResponse.setDomainId(acct.getDomainId()); + userVmResponse.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName()); + } else { + return null; // the account has been deleted, skip this VM in the response + } + + userVmResponse.setId(userVm.getId()); + AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("vm_instance", userVm.getId()); + if (asyncJob != null) { + userVmResponse.setJobId(asyncJob.getId()); + userVmResponse.setJobStatus(asyncJob.getStatus()); + } + + userVmResponse.setName(userVm.getHostName()); + userVmResponse.setCreated(userVm.getCreated()); + + if (userVm.getState() != null) { + userVmResponse.setState(userVm.getState().toString()); + } + + userVmResponse.setHaEnable(userVm.isHaEnabled()); + + if (userVm.getDisplayName() != null) { + userVmResponse.setDisplayName(userVm.getDisplayName()); + } else { + userVmResponse.setDisplayName(userVm.getHostName()); + } + + InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId()); + if (group != null) { + userVmResponse.setGroup(group.getName()); + userVmResponse.setGroupId(group.getId()); + } + + // Data Center Info + userVmResponse.setZoneId(userVm.getDataCenterId()); + userVmResponse.setZoneName(ApiDBUtils.findZoneById(userVm.getDataCenterId()).getName()); + + Account account = UserContext.current().getAccount(); + //if user is an admin, display host id + if (((account == null) || (account.getType() == Account.ACCOUNT_TYPE_ADMIN)) && (userVm.getHostId() != null)) { + userVmResponse.setHostId(userVm.getHostId()); + userVmResponse.setHostName(ApiDBUtils.findHostById(userVm.getHostId()).getName()); + } + + // Template Info + VMTemplateVO template = ApiDBUtils.findTemplateById(userVm.getTemplateId()); + if (template != null) { + userVmResponse.setTemplateId(userVm.getTemplateId()); + userVmResponse.setTemplateName(template.getName()); + userVmResponse.setTemplateDisplayText(template.getDisplayText()); + userVmResponse.setPasswordEnabled(template.getEnablePassword()); + } else { + userVmResponse.setTemplateId(-1L); + userVmResponse.setTemplateName("ISO Boot"); + userVmResponse.setTemplateDisplayText("ISO Boot"); + userVmResponse.setPasswordEnabled(false); + } + + if (userVm.getPassword() != null) { + userVmResponse.setPassword(userVm.getPassword()); + } + + // ISO Info + if (userVm.getIsoId() != null) { + VMTemplateVO iso = ApiDBUtils.findTemplateById(userVm.getIsoId().longValue()); + if (iso != null) { + userVmResponse.setIsoId(userVm.getIsoId()); + userVmResponse.setIsoName(iso.getName()); + } + } + + // Service Offering Info + ServiceOffering offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId()); + userVmResponse.setServiceOfferingId(userVm.getServiceOfferingId()); + userVmResponse.setServiceOfferingName(offering.getName()); + userVmResponse.setCpuNumber(offering.getCpu()); + userVmResponse.setCpuSpeed(offering.getSpeed()); + userVmResponse.setMemory(offering.getRamSize()); + + VolumeVO rootVolume = ApiDBUtils.findRootVolume(userVm.getId()); + if (rootVolume != null) { + userVmResponse.setRootDeviceId(rootVolume.getDeviceId()); + String rootDeviceType = "Not created"; + if (rootVolume.getPoolId() != null){ + StoragePoolVO storagePool = ApiDBUtils.findStoragePoolById(rootVolume.getPoolId()); + rootDeviceType = storagePool.getPoolType().toString(); + } + userVmResponse.setRootDeviceType(rootDeviceType); + } + + //stats calculation + DecimalFormat decimalFormat = new DecimalFormat("#.##"); + String cpuUsed = null; + VmStats vmStats = ApiDBUtils.getVmStatistics(userVm.getId()); + if (vmStats != null) { + float cpuUtil = (float) vmStats.getCPUUtilization(); + cpuUsed = decimalFormat.format(cpuUtil) + "%"; + userVmResponse.setCpuUsed(cpuUsed); + + long networkKbRead = (long)vmStats.getNetworkReadKBs(); + userVmResponse.setNetworkKbsRead(networkKbRead); + + long networkKbWrite = (long)vmStats.getNetworkWriteKBs(); + userVmResponse.setNetworkKbsWrite(networkKbWrite); + } + + userVmResponse.setGuestOsId(userVm.getGuestOSId()); + //network groups + userVmResponse.setNetworkGroupList(ApiDBUtils.getNetworkGroupsNamesForVm(userVm.getId())); + + List nics = BaseCmd._networkMgr.getNics(userVm); + for (Nic singleNic : nics) { + long configId = singleNic.getNetworkConfigurationId(); + NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId); + if (networkConf.getTrafficType() == TrafficType.Guest) { + userVmResponse.setIpAddress(singleNic.getIp4Address()); + } + } + + userVmResponse.setObjectName("virtualmachine"); + return userVmResponse; + } + + + public static DomainRouterResponse createDomainRouter2Response (DomainRouter router) { + DomainRouterResponse routerResponse = new DomainRouterResponse(); + routerResponse.setId(router.getId()); + routerResponse.setZoneId(router.getDataCenterId()); + routerResponse.setName(router.getHostName()); + routerResponse.setPodId(router.getPodId()); + routerResponse.setTemplateId(router.getTemplateId()); + routerResponse.setCreated(router.getCreated()); + routerResponse.setState(router.getState()); + routerResponse.setNetworkDomain(router.getDomain()); + + if (router.getHostId() != null) { + routerResponse.setHostId(router.getHostId()); + routerResponse.setHostName(ApiDBUtils.findHostById(router.getHostId()).getName()); + } + + Account accountTemp = ApiDBUtils.findAccountById(router.getAccountId()); + if (accountTemp != null) { + routerResponse.setAccountName(accountTemp.getAccountName()); + routerResponse.setDomainId(accountTemp.getDomainId()); + routerResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName()); + } + + AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("domain_router", router.getId()); + if (asyncJob != null) { + routerResponse.setJobId(asyncJob.getId()); + routerResponse.setJobStatus(asyncJob.getStatus()); + } + + List nics = BaseCmd._networkMgr.getNics(router); + for (Nic singleNic : nics) { + long configId = singleNic.getNetworkConfigurationId(); + NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId); + + if (networkConf.getTrafficType() == TrafficType.Guest) { + routerResponse.setGuestIpAddress(singleNic.getIp4Address()); + routerResponse.setGuestMacAddress(singleNic.getMacAddress()); + routerResponse.setGuestNetmask(singleNic.getNetmask()); + } + + if (networkConf.getTrafficType() == TrafficType.Control) { + routerResponse.setPrivateIp(singleNic.getIp4Address()); + routerResponse.setPrivateMacAddress(singleNic.getMacAddress()); + routerResponse.setPrivateNetmask(singleNic.getNetmask()); + } + + if (networkConf.getTrafficType() == TrafficType.Public) { + routerResponse.setPublicIp(singleNic.getIp4Address()); + routerResponse.setPublicMacAddress(singleNic.getMacAddress()); + routerResponse.setPublicNetmask(singleNic.getNetmask()); + routerResponse.setGateway(singleNic.getGateway()); + } + + DataCenter zone = ApiDBUtils.findZoneById(router.getDataCenterId()); + if (zone != null) { + routerResponse.setZoneName(zone.getName()); + routerResponse.setDns1(zone.getDns1()); + routerResponse.setDns2(zone.getDns2()); + } + } + + routerResponse.setObjectName("domainrouter"); + return routerResponse; + } + + + public static SystemVmResponse createSystemVm2Response (VMInstanceVO systemVM) { + SystemVmResponse vmResponse = new SystemVmResponse(); + if (systemVM instanceof SystemVm) { + SystemVm vm = (SystemVm)systemVM; + + vmResponse.setId(vm.getId()); + vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); + vmResponse.setZoneId(vm.getDataCenterId()); + + vmResponse.setNetworkDomain(vm.getDomain()); + vmResponse.setName(vm.getHostName()); + vmResponse.setPodId(vm.getPodId()); + vmResponse.setTemplateId(vm.getTemplateId()); + vmResponse.setCreated(vm.getCreated()); + + if (vm.getHostId() != null) { + vmResponse.setHostId(vm.getHostId()); + vmResponse.setHostName(ApiDBUtils.findHostById(vm.getHostId()).getName()); + } + + if (vm.getState() != null) { + vmResponse.setState(vm.getState().toString()); + } + + String instanceType = "console_proxy"; + if (systemVM instanceof SecondaryStorageVmVO) { + instanceType = "sec_storage_vm"; // FIXME: this should be a constant so that the async jobs get updated with the correct instance type, they are using + // different instance types at the moment + } + + AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob(instanceType, vm.getId()); + if (asyncJob != null) { + vmResponse.setJobId(asyncJob.getId()); + vmResponse.setJobStatus(asyncJob.getStatus()); + } + + // for console proxies, add the active sessions + if (systemVM instanceof ConsoleProxyVO) { + ConsoleProxyVO proxy = (ConsoleProxyVO)systemVM; + vmResponse.setActiveViewerSessions(proxy.getActiveSession()); + } + + DataCenter zone = ApiDBUtils.findZoneById(vm.getDataCenterId()); + if (zone != null) { + vmResponse.setZoneName(zone.getName()); + vmResponse.setDns1(zone.getDns1()); + vmResponse.setDns2(zone.getDns2()); + } + + List nics = BaseCmd._networkMgr.getNics(systemVM); + for (Nic singleNic : nics) { + long configId = singleNic.getNetworkConfigurationId(); + NetworkConfiguration networkConf = BaseCmd._networkMgr.getNetworkConfiguration(configId); + + if (networkConf.getTrafficType() == TrafficType.Management) { + vmResponse.setPrivateIp(singleNic.getIp4Address()); + vmResponse.setPrivateMacAddress(singleNic.getMacAddress()); + vmResponse.setPrivateNetmask(singleNic.getNetmask()); + } + + if (networkConf.getTrafficType() == TrafficType.Public) { + vmResponse.setPublicIp(singleNic.getIp4Address()); + vmResponse.setPublicMacAddress(singleNic.getMacAddress()); + vmResponse.setPublicNetmask(singleNic.getNetmask()); + vmResponse.setGateway(singleNic.getGateway()); + } + } + } + + vmResponse.setObjectName("systemvm"); + return vmResponse; + } } diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 583567af40a..2978b8f4ce5 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -90,6 +90,7 @@ import com.cloud.exception.CloudAuthenticationException; import com.cloud.maid.StackMaid; import com.cloud.server.ManagementServer; import com.cloud.user.Account; +import com.cloud.user.AccountManager; import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.user.UserContext; @@ -113,6 +114,9 @@ public class ApiServer implements HttpRequestHandler { //private AsyncJobManager _asyncMgr; private ApiDispatcher _dispatcher; private ManagementServer _ms = null; + private AccountManager _accountMgr = null; + private Account _systemAccount = null; + private User _systemUser = null; private static int _workerCount = 0; @@ -187,6 +191,9 @@ public class ApiServer implements HttpRequestHandler { _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name); ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + _accountMgr = locator.getManager(AccountManager.class); + _systemAccount = _accountMgr.getSystemAccount(); + _systemUser = _accountMgr.getSystemUser(); //_asyncMgr = locator.getManager(AsyncJobManager.class); _dispatcher = ApiDispatcher.getInstance(); @@ -247,7 +254,7 @@ public class ApiServer implements HttpRequestHandler { } try { // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM - UserContext.registerContext(User.UID_SYSTEM, null, null, Account.ACCOUNT_ID_SYSTEM, null, null, true); + UserContext.registerContext(_systemUser.getId(), _systemAccount, _systemAccount.getAccountName(), _systemAccount.getId(), null, null, true); sb.insert(0,"(userId="+User.UID_SYSTEM+ " accountId="+Account.ACCOUNT_ID_SYSTEM+ " sessionId="+null+ ") " ); String responseText = handleRequest(parameterMap, true, responseType, sb); sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length())); @@ -362,7 +369,7 @@ public class ApiServer implements HttpRequestHandler { UserContext ctx = UserContext.current(); Long userId = ctx.getUserId(); - Account account = (Account)ctx.getAccount(); + Account account = ctx.getAccount(); if (userId != null) { params.put("ctxUserId", userId.toString()); } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 2ef67c55e0a..ee9b45e7a84 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -101,7 +101,9 @@ public class ApiServlet extends HttpServlet { if (userId != null) { _apiServer.logoutUser(userId); } - session.invalidate(); + try { + session.invalidate(); + }catch (IllegalStateException ise) {} } auditTrailSb.append("command=logout"); auditTrailSb.append(" " +HttpServletResponse.SC_OK); @@ -110,7 +112,11 @@ public class ApiServlet extends HttpServlet { } else if ("login".equalsIgnoreCase(command)) { auditTrailSb.append("command=login"); // if this is a login, authenticate the user and return - if (session != null) session.invalidate(); + if (session != null) { + try { + session.invalidate(); + }catch (IllegalStateException ise) {} + } session = req.getSession(true); String[] username = (String[])params.get("username"); String[] password = (String[])params.get("password"); @@ -160,7 +166,9 @@ public class ApiServlet extends HttpServlet { return; } catch (CloudAuthenticationException ex) { // TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401) - session.invalidate(); + try { + session.invalidate(); + }catch (IllegalStateException ise) {} auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "failed to authenticated user, check username/password are correct"); resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "failed to authenticated user, check username/password are correct"); return; @@ -185,7 +193,9 @@ public class ApiServlet extends HttpServlet { String sessionKey = (String)session.getAttribute("sessionkey"); String[] sessionKeyParam = (String[])params.get("sessionkey"); if ((sessionKeyParam == null) || (sessionKey == null) || !sessionKey.equals(sessionKeyParam[0])) { - session.invalidate(); + try { + session.invalidate(); + }catch (IllegalStateException ise) {} auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials"); return; @@ -204,7 +214,9 @@ public class ApiServlet extends HttpServlet { } else { // Invalidate the session to ensure we won't allow a request across management server restarts if the userId was serialized to the // stored session - session.invalidate(); + try { + session.invalidate(); + }catch (IllegalStateException ise) {} auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials"); resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials"); return; @@ -242,7 +254,9 @@ public class ApiServlet extends HttpServlet { } } else { if (session != null) { - session.invalidate(); + try { + session.invalidate(); + }catch (IllegalStateException ise) {} } auditTrailSb.append(" " + HttpServletResponse.SC_UNAUTHORIZED + " " + "unable to verify user credentials and/or request signature"); resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature"); diff --git a/server/src/com/cloud/api/BaseAsyncCreateCmd.java b/server/src/com/cloud/api/BaseAsyncCreateCmd.java index 32a932908a6..6739fd08599 100644 --- a/server/src/com/cloud/api/BaseAsyncCreateCmd.java +++ b/server/src/com/cloud/api/BaseAsyncCreateCmd.java @@ -6,6 +6,7 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; diff --git a/server/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java b/server/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java new file mode 100644 index 00000000000..118f3f0b79e --- /dev/null +++ b/server/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.BaseAsyncCreateCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.FirewallRuleResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.FirewallRuleVO; +import com.cloud.user.Account; + +@Implementation(description="Creates an ip forwarding rule") +public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd { + public static final Logger s_logger = Logger.getLogger(CreateIpForwardingRuleCmd.class.getName()); + + private static final String s_name = "createipforwardingruleresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the public IP address of the forwarding rule, already associated via associateIp") + private String ipAddress; + + @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the ID of the virtual machine for the forwarding rule") + private Long virtualMachineId; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getIpAddress() { + return ipAddress; + } + + public Long getVirtualMachineId() { + return virtualMachineId; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ + FirewallRuleVO result = _networkMgr.createIpForwardingRuleOnDomr(this.getId()); + if (result != null) { + FirewallRuleResponse fwResponse = ApiResponseHelper.createFirewallRuleResponse(result); + fwResponse.setResponseName(getName()); + this.setResponseObject(fwResponse); + } else { + throw new ServerApiException(NET_CREATE_IPFW_RULE_ERROR, "Error in creating ip forwarding rule on the domr"); + } + + } + + @Override + public void callCreate() throws ServerApiException,InvalidParameterValueException, PermissionDeniedException,InsufficientAddressCapacityException,InsufficientCapacityException, ResourceUnavailableException,ConcurrentOperationException, ResourceAllocationException{ + FirewallRuleVO rule = _networkMgr.createIpForwardingRuleInDb(ipAddress,virtualMachineId); + this.setId(rule.getId()); + } + + @Override + public long getAccountId() { + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NET_RULE_ADD; + } + + @Override + public String getEventDescription() { + return ("Creating an ipforwarding 1:1 NAT rule for "+ipAddress+" with virtual machine:"+virtualMachineId); + } + +} diff --git a/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java b/server/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java similarity index 97% rename from server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java rename to server/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 67c3dd603b5..cd988eef39d 100644 --- a/server/src/com/cloud/api/commands/CreateIPForwardingRuleCmd.java +++ b/server/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -36,8 +36,8 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.network.FirewallRuleVO; @Implementation(description="Creates a port forwarding rule") -public class CreateIPForwardingRuleCmd extends BaseCmd { - public static final Logger s_logger = Logger.getLogger(CreateIPForwardingRuleCmd.class.getName()); +public class CreatePortForwardingRuleCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(CreatePortForwardingRuleCmd.class.getName()); private static final String s_name = "createportforwardingruleresponse"; diff --git a/server/src/com/cloud/api/commands/DeleteIpForwardingRuleCmd.java b/server/src/com/cloud/api/commands/DeleteIpForwardingRuleCmd.java new file mode 100644 index 00000000000..b3f475dea56 --- /dev/null +++ b/server/src/com/cloud/api/commands/DeleteIpForwardingRuleCmd.java @@ -0,0 +1,99 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.BaseCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SuccessResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.user.Account; + +@Implementation(description="Deletes an ip forwarding rule") +public class DeleteIpForwardingRuleCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(DeleteIpForwardingRuleCmd.class.getName()); + + private static final String s_name = "deleteipforwardingruleresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the id of the forwarding rule") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ + try { + boolean result = false; + result = _networkMgr.deleteIpForwardingRule(id); + if (result) { + SuccessResponse response = new SuccessResponse(getName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to delete ip forwarding rule"); + } + } catch (Exception ex) { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + } + + @Override + public long getAccountId() { + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_NET_RULE_ADD; + } + + @Override + public String getEventDescription() { + return ("Deleting an ipforwarding 1:1 NAT rule id:"+id); + } + +} diff --git a/server/src/com/cloud/api/commands/DeleteIPForwardingRuleCmd.java b/server/src/com/cloud/api/commands/DeletePortForwardingRuleCmd.java similarity index 94% rename from server/src/com/cloud/api/commands/DeleteIPForwardingRuleCmd.java rename to server/src/com/cloud/api/commands/DeletePortForwardingRuleCmd.java index ddfb872db95..e93cb77eb31 100644 --- a/server/src/com/cloud/api/commands/DeleteIPForwardingRuleCmd.java +++ b/server/src/com/cloud/api/commands/DeletePortForwardingRuleCmd.java @@ -32,8 +32,8 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; @Implementation(description="Deletes a port forwarding rule") -public class DeleteIPForwardingRuleCmd extends BaseCmd { - public static final Logger s_logger = Logger.getLogger(DeleteIPForwardingRuleCmd.class.getName()); +public class DeletePortForwardingRuleCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(DeletePortForwardingRuleCmd.class.getName()); private static final String s_name = "deleteportforwardingruleresponse"; ///////////////////////////////////////////////////// @@ -63,7 +63,7 @@ public class DeleteIPForwardingRuleCmd extends BaseCmd { @Override public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ - boolean result = _networkMgr.deleteIpForwardingRule(this); + boolean result = _networkMgr.deletePortForwardingRule(this); if (result) { SuccessResponse response = new SuccessResponse(getName()); this.setResponseObject(response); diff --git a/server/src/com/cloud/api/commands/DeployVm2Cmd.java b/server/src/com/cloud/api/commands/DeployVm2Cmd.java index 75f56e5074c..ebf730f9a68 100644 --- a/server/src/com/cloud/api/commands/DeployVm2Cmd.java +++ b/server/src/com/cloud/api/commands/DeployVm2Cmd.java @@ -24,8 +24,8 @@ import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; import com.cloud.api.ApiDBUtils; +import com.cloud.api.ApiResponseHelper; import com.cloud.api.BaseAsyncCreateCmd; -import com.cloud.api.BaseCmd; import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; @@ -36,15 +36,10 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.offering.ServiceOffering; -import com.cloud.storage.VMTemplateVO; import com.cloud.user.Account; -import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; -import com.cloud.vm.InstanceGroupVO; @Implementation(description="Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.") public class DeployVm2Cmd extends BaseAsyncCreateCmd { @@ -161,127 +156,19 @@ public class DeployVm2Cmd extends BaseAsyncCreateCmd { /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @Override - public void execute() { - try { - UserVm userVm = _userVmService.startVirtualMachine(this); - - UserVmResponse response = new UserVmResponse(); - response.setId(userVm.getId()); - response.setName(userVm.getHostName()); - response.setCreated(userVm.getCreated()); - response.setZoneId(userVm.getDataCenterId()); - response.setZoneName(ApiDBUtils.findZoneById(userVm.getDataCenterId()).getName()); - response.setIpAddress(userVm.getPrivateIpAddress()); - response.setServiceOfferingId(userVm.getServiceOfferingId()); - response.setHaEnable(userVm.isHaEnabled()); - - InstanceGroupVO group = ApiDBUtils.findInstanceGroupForVM(userVm.getId()); - if (group != null) { - response.setGroup(group.getName()); - response.setGroupId(group.getId()); - } - - if (userVm.getDisplayName() == null || userVm.getDisplayName().length() == 0) { - response.setDisplayName(userVm.getHostName()); - } else { - response.setDisplayName(userVm.getDisplayName()); - } - - if (userVm.getState() != null) { - response.setState(userVm.getState().toString()); - } - - VMTemplateVO template = ApiDBUtils.findTemplateById(userVm.getTemplateId()); - - Account acct = ApiDBUtils.findAccountById(Long.valueOf(userVm.getAccountId())); - if (acct != null) { - response.setAccountName(acct.getAccountName()); - response.setDomainId(acct.getDomainId()); - response.setDomainName(ApiDBUtils.findDomainById(acct.getDomainId()).getName()); - } - - Long userId = UserContext.current().getUserId(); - if (userId == null) { - userId = User.UID_SYSTEM; - } - - //this is for the case where the admin deploys a vm for a normal user - User userExecutingCmd = ApiDBUtils.findUserById(userId); - Account acctForUserExecutingCmd = ApiDBUtils.findAccountById(Long.valueOf(userExecutingCmd.getAccountId())); - if ((BaseCmd.isAdmin(acctForUserExecutingCmd.getType()) && (userVm.getHostId() != null)) || (BaseCmd.isAdmin(acct.getType()) && (userVm.getHostId() != null))) { - response.setHostName(ApiDBUtils.findHostById(userVm.getHostId()).getName()); - response.setHostId(userVm.getHostId()); - } - - String templateName = "none"; - boolean templatePasswordEnabled = false; - String templateDisplayText = null; - - if (template != null) { - templateName = template.getName(); - templatePasswordEnabled = template.getEnablePassword(); - templateDisplayText = template.getDisplayText(); - if (templateDisplayText == null) { - templateDisplayText = templateName; - } - } - - if (templatePasswordEnabled) { // FIXME: where will the password come from in this case? - response.setPassword(getPassword()); - } - - // ISO Info - Long isoId = userVm.getIsoId(); - if (isoId != null) { - VMTemplateVO iso = ApiDBUtils.findTemplateById(isoId.longValue()); - if (iso != null) { - response.setIsoId(isoId.longValue()); - response.setIsoName(iso.getName()); - response.setTemplateId(isoId.longValue()); - response.setTemplateName(iso.getName()); - - templateDisplayText = iso.getDisplayText(); - if(templateDisplayText == null) - templateDisplayText = iso.getName(); - response.setIsoDisplayText(templateDisplayText); - response.setTemplateDisplayText(templateDisplayText); - } - } else { - response.setTemplateId(userVm.getTemplateId()); - response.setTemplateName(templateName); - response.setTemplateDisplayText(templateDisplayText); - response.setPasswordEnabled(templatePasswordEnabled); - } - - ServiceOffering offering = ApiDBUtils.findServiceOfferingById(userVm.getServiceOfferingId()); - response.setServiceOfferingId(userVm.getServiceOfferingId()); - response.setServiceOfferingName(offering.getName()); - - response.setCpuNumber(offering.getCpu()); - response.setCpuSpeed(offering.getSpeed()); - response.setMemory(offering.getRamSize()); - - response.setNetworkGroupList(ApiDBUtils.getNetworkGroupsNamesForVm(userVm.getId())); - + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException{ + UserVm result; + result = _userVmService.startVirtualMachine(this); + UserVmResponse response = ApiResponseHelper.createUserVm2Response(result); + response.setPassword(password); response.setResponseName(getName()); - response.setObjectName("virtualmachine"); this.setResponseObject(response); - } catch (Exception ex) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to deploy virtual machine"); - } } @Override - public void callCreate() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException, ResourceAllocationException{ - try { - UserVm vm = _userVmService.createVirtualMachine(this); - if (vm != null) { - this.setId(vm.getId()); - } - } catch (ResourceUnavailableException ex) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create a vm"); - } - + public void callCreate() throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + UserVm vm = _userVmService.createVirtualMachine(this); + this.setId(vm.getId()); } diff --git a/server/src/com/cloud/api/commands/StartSystemVm2Cmd.java b/server/src/com/cloud/api/commands/StartSystemVm2Cmd.java new file mode 100644 index 00000000000..dfd1cb677b5 --- /dev/null +++ b/server/src/com/cloud/api/commands/StartSystemVm2Cmd.java @@ -0,0 +1,103 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SystemVmResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.UserContext; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; + +@Implementation(method="startSystemVM", manager=ManagementServer.class, description="Starts a system virtual machine.") +public class StartSystemVm2Cmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(StartSystemVm2Cmd.class.getName()); + + private static final String s_name = "startsystemvmresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the system virtual machine") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + public static String getResultObjectName() { + return "systemvm"; + } + + @Override + public long getAccountId() { + Account account = UserContext.current().getAccount(); + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SSVM_START; + } + + @Override + public String getEventDescription() { + return "starting system vm: " + getId(); + } + + @Override + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ + VirtualMachine instance = _mgr.startSystemVm(this); + SystemVmResponse response = ApiResponseHelper.createSystemVmResponse((VMInstanceVO)instance); + response.setResponseName(getName()); + this.setResponseObject(response); + } +} diff --git a/server/src/com/cloud/api/commands/StopSystemVm2Cmd.java b/server/src/com/cloud/api/commands/StopSystemVm2Cmd.java new file mode 100644 index 00000000000..90a341ed3d9 --- /dev/null +++ b/server/src/com/cloud/api/commands/StopSystemVm2Cmd.java @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.api.commands; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiConstants; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.Implementation; +import com.cloud.api.Parameter; +import com.cloud.api.ServerApiException; +import com.cloud.api.response.SystemVmResponse; +import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.server.ManagementServer; +import com.cloud.user.Account; +import com.cloud.user.UserContext; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; + +@Implementation(method="stopSystemVM", manager=ManagementServer.class, description="Stops a system VM.") +public class StopSystemVm2Cmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(StopSystemVm2Cmd.class.getName()); + + private static final String s_name = "stopsystemvmresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the system virtual machine") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getName() { + return s_name; + } + + @Override + public long getAccountId() { + Account account = UserContext.current().getAccount(); + if (account != null) { + return account.getId(); + } + + return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked + } + + @Override + public String getEventType() { + return EventTypes.EVENT_SSVM_STOP; + } + + @Override + public String getEventDescription() { + return "stopping system vm: " + getId(); + } + + @Override + public void execute() throws ServerApiException, InvalidParameterValueException, PermissionDeniedException, InsufficientAddressCapacityException, InsufficientCapacityException, ConcurrentOperationException{ + VirtualMachine instance = _mgr.stopSystemVm(this); + SystemVmResponse response = ApiResponseHelper.createSystemVmResponse((VMInstanceVO)instance); + response.setResponseName(getName()); + } +} diff --git a/server/src/com/cloud/api/commands/UpdateIPForwardingRuleCmd.java b/server/src/com/cloud/api/commands/UpdatePortForwardingRuleCmd.java similarity index 91% rename from server/src/com/cloud/api/commands/UpdateIPForwardingRuleCmd.java rename to server/src/com/cloud/api/commands/UpdatePortForwardingRuleCmd.java index 352666d9fed..3674c320107 100644 --- a/server/src/com/cloud/api/commands/UpdateIPForwardingRuleCmd.java +++ b/server/src/com/cloud/api/commands/UpdatePortForwardingRuleCmd.java @@ -19,10 +19,10 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.network.FirewallRuleVO; import com.cloud.network.IPAddressVO; import com.cloud.user.Account; - + @Implementation(description="Updates a port forwarding rule. Only the private port and the virtual machine can be updated.") -public class UpdateIPForwardingRuleCmd extends BaseAsyncCmd { - public static final Logger s_logger = Logger.getLogger(UpdateIPForwardingRuleCmd.class.getName()); +public class UpdatePortForwardingRuleCmd extends BaseAsyncCmd { + public static final Logger s_logger = Logger.getLogger(UpdatePortForwardingRuleCmd.class.getName()); private static final String s_name = "updateportforwardingruleresponse"; ///////////////////////////////////////////////////// @@ -38,7 +38,7 @@ public class UpdateIPForwardingRuleCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, required=true, description="the protocol for the port fowarding rule. Valid values are TCP or UDP.") private String protocol; - @Parameter(name=ApiConstants.PUBLIC_IP, type=CommandType.STRING, required=true, description="the public IP address of the port forwarding rule") + @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required=true, description="the IP address of the port forwarding rule") private String publicIp; @Parameter(name=ApiConstants.PUBLIC_PORT, type=CommandType.STRING, required=true, description="the public port of the port forwarding rule") diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index f4daf1068b8..55e279909fd 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -48,7 +48,7 @@ public enum Config { StorageOverprovisioningFactor("Storage", StoragePoolAllocator.class, String.class, "storage.overprovisioning.factor", "2", "Used for storage overprovisioning calculation; available storage will be (actualStorageSize * storage.overprovisioning.factor)", null), StorageStatsInterval("Storage", ManagementServer.class, String.class, "storage.stats.interval", "60000", "The interval in milliseconds when storage stats (per host) are retrieved from agents.", null), - MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.gb", "2000", "The maximum size for a volume in gigabytes.", null), + MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "max.volume.size.mb", "1024000", "The maximum size for a volume in megabytes.", null), TotalRetries("Storage", AgentManager.class, Integer.class, "total.retries", "4", "The number of times each command sent to a host should be retried in case of failure.", null), // Network diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 07ad08574a8..eae74424666 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -52,16 +52,18 @@ import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.AccountVlanMapVO; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; import com.cloud.dc.Vlan; -import com.cloud.dc.VlanVO; import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; +import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.PodVlanMapDao; import com.cloud.dc.dao.VlanDao; @@ -81,8 +83,8 @@ import com.cloud.network.NetworkManager; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; -import com.cloud.offering.ServiceOffering; import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -97,6 +99,7 @@ import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.Adapters; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; @@ -140,6 +143,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Inject NetworkManager _networkMgr; @Inject(adapter=SecurityChecker.class) Adapters _secChecker; + + //FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao? + protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); private int _maxVolumeSizeInGb; @@ -437,14 +443,27 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura HostPodVO pod = _podDao.findById(podId); DataCenterVO zone = _zoneDao.findById(pod.getDataCenterId()); + + //Delete private ip addresses for the pod if there are any + List privateIps = _privateIpAddressDao.listByPodIdDcId(Long.valueOf(podId), pod.getDataCenterId()); + if (privateIps != null && privateIps.size() != 0) { + if (!(_privateIpAddressDao.deleteIpAddressByPod(podId))) { + throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); + } + } + + //Delete link local ip addresses for the pod + if (!(_LinkLocalIpAllocDao.deleteIpAddressByPod(podId))) { + throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); + } - //Delete the pod and private IP addresses in the pod - if (_podDao.expunge(podId) && _privateIpAddressDao.deleteIpAddressByPod(podId)) { - saveConfigurationEvent(userId, null, EventTypes.EVENT_POD_DELETE, "Successfully deleted pod with name: " + pod.getName() + " in zone: " + zone.getName() + ".", "podId=" + podId, "dcId=" + zone.getId()); - return true; - } else { - return false; + //Delete the pod + if (!(_podDao.expunge(podId))) { + throw new CloudRuntimeException("Failed to delete pod " + podId); } + + saveConfigurationEvent(userId, null, EventTypes.EVENT_POD_DELETE, "Successfully deleted pod with name: " + pod.getName() + " in zone: " + zone.getName() + ".", "podId=" + podId, "dcId=" + zone.getId()); + return true; } @Override @@ -974,7 +993,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura @Override @DB public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String vnetRange, String guestCidr, String domain, Long domainId) { - int vnetStart, vnetEnd; + int vnetStart = -1; + int vnetEnd = -1; if (vnetRange != null) { String[] tokens = vnetRange.split("-"); @@ -993,9 +1013,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (networkType != null && networkType.equals("vnet")) { vnetStart = 1000; vnetEnd = 2000; - } else { - throw new InvalidParameterValueException("Please specify a vlan range."); - } + } } //checking the following params outside checkzoneparams method as we do not use these params for updatezone @@ -1011,8 +1029,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura zone = _zoneDao.persist(zone); // Add vnet entries for the new zone - _zoneDao.addVnet(zone.getId(), vnetStart, vnetEnd); - + if (vnetStart != -1 && vnetEnd != -1) { + _zoneDao.addVnet(zone.getId(), vnetStart, vnetEnd); + } saveConfigurationEvent(userId, null, EventTypes.EVENT_ZONE_CREATE, "Successfully created new zone with name: " + zoneName + ".", "dcId=" + zone.getId(), "dns1=" + dns1, "dns2=" + dns2, "internalDns1=" + internalDns1, "internalDns2=" + internalDns2, "vnetRange=" + vnetRange, "guestCidr=" + guestCidr); return zone; diff --git a/server/src/com/cloud/hypervisor/KVMGuru.java b/server/src/com/cloud/hypervisor/KVMGuru.java new file mode 100644 index 00000000000..32527dc5b88 --- /dev/null +++ b/server/src/com/cloud/hypervisor/KVMGuru.java @@ -0,0 +1,37 @@ +package com.cloud.hypervisor; + +import javax.ejb.Local; + +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.utils.component.Inject; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value=HypervisorGuru.class) +public class KVMGuru extends HypervisorGuruBase implements HypervisorGuru { + @Inject GuestOSDao _guestOsDao; + @Override + public HypervisorType getHypervisorType() { + return HypervisorType.KVM; + } + + protected KVMGuru() { + super(); + } + + @Override + public VirtualMachineTO implement( + VirtualMachineProfile vm) { + VirtualMachineTO to = toVirtualMachineTO(vm); + + // Determine the VM's OS description + GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); + to.setOs(guestOS.getDisplayName()); + + return to; + } + +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 403d45cb372..54fec363354 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -20,13 +20,16 @@ package com.cloud.network; import java.util.List; import java.util.Map; +import com.cloud.api.ServerApiException; import com.cloud.api.commands.AddVpnUserCmd; import com.cloud.api.commands.AssignToLoadBalancerRuleCmd; import com.cloud.api.commands.AssociateIPAddrCmd; -import com.cloud.api.commands.CreateIPForwardingRuleCmd; +import com.cloud.api.commands.CreateIpForwardingRuleCmd; +import com.cloud.api.commands.CreatePortForwardingRuleCmd; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; import com.cloud.api.commands.CreateRemoteAccessVpnCmd; -import com.cloud.api.commands.DeleteIPForwardingRuleCmd; +import com.cloud.api.commands.DeleteIpForwardingRuleCmd; +import com.cloud.api.commands.DeletePortForwardingRuleCmd; import com.cloud.api.commands.DeleteLoadBalancerRuleCmd; import com.cloud.api.commands.DeleteRemoteAccessVpnCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; @@ -61,11 +64,12 @@ import com.cloud.user.AccountVO; import com.cloud.utils.Pair; import com.cloud.vm.DomainRouter; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -210,7 +214,7 @@ public interface NetworkManager { * @param cmd the command specifying the ip address, public port, protocol, private port, and virtual machine id. * @return the newly created FirewallRuleVO if successful, null otherwise. */ - public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws NetworkRuleConflictException; + public FirewallRuleVO createPortForwardingRule(CreatePortForwardingRuleCmd cmd) throws NetworkRuleConflictException; /** * List port forwarding rules assigned to an ip address @@ -302,8 +306,6 @@ public interface NetworkManager { List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat); public boolean disassociateIpAddress(DisassociateIPAddrCmd cmd); - - public boolean deleteIpForwardingRule(DeleteIPForwardingRuleCmd cmd); List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, DeploymentPlan plan); List setupNetworkConfiguration(Account owner, NetworkOfferingVO offering, NetworkConfiguration predefined, DeploymentPlan plan); @@ -316,7 +318,7 @@ public interface NetworkManager { void release(VirtualMachineProfile vmProfile); DomainRouter upgradeRouter(UpgradeRouterCmd cmd); - List getNics(VMInstanceVO vm); + List getNics (VirtualMachine vm); List getAccountsUsingNetworkConfiguration(long configurationId); AccountVO getNetworkConfigurationOwner(long configurationId); @@ -357,5 +359,14 @@ public interface NetworkManager { boolean removeVpnUser(RemoveVpnUserCmd cmd) throws ConcurrentOperationException; - String getNextAvailableMacAddressInNetwork(long networkConfigurationId); + NetworkConfiguration getNetworkConfiguration(long id); + String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException; + + FirewallRuleVO createIpForwardingRuleInDb(String ipAddr, Long virtualMachineId) throws ServerApiException; + + public boolean deletePortForwardingRule(DeletePortForwardingRuleCmd cmd); + + FirewallRuleVO createIpForwardingRuleOnDomr(Long ruleId); + + boolean deleteIpForwardingRule(Long id); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index f7af2a0352b..cc7f193ad33 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -49,10 +49,12 @@ import com.cloud.api.ServerApiException; import com.cloud.api.commands.AddVpnUserCmd; import com.cloud.api.commands.AssignToLoadBalancerRuleCmd; import com.cloud.api.commands.AssociateIPAddrCmd; -import com.cloud.api.commands.CreateIPForwardingRuleCmd; +import com.cloud.api.commands.CreateIpForwardingRuleCmd; +import com.cloud.api.commands.CreatePortForwardingRuleCmd; import com.cloud.api.commands.CreateLoadBalancerRuleCmd; import com.cloud.api.commands.CreateRemoteAccessVpnCmd; -import com.cloud.api.commands.DeleteIPForwardingRuleCmd; +import com.cloud.api.commands.DeleteIpForwardingRuleCmd; +import com.cloud.api.commands.DeletePortForwardingRuleCmd; import com.cloud.api.commands.DeleteLoadBalancerRuleCmd; import com.cloud.api.commands.DeleteRemoteAccessVpnCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; @@ -156,13 +158,16 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouter; import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; import com.cloud.vm.State; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; @@ -727,7 +732,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Pair ipAndVlan = _vlanDao.assignIpAddress(zoneId, accountId, domainId, VlanType.VirtualNetwork, false); if (ipAndVlan == null) { - throw new InsufficientAddressCapacityException("Unable to find available public IP addresses"); + throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zoneId); } else { ipAddress = ipAndVlan.first(); _accountMgr.incrementResourceCount(accountId, ResourceType.public_ip); @@ -892,7 +897,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (rule.isForwarding()) { fwdRules.add(rule); - final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp, rule); + final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(routerName, routerIp, false, rule, false); cmds.addCommand(cmd); } else { lbRules.add(rule); @@ -971,7 +976,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag rule.setVlanNetmask(vlanNetmask); if (rule.isForwarding()) { fwdRules.add(rule); - final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), rule); + final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), false, rule, false); cmds.addCommand(cmd); } } @@ -999,7 +1004,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public FirewallRuleVO createPortForwardingRule(CreateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException { + public FirewallRuleVO createPortForwardingRule(CreatePortForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException, NetworkRuleConflictException { // validate IP Address exists IPAddressVO ipAddress = _ipAddressDao.findById(cmd.getIpAddress()); if (ipAddress == null) { @@ -1376,6 +1381,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag EventUtils.saveEvent(UserContext.current().getUserId(), loadBalancer.getAccountId(), level, type, description); } } + return true; } else { // Remove the instanceIds from the load balancer since there was a failure. Make sure to commit the // transaction here, otherwise the act of throwing the internal error exception will cause this @@ -1391,7 +1397,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _loadBalancerDao.releaseFromLockTable(loadBalancerId); } } - return true; } @Override @DB @@ -2086,7 +2091,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public List getNics(VMInstanceVO vm) { + public List getNics(VirtualMachine vm) { return _nicDao.listBy(vm.getId()); } @@ -2507,7 +2512,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override @DB - public boolean deleteIpForwardingRule(DeleteIPForwardingRuleCmd cmd) { + public boolean deletePortForwardingRule(DeletePortForwardingRuleCmd cmd) { Long ruleId = cmd.getId(); Long userId = UserContext.current().getUserId(); Account account = UserContext.current().getAccount(); @@ -2921,7 +2926,247 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) { - return _networkConfigDao.getNextAvailableMacAddress(networkConfigurationId); + public String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException { + String mac = _networkConfigDao.getNextAvailableMacAddress(networkConfigurationId); + if (mac == null) { + throw new InsufficientAddressCapacityException("Unable to create another mac address", NetworkConfiguration.class, networkConfigurationId); + } + return mac; } + + @Override + public NetworkConfiguration getNetworkConfiguration(long id) { + return _networkConfigDao.findById(id); + } + + @Override + public FirewallRuleVO createIpForwardingRuleOnDomr(Long ruleId) throws ServerApiException{ + boolean success = false; + //get the rule + FirewallRuleVO rule = _rulesDao.findById(ruleId); + + if(rule == null){ + throw new PermissionDeniedException("Cannot create ip forwarding rule in db"); + } + + //get ip address + IPAddressVO ipAddress = _ipAddressDao.findById(rule.getPublicIpAddress()); + if (ipAddress == null) { + throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified."); + } + + //get the domain router object + DomainRouterVO router = _routerMgr.getRouter(ipAddress.getAccountId(), ipAddress.getDataCenterId()); + success = createOrDeleteIpForwardingRuleOnDomr(rule,router,rule.getPrivateIpAddress(),true); //true +> create + + if(!success){ + //corner case; delete record from db as domR rule creation failed + try { + _rulesDao.remove(ruleId); + throw new PermissionDeniedException("Cannot create ip forwarding rule on domr, hence deleting created record in db"); + } catch (Exception e) { + throw new ServerApiException(BaseCmd.NET_CREATE_IPFW_RULE_ERROR, e.getMessage()); + } + } + + // Save and create the event + String description; + String ruleName = "ip forwarding"; + String level = EventVO.LEVEL_INFO; + + description = "created new " + ruleName + " rule [" + rule.getPublicIpAddress() + "]->[" + + rule.getPrivateIpAddress() + "]" + ":" + rule.getProtocol(); + + EventUtils.saveEvent(UserContext.current().getUserId(), ipAddress.getAccountId(), level, EventTypes.EVENT_NET_RULE_ADD, description); + + return rule; + + } + + @Override @DB + public FirewallRuleVO createIpForwardingRuleInDb(String ipAddr, Long virtualMachineId) throws ServerApiException { + + Transaction txn = Transaction.currentTxn(); + txn.start(); + UserVmVO userVM = null; + FirewallRuleVO newFwRule = null; + boolean locked = false; + try { + // validate IP Address exists + IPAddressVO ipAddress = _ipAddressDao.findById(ipAddr); + if (ipAddress == null) { + throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid IP address specified."); + } + + // validate user VM exists + userVM = _vmDao.findById(virtualMachineId); + if (userVM == null) { + throw new InvalidParameterValueException("Unable to create ip forwarding rule on address " + ipAddress + ", invalid virtual machine id specified (" + virtualMachineId + ")."); + } + + //sync point; cannot lock on rule ; hence sync on vm + userVM = _vmDao.acquireInLockTable(userVM.getId()); + + if(userVM == null){ + s_logger.warn("Unable to acquire lock on user vm for creating 1-1 NAT rule"); + return newFwRule; + }else{ + locked = true; + } + + // validate that IP address and userVM belong to the same account + if ((ipAddress.getAccountId() == null) || (ipAddress.getAccountId().longValue() != userVM.getAccountId())) { + throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress + " owner is not the same as owner of virtual machine " + userVM.toString()); + } + + // validate that userVM is in the same availability zone as the IP address + if (ipAddress.getDataCenterId() != userVM.getDataCenterId()) { + throw new InvalidParameterValueException("Unable to create ip forwarding rule, IP address " + ipAddress + " is not in the same availability zone as virtual machine " + userVM.toString()); + } + + // if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters + Account account = UserContext.current().getAccount(); + if (account != null) { + if ((account.getType() == Account.ACCOUNT_TYPE_ADMIN) || (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) { + if (!_domainDao.isChildDomain(account.getDomainId(), userVM.getDomainId())) { + throw new PermissionDeniedException("Unable to create ip forwarding rule, IP address " + ipAddress + " to virtual machine " + virtualMachineId + ", permission denied."); + } + } else if (account.getId() != userVM.getAccountId()) { + throw new PermissionDeniedException("Unable to create ip forwarding rule, IP address " + ipAddress + " to virtual machine " + virtualMachineId + ", permission denied."); + } + } + + // check for ip address/port conflicts by checking existing forwarding and load balancing rules + List existingNatRules = _rulesDao.findByPublicIpPrivateIpForNatRule(ipAddr, userVM.getGuestIpAddress()); + + if(existingNatRules.size() > 0){ + throw new NetworkRuleConflictException("The specified rule for public ip:"+ipAddr+" vm id:"+virtualMachineId+" already exists"); + } + + newFwRule = new FirewallRuleVO(); + newFwRule.setEnabled(true); + newFwRule.setForwarding(true); + newFwRule.setPrivatePort(null); + newFwRule.setProtocol("NAT");//protocol cannot be null; adding this as a NAT + newFwRule.setPublicPort(null); + newFwRule.setPublicIpAddress(ipAddress.getAddress()); + newFwRule.setPrivateIpAddress(userVM.getGuestIpAddress()); + newFwRule.setGroupId(null); + + _rulesDao.persist(newFwRule); + txn.commit(); + } catch (Exception e) { + s_logger.warn("Unable to create new firewall rule for 1:1 NAT"); + txn.rollback(); + throw new ServerApiException(BaseCmd.IP_ALLOCATION_ERROR,"Unable to create new firewall rule for 1:1 NAT:"+e.getMessage()); + }finally{ + if(locked) + _vmDao.releaseFromLockTable(userVM.getId()); + } + + return newFwRule; + } + + @Override @DB + public boolean deleteIpForwardingRule(Long id) { + Long ruleId = id; + Long userId = UserContext.current().getUserId(); + Account account = UserContext.current().getAccount(); + + //verify input parameters here + FirewallRuleVO rule = _firewallRulesDao.findById(ruleId); + if (rule == null) { + throw new InvalidParameterValueException("Unable to find port forwarding rule " + ruleId); + } + + String publicIp = rule.getPublicIpAddress(); + + + IPAddressVO ipAddress = _ipAddressDao.findById(publicIp); + if (ipAddress == null) { + throw new InvalidParameterValueException("Unable to find IP address for ip forwarding rule " + ruleId); + } + + // although we are not writing these values to the DB, we will check + // them out of an abundance + // of caution (may not be warranted) + + Account ruleOwner = _accountDao.findById(ipAddress.getAccountId()); + if (ruleOwner == null) { + throw new InvalidParameterValueException("Unable to find owning account for ip forwarding rule " + ruleId); + } + + // if an admin account was passed in, or no account was passed in, make sure we honor the accountName/domainId parameters + if (account != null) { + if (isAdmin(account.getType())) { + if (!_domainDao.isChildDomain(account.getDomainId(), ruleOwner.getDomainId())) { + throw new PermissionDeniedException("Unable to delete ip forwarding rule " + ruleId + ", permission denied."); + } + } else if (account.getId() != ruleOwner.getId()) { + throw new PermissionDeniedException("Unable to delete ip forwarding rule " + ruleId + ", permission denied."); + } + } + + Transaction txn = Transaction.currentTxn(); + boolean locked = false; + boolean success = false; + try { + + ipAddress = _ipAddressDao.acquireInLockTable(publicIp); + if (ipAddress == null) { + throw new PermissionDeniedException("Unable to obtain lock on record for deletion"); + } + + locked = true; + txn.start(); + + final DomainRouterVO router = _routerMgr.getRouter(ipAddress.getAccountId(), ipAddress.getDataCenterId()); + success = createOrDeleteIpForwardingRuleOnDomr(rule, router, rule.getPrivateIpAddress(), false); + _firewallRulesDao.remove(ruleId); + + String description; + String type = EventTypes.EVENT_NET_RULE_DELETE; + String level = EventVO.LEVEL_INFO; + String ruleName = rule.isForwarding() ? "ip forwarding" : "load balancer"; + + if (success) { + description = "deleted " + ruleName + " rule [" + publicIp +"]->[" + rule.getPrivateIpAddress() + "] " + rule.getProtocol(); + } else { + level = EventVO.LEVEL_ERROR; + description = "Error while deleting " + ruleName + " rule [" + publicIp + "]->[" + rule.getPrivateIpAddress() +"] " + rule.getProtocol(); + } + EventUtils.saveEvent(userId, ipAddress.getAccountId(), level, type, description); + txn.commit(); + }catch (Exception ex) { + txn.rollback(); + s_logger.error("Unexpected exception deleting port forwarding rule " + ruleId, ex); + return false; + }finally { + if (locked) { + _ipAddressDao.releaseFromLockTable(publicIp); + } + txn.close(); + } + return success; + } + + private boolean createOrDeleteIpForwardingRuleOnDomr(FirewallRuleVO fwRule, DomainRouterVO router, String guestIp, boolean create){ + + Commands cmds = new Commands(OnError.Continue); + final SetFirewallRuleCommand cmd = new SetFirewallRuleCommand(router.getInstanceName(), router.getPrivateIpAddress(), true, fwRule, create); + cmds.addCommand(cmd); + try { + _agentMgr.send(router.getHostId(), cmds); + } catch (final AgentUnavailableException e) { + s_logger.warn("agent unavailable", e); + } catch (final OperationTimedoutException e) { + s_logger.warn("Timed Out", e); + } + Answer[] answers = cmds.getAnswers(); + if (answers == null || answers[0].getResult() == false ){ + return false; + }else{ + return true; + } + } } diff --git a/server/src/com/cloud/network/configuration/ControlNetworkGuru.java b/server/src/com/cloud/network/configuration/ControlNetworkGuru.java index 3df93604afe..ffda1027d96 100644 --- a/server/src/com/cloud/network/configuration/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/ControlNetworkGuru.java @@ -140,4 +140,9 @@ public class ControlNetworkGuru extends AdapterBase implements NetworkGuru { return true; } + @Override + public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) { + return true; + } + } diff --git a/server/src/com/cloud/network/configuration/GuestNetworkGuru.java b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java index ec13b100fd1..1e6814e9d76 100644 --- a/server/src/com/cloud/network/configuration/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java @@ -174,7 +174,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (nic.getMacAddress() == null) { nic.setMacAddress(_networkMgr.getNextAvailableMacAddressInNetwork(config.getId())); if (nic.getMacAddress() == null) { - throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses"); + throw new InsufficientAddressCapacityException("Unable to allocate more mac addresses", NetworkConfiguration.class, config.getId()); } } @@ -225,4 +225,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { public void destroy(NetworkConfiguration config, NetworkOffering offering) { config.getBroadcastUri(); } + + @Override + public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) { + // TODO Auto-generated method stub + return true; + } } diff --git a/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java index 7883d2315f1..eddc5698434 100644 --- a/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java @@ -83,7 +83,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { String ip = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), dest.getPod().getId(), nic.getId(), context.getReservationId()); if (ip == null) { - throw new InsufficientAddressCapacityException("Unable to get a management ip address"); + throw new InsufficientAddressCapacityException("Unable to get a management ip address", Pod.class, pod.getId()); } nic.setIp4Address(ip); @@ -108,4 +108,9 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { @Override public void destroy(NetworkConfiguration config, NetworkOffering offering) { } + + @Override + public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) { + return true; + } } diff --git a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java index 54b36829a9f..7dcc049567f 100644 --- a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java @@ -62,7 +62,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { if (nic.getIp4Address() == null) { Pair ipAndVlan = _vlanDao.assignIpAddress(dc.getId(), vm.getVirtualMachine().getAccountId(), vm.getVirtualMachine().getDomainId(), VlanType.VirtualNetwork, true); if (ipAndVlan == null) { - throw new InsufficientVirtualNetworkCapcityException("Unable to get public ip address in " + dc.getId()); + throw new InsufficientVirtualNetworkCapcityException("Unable to get public ip address in " + dc.getId(), DataCenter.class, dc.getId()); } VlanVO vlan = ipAndVlan.second(); nic.setIp4Address(ipAndVlan.first()); @@ -92,9 +92,6 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } String mac = _networkMgr.getNextAvailableMacAddressInNetwork(config.getId()); - if (mac == null) { - throw new InsufficientAddressCapacityException("Not enough mac addresses"); - } nic.setMacAddress(mac); DataCenter dc = _dcDao.findById(config.getDataCenterId()); @@ -128,4 +125,9 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { @Override public void destroy(NetworkConfiguration config, NetworkOffering offering) { } + + @Override + public boolean trash(NetworkConfiguration config, NetworkOffering offering, Account owner) { + return true; + } } diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java index 8adea84dcc0..8d1ed5a0e0a 100644 --- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java +++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java @@ -2131,6 +2131,8 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { NicProfile controlNic = (NicProfile)profile.getParameter("control.nic"); cmds.addCommand("checkSsh", new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922, 5, 20)); + + return true; } @@ -2371,7 +2373,11 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute @Override public DomainRouter stopRouter(StopRouter2Cmd cmd) throws ResourceUnavailableException, ConcurrentOperationException { Long routerId = cmd.getId(); - Account account = UserContext.current().getAccount(); + UserContext context = UserContext.current(); + Account account = context.getAccount(); + long accountId = context.getAccountId(); + long userId = context.getUserId(); + // verify parameters DomainRouterVO router = _routerDao.findById(routerId); @@ -2381,9 +2387,9 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute _accountMgr.checkAccess(account, router); - long eventId = EventUtils.saveScheduledEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_ROUTER_STOP, "stopping Router with Id: "+routerId); + long eventId = EventUtils.saveScheduledEvent(userId, accountId, EventTypes.EVENT_ROUTER_STOP, "stopping Router with Id: "+routerId); - UserVO user = _userDao.findById(UserContext.current().getUserId()); + UserVO user = _userDao.findById(context.getUserId()); try { if (!_itMgr.stop(router, user, account)) { @@ -2397,4 +2403,73 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute return router; } + + private boolean resendRouterState(NetworkConfiguration config, DomainRouterVO router, Commands cmds) { + if (router.getRole() == Role.DHCP_FIREWALL_LB_PASSWD_USERDATA) { + //source NAT address is stored in /proc/cmdline of the domR and gets + //reassigned upon powerup. Source NAT rule gets configured in StartRouter command + List ipAddrs = _networkMgr.listPublicIpAddressesInVirtualNetwork(router.getAccountId(), router.getDataCenterId(), null); + List ipAddrList = new ArrayList(); + for (final IPAddressVO ipVO : ipAddrs) { + ipAddrList.add(ipVO.getAddress()); + } + if (!ipAddrList.isEmpty()) { + try { + final boolean success = _networkMgr.associateIP(router, ipAddrList, true, 0); + if (!success) { + return false; + } + } catch (ConcurrentOperationException e) { + s_logger.warn("unable to associate ip due to ", e); + return false; + } + } + final List fwRules = new ArrayList(); + for (final IPAddressVO ipVO : ipAddrs) { + fwRules.addAll(_rulesDao.listIPForwarding(ipVO.getAddress())); + } + final List result = _networkMgr.updateFirewallRules(router + .getPublicIpAddress(), fwRules, router); + if (result.size() != fwRules.size()) { + return false; + } + } + return resendDhcpEntries(router) && resendVpnServerData(router); + + } + + private boolean resendDhcpEntries(NetworkConfiguration config, DomainRouterVO router, Commands cmd){ + final List vms = _vmDao.listBy(router.getId(), State.Creating, State.Starting, State.Running, State.Stopping, State.Stopped, State.Migrating); + Commands cmds = new Commands(OnError.Continue); + for (UserVmVO vm: vms) { + if (vm.getGuestIpAddress() == null || vm.getGuestMacAddress() == null || vm.getHostName() == null) + continue; + DhcpEntryCommand decmd = new DhcpEntryCommand(vm.getGuestMacAddress(), vm.getGuestIpAddress(), router.getPrivateIpAddress(), vm.getHostName()); + cmds.addCommand(decmd); + } + if (cmds.size() > 0) { + try { + _agentMgr.send(router.getHostId(), cmds); + } catch (final AgentUnavailableException e) { + s_logger.warn("agent unavailable", e); + } catch (final OperationTimedoutException e) { + s_logger.warn("Timed Out", e); + } + Answer[] answers = cmds.getAnswers(); + if (answers == null ){ + return false; + } + int i=0; + while (i < cmds.size()) { + Answer ans = answers[i]; + i++; + if ((ans != null) && (ans.getResult())) { + continue; + } else { + return false; + } + } + } + return true; + } } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index e86dc14b6c8..73db6a9fec3 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -71,9 +71,11 @@ import com.cloud.api.commands.RebootSystemVmCmd; import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.RegisterPreallocatedLunCmd; import com.cloud.api.commands.StartSystemVMCmd; +import com.cloud.api.commands.StartSystemVm2Cmd; +import com.cloud.api.commands.StopSystemVm2Cmd; import com.cloud.api.commands.StopSystemVmCmd; import com.cloud.api.commands.UpdateDomainCmd; -import com.cloud.api.commands.UpdateIPForwardingRuleCmd; +import com.cloud.api.commands.UpdatePortForwardingRuleCmd; import com.cloud.api.commands.UpdateIsoCmd; import com.cloud.api.commands.UpdateIsoPermissionsCmd; import com.cloud.api.commands.UpdateTemplateCmd; @@ -144,6 +146,7 @@ import com.cloud.vm.VirtualMachine; */ public interface ManagementServer { static final String Name = "management-server"; + List listClusterByPodId(long podId); @@ -549,10 +552,10 @@ public interface ManagementServer { /** * Update an existing port forwarding rule on the given public IP / public port for the given protocol - * @param cmd - the UpdateIPForwardingRuleCmd command that wraps publicIp, privateIp, publicPort, privatePort, protocol of the rule to update + * @param cmd - the UpdatePortForwardingRuleCmd command that wraps publicIp, privateIp, publicPort, privatePort, protocol of the rule to update * @return the new firewall rule if updated, null if no rule on public IP / public port of that protocol could be found */ - FirewallRuleVO updatePortForwardingRule(UpdateIPForwardingRuleCmd cmd); + FirewallRuleVO updatePortForwardingRule(UpdatePortForwardingRuleCmd cmd); /** * Find a firewall rule by rule id @@ -679,6 +682,9 @@ public interface ManagementServer { VMInstanceVO stopSystemVM(StopSystemVmCmd cmd); VMInstanceVO startSystemVM(StartSystemVMCmd cmd); VMInstanceVO rebootSystemVM(RebootSystemVmCmd cmd); + + VirtualMachine startSystemVm(StartSystemVm2Cmd cmd); + VirtualMachine stopSystemVm(StopSystemVm2Cmd cmd); /** * Returns a configuration value with the specified name diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 72f7a626bcc..05826ca5145 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -121,9 +121,11 @@ import com.cloud.api.commands.RebootSystemVmCmd; import com.cloud.api.commands.RegisterCmd; import com.cloud.api.commands.RegisterPreallocatedLunCmd; import com.cloud.api.commands.StartSystemVMCmd; +import com.cloud.api.commands.StartSystemVm2Cmd; +import com.cloud.api.commands.StopSystemVm2Cmd; import com.cloud.api.commands.StopSystemVmCmd; import com.cloud.api.commands.UpdateDomainCmd; -import com.cloud.api.commands.UpdateIPForwardingRuleCmd; +import com.cloud.api.commands.UpdatePortForwardingRuleCmd; import com.cloud.api.commands.UpdateIsoCmd; import com.cloud.api.commands.UpdateIsoPermissionsCmd; import com.cloud.api.commands.UpdateTemplateCmd; @@ -391,7 +393,7 @@ public class ManagementServerImpl implements ManagementServer { private final int _routerRamSize; private final int _proxyRamSize; private final int _ssRamSize; - private int _maxVolumeSizeInGb; + private int _maxVolumeSizeInMb; private final Map _availableIdsMap; @@ -510,9 +512,9 @@ public class ManagementServerImpl implements ManagementServer { _networkGroupsEnabled = true; } - String maxVolumeSizeInGbString = _configDao.getValue("max.volume.size.gb"); - int maxVolumeSizeGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, 2000); - _maxVolumeSizeInGb = maxVolumeSizeGb; + String maxVolumeSizeInMbString = _configDao.getValue("max.volume.size.gb"); + int maxVolumeSizeMb = NumbersUtil.parseInt(maxVolumeSizeInMbString, (2000*1024));//2000 gb + _maxVolumeSizeInMb = maxVolumeSizeMb; } protected Map getConfigs() { @@ -1214,8 +1216,8 @@ public class ManagementServerImpl implements ManagementServer { throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering has no size set"); } - if(diskOffering != null && diskOffering.isCustomized() && size > _maxVolumeSizeInGb){ - throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering max size is:"+_maxVolumeSizeInGb); + if(diskOffering != null && diskOffering.isCustomized() && size > _maxVolumeSizeInMb){ + throw new InvalidParameterValueException("Please specify a valid disk size for VM creation; custom disk offering max size is:"+_maxVolumeSizeInMb); } // validate that the template is usable by the account @@ -1489,10 +1491,10 @@ public class ManagementServerImpl implements ManagementServer { // default domainId to the admin's domain domainId = ((account == null) ? DomainVO.ROOT_DOMAIN : account.getDomainId()); } - + Filter searchFilter = new Filter(UserAccountVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); - Object id = cmd.getId(); + Long id = cmd.getId(); Object username = cmd.getUsername(); Object type = cmd.getAccountType(); Object accountName = cmd.getAccountName(); @@ -1501,7 +1503,17 @@ public class ManagementServerImpl implements ManagementServer { SearchBuilder sb = _userAccountDao.createSearchBuilder(); sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + if (id != null && id == 1) { + //system user should NOT be searchable + List emptyList = new ArrayList(); + return emptyList; + } else if (id != null) { + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + } else { + //this condition is used to exclude system user from the search results + sb.and("id", sb.entity().getId(), SearchCriteria.Op.NEQ); + } + sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.LIKE); @@ -1534,6 +1546,9 @@ public class ManagementServerImpl implements ManagementServer { if (id != null) { sc.setParameters("id", id); + } else { + //Don't return system user, search builder with NEQ + sc.setParameters("id", 1); } if (type != null) { @@ -2565,7 +2580,7 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public FirewallRuleVO updatePortForwardingRule(UpdateIPForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{ + public FirewallRuleVO updatePortForwardingRule(UpdatePortForwardingRuleCmd cmd) throws InvalidParameterValueException, PermissionDeniedException{ String publicIp = cmd.getPublicIp(); String privateIp = cmd.getPrivateIp(); String privatePort = cmd.getPrivatePort(); @@ -3462,7 +3477,13 @@ public class ManagementServerImpl implements ManagementServer { Filter searchFilter = new Filter(DomainVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); Long domainId = cmd.getId(); String domainName = cmd.getDomainName(); + Boolean isRecursive = cmd.isRecursive(); Object keyword = cmd.getKeyword(); + List domainList = null; + + if (isRecursive == null) { + isRecursive = false; + } Account account = UserContext.current().getAccount(); if (account != null) { @@ -3475,12 +3496,24 @@ public class ManagementServerImpl implements ManagementServer { } } - return searchForDomainChildren(searchFilter, domainId, domainName, - keyword); + domainList = searchForDomainChildren(searchFilter, domainId, domainName, + keyword, null); + + if (isRecursive) { + List childDomains = new ArrayList(); + for (DomainVO domain : domainList) { + String path = domain.getPath(); + childDomains.addAll(searchForDomainChildren(searchFilter, null, null, + null, path)); + } + return childDomains; + } else { + return domainList; + } } private List searchForDomainChildren(Filter searchFilter, - Long domainId, String domainName, Object keyword) { + Long domainId, String domainName, Object keyword, String path) { SearchCriteria sc = _domainDao.createSearchCriteria(); if (keyword != null) { @@ -3497,6 +3530,10 @@ public class ManagementServerImpl implements ManagementServer { if (domainName != null) { sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + domainName + "%"); } + + if (path != null) { + sc.addAnd("path", SearchCriteria.Op.LIKE, path + "%"); + } return _domainDao.search(sc, searchFilter); } @@ -4796,6 +4833,76 @@ public class ManagementServerImpl implements ManagementServer { } } + @Override + public VirtualMachine startSystemVm(StartSystemVm2Cmd cmd) { + UserContext context = UserContext.current(); + long callerId = context.getUserId(); + long callerAccountId = context.getAccountId(); + + //verify input + Long id = cmd.getId(); + + VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); + if (systemVm == null) { + throw new InvalidParameterValueException("unable to find a system vm with id " + id); + } + + if (systemVm.getType() == VirtualMachine.Type.ConsoleProxy) { + long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_PROXY_START, "Starting console proxy with Id: "+id); + try { + checkIfStoragePoolAvailable(id); + } catch (StorageUnavailableException e) { + s_logger.warn(e.getMessage()); + return null; + } catch (Exception e){ + //unforseen exceptions + s_logger.warn(e.getMessage()); + return null; + } + return startConsoleProxy(id, eventId); + } else if (systemVm.getType() == VirtualMachine.Type.SecondaryStorageVm) { + long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_SSVM_START, "Starting secondary storage Vm Id: "+id); + try { + checkIfStoragePoolAvailable(id); + } catch (StorageUnavailableException e) { + s_logger.warn(e.getMessage()); + return null; + } catch (Exception e){ + //unforseen exceptions + s_logger.warn(e.getMessage()); + return null; + } + return startSecondaryStorageVm(id, eventId); + } else { + throw new InvalidParameterValueException("Unable to find a system vm: " + id); + } + } + + @Override + public VirtualMachine stopSystemVm(StopSystemVm2Cmd cmd) { + UserContext context = UserContext.current(); + + long callerId = context.getUserId(); + long callerAccountId = context.getAccountId(); + + Long id = cmd.getId(); + + // verify parameters + VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); + if (systemVm == null) { + throw new ServerApiException (BaseCmd.PARAM_ERROR, "unable to find a system vm with id " + id); + } + + // FIXME: We need to return the system VM from this method, so what do we do with the boolean response from stopConsoleProxy and stopSecondaryStorageVm? + if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)){ + long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_PROXY_STOP, "stopping console proxy with Id: "+id); + return stopConsoleProxy(id, eventId); + } else { + long eventId = EventUtils.saveScheduledEvent(callerId, callerAccountId, EventTypes.EVENT_SSVM_STOP, "stopping secondary storage Vm Id: "+id); + return stopSecondaryStorageVm(id, eventId); + } + } + private void checkIfStoragePoolAvailable(Long id) throws StorageUnavailableException { //check if the sp is up before starting List rootVolList = _volumeDao.findByInstanceAndType(id, VolumeType.ROOT); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index c3aeb3b82b9..86d9c7b508f 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -716,6 +716,9 @@ public class StorageManagerImpl implements StorageManager { StoragePoolVO pool = null; final HashSet avoidPools = new HashSet(avoids); + if(diskOffering != null && diskOffering.isCustomized()){ + diskOffering.setDiskSize(size); + } DiskProfile dskCh = null; if (volume.getVolumeType() == VolumeType.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { dskCh = createDiskCharacteristics(volume, template, dc, offering); @@ -842,7 +845,7 @@ public class StorageManagerImpl implements StorageManager { rootVol.setDeviceId(0l); rootVol = _volsDao.persist(rootVol); - if (diskOffering != null && diskOffering.getDiskSizeInBytes() > 0) { + if ((diskOffering != null && diskOffering.getDiskSizeInBytes() > 0) || (diskOffering != null && diskOffering.isCustomized())) { dataVol = new VolumeVO(VolumeType.DATADISK, vm.getId(), vm.getInstanceName() + "-DATA", dc.getId(), pod.getId(), account.getId(), account.getDomainId(), (size>0)? size : diskOffering.getDiskSizeInBytes()); createStartedEvent(account, dataVol); @@ -1458,10 +1461,12 @@ public class StorageManagerImpl implements StorageManager { //verify parameters StoragePoolVO sPool = _storagePoolDao.findById(id); if (sPool == null) { + s_logger.warn("Unable to find pool:"+id); throw new InvalidParameterValueException("Unable to find pool by id " + id); } if (sPool.getPoolType().equals(StoragePoolType.LVM)) { + s_logger.warn("Unable to delete local storage id:"+id); throw new InvalidParameterValueException("Unable to delete local storage id: " + id); } @@ -1481,6 +1486,7 @@ public class StorageManagerImpl implements StorageManager { Pair volumeRecords = _volsDao.getCountAndTotalByPool(id); if (volumeRecords.first() > 0) { + s_logger.warn("Cannot delete pool "+sPool.getName()+" as there are associated vols for this pool"); return false; // cannot delete as there are associated vols } // 3. Else part, remove the SR associated with the Xenserver @@ -1490,7 +1496,8 @@ public class StorageManagerImpl implements StorageManager { StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId()); try { if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting StoragePool with ID: " + sPool.getId()); + if(s_logger.isDebugEnabled()) + s_logger.debug("Failed to acquire lock when deleting StoragePool with ID: " + sPool.getId()); return false; } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 453015b42dc..47e3d68d3ec 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -17,6 +17,7 @@ */ package com.cloud.storage.secondary; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; @@ -49,6 +50,9 @@ import com.cloud.agent.api.StartSecStorageVmCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.check.CheckSshAnswer; +import com.cloud.agent.api.check.CheckSshCommand; +import com.cloud.agent.manager.Commands; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -64,6 +68,8 @@ import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; import com.cloud.domain.DomainVO; import com.cloud.event.EventState; import com.cloud.event.EventTypes; @@ -73,6 +79,7 @@ import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.OperationTimedoutException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; import com.cloud.ha.HighAvailabilityManager; import com.cloud.ha.dao.HighAvailabilityDao; @@ -83,10 +90,13 @@ import com.cloud.info.RunningHostCountInfo; import com.cloud.info.RunningHostInfoAgregator; import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo; import com.cloud.network.IpAddrAllocator; +import com.cloud.network.NetworkConfigurationVO; import com.cloud.network.IpAddrAllocator.networkInfo; +import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkManager; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; @@ -107,6 +117,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; import com.cloud.user.User; +import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; @@ -122,9 +133,16 @@ import com.cloud.utils.events.SubscriptionMgr; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.net.NetUtils; +import com.cloud.utils.net.NfsUtils; +import com.cloud.vm.ConsoleProxyVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.State; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineGuru; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.VmManager; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineName; @@ -151,7 +169,7 @@ import com.cloud.vm.dao.VMInstanceDao; // because sooner or later, it will be driven into Running state // @Local(value={SecondaryStorageVmManager.class}) -public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineManager { +public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, VirtualMachineManager, VirtualMachineGuru { private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class); private static final int DEFAULT_FIND_HOST_RETRY_COUNT = 2; @@ -208,6 +226,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V @Inject private ServiceOfferingDao _offeringDao; @Inject private AccountManager _accountMgr; @Inject GuestOSDao _guestOSDao = null; + @Inject private VmManager _itMgr; private IpAddrAllocator _IpAllocator; @@ -227,6 +246,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V private String _instance; private boolean _useLocalStorage; private boolean _useSSlCopy; + private String _secHostUuid; + private String _nfsShare; private String _allowedInternalSites; @@ -240,7 +261,9 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V @Override public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId, long startEventId) { try { + return start(secStorageVmId, startEventId); + } catch (StorageUnavailableException e) { s_logger.warn("Exception while trying to start secondary storage vm", e); return null; @@ -250,8 +273,17 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } catch (ConcurrentOperationException e) { s_logger.warn("Exception while trying to start secondary storage vm", e); return null; + } catch (ResourceUnavailableException e) { + return null; } } + + public SecondaryStorageVmVO start2(long secStorageVmId, long startEventId) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); + AccountVO systemAcct = _accountMgr.getSystemAccount(); + UserVO systemUser = _accountMgr.getSystemUser(); + return _itMgr.start(secStorageVm, null, systemUser, systemAcct); + } @Override @DB public SecondaryStorageVmVO start(long secStorageVmId, long startEventId) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException { @@ -666,6 +698,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V return null; } + //SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); SecondaryStorageVmVO secStorageVm = allocSecStorageVmStorage(dataCenterId, secStorageVmId); if (secStorageVm != null) { SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this, @@ -688,6 +721,52 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } return null; } + + protected Map createSecStorageVmInstance2(long dataCenterId) { + long startEventId = saveStartedEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_CREATE, "Creating secondary storage Vm in zone : "+dataCenterId, 0); + HostVO secHost = _hostDao.findSecondaryStorageHost(dataCenterId); + if (secHost == null) { + String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm"; + s_logger.warn(msg); + saveFailedEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM, EventTypes.EVENT_SSVM_CREATE, msg, startEventId); + throw new CloudRuntimeException(msg); + } + + _secHostUuid = secHost.getGuid(); + _nfsShare = secHost.getStorageUrl(); + + long id = _secStorageVmDao.getNextInSequence(Long.class, "id"); + String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern(); + AccountVO systemAcct = _accountMgr.getSystemAccount(); + + DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); + + List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork); + List> networks = new ArrayList>(offerings.size() + 1); + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setDeviceId(2); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan).get(0), defaultNic)); + for (NetworkOfferingVO offering : offerings) { + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan).get(0), null)); + } + SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, _template.getId(), + _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId()); + try { + secStorageVm = _itMgr.allocate(secStorageVm, _template, _serviceOffering, networks, plan, systemAcct); + } catch (InsufficientCapacityException e) { + s_logger.warn("InsufficientCapacity", e); + throw new CloudRuntimeException("Insufficient capacity exception", e); + } catch (StorageUnavailableException e) { + s_logger.warn("Unable to contact storage", e); + throw new CloudRuntimeException("Unable to contact storage", e); + } + + Map context = new HashMap(); + context.put("secStorageVmId", secStorageVm.getId()); + return context; + } @DB protected Map createSecStorageVmInstance(long dataCenterId) { @@ -1379,12 +1458,15 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V haMgr.registerHandler(VirtualMachine.Type.SecondaryStorageVm, this); } + _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this); + Adapters ipAllocators = locator.getAdapters(IpAddrAllocator.class); if (ipAllocators != null && ipAllocators.isSet()) { Enumeration it = ipAllocators.enumeration(); _IpAllocator = it.nextElement(); } + boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); String networkRateStr = _configDao.getValue("network.throttling.rate"); String multicastRateStr = _configDao.getValue("multicast.throttling.rate"); @@ -1908,4 +1990,110 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V _eventDao.persist(event); return; } + + @Override + public SecondaryStorageVmVO findByName(String name) { + if (!VirtualMachineName.isValidSecStorageVmName(name, null)) { + return null; + } + return findById(VirtualMachineName.getSystemVmId(name)); + } + + @Override + public SecondaryStorageVmVO findById(long id) { + return _secStorageVmDao.findById(id); + } + + @Override + public SecondaryStorageVmVO persist(SecondaryStorageVmVO vm) { + return _secStorageVmDao.persist(vm); + } + + @Override + public boolean finalizeVirtualMachineProfile( + VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) { + + StringBuilder buf = profile.getBootArgsBuilder(); + buf.append(" template=domP type=secstorage"); + buf.append(" host=").append(_mgmt_host); + buf.append(" port=").append(_mgmt_port); + buf.append(" name=").append(profile.getVirtualMachine().getHostName()); + + buf.append(" zone=").append(dest.getDataCenter().getId()); + buf.append(" pod=").append(dest.getPod().getId()); + buf.append(" guid=").append(_secHostUuid); + buf.append(" mount.path=").append(_nfsShare); + buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource"); + buf.append(" instance=SecStorage"); + buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy)); + + NicProfile controlNic = null; + for (NicProfile nic : profile.getNics()) { + int deviceId = nic.getDeviceId(); + if (nic.getIp4Address() == null) { + /*External DHCP mode*/ + buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0"); + buf.append(" bootproto=dhcp"); + } else { + buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address()); + } + + buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask()); + if (nic.isDefaultNic()) { + buf.append(" gateway=").append(nic.getGateway()); + buf.append(" dns1=").append(nic.getDns1()); + if (nic.getDns2() != null) { + buf.append(" dns2=").append(nic.getDns2()); + } + } + if (nic.getTrafficType() == TrafficType.Management) { + buf.append(" localgw=").append(dest.getPod().getGateway()); + } else if (nic.getTrafficType() == TrafficType.Control) { + controlNic = nic; + } + + } + + String bootArgs = buf.toString(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Boot Args for " + profile + ": " + bootArgs); + } + + if (controlNic == null) { + throw new CloudRuntimeException("Didn't start a control port"); + } + + profile.setParameter("control.nic", controlNic); + + return true; + } + + @Override + public boolean finalizeDeployment(Commands cmds, + VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) { + NicProfile controlNic = (NicProfile)profile.getParameter("control.nic"); + CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922, 5, 20); + cmds.addCommand("checkSsh", check); + return true; + } + + @Override + public boolean finalizeStart(Commands cmds, + VirtualMachineProfile profile, + DeployDestination dest, ReservationContext context) { + CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh"); + if (!answer.getResult()) { + s_logger.warn("Unable to ssh to the VM: " + answer.getDetails()); + return false; + } + return true; + } + + @Override + public void finalizeStop( + VirtualMachineProfile profile, long hostId, + String reservationId) { + } } diff --git a/server/src/com/cloud/vm/MauriceMoss.java b/server/src/com/cloud/vm/MauriceMoss.java index a34cb79ccc5..63ab534975e 100644 --- a/server/src/com/cloud/vm/MauriceMoss.java +++ b/server/src/com/cloud/vm/MauriceMoss.java @@ -41,6 +41,7 @@ import com.cloud.cluster.ClusterManagerListener; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; @@ -307,7 +308,7 @@ public class MauriceMoss implements VmManager, ClusterManagerListener { } if (dest == null) { - throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile); + throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); } vm.setDataCenterId(dest.getDataCenter().getId()); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 91c0e1276e0..fed523c8d63 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -740,17 +740,17 @@ CREATE TABLE `cloud`.`secondary_storage_vm` ( `dns1` varchar(15) COMMENT 'dns1', `dns2` varchar(15) COMMENT 'dns2', `domain` varchar(255) COMMENT 'domain', - `public_mac_address` varchar(17) NOT NULL unique COMMENT 'mac address of the public facing network card', + `public_mac_address` varchar(17) unique COMMENT 'mac address of the public facing network card', `public_ip_address` varchar(15) UNIQUE COMMENT 'public ip address for the sec storage vm', `public_netmask` varchar(15) COMMENT 'public netmask used for the sec storage vm', - `guest_mac_address` varchar(17) NOT NULL unique COMMENT 'mac address of the guest facing network card', + `guest_mac_address` varchar(17) unique COMMENT 'mac address of the guest facing network card', `guest_ip_address` varchar(15) UNIQUE COMMENT 'guest ip address for the console proxy', `guest_netmask` varchar(15) COMMENT 'guest netmask used for the console proxy', `vlan_db_id` bigint unsigned COMMENT 'Foreign key into vlan id table', `vlan_id` varchar(255) COMMENT 'optional VLAN ID for sec storage vm that can be used', `ram_size` int(10) unsigned NOT NULL DEFAULT 512 COMMENT 'memory to use in mb', - `guid` varchar(255) NOT NULL COMMENT 'copied from guid of secondary storage host', - `nfs_share` varchar(255) NOT NULL COMMENT 'server and path exported by the nfs server ', + `guid` varchar(255) COMMENT 'copied from guid of secondary storage host', + `nfs_share` varchar(255) COMMENT 'server and path exported by the nfs server ', `last_update` DATETIME NULL COMMENT 'Last session update time', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; diff --git a/ui/jsp/pod.jsp b/ui/jsp/pod.jsp index 27d0fbdfdef..d3a372123c1 100644 --- a/ui/jsp/pod.jsp +++ b/ui/jsp/pod.jsp @@ -22,108 +22,207 @@
<%=t.t("details")%>
+
+ <%=t.t("network")%>
+
- +
+
+
+
+ (title)
+ +
+
+
+

+ Waiting …

+
+
+
+
+
+ <%=t.t("ID")%>:
+
+
+
+
+
+
+
+
+
+ <%=t.t("name")%>:
+
+
+
+
+ + +
+
+
+
+
+ <%=t.t("private.cidr")%>:
+
+
+
+
+ + +
+
+
+
+
+ <%=t.t("private.ip.range")%>:
+
+
+
+
+ + + + +
+
+
+
+
+ <%=t.t("gateway")%>:
+
+
+
+
+ + +
+
+
+
+ + +
+
+ + + + + + + + + + +
Step 2
-
+
Step 3
-
+
diff --git a/ui/jsp/zone.jsp b/ui/jsp/zone.jsp index 2e1219c4715..dd12909b357 100644 --- a/ui/jsp/zone.jsp +++ b/ui/jsp/zone.jsp @@ -131,7 +131,7 @@
-
+
<%=t.t("vlan")%>:
diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index 417e1ef7ba6..c77cc14b8e4 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -152,14 +152,7 @@ $(document).ready(function() { disableMultipleSelectionInMidMenu(); clearMiddleMenu(); - $arrowIcon = $(this).find("#physical_resource_arrow"); - if($arrowIcon.hasClass("expanded_close") == true) { - $arrowIcon.removeClass("expanded_close").addClass("expanded_open"); - buildZoneTree(); - } else { - $arrowIcon.removeClass("expanded_open").addClass("expanded_close"); - $("#leftmenu_zone_tree").find("#tree_container").empty(); - } + expandOrCollapseZoneTree(); resourceLoadPage("jsp/resource.jsp", null); return false; diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js index a2c471299ba..5e0c1b6189c 100644 --- a/ui/scripts/cloud.core.ipaddress.js +++ b/ui/scripts/cloud.core.ipaddress.js @@ -909,7 +909,7 @@ function portForwardingJsonToTemplate(jsonObj, $template) { var virtualMachineId = $rowContainerEdit.find("#vm").val(); var array1 = []; - array1.push("&publicip="+ipAddress); + array1.push("&ipaddress="+ipAddress); array1.push("&privateport="+privatePort); array1.push("&publicport="+publicPort); array1.push("&protocol="+protocol); diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index 3b1a8defcfe..2e3ec423fa6 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -1051,6 +1051,17 @@ function drawBarChart($capacity, percentused) { //percentused == "0.01%" (having else if (percentusedFloat > 0.8 ) $capacity.find("#bar_chart").removeClass().addClass("db_barbox high").css("width", percentused); } + +function expandOrCollapseZoneTree() { + $arrowIcon = $("#leftmenu_physical_resource").find("#physical_resource_arrow"); + if($arrowIcon.hasClass("expanded_close") == true) { + $arrowIcon.removeClass("expanded_close").addClass("expanded_open"); + buildZoneTree(); + } else { + $arrowIcon.removeClass("expanded_open").addClass("expanded_close"); + $("#leftmenu_zone_tree").find("#tree_container").empty(); + } +} diff --git a/ui/scripts/cloud.core.pod.js b/ui/scripts/cloud.core.pod.js index 9dffab77710..06f16c20ca0 100644 --- a/ui/scripts/cloud.core.pod.js +++ b/ui/scripts/cloud.core.pod.js @@ -16,7 +16,7 @@ * */ - function afterLoadPodJSP($midmenuItem1) { + function afterLoadPodJSP($leftmenuItem1) { hideMiddleMenu(); initAddHostButton($("#midmenu_add_link"), "pod_page"); @@ -29,36 +29,76 @@ if (getHypervisorType() == 'kvm') $("#dialog_add_pool").find("#add_pool_protocol").empty().html(''); bindEventHandlerToDialogAddPool(); - - podJsonToRightPanel($midmenuItem1); + + //switch between different tabs + var tabArray = [$("#tab_details"), $("#tab_network")]; + var tabContentArray = [$("#tab_content_details"), $("#tab_content_network")]; + var afterSwitchFnArray = [podJsonToDetailsTab, podJsonToNetworkTab]; + switchBetweenDifferentTabs(tabArray, tabContentArray, afterSwitchFnArray); + + podJsonToRightPanel($leftmenuItem1); } function podJsonToRightPanel($leftmenuItem1) { - podJsonToDetailsTab($leftmenuItem1); + $("#right_panel_content").data("$leftmenuItem1", $leftmenuItem1); + $("#tab_details").click(); } -function podJsonToDetailsTab($leftmenuItem1) { - var jsonObj = $leftmenuItem1.data("jsonObj"); - var $detailsTab = $("#tab_content_details"); - $detailsTab.data("jsonObj", jsonObj); - $detailsTab.find("#id").text(fromdb(jsonObj.id)); - $detailsTab.find("#grid_header_title").text(fromdb(jsonObj.name)); +function podJsonToDetailsTab() { + var $thisTab = $("#right_panel_content #tab_content_details"); + $thisTab.find("#tab_container").hide(); + $thisTab.find("#tab_spinning_wheel").show(); - $detailsTab.find("#name").text(fromdb(jsonObj.name)); - $detailsTab.find("#name_edit").val(fromdb(jsonObj.name)); + var $leftmenuItem1 = $("#right_panel_content").data("$leftmenuItem1"); + var jsonObj = $leftmenuItem1.data("jsonObj"); + $thisTab.data("jsonObj", jsonObj); + + $thisTab.find("#id").text(fromdb(jsonObj.id)); + $thisTab.find("#grid_header_title").text(fromdb(jsonObj.name)); - $detailsTab.find("#cidr").text(fromdb(jsonObj.cidr)); - $detailsTab.find("#cidr_edit").val(fromdb(jsonObj.cidr)); + $thisTab.find("#name").text(fromdb(jsonObj.name)); + $thisTab.find("#name_edit").val(fromdb(jsonObj.name)); + + $thisTab.find("#cidr").text(fromdb(jsonObj.cidr)); + $thisTab.find("#cidr_edit").val(fromdb(jsonObj.cidr)); - $detailsTab.find("#ipRange").text(getIpRange(jsonObj.startip, jsonObj.endip)); - $detailsTab.find("#startIpRange_edit").val(fromdb(jsonObj.startip)); - $detailsTab.find("#endIpRange_edit").val(fromdb(jsonObj.endip)); + $thisTab.find("#ipRange").text(getIpRange(jsonObj.startip, jsonObj.endip)); + $thisTab.find("#startIpRange_edit").val(fromdb(jsonObj.startip)); + $thisTab.find("#endIpRange_edit").val(fromdb(jsonObj.endip)); + + $thisTab.find("#gateway").text(fromdb(jsonObj.gateway)); + $thisTab.find("#gateway_edit").val(fromdb(jsonObj.gateway)); + + + // hide network tab upon zone vlan + var zoneVlan; + $.ajax({ + data: createURL("command=listZones&id="+jsonObj.zoneid), + dataType: "json", + async: false, + success: function(json) { + var items = json.listzonesresponse.zone; + if (items != null && items.length > 0) { + //zoneVlan = items[0].vlan; //comment this one out until bug 7162 is fixed ("listZones API should take in id parameter") + + //temporary code before bug 7162 is fixed ********(begin)*********** + for(var i=0; i 0) { + for (var i = 0; i < items.length; i++) { + var newTemplate = template.clone(true); + podVLANJSONToTemplate(items[i], newTemplate); + $container.append(newTemplate.show()); + } + } + $thisTab.find("#tab_spinning_wheel").hide(); + $thisTab.find("#tab_container").show(); + } + }); +} + +function podVLANJSONToTemplate(jsonObj, template) { + template.data("jsonObj", jsonObj); + template.attr("id", "pod_VLAN_"+jsonObj.id).data("podVLANId", jsonObj.id); + template.find("#grid_header_title").text(fromdb(jsonObj.description)); + template.find("#id").text(jsonObj.id); + template.find("#iprange").text(jsonObj.description); + template.find("#netmask").text(jsonObj.netmask); + template.find("#gateway").text(jsonObj.gateway); + template.find("#podname").text(jsonObj.podname); + +} + function podJsonClearRightPanel(jsonObj) { podJsonClearDetailsTab(jsonObj); } function podJsonClearDetailsTab(jsonObj) { - var $detailsTab = $("#tab_content_details"); - $detailsTab.find("#id").text(""); + var $thisTab = $("#right_panel_content #tab_content_details"); + $thisTab.find("#id").text(""); - $detailsTab.find("#name").text(""); - $detailsTab.find("#name_edit").val(""); + $thisTab.find("#name").text(""); + $thisTab.find("#name_edit").val(""); - $detailsTab.find("#cidr").text(""); - $detailsTab.find("#cidr_edit").val(""); + $thisTab.find("#cidr").text(""); + $thisTab.find("#cidr_edit").val(""); - $detailsTab.find("#ipRange").text(""); - $detailsTab.find("#startIpRange_edit").val(""); - $detailsTab.find("#endIpRange_edit").val(""); + $thisTab.find("#ipRange").text(""); + $thisTab.find("#startIpRange_edit").val(""); + $thisTab.find("#endIpRange_edit").val(""); - $detailsTab.find("#gateway").text(""); - $detailsTab.find("#gateway_edit").val(""); + $thisTab.find("#gateway").text(""); + $thisTab.find("#gateway_edit").val(""); //if (getDirectAttachUntaggedEnabled() == "true") // $("#submenu_content_zones #action_add_directip_vlan").data("type", "pod").data("id", obj.id).data("name", obj.name).data("zoneid", obj.zoneid).show(); diff --git a/ui/scripts/cloud.core.primarystorage.js b/ui/scripts/cloud.core.primarystorage.js index 7b374a2bc77..56fb52f092c 100644 --- a/ui/scripts/cloud.core.primarystorage.js +++ b/ui/scripts/cloud.core.primarystorage.js @@ -39,7 +39,9 @@ function primarystorageToMidmenu(jsonObj, $midmenuItem1) { $iconContainer.find("#icon").attr("src", "images/midmenuicon_primarystorage.png"); $midmenuItem1.find("#first_row").text(fromdb(jsonObj.name).substring(0,25)); - $midmenuItem1.find("#second_row").text(jsonObj.ipaddress.substring(0,25)); + $midmenuItem1.find("#second_row").text(jsonObj.ipaddress.substring(0,25)); + + updateHostStateInMidMenu(jsonObj, $midmenuItem1); } function primarystorageToRightPanel($midmenuItem1) { diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js index 2bb6f2da2aa..cbe27547af2 100644 --- a/ui/scripts/cloud.core.resource.js +++ b/ui/scripts/cloud.core.resource.js @@ -347,13 +347,10 @@ function initAddZoneShortcut() { } }); - $("#add_zone_shortcut").unbind("click").bind("click", function(event) { - /* + $("#add_zone_shortcut").unbind("click").bind("click", function(event) { if($("#leftmenu_physical_resource").find("#physical_resource_arrow").hasClass("expanded_close") == true) - $("#leftmenu_physical_resource").click(); //if Physical Resource arrow shows closed (i.e. zonetree is hidden), expand and show zonetree. - */ - - //$addZoneWizard.find("#info_container").hide(); + expandOrCollapseZoneTree(); //if Physical Resource arrow shows closed (i.e. zonetree is hidden), expand and show zonetree. + openAddZoneWizard(); return false; }); @@ -483,9 +480,6 @@ function addZoneWizardSubmit($thisWizard) { else moreCriteria.push("&vlan=" + encodeURIComponent(vlanStart)); } - else { - moreCriteria.push("&vlan=30"); //temporary hacking before bug 7143 is fixed ("VLAN parameter in CreateZone shouldn't be required") - } var guestcidraddress = trim($thisWizard.find("#add_zone_guestcidraddress").val()); moreCriteria.push("&guestcidraddress="+encodeURIComponent(guestcidraddress)); @@ -502,9 +496,8 @@ function addZoneWizardSubmit($thisWizard) { dataType: "json", async: false, success: function(json) { - afterActionMsg += "Zone was created successfully
"; - $thisWizard.find("#spinning_wheel").hide(); - + afterActionMsg += "Zone was created successfully

"; + $zoneNode = $("#leftmenu_zone_node_template").clone(true); var $zoneTree = $("#leftmenu_zone_tree").find("#tree_container"); $zoneTree.prepend($zoneNode); @@ -517,8 +510,7 @@ function addZoneWizardSubmit($thisWizard) { }, error: function(XMLHttpResponse) { handleError(XMLHttpResponse, function() { - afterActionMsg += ("Failed to create zone. " + parseXMLHttpResponse(XMLHttpResponse) + "
"); - $thisWizard.find("#spinning_wheel").hide(); + afterActionMsg += ("Failed to create zone. " + parseXMLHttpResponse(XMLHttpResponse) + "

"); }); } }); @@ -544,8 +536,7 @@ function addZoneWizardSubmit($thisWizard) { dataType: "json", async: false, success: function(json) { - afterActionMsg += "Pod was created successfully
"; - $thisWizard.find("#spinning_wheel").hide(); + afterActionMsg += "Pod was created successfully

"; var item = json.createpodresponse.pod; podId = item.id; @@ -569,8 +560,7 @@ function addZoneWizardSubmit($thisWizard) { }, error: function(XMLHttpResponse) { handleError(XMLHttpResponse, function() { - afterActionMsg += ("Failed to create Pod. " + parseXMLHttpResponse(XMLHttpResponse) + "
"); - $thisWizard.find("#spinning_wheel").hide(); + afterActionMsg += ("Failed to create Pod. " + parseXMLHttpResponse(XMLHttpResponse) + "

"); }); } }); @@ -595,20 +585,21 @@ function addZoneWizardSubmit($thisWizard) { $.ajax({ data: createURL("command=createVlanIpRange" + array1.join("")), dataType: "json", + async: false, success: function(json) { - afterActionMsg += "Guest IP range was created successfully
"; + afterActionMsg += "Guest IP range was created successfully

"; var item = json.createvlaniprangeresponse.vlan; vlanId = item.id; }, error: function(XMLHttpResponse) { handleError(XMLHttpResponse, function() { - afterActionMsg += ("Failed to create Guest IP range. " + parseXMLHttpResponse(XMLHttpResponse) + "
"); - $thisWizard.find("#spinning_wheel").hide(); + afterActionMsg += ("Failed to create Guest IP range. " + parseXMLHttpResponse(XMLHttpResponse) + "

"); }); } }); } - + + $thisWizard.find("#spinning_wheel").hide(); $thisWizard.find("#after_action_message").html(afterActionMsg); } diff --git a/ui/scripts/cloud.core.zone.js b/ui/scripts/cloud.core.zone.js index 3c817dd15c9..5e7d5f06521 100644 --- a/ui/scripts/cloud.core.zone.js +++ b/ui/scripts/cloud.core.zone.js @@ -81,8 +81,9 @@ function zoneJsonToDetailsTab($leftmenuItem1) { $detailsTab.find("#internaldns2_edit").val(fromdb(jsonObj.internaldns2)); $detailsTab.find("#vlan").text(fromdb(jsonObj.vlan)); - var vlan = fromdb(jsonObj.vlan); + var vlan = jsonObj.vlan; if(vlan != null) { + $("#midmenu_add2_link, #tab_network, #tab_content_details #vlan_container").show(); if(vlan.indexOf("-")!==-1) { var startVlan = vlan.substring(0, vlan.indexOf("-")); var endVlan = vlan.substring((vlan.indexOf("-")+1)); @@ -93,6 +94,9 @@ function zoneJsonToDetailsTab($leftmenuItem1) { $detailsTab.find("#startvlan_edit").val(vlan); } } + else { + $("#midmenu_add2_link, #tab_network, #tab_content_details #vlan_container").hide(); + } $detailsTab.find("#guestcidraddress").text(fromdb(jsonObj.guestcidraddress)); $detailsTab.find("#guestcidraddress_edit").val(fromdb(jsonObj.guestcidraddress)); @@ -758,9 +762,9 @@ function doEditZone2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $ isValid &= validateIp("DNS 2", $detailsTab.find("#dns2_edit"), $detailsTab.find("#dns2_edit_errormsg"), true); //optional isValid &= validateIp("Internal DNS 1", $detailsTab.find("#internaldns1_edit"), $detailsTab.find("#internaldns1_edit_errormsg"), false); //required isValid &= validateIp("Internal DNS 2", $detailsTab.find("#internaldns2_edit"), $detailsTab.find("#internaldns2_edit_errormsg"), true); //optional - if (getNetworkType() != "vnet") { - isValid &= validateString("Zone - Start VLAN Range", $detailsTab.find("#startvlan_edit"), $detailsTab.find("#startvlan_edit_errormsg"), false); //required - isValid &= validateString("Zone - End VLAN Range", $detailsTab.find("#endvlan_edit"), $detailsTab.find("#endvlan_edit_errormsg"), true); //optional + if ($("#tab_content_details #vlan_container").css("display") != "none") { + isValid &= validateString("Start VLAN Range", $detailsTab.find("#startvlan_edit"), $detailsTab.find("#startvlan_edit_errormsg"), false); //required + isValid &= validateString("End VLAN Range", $detailsTab.find("#endvlan_edit"), $detailsTab.find("#endvlan_edit_errormsg"), true); //optional } isValid &= validateCIDR("Guest CIDR", $detailsTab.find("#guestcidraddress_edit"), $detailsTab.find("#guestcidraddress_edit_errormsg"), false); //required if (!isValid) @@ -790,7 +794,7 @@ function doEditZone2($actionLink, $detailsTab, $midmenuItem1, $readonlyFields, $ moreCriteria.push("&internaldns2="+encodeURIComponent(internaldns2)); var vlan; - if (getNetworkType() != "vnet") { + if ($("#tab_content_details #vlan_container").css("display") != "none") { var vlanStart = trim($detailsTab.find("#startvlan_edit").val()); var vlanEnd = trim($detailsTab.find("#endvlan_edit").val()); if (vlanEnd != null && vlanEnd.length > 0) diff --git a/vnet/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in b/vnet/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in deleted file mode 100755 index e463a54ac12..00000000000 --- a/vnet/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# chkconfig: 35 99 05 -# description: CloudStack Virtual Network Daemon - -# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well - -. /etc/rc.d/init.d/functions - -whatami=cloud-vnetd - -# set environment variables - -SHORTNAME="$whatami" -PIDFILE=@PIDDIR@/"$whatami".pid -LOCKFILE=@LOCKDIR@/"$SHORTNAME" -LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log -PROGNAME="CloudStack Virtual Network Daemon" - -unset OPTIONS -[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME" -DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize -PROG=@SBINDIR@/$SHORTNAME - -start() { - echo -n $"Starting $PROGNAME: " - daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \ - -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS - RETVAL=$? - echo - [ $RETVAL = 0 ] && touch ${LOCKFILE} - return $RETVAL -} - -stop() { - echo -n $"Stopping $PROGNAME: " - killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME - RETVAL=$? - echo - [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} -} - -recreate_vnets() { - for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`; - do - vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-` - vn vnet-create -b $br $vnetid &> /dev/null; - done -} - -# See how we were called. -case "$1" in - start) - start - sleep 1 - recreate_vnets - ;; - stop) - stop - ;; - status) - status -p ${PIDFILE} $SHORTNAME - RETVAL=$? - ;; - restart) - stop - sleep 2 - start - recreate_vnets - ;; - condrestart) - if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then - stop - sleep 2 - start - recreate_vnets - fi - ;; - *) - echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" - RETVAL=3 -esac - -exit $RETVAL - diff --git a/vnet/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in b/vnet/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in deleted file mode 100755 index e463a54ac12..00000000000 --- a/vnet/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-vnetd.in +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# chkconfig: 35 99 05 -# description: CloudStack Virtual Network Daemon - -# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well - -. /etc/rc.d/init.d/functions - -whatami=cloud-vnetd - -# set environment variables - -SHORTNAME="$whatami" -PIDFILE=@PIDDIR@/"$whatami".pid -LOCKFILE=@LOCKDIR@/"$SHORTNAME" -LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log -PROGNAME="CloudStack Virtual Network Daemon" - -unset OPTIONS -[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME" -DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize -PROG=@SBINDIR@/$SHORTNAME - -start() { - echo -n $"Starting $PROGNAME: " - daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \ - -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS - RETVAL=$? - echo - [ $RETVAL = 0 ] && touch ${LOCKFILE} - return $RETVAL -} - -stop() { - echo -n $"Stopping $PROGNAME: " - killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME - RETVAL=$? - echo - [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} -} - -recreate_vnets() { - for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`; - do - vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-` - vn vnet-create -b $br $vnetid &> /dev/null; - done -} - -# See how we were called. -case "$1" in - start) - start - sleep 1 - recreate_vnets - ;; - stop) - stop - ;; - status) - status -p ${PIDFILE} $SHORTNAME - RETVAL=$? - ;; - restart) - stop - sleep 2 - start - recreate_vnets - ;; - condrestart) - if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then - stop - sleep 2 - start - recreate_vnets - fi - ;; - *) - echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" - RETVAL=3 -esac - -exit $RETVAL - diff --git a/vnet/distro/ubuntu/SYSCONFDIR/init.d/cloud-vnetd.in b/vnet/distro/ubuntu/SYSCONFDIR/init.d/cloud-vnetd.in deleted file mode 100755 index 0c143657bc4..00000000000 --- a/vnet/distro/ubuntu/SYSCONFDIR/init.d/cloud-vnetd.in +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash - -# chkconfig: 35 99 05 -# description: CloudStack Virtual Network Daemon - -# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well - -. /lib/lsb/init-functions -. /etc/default/rcS - -whatami=cloud-vnetd - -# set environment variables - -SHORTNAME="$whatami" -PIDFILE=@PIDDIR@/"$whatami".pid -LOCKFILE=@LOCKDIR@/"$SHORTNAME" -LOGFILE=@LOCALSTATEDIR@/log/cloud/vnetd.log -PROGNAME="CloudStack Virtual Network Daemon" - -unset OPTIONS -[ -r @SYSCONFDIR@/default/"$SHORTNAME" ] && source @SYSCONFDIR@/default/"$SHORTNAME" -DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize -PROG=@SBINDIR@/$SHORTNAME - -start() { - log_daemon_msg $"Starting $PROGNAME" "$SHORTNAME" - if [ -s "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then - log_progress_msg "apparently already running" - log_end_msg 0 - exit 0 - fi - - if "$DAEMONIZE" -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS - RETVAL=$? - then - rc=0 - sleep 1 - if ! kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then - log_failure_msg "$PROG failed to start" - rc=1 - fi - else - rc=1 - fi - - if [ $rc -eq 0 ]; then - log_end_msg 0 - else - log_end_msg 1 - rm -f "$PIDFILE" - fi -} - -stop() { - echo -n $"Stopping $PROGNAME" "$SHORTNAME" - start-stop-daemon --stop --quiet --oknodo --pidfile "$PIDFILE" - log_end_msg $? - rm -f "$PIDFILE" -} - -recreate_vnets() { - for br in `ip link | grep vnbr | cut -d":" -f2| cut --complement -c1`; - do - vnetid=0000:0000:0000:0000:0000:0000:0000:`echo $br | cut -c5-` - vn vnet-create -b $br $vnetid &> /dev/null; - done -} - -# See how we were called. -case "$1" in - start) - start - sleep 1 - recreate_vnets - ;; - stop) - stop - ;; - status) - status_of_proc -p "$PIDFILE" "$PROG" "$SHORTNAME" - RETVAL=$? - ;; - restart) - stop - sleep 2 - start - recreate_vnets - ;; - condrestart) - if [ -f "$PIDFILE" ] ; then - stop - sleep 2 - start - recreate_vnets - fi - ;; - *) - echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" - RETVAL=3 -esac - -exit $RETVAL - diff --git a/vnet/sbindir/cloud-vn.in b/vnet/sbindir/cloud-vn.in deleted file mode 100755 index 6e16eadd2a9..00000000000 --- a/vnet/sbindir/cloud-vn.in +++ /dev/null @@ -1,904 +0,0 @@ -#!/usr/bin/env python -# -*- mode: python; -*- -#============================================================================ -# Copyright (C) 2005, 2006 Mike Wray -# -# This library is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -# Vnet (network virtualization) control utility. - -import os -import os.path -import re -import socket -import sys -sys.path.insert(0,"@PYTHONDIR@") -from getopt import getopt, GetoptError - -#from xen.xend import sxp -#from xen.xend.PrettyPrint import prettyprint -import cloud_sxp as sxp -from cloud_PrettyPrint import prettyprint - -# Path of unix-domain socket to vnetd. -VNETD_PATH = "/tmp/vnetd" - -def vnetd_running(): - return os.path.exists(VNETD_PATH) - -def vnetd_open(): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(VNETD_PATH) - fi = sock.makefile('r', 0) - fo = sock.makefile('w', 0) - return (fi, fo) - -os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin' -CMD_IFCONFIG = 'ifconfig' -CMD_BRCTL = 'brctl' - -opts = None - -class Opts: - - def __init__(self, **kwds): - for (k, v) in kwds.items(): - setattr(self, k, v) - -opts = Opts(verbose=False, dryrun=False) - -def set_opts(val): - global opts - opts = val - return opts - -def cmd(prog, *args): - """Execute command 'prog' with 'args', optionally printing the command. - """ - global opts - command = " ".join([ prog ] + map(str, args)) - if opts.verbose: - print command - if not opts.dryrun: - os.system(command) - -def vif_bridge_add(bridge, vif): - """Add a network interface to a bridge. - """ - cmd(CMD_BRCTL, 'addif', bridge, vif) - -def vif_bridge_rem(bridge, vif): - """Remove a network interface from a bridge. - """ - cmd(CMD_BRCTL, 'delif', bridge, vif) - -def bridge_create(bridge, **kwd): - """Create a bridge. - Defaults hello time to 0, forward delay to 0 and stp off. - """ - cmd(CMD_BRCTL, 'addbr', bridge) - if kwd.get('hello', None) is None: - kwd['hello'] = 0 - if kwd.get('fd', None) is None: - kwd['fd'] = 0 - if kwd.get('stp', None) is None: - kwd['stp'] = 'off' - bridge_set(bridge, **kwd) - cmd(CMD_IFCONFIG, bridge, "up") - -def bridge_set(bridge, hello=None, fd=None, stp=None): - """Set bridge parameters. - """ - if hello is not None: - cmd(CMD_BRCTL, 'sethello', bridge, hello) - if fd is not None: - cmd(CMD_BRCTL, 'setfd', bridge, fd) - if stp is not None: - cmd(CMD_BRCTL, 'stp', bridge, stp) - -def bridge_del(bridge): - """Delete a bridge. - """ - cmd(CMD_IFCONFIG, bridge, 'down') - cmd(CMD_BRCTL, 'delbr', bridge) - -class Bridge: - # Network interfaces are at /sys/class/net/*. - # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces - # (symlinks to the brport dirs). - # If an interface is bridged ./brport is bridged port info, - # brport/bridge is a symlink to the bridge. - - INTERFACE_DIR = "/sys/class/net" - - def isBridge(klass, dev): - """Test if a network interface is a bridge. - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - brdir = os.path.join(devdir, "bridge") - try: - os.stat(brdir) - return True - except: - return False - - isBridge = classmethod(isBridge) - - def getInterfaces(klass): - """Get a list of the network interfaces. - """ - try: - v = os.listdir(klass.INTERFACE_DIR) - v.sort() - return v - except: - return [] - - getInterfaces = classmethod(getInterfaces) - - def getInterfaceAddr(klass, intf): - intfdir = os.path.join(klass.INTERFACE_DIR, intf) - addrfile = os.path.join(intfdir, "address") - try: - f = file(addrfile, "rb") - except Exception, ex: - #print ex - return None - try: - return f.readline().strip() - finally: - f.close() - - getInterfaceAddr = classmethod(getInterfaceAddr) - - def getBridges(klass): - """Get a list of the bridges. - """ - return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ] - - getBridges = classmethod(getBridges) - - def getBridgeInterfaces(klass, dev): - """Get a list of the interfaces attached to a bridge. - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - intfdir = os.path.join(devdir, "brif") - try: - v = os.listdir(intfdir) - v.sort() - return v - except: - return [] - - getBridgeInterfaces = classmethod(getBridgeInterfaces) - - def getBridge(klass, dev): - """Get the bridge an interface is attached to (if any). - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - brfile = os.path.join(devdir, "brport/bridge") - try: - brpath = os.readlink(brfile) - return os.path.basename(brpath) - except: - return None - - getBridge = classmethod(getBridge) - -def vnet_cmd(expr): - """Send a command expression to the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - else: - fi = None - fo = file("/proc/vnet/policy", "wb") - try: - sxp.show(expr, fo) - fo.flush() - finally: - if fi: fi.close() - if fo: fo.close() - -def varp_flush(): - """Flush the varp cache. - """ - expr = ['varp.flush'] - return vnet_cmd(expr) - -def vif_add(vnetid, vmac): - """Tell the vnet implementation to add a vif to a vnet. - """ - expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]] - return vnet_cmd(expr) - -def vif_del(vnetid, vmac): - """Tell the vnet implementation to delete a vif from a vnet. - """ - expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]] - return vnet_cmd(expr) - -def vnet_add(vnetid, vnetif=None, security=None): - """Tell the vnet implementation to add a vnet. - """ - expr = ['vnet.add', ['id', vnetid]] - if vnetif: - expr.append(['vnetif', vnetif]) - if security: - expr.append(['security', security]) - return vnet_cmd(expr) - -def peer_add(addr, port=None): - expr = ['peer.add', ['addr', addr]] - if port: - expr.append(['port', port]) - return vnet_cmd(expr) - -def peer_del(addr, port=None): - expr = ['peer.del', ['addr', addr]] - return vnet_cmd(expr) - -def vnet_del(vnetid): - """Tell the vnet implementation to delete a vnet. - """ - expr = ['vnet.del', ['id', vnetid]] - return vnet_cmd(expr) - -def vnet_create(vnetid, vnetif=None, bridge=None, security=None): - """Tell the vnet implementation to add a vnet. - If 'bridge' is non-null, create the bridge and add the vnet interface - to it. - """ - vnet_add(vnetid, vnetif=vnetif, security=security) - val = vnet_lookup(vnetid) - if not vnetif: - vnetif = sxp.child_value(val, "vnetif") - vmac = get_mac(vnetif) - emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2") - if emac and vmac != emac: - set_mac(vnetif, emac) - cmd(CMD_IFCONFIG, vnetif, 'up') - if bridge: - bridge_create(bridge) - vif_bridge_add(bridge, vnetif) - return val - -def vnet_delete(vnet, delbridge=False): - """Tell the vnet implementation to delete a vnet. - If the vnet interface is attached to a bridge, - remove it from the bridge, and if delbridge is true - delete the bridge. - """ - v = vnet_lookup(vnet) - if not v: - raise GetoptError("vnet not found: %s" % vnet) - vnetid = sxp.child_value(v, "id") - vnetif = sxp.child_value(v, "vnetif") - bridge = Bridge.getBridge(vnetif) - if bridge: - vif_bridge_rem(bridge, vnetif) - if delbridge: - bridge_del(bridge) - return vnet_del(vnetid) - -def get_mac(intf): - """Get the mac address of an interface. - """ - try: - return Bridge.getInterfaceAddr(intf) - except: - pass - - hwre = re.compile(".*\s+HWaddr\s+(?P\S*)\s+.*") - fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r') - try: - for x in fin: - m = hwre.match(x) - if not m: - continue - info = m.groupdict() - return info['mac'] - return None - finally: - fin.close() - -def set_mac(intf, mac): - cmd(CMD_IFCONFIG, intf, 'down') - cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac) - cmd(CMD_IFCONFIG, intf, 'up') - -def get_addr(host): - return socket.gethostbyname(host) - -def get_port(srv): - return srv - -def vnetidof(v): - """Normalise a vnet id. Adds leading 0 fields to make up 8 if - there aren't enough. Pads all fields to 4 hex digits. - """ - try: - l = v.split(":") - l = [ int(x or 0, 16) for x in l ] - l = [ 0 ] * (8 - len(l)) + l - return ":".join([ "%04x" % x for x in l ]) - except: - return None - -def vnet_lookup(vnet, vnets=None): - """Find the vnet with the given vnet id or vnet interface. - - @param vnet id or interface - @param vnets list of vnet info to use (get from implementation if None) - @return vnet info or None if not found - """ - vnetid = vnetidof(vnet) - if vnets is None: - vnets = vnet_list() - for v in vnets: - vid = sxp.child_value(v, "id") - if vid == vnet or vid == vnetid: - return v - if sxp.child_value(v, "vnetif") == vnet: - return v - return None - -def get_vnetid(vnet): - """Get the normalised vnet id of the given vnet id or vnet interface. - Raises an error if the vnet cannot be found. - """ - v = vnet_lookup(vnet) - if not v: - raise GetoptError("vnet not found: %s" % vnet) - vnetid = sxp.child_value(v, "id") - return vnetid - -def vif_list(): - """Get the list of vif info from the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['vif.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/vifs") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -def vnets_filter(vnetlist, vnets): - """Filter a list of vnet info by a list of vnet ids or interfaces. - """ - if vnets is None: - val = vnetlist - else: - val = [] - for x in vnets: - v = vnet_lookup(x, vnets=vnetlist) - if not v: - continue - val.append(v) - return val - -def vnet_list(vnets=None): - """Get the list of vnet info from the vnet implementation, - sorted by vnet id. - - @param vnets list of vnet ids or interfaces to filter the results by - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['vnet.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/vnets") - fo = None - try: - val = vnets_filter(sxp.parse(fi) or [], vnets) - val.sort(lambda x, y: - cmp(sxp.child_value(x, "id"), - sxp.child_value(y, "id"))) - return val - finally: - if fi: fi.close() - if fo: fo.close() - -def vnif_list(vnets=None): - """Get the list of vnet interface names from the vnet implementation. - - @param vnets list of vnet ids or interfaces to filter the results by - """ - vnifs = [] - for v in vnet_list(vnets=vnets): - vnetif = sxp.child_value(v, "vnetif") - if vnetif: - vnifs.append(vnetif) - return vnifs - -def varp_list(): - """Get the list of varp info from the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['varp.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/varp") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -def peer_list(): - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['peer.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/peers") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -class Opt: - """Declares command-line options for a command. - """ - - def getopt(klass, argv, opts, args): - """Get options and args from argv. - The value opts in the return value has an attribute for - eacho option or arg. The value args in the return value - is the remaining arguments. - - @param argv arguments - @param opts option specifiers (list of Opt objects) - @param args arg specififiers (list of Arg objects) - @return (opts, args) - """ - shortopts = "".join([ x.optShort() for x in opts ]) - longopts = [ x.optLong() for x in opts ] - (ovals, oargs) = getopt(argv[1:], shortopts, longopts) - odir = Opts() - for x in opts: - x.setDefault(odir) - for (k, v) in ovals: - for x in opts: - x.setOpt(k, v, odir) - argc = len(oargs) - if len(oargs) < len(args): - raise GetoptError("insufficient arguments for %s" % argv[0]) - for (x, v) in zip(args, oargs): - x.setArg(v, odir) - return (odir, oargs[len(args): ]) - - getopt = classmethod(getopt) - - def gethelp(klass, opts, args): - l = [] - for x in opts: - l.append(x.help()) - for x in args: - l.append(x.help()) - return " ".join(l) - - gethelp = classmethod(gethelp) - - """A command=-line option. - - @param name option name (this attribute is set to value in opts) - @param short short option flag (single-character string) - @param long long option name (defaults to option name, pass "" to suppress) - @param arg argument name (option has no arg if not specified) - """ - def __init__(self, name, short=None, long=None, arg=False): - self.name = name - self.short = short - if long is None: - long = name - elif not long: - long = None - self.long = long - self.arg = arg - - def help(self): - s = self.keyShort() - l = self.keyLong() - if s and l: - return "[%s | %s]" % (s, l) - else: - return s or l - - def keyShort(self): - if self.short: - return "-%s" % self.short - else: - return None - - def keyLong(self): - if self.long: - return "--%s" % self.long - else: - return None - - def optLong(self): - if not self.long: - return None - if self.arg: - return "%s=" % self.long - else: - return self.long - - def optShort(self): - if not self.short: - return None - if self.arg: - return "%s:" % self.short - else: - return self.short - - def setDefault(self, vals): - if self.arg: - setattr(vals, self.name, None) - else: - setattr(vals, self.name, False) - - def setOpt(self, k, v, vals): - if k in [ self.keyShort(), self.keyLong() ]: - if self.arg: - setattr(vals, self.name, v) - else: - if v not in [ None, '' ]: - raise GetoptError("option %s does not take an argument" % k) - setattr(vals, self.name, True) - -class Arg: - - """A command-line parameter. Args get their values from arguments - left over after option processing and are assigned in order. - The value is accessible as the attribute called 'name' in opts. - - @param name argument name - """ - def __init__(self, name): - self.name = name - - def setArg(self, v, vals): - setattr(vals, self.name, v) - - def help(self): - return "<%s>" % self.name - -class VnMain: - - """Methods beginning with this prefix are commands. - They must all have arguments like this: - - op_foo(self, argv, args, opts) - - argv: original command-line arguments - args: arguments left after option processing - opts: option and arg values (accessible as attributes) - - Method options are specified by setting attribute - .opts on the method to a list of Option objects. - For args set .args to a list of Arg objects. - Use .use for short usage string, .help for long help. - - Each option or arg defines an attribute in opts. For example - an option with name 'foo' is accessible as 'opts.foo'. - """ - opPrefix = "op_" - - def __init__(self, argv): - if argv: - self.name = argv[0] - else: - self.name = "vn" - self.argv = argv - self.argc = len(argv) - - def error(self, v): - print >>sys.stderr, "%s: %s" % (self.name, v) - sys.exit(1) - - def getFunction(self, opname): - key = self.opPrefix + opname.replace("-", "_") - fn = getattr(self, key, None) - if not fn: - raise ValueError("unknown command: %s" % opname) - return fn - - def main(self): - if self.argc < 2: - args = ["help"] - else: - args = self.argv[1:] - try: - fn = self.getFunction(args[0]) - except ValueError, ex: - self.error(ex) - try: - fnopts = self.getOpts(fn) - fnargs = self.getArgs(fn) - (opts, parms) = Opt.getopt(args, fnopts, fnargs) - return fn(args, parms, opts) - except GetoptError, ex: - self.error(ex) - except ValueError, ex: - self.error(ex) - except Exception, ex: - import traceback; traceback.print_exc() - self.error(ex) - - def getOpts(self, meth): - return getattr(meth, "opts", []) - - def getArgs(self, meth): - return getattr(meth, "args", []) - - def getUse(self, meth): - return getattr(meth, "use", "") - - def getHelp(self, meth): - return getattr(meth, "help", "") or self.getUse(meth) - - def fnHelp(self, meth): - return Opt.gethelp(self.getOpts(meth), self.getArgs(meth)) - - def printHelp(self, fn, opt_long): - meth = getattr(self, fn) - opname = fn[len(self.opPrefix):].replace("_", "-") - if opt_long: - help = self.getHelp(meth) - print "\n %s" % opname - if help: - print "%s" % help - else: - use = self.getUse(meth) - print " %s %s" % (opname, self.fnHelp(meth)) - if use: - print "\t\t%s" % use - - def show_vnif(self, dev): - cmd(CMD_IFCONFIG, dev) - bridge = Bridge.getBridge(dev) - if bridge: - print " Bridge:", bridge - interfaces = Bridge.getBridgeInterfaces(bridge) - if dev in interfaces: - interfaces.remove(dev) - if interfaces: - print " Interfaces:", ", ".join(interfaces) - print - - def op_help(self, argv, args, opts): - if opts.long: - print '%s ' % self.name - print self.long_help - else: - print '%s:' % self.name - l = dir(self) - l.sort() - for fn in l: - if fn.startswith(self.opPrefix): - self.printHelp(fn, opts.long) - print - - op_help.opts = [ Opt('long', short='l') ] - - def op_vnets(self, argv, args, opts): - vnets = vnet_list(vnets=args or None) - for v in vnets: - prettyprint(v, width=50) - print - if not opts.long: - continue - vnif = sxp.child_value(v, "vnetif") - if not vnif: - continue - self.show_vnif(vnif) - if opts.all: - vnetids = {} - for v in vnets: - vnetids[sxp.child_value(v, "id")] = v - for v in vif_list(): - vnet = sxp.child_value(v, "vnet") - if vnet not in vnetids: - continue - prettyprint(v) - print - for v in varp_list(): - prettyprint(v) - print - - op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ] - - def op_vnifs(self, argv, args, opts): - vnifs = vnif_list(vnets=args or None) - for vnif in vnifs: - self.show_vnif(vnif) - - def op_vifs(self, argv, args, opts): - for v in vif_list(): - prettyprint(v) - print - - def op_varp(self, argv, args, opts): - for v in varp_list(): - prettyprint(v) - print - - def op_varp_flush(self, argv, args, opts): - varp_flush() - - def op_vnet_create(self, argv, args, opts): - return vnet_create(opts.vnet, - vnetif=opts.vnetif, - bridge=opts.bridge, - security=opts.security) - - op_vnet_create.args = [ Arg('vnet') ] - op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"), - Opt('bridge', short='b', arg="BRIDGE"), - Opt('vnetif', short='v', arg="VNETIF") ] - - def op_vnet_delete(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - return vnet_delete(vnetid, delbridge=opts.bridge) - - op_vnet_delete.args = [ Arg('vnet') ] - op_vnet_delete.opts = [ Opt('bridge', short='b') ] - - def op_vif_add(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - if opts.interface: - vmac = get_mac(opts.vmac) - if not vmac: - raise ValueError("interface not found: %s" % opts.vmac) - else: - vmac = opts.vmac - return vif_add(vnetid, vmac) - - op_vif_add.args = [ Arg('vnet'), Arg('vmac') ] - op_vif_add.opts = [ Opt('interface', short='i') ] - - def op_vif_delete(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - if opts.interface: - vmac = get_mac(opts.vmac) - else: - vmac = opts.vmac - return vif_del(vnetid, vmac) - - op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ] - op_vif_delete.opts = [ Opt('interface', short='i') ] - - def op_peer_add(self, argv, args, opts): - addr = get_addr(opts.addr) - if(opts.port): - port = get_port(opts.port) - else: - port = None - return peer_add(addr, port) - - op_peer_add.args = [ Arg('addr') ] - op_peer_add.opts = [ Opt('port', short='p') ] - - def op_peer_delete(self, argv, args, opts): - addr = get_addr(opts.addr) - return peer_del(addr) - - op_peer_delete.args = [ Arg('addr') ] - - def op_peers(self, argv, args, opts): - for v in peer_list(): - prettyprint(v) - print - - def op_bridges(self, argv, args, opts): - if opts.long: - for bridge in Bridge.getBridges(): - cmd(CMD_IFCONFIG, bridge) - interfaces = Bridge.getBridgeInterfaces(bridge) - if interfaces: - print " Interfaces:", ", ".join(interfaces) - print - else: - for bridge in Bridge.getBridges(): - print bridge, - interfaces = Bridge.getBridgeInterfaces(bridge) - if interfaces: - print ":", ", ".join(interfaces) - else: - print - - op_bridges.opts = [ Opt('long', short='l') ] - - def op_insmod(self, argv, args, opts): - """Insert the vnet kernel module.""" - """cmd("/etc/xen/scripts/vnet-insert", *args)""" - - long_help = """Control utility for vnets (virtual networking). -Report bugs to Mike Wray . -""" - - op_help.use = "Print help." - op_help.help = "Print help, long help if the option -l or --long is given." - - op_vnets.use = """Print vnets.""" - op_vnets.help = """Print vnet information, where options are: - -a, -all Print vnets, vifs and varp info. - -l, --long Print ifconfigs for vnet interfaces.""" - - op_vifs.use = "Print vifs." - - op_vnifs.use = "Print ifconfigs for vnet network interfaces." - - op_varp.use = "Print varp info and entries in the varp cache." - - op_varp_flush.use = "Flush the varp cache." - - op_vnet_create.use = "Create a vnet." - - op_vnet_delete.use = "Delete a vnet." - op_vnet_delete.help = """Delete a vnet. - -b, --bridge Delete the bridge the vnet interface is attached to. - """ - - op_vif_add.use = "Add a vif to a vnet." - op_vif_add.help = """Add a vif to a vnet. Not usually needed as vifs -are added automatically. - -i, --interface The vmac is the name of an interface to get the mac from.""" - - op_vif_delete.use = "Delete a vif from a vnet." - op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as vifs -are removed periodically. - -i, --interface The vmac is the name of an interface to get the mac from.""" - - op_peer_add.use = "Add a peer." - op_peer_add.help = """Add a peer: -Vnets use multicast to discover interfaces, but networks are often configured -not to forward multicast. Vnets forward multicasts to peers using UDP. -Only add peers if multicasts are not working, check with - -ping -b 224.10.0.1 - -Only add peers at one machine in a subnet, otherwise you may cause forwarding -loops. -""" - - op_peer_delete.use = "Delete a peer." - op_peer_delete.help= "Delete a peer: " - - op_peers.use = "List peers." - op_peers.help = "List peers." - - op_bridges.use = "Print bridges." - - op_insmod.use = "Insert the vnet kernel module, optionally with parameters." - -if __name__ == "__main__": - vn = VnMain(sys.argv) - vn.main() - diff --git a/vnet/src/00INSTALL b/vnet/src/00INSTALL deleted file mode 100644 index 66bb318249c..00000000000 --- a/vnet/src/00INSTALL +++ /dev/null @@ -1,55 +0,0 @@ -This directory contains the implementation of vnets: -virtual private networks for virtual machines. - -make - - compile in local dirs. The module is in vnet-module/vnet_module.ko. - -make dist - - compile and install into $(XEN_ROOT)/dist/install, - - where XEN_ROOT is the root of the xen tree. - -make install - - compile and install into system. - -By default the makefiles expect this code to have been installed -in tools/vnet in a xen source tree. If compiling outside the xen -source tree, set XEN_ROOT to the location of the xen source. -You can do this in the environment or in a Make.local file -in the current directory (see Make.env for details). - -The xen0 kernel must have been compiled before building the vnet module. -The vnet module installs to - /lib/modules/-xen0/kernel/xen/vnet_module.ko - -The vnet module should be loaded before starting xend, or -xend will fail to create any persistent vnets it has in its configuration. -The script network-vnet is a modified version of the xen network script -that loads the module if it's not already loaded. - -The module uses kernel crypto functions, and these need to be -enabled in the xen0 kernel config. They should be on by default - -if they're not you will get compile or insmod errors (see below). - -Kernel config options: - -1) You will need to have your xen0 kernel compiled with HMAC_SUPPORT - 2.6.x = (MAIN MENU: Cryptographic Options -> HMAC Support) - BEFORE running "make install". - -2) You will want at least some of the other algorithms listed under - "Cryptographic Options" for the kernel compiled as modules. - -3) You will want the networking IPsec/VLAN options compiled in as modules - 2.6.x = (MAIN MENU: Device Drivers -> Networking Support -> - Networking Options -> - IP: AH transformation - IP: ESP transformation - IP: IPComp transformation - IP: tunnel transformation - - IPsec user configuration interface - - 802.1Q VLAN Support - -Please refer to the additional documentation found in tools/vnet/doc for -proper syntax and config file parameters. diff --git a/vnet/src/00README b/vnet/src/00README deleted file mode 100644 index fc76b7f0128..00000000000 --- a/vnet/src/00README +++ /dev/null @@ -1,15 +0,0 @@ -This directory contains the implementation of vnets: -virtual private networks for virtual machines. - -See 00INSTALL for build instructions, doc/ for more information -and examples/ for example configurations. - -The vnet implementation can be run using a kernel module -or a user-space daemon. The kernel module is in vnet-module/ and the -user-space daemon (varpd) is in vnetd/. The user-space daemon -needs the tun/tap kernel module. Vnets use multicast to find -virtual interfaces and support broadcast. Either implementation can -tunnel multicast packets to other implementations if wide-area -multicast routing is not available. - -Mike Wray \ No newline at end of file diff --git a/vnet/src/Make.env b/vnet/src/Make.env deleted file mode 100644 index 01b03c142b6..00000000000 --- a/vnet/src/Make.env +++ /dev/null @@ -1,28 +0,0 @@ -# -*- mode: Makefile; -*- - -# Include any local overrides. --include $(VNET_ROOT)/Make.local - -# If building vnets outside the xen source tree, set XEN_ROOT to the -# absolute path of the root of the xen source tree. Edit this file -# or set XEN_ROOT in Make.local, the make command line or -# the environment. For example put this in Make.local: -# export XEN_ROOT = $(shell cd ~/xen-unstable.hg && pwd) - -export XEN_ROOT ?= $(shell cd $(VNET_ROOT)/../.. && pwd) - -export LINUX_SERIES ?= 2.6 - -DISTDIR ?= $(XEN_ROOT)/dist -export DESTDIR ?= $(DISTDIR)/install - -export VNET_MODULE_DIR = $(VNET_ROOT)/vnet-module -export VNETD_DIR = $(VNET_ROOT)/vnetd -export LIBXUTIL_DIR = $(VNET_ROOT)/libxutil - - -export GC_DIR = $(VNET_ROOT)/build/gc -export GC_INCLUDE = $(GC_DIR)/include -export GC_LIB_DIR = $(GC_DIR)/lib -export GC_LIB_A = $(GC_LIB_DIR)/libgc.a -export GC_LIB_SO = $(GC_LIB_DIR)/libgc.so diff --git a/vnet/src/Makefile b/vnet/src/Makefile deleted file mode 100644 index 8dbef89c040..00000000000 --- a/vnet/src/Makefile +++ /dev/null @@ -1,89 +0,0 @@ -# -*- mode: Makefile; -*- - -ifndef VNET_ROOT -export VNET_ROOT = $(shell pwd) -include $(VNET_ROOT)/Make.env -endif - -SUBDIRS:= -SUBDIRS+= examples -SUBDIRS+= scripts -#SUBDIRS+= gc -SUBDIRS+= libxutil -SUBDIRS+= vnetd -SUBDIRS+= vnet-module - -.PHONY: all -all: compile - -gc.tar.gz: - wget http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/$@ - -.PHONY: gc -gc: gc.tar.gz - tar xfz gc.tar.gz - ln -sf gc?.? gc - -$(GC_LIB_A): gc - (cd gc && ./configure --prefix=$(GC_DIR) ) - make -C gc - DESTDIR="" make -C gc install - -.PHONY: gc-all -gc-all: $(GC_LIB_A) - -.PHONY: gc-install -gc-install: - -.PHONY: gc-clean -gc-clean: - -@$(RM) -r gc?.? gc - -submak = $(MAKE) -C $(patsubst %-$(1),%,$(@)) $(1) -subtgt = $(patsubst %,%-$(1),$(SUBDIRS)) - -%-all: - $(call submak,all) - -%-clean: - -$(call submak,clean) - -%-install: - $(call submak,install) - -.PHONY: compile -compile: $(call subtgt,all) - -.PHONY: install -install: DESTDIR= -install: dist - -.PHONY: dist -dist: compile $(call subtgt,install) - -.PHONY: clean -clean: $(call subtgt,clean) - -@$(RM) -r build - -.PHONY: pristine -pristine: clean - -@$(RM) gc.tar.gz - -.PHONY: help -help: - @echo 'Cleaning targets:' - @echo ' clean - clean subdirs and remove the build dir' - @echo ' pristine - clean, then remove the gc tarball' - @echo '' - @echo 'Installation targets:' - @echo ' install - build and install relative to /' - @echo ' dist - build and install relative to DESTDIR (default XEN_ROOT/dist/install)' - @echo '' - @echo 'Compilation targets:' - @echo ' all - same as compile' - @echo ' compile - build everything' - @echo '' - @echo 'To build everything locally use "make" or "make all"'. - @echo 'To build and install into XEN_ROOT/dist/install use "make dist".' - @echo 'To build and install into the system use "make dist".' - @echo 'See ./00README and ./00INSTALL for more information.' diff --git a/vnet/src/doc/Makefile b/vnet/src/doc/Makefile deleted file mode 100644 index a234721b511..00000000000 --- a/vnet/src/doc/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/make -f -# -*- mode: Makefile; -*- -XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/Rules.mk - -VERSION = 1.0 -HEADER = Vnet - -PS2PDF := ps2pdf -DVIPS := dvips -LATEX := latex -LATEX2HTML := latex2html -DOXYGEN := doxygen -POD2MAN := pod2man - -DOC_MAN5SRC := $(wildcard man/*.pod.5) -DOC_MAN1SRC := $(wildcard man/*.pod.1) -DOC_MAN1 := $(patsubst man/%.pod.1,man1/%.1,$(DOC_MAN1SRC)) -DOC_MAN5 := $(patsubst man/%.pod.5,man5/%.5,$(DOC_MAN5SRC)) - -.PHONY: all man clean install - -.PHONY: all -all: man - -.PHONY: man -man: - @if which $(POD2MAN) 1>/dev/null 2>/dev/null; then \ - $(MAKE) $(DOC_MAN1) $(DOC_MAN5); fi - -man1/%.1: man/%.pod.1 Makefile - $(INSTALL_DIR) $(@D) - $(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man1.//'| \ - sed 's/.1//'` -s 1 -c $(HEADER) $< $@ - -man5/%.5: man/%.pod.5 Makefile - $(INSTALL_DIR) $(@D) - $(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man5.//'| \ - sed 's/.5//'` -s 5 -c $(HEADER) $< $@ - -.PHONY: clean -clean: - @$(RM) -rf man5 - @$(RM) -rf man1 - -.PHONY: install - install: all - $(INSTALL_DIR) $(DESTDIR)$(MANDIR) - $(CP) -dR man1 $(DESTDIR)$(MANDIR) - $(CP) -dR man5 $(DESTDIR)$(MANDIR) - diff --git a/vnet/src/doc/man/vn.pod.1 b/vnet/src/doc/man/vn.pod.1 deleted file mode 100644 index a7707bd509b..00000000000 --- a/vnet/src/doc/man/vn.pod.1 +++ /dev/null @@ -1,176 +0,0 @@ -=head1 NAME - -vn - Vnet (virtual networking) management utility. - -=head1 SYNOPSIS - -vn [args] - -=head1 DESCRIPTION - -The B utility manages vnets, virtual networks for virtual machines. -Before using vnets, the vnet kernel module must be installed or -the user-space daemon vnetd must be running. Using the kernel module is recommended, -see the B command below. - -A vnet is a virtual network that behaves like a private LAN, transporting -Ethernet frames. Each vnet is identified by a 128-bit vnet id and -has a network device that interfaces to it. Ethernet packets written -to the device are encapsulated and sent to the network. -Received vnet packets are decapsulated and delivered from the device -corresponding to their vnet id. The default encapsulation uses UDP on port 1798. - -Usually each vnet device is enslaved to a corresponding bridge, and virtual -machine interfaces are attached to vnets by enslaving them to the bridge. -Each vnet behaves like a private LAN: traffic on one vnet is not visible -on other vnets, and interfaces on a vnet cannot see traffic on the -physical network. - -Vnets can be connected together into larger networks -by direct bridging or packet forwarding, or by using multihomed vms -with interfaces on several vnets, or vnets and the physical network. -As vnet interfaces are discovered dynamically, vnet connectivity is maintained -if a vm using a vnet is migrated from one physical machine to another. - -In the commands vnet ids can be given in two forms. Long form, as 8 4-digit hex fields -separated by colons, for example 0000:0000:0000:0000:0000:0000:0000:0004, and -short form as a hex field, for example 0004 or 4. The short form is the same as the -long form with the first 7 fields zero. Vnet id 0000:0000:0000:0000:0000:0000:0000:0001 -is reserved for the physical network and has no vnet device. - -Vnets use multicast to discover the location of virtual interfaces, by default -using multicast group 224.10.0.1. If all the machines hosting vnets are on -the same subnet, or reachable by multicast, vnets will span all the machines -automatically. If some machines are not reachable by multicast you can configure -vnets to perform multicast forwarding using UDP. - -The vnet devices are fully-functional network devices, so you can add IP addresses -to them and test connectivity without any vms running. -For example, using vnif0004 on machines A and B: - - A> ifconfig vnif0004 192.0.2.11 - B> ifconfig vnif0004 192.0.2.12 - B> ping 192.0.2.11 - -If the vnet device is enslaved to a bridge you will have to add the IP address -to the bridge instead. Use C or C to see if a vnet -device is on a bridge. - -=over 4 - -=item B I<[varp_mcaddr=ADDR]> - -Insert the vnet kernel module, optionally supplying the multicast -address to use, default 224.10.0.1. - -=item B - -Print varp infrormation and varp cache. - -=item B [options] - -Print the list of vnets (virtual networks). If a vnet device is on a bridge, -also shows the bridge and its bridged interfaces. - -=over 4 - -=item B<-a | --all> - -Also print the vifs on each vnet and varp information. - -=item B<-l | --long> - -Also print the ifconfig for the vnet devices. - -=back - -=item B I<[options]> I - -Create a vnet with the given id. The options are: - -=over 4 - -=item B<-s | --security> I - -Security level, which can be one of I for no security, -I for message authentication, and I for message -authentication and confidentiality. The default is no security. -Security is provided using IPSEC, but uses hard-wired keys. - -=item B<-b | --bridge> I - -Create a bridge for the vnet called I and enslave -the vnet device to it. - -=item B<-v | --vnetif> I - -Use I as the name for the vnet device. If this option -is not specified the default is to name the device vnifN where N -is the last field of the vnet id as 4 hex characters. -For example vnif0004. Network device names can be at -most 14 characters. - -=back - -=item B I<[options]> I - -Delete the vnet with the given id. The vnet device goes away too. - -=over 4 - -=item B<-b | --bridge> - -If this option is specified, delete the bridge associated with the vnet. - -=back - -=item B - -Print the list of vifs (virtual interfaces). - -=item B I<[-i|-interface]> I I - -Add a vif to a vnet. Here I is the vnet id and I -is the vif's MAC address. Alternatively, I can be the name of -a network device if the I<-i> or -I<--interface> flag is given. - -It is not usually necessary to use B as vnets automatically -add vifs for the MAC addresses they see. - -=item B I<[-i|-interface]> I I - -Delete a vif from a vnet. Here I is the vnet id and I -is the vif's MAC address. Alternatively, I can be the name of -a network device if the I<-i> of -I<--interface> flag is given. - -It is not usually necessary to use B as vnets periodically -delete unused vifs. - -=item B - -Print the list of peer vnet machines to forward multicasts to, and accept -forwarded multicasts from. - -=item B I - -Add the peer with the given IP address or hostname. - -=item B I - -Delete the peer with the given IP address or hostname. - -=back - -=head1 AUTHOR - -The author of vn and vnets is Mike Wray of HP Labs. Please send problems, bugs, -enhancements requests etc. to mike.wray@hp.com. - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2006 Mike Wray . - -This library is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 of the License, or -(at your option) any later version. diff --git a/vnet/src/doc/vnet-module.txt b/vnet/src/doc/vnet-module.txt deleted file mode 100644 index c2fabe6415b..00000000000 --- a/vnet/src/doc/vnet-module.txt +++ /dev/null @@ -1,72 +0,0 @@ -Vnet Low-level Command Interface -Mike Wray -2006/10/12 - -The vnet kernel module and user-space daemon vnetd support a low-level -command interface to control vnets. The kernel module creates /proc/vnet/policy, -which is used by writing commands into it. Vnetd listens on the unix-domain -socket /tmp/vnetd. - -The vn utility in ../scripts provides a higher-level interface to -the vnet commands (using the kernel module or vnetd). - -The commands are: - -(vnet.add (id ) [(vnetif )] [(security { none | auth | conf } )] ) - -Create the vnet with id and the given security level (default none). -Vnet ids are 128-bit and can be specified as 8 fields of 1 to 4 hex digits -separated by colons. A vnet id with no colons is treated as one with the first -7 fields zero. Examples: - -1500 - equivalent to 0:0:0:0:0:0:0:1500 -aaff:0:0:0:0:0:77:88 - -Security levels: -- none: no security -- auth: message authentication (IPSEC hmac) -- conf: message confidentiality (IPSEC hmac and encryption) - -The is the name of the network device created for the vnet. -If not given it defaults to vnif, where is the hex for the -8-th field in the id. Note that network device names can have a -maximum of 14 characters. - -(vnet.del (id )) - -Delete the vnet with id . - -(vif.add (vnet ) (vmac )) - -Add the vif with MAC address to the vnet with id . -This makes the vnet module respond to VARP requests for -on vnet . The vnet implementation learns MAC addresses -so doing this should not be necessary. - -(vif.del (vnet ) (vmac )) - -Remove the vif with MAC address from the vnet with id . -The vnet module will stop responding to VARP for the vif. - -(peer.add (addr )) - -Add a peer at IP address to forward multicasts to, -and accept forwarded multicasts from. - -(peer.del (addr )) - -Delete a peer. - -(vif.list) - get list of vifs. -(vnet.list) - get list of vnets. -(varp.list) - get vnet/varp info. -(peer.list) - get list of peers. - -The kernel module produces output on the console, and vnetd -returns output on the unix socket. The kernel module also provides -the following files which can be read to get information: - -/proc/vnet/vifs - get list of vifs. -/proc/vnet/vnets - get list of vnets. -/proc/vnet/varp - get vnet/varp info. -/proc/vnet/peers - get list of peers. diff --git a/vnet/src/doc/vnet-xend.txt b/vnet/src/doc/vnet-xend.txt deleted file mode 100644 index ee55d06f906..00000000000 --- a/vnet/src/doc/vnet-xend.txt +++ /dev/null @@ -1,167 +0,0 @@ - -Vnets: Virtual Networks for Virtual Machines - -Mike Wray - -2005/12/13 - -0) Introduction ---------------- - -Vnets provide virtual private LANs for virtual machines. -This is done using bridging and multipoint tunneling. A virtual interface -on a vnet can only see other interfaces on the same vnet - it cannot -see the real network, and the real network cannot see it either. - -Virtual interfaces on the same vnet can be on the same machine -or on different machines, they can still talk. The hosting machines -can even be on different subnets if you configure vnet forwarding, -or have multicast routing enabled. - - -1) Installing vnet support --------------------------- - -Assuming the code has been installed (make install in the parent directory), -configure xend to use 'network-vnet' instead of the default 'network' to -start up networking. This just loads the vnet module when networking starts. - -In /etc/xend/xend-config.sxp: - -Configure the network script: - -(network-script network-vnet) - -Restart xend. - -Alternatively insert the vnet module using 'vn insmod', -preferably before xend starts. - -2) Creating vnets ------------------ - -Xend already implements commands to add/remove vnets and -bridge to them. To add a vnet use - -xm vnet-create - -For example, if vnet97.sxp contains: - -(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none)) - -do - -xm vnet-create vnet97.sxp - -This will define a vnet with id 97 and no security. The bridge for the -vnet is called vnet97 and the virtual interface for it is vnif97. -To add an interface on a vm to this vnet simply set its bridge to vnet97 -in its configuration. - -In Python: - -vif="bridge=vnet97" - -In sxp: - -(dev (vif (mac aa:00:00:01:02:03) (bridge vnet97))) - -By default vnets use udp encapsulation, but if you use etherip encapsulation -you will also have to reduce the MTU of the corresponding -device in the domain (because of the tunneling). Reducing the MTU may improve -performance for udp encapsulation, but is not necessary. - -For example, for eth0 (in the domain, not dom0) use - -ifconfig eth0 mtu 1400 - -or, better, put - -MTU=1400 - -in /etc/sysconfig/network-scripts/ifcfg-eth0. You may also have to change or remove -cached config files for eth0 under /etc/sysconfig/networking. - -Once configured, vnets are persistent in the xend database. -To remove a vnet use - -xm vnet-delete - -To list vnets use - -xm vnet-list - -To get information on one or more vnet ids use - -xm vnet-list ... - -You can also manage vnets using the vn utility which talks -directly to the vnet implementation. The source is in ../scripts/vn -and is installed in /usr/sbin/vn. - -3) Troubleshooting ------------------- - -The vnet module should appear in 'lsmod'. -If a vnet has been configured it should appear in the output of 'xm vnet-list'. -Its bridge and interface should appear in 'ifconfig'. -It should also show in 'brctl show', with its attached interfaces. - -You can 'see into' a vnet from dom0 if you put an IP address on the bridge. -For example, if you have vnet97 and a vm with ip addr 192.0.2.12 connected to it, -then - -ifconfig vnet97 192.0.2.20 up - -should let you ping 192.0.2.12 via the vnet97 bridge. - -4) Examples ------------ - -These assume a vnet with a bridge 'vnet97' has been created. - -Here's the full config for a vm on vnet 97, using ip addr 192.0.2.12: - -(vm - (name dom12) - (memory '64') - (cpu '1') - (console '8502') - (image - (linux - (kernel /boot/vmlinuz-2.6-xenU) - (ip 192.0.2.12:192.0.2.4::::eth0:off) - (root /dev/sda1) - (args 'rw fastboot 4') - ) - ) - (device (vbd (uname phy:hda2) (dev sda1) (mode w))) - (device (vif (mac aa:00:00:11:00:12) (bridge vnet97))) -) - -If you run another vm on the same vnet: - -(vm - (name dom11) - (memory '64') - (cpu '1') - (console '8501') - (image - (linux - (kernel /boot/vmlinuz-2.6-xenU) - (ip 192.0.2.11:192.0.2.4::::eth0:off) - (root /dev/sda1) - (args 'rw fastboot 4') - ) - ) - (device (vbd (uname phy:hda3) (dev sda1) (mode w))) - (device (vif (mac aa:00:00:11:00:11) (bridge vnet97))) -) - -the vms should be able to talk over the vnet. Check with ping. -If they are both on the same machine the connection will simply -be the vnet97 bridge, if they are on separate machines their -packets will be tunneled in udp (or etherip). They should be able to -see each other, but not the real network. - - diff --git a/vnet/src/examples/Makefile b/vnet/src/examples/Makefile deleted file mode 100644 index c3aab0c70e2..00000000000 --- a/vnet/src/examples/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/Rules.mk - -XEN_SCRIPT_DIR = $(DESTDIR)/etc/xen/scripts - -.PHONY: all -all: - -.PHONY: install -install: - $(INSTALL_DIR) $(XEN_SCRIPT_DIR) - $(INSTALL_PROG) network-vnet $(XEN_SCRIPT_DIR) - $(INSTALL_PROG) vnet-insert $(XEN_SCRIPT_DIR) - -.PHONY: clean -clean: diff --git a/vnet/src/examples/network-vnet b/vnet/src/examples/network-vnet deleted file mode 100755 index d644a48333a..00000000000 --- a/vnet/src/examples/network-vnet +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -scriptdir=/etc/xen/scripts/ - -case ${1} in - start) - ${scriptdir}/vnet-insert - ;; -esac - -${scriptdir}/network-bridge "$@" diff --git a/vnet/src/examples/vnet-insert b/vnet/src/examples/vnet-insert deleted file mode 100644 index 49269f6646f..00000000000 --- a/vnet/src/examples/vnet-insert +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Insert the vnet module if it can be found and -# it's not already there. -vnet_insert () { - local module="vnet_module" - local mod_dir=/lib/modules/$(uname -r) - local mod_obj="" - - if lsmod | grep -q ${module} ; then - echo "VNET: ${module} loaded" - return - fi - local mods=$(find ${mod_dir} -name "${module}.*o") - if [[ ${mods} ]] ; then - for mod_obj in ${mods} ; do - break - done - fi - if [ -z "${mod_obj}" ] ; then - echo "VNET: ${module} not found" - exit 1 - fi - echo "VNET: Loading ${module} from ${mod_obj}" - insmod ${mod_obj} "$@" -} - -vnet_insert "$@" diff --git a/vnet/src/examples/vnet97.sxp b/vnet/src/examples/vnet97.sxp deleted file mode 100644 index 1b4c1f4809e..00000000000 --- a/vnet/src/examples/vnet97.sxp +++ /dev/null @@ -1,2 +0,0 @@ -# Vnet configuration for a vnet with id 97 and no security. -(vnet (id 97) (bridge vnet97) (vnetif vnif97) (security none)) diff --git a/vnet/src/examples/vnet98.sxp b/vnet/src/examples/vnet98.sxp deleted file mode 100644 index 2f557ac5d87..00000000000 --- a/vnet/src/examples/vnet98.sxp +++ /dev/null @@ -1,2 +0,0 @@ -# Vnet configuration for a vnet with id 98 and message authentication. -(vnet (id 98) (bridge vnet98) (vnetif vnif98) (security auth)) diff --git a/vnet/src/examples/vnet99.sxp b/vnet/src/examples/vnet99.sxp deleted file mode 100644 index e6497e88d06..00000000000 --- a/vnet/src/examples/vnet99.sxp +++ /dev/null @@ -1,2 +0,0 @@ -# Vnet configuration for a vnet with id 99 and message confidentiality. -(vnet (id 99) (bridge vnet99) (vnif vnetif99) (security conf)) diff --git a/vnet/src/libxutil/Makefile b/vnet/src/libxutil/Makefile deleted file mode 100644 index 0c8ef6bb73e..00000000000 --- a/vnet/src/libxutil/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -ifndef VNET_ROOT -export VNET_ROOT = $(shell cd .. && pwd) -include $(VNET_ROOT)/Make.env -endif - -include $(XEN_ROOT)/tools/Rules.mk - -LIB_SRCS := -LIB_SRCS += allocate.c -LIB_SRCS += enum.c -LIB_SRCS += file_stream.c -#LIB_SRCS += gzip_stream.c -LIB_SRCS += hash_table.c -LIB_SRCS += iostream.c -LIB_SRCS += lexis.c -LIB_SRCS += mem_stream.c -LIB_SRCS += string_stream.c -LIB_SRCS += sxpr.c -LIB_SRCS += sxpr_parser.c -LIB_SRCS += sys_net.c -LIB_SRCS += sys_string.c -LIB_SRCS += util.c - -LIB_OBJS := $(LIB_SRCS:.c=.o) -PIC_OBJS := $(LIB_SRCS:.c=.opic) - -CFLAGS += -Werror -fno-strict-aliasing $(call cc-option,$(CC),-fgnu89-inline,) -CFLAGS += -O3 -#CFLAGS += -g - -# Get gcc to generate the dependencies for us. -CFLAGS += -Wp,-MD,.$(@F).d -DEPS = .*.d - -MAJOR := 3.0 -MINOR := 0 -LIB := libxutil.so -LIB += libxutil.so.$(MAJOR) -LIB += libxutil.so.$(MAJOR).$(MINOR) -LIB += libxutil.a - -.PHONY: all -all: build - -.PHONY: build -build: #check-for-zlib - $(MAKE) $(LIB) - -gzip_stream.o: check-for-zlib - -libxutil.so: libxutil.so.$(MAJOR) - ln -sf $^ $@ - -libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR) - ln -sf $^ $@ - -libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) $(CFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxutil.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ - -libxutil.a: $(LIB_OBJS) - $(AR) rc $@ $^ - -.PHONY: check-for-zlib -check-for-zlib: - @if [ ! -e /usr/include/zlib.h ]; then \ - echo "***********************************************************"; \ - echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \ - echo "***********************************************************"; \ - false; \ - fi - -.PHONY: install -install: build - $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) - $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR) - $(INSTALL_DATA) libxutil.a $(DESTDIR)$(LIBDIR) - ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxutil.so.$(MAJOR) - ln -sf libxutil.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxutil.so - -.PHONY: clean -clean: - -@$(RM) *.a *.so* *.o *.opic *.rpm - -@$(RM) *~ - -@$(RM) $(DEPS) - --include $(DEPS) diff --git a/vnet/src/libxutil/allocate.c b/vnet/src/libxutil/allocate.c deleted file mode 100644 index 600ebabda60..00000000000 --- a/vnet/src/libxutil/allocate.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "allocate.h" - -/** @file - * Support for allocating memory. - * Usable from user code or kernel code (with __KERNEL__ defined). - * In user code will use GC if USE_GC is defined. - */ - -#ifdef __KERNEL__ -/*----------------------------------------------------------------------------*/ -# include -# include -# include -# include - -# define DEFAULT_TYPE 0 -# define MALLOC(n, type) kmalloc(n, type) -# define FREE(ptr) kfree(ptr) - -/*----------------------------------------------------------------------------*/ -#else /* ! __KERNEL__ */ - -# include -# include - -# define DEFAULT_TYPE 0 - -#ifdef USE_GC -# include "gc.h" -# define MALLOC(n, typ) GC_malloc(n) -# define FREE(ptr) (ptr=NULL) -//typedef void *GC_PTR; -//GC_PTR (*GC_oom_fn)(size_t n); -#else -# define MALLOC(n, type) malloc(n) -# define FREE(ptr) free(ptr) -#endif - -/*----------------------------------------------------------------------------*/ -#endif - -/** Function to call when memory cannot be allocated. */ -AllocateFailedFn *allocate_failed_fn = NULL; - -/** Allocate memory and zero it. - * The type is only relevant when calling from kernel code, - * from user code it is ignored. - * In kernel code the values accepted by kmalloc can be used: - * GFP_USER, GFP_ATOMIC, GFP_KERNEL. - * - * @param size number of bytes to allocate - * @param type memory type to allocate (kernel only) - * @return pointer to the allocated memory or zero - * if malloc failed - */ -void *allocate_type(int size, int type){ - void *p = MALLOC(size, type); - if(p){ - memzero(p, size); - } else if(allocate_failed_fn){ - allocate_failed_fn(size, type); - } - return p; -} - -/** Allocate memory and zero it. - * - * @param size number of bytes to allocate - * @return pointer to the allocated memory or zero - * if malloc failed - */ -void *allocate(int size){ - return allocate_type(size, DEFAULT_TYPE); -} - -/** Free memory allocated by allocate(). - * No-op if 'p' is null. - * - * @param p memory to free - */ -void deallocate(void *p){ - if(p){ - FREE(p); - } -} - -/** Set bytes to zero. - * No-op if 'p' is null. - * - * @param p memory to zero - * @param size number of bytes to zero - */ -void memzero(void *p, int size){ - if(p){ - memset(p, 0, (size_t)size); - } -} - diff --git a/vnet/src/libxutil/allocate.h b/vnet/src/libxutil/allocate.h deleted file mode 100644 index 391b7be2bd9..00000000000 --- a/vnet/src/libxutil/allocate.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_ALLOCATE_H_ -#define _XUTIL_ALLOCATE_H_ - -/** Allocate memory for a given type, and cast. */ -#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype)) - -/** Allocate memory for a given type, and cast. */ -#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype)) - -extern void *allocate_type(int size, int type); -extern void *allocate(int size); -extern void deallocate(void *); -extern void memzero(void *p, int size); - -typedef void AllocateFailedFn(int size, int type); -extern AllocateFailedFn *allocate_failed_fn; - -#endif /* _XUTIL_ALLOCATE_H_ */ - - - - - - - - - diff --git a/vnet/src/libxutil/debug.h b/vnet/src/libxutil/debug.h deleted file mode 100644 index 78c801d9885..00000000000 --- a/vnet/src/libxutil/debug.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _XUTIL_DEBUG_H_ -#define _XUTIL_DEBUG_H_ - -#ifndef MODULE_NAME -#define MODULE_NAME "" -#endif - -#ifdef __KERNEL__ -#include -#include - -#ifdef DEBUG - -#define dprintf(fmt, args...) printk(KERN_DEBUG "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) -#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) -#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args) - -#else - -#define dprintf(fmt, args...) do {} while(0) -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args) -#define iprintf(fmt, args...) printk(KERN_INFO "[INF] " MODULE_NAME fmt, ##args) -#define eprintf(fmt, args...) printk(KERN_ERR "[ERR] " MODULE_NAME fmt, ##args) - -#endif - -#else - -#include - -#ifdef DEBUG - -#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) -#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) -#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) -#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args) - -#else - -#define dprintf(fmt, args...) do {} while(0) -#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args) -#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args) -#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args) - -#endif - -#endif - -/** Print format for an IP address. - * See NIPQUAD(), HIPQUAD() - */ -#define IPFMT "%u.%u.%u.%u" - -#endif /* ! _XUTIL_DEBUG_H_ */ diff --git a/vnet/src/libxutil/enum.c b/vnet/src/libxutil/enum.c deleted file mode 100644 index 95f6e31a871..00000000000 --- a/vnet/src/libxutil/enum.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2002, 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __KERNEL__ -#include -#else -#include -#endif - -#include "sys_string.h" -#include "enum.h" - -/** Map an enum name to its value using a table. - * - * @param name enum name - * @param defs enum definitions - * @return enum value or -1 if not known - */ -int enum_name_to_val(char *name, EnumDef *defs){ - int val = -1; - for(; defs->name; defs++){ - if(!strcmp(defs->name, name)){ - val = defs->val; - break; - } - } - return val; -} - -/** Map an enum value to its name using a table. - * - * @param val enum value - * @param defs enum definitions - * @param defs_n number of definitions - * @return enum name or NULL if not known - */ -char *enum_val_to_name(int val, EnumDef *defs){ - char *name = NULL; - for(; defs->name; defs++){ - if(val == defs->val){ - name = defs->name; - break; - } - } - return name; -} - diff --git a/vnet/src/libxutil/enum.h b/vnet/src/libxutil/enum.h deleted file mode 100644 index cdc0f6f1b11..00000000000 --- a/vnet/src/libxutil/enum.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2002, 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_ENUM_H_ -#define _XUTIL_ENUM_H_ - -/** Mapping of an enum value to a name. */ -typedef struct EnumDef { - int val; - char *name; -} EnumDef; - -extern int enum_name_to_val(char *name, EnumDef *defs); -extern char *enum_val_to_name(int val, EnumDef *defs); - -#endif /* _XUTIL_ENUM_H_ */ diff --git a/vnet/src/libxutil/fd_stream.c b/vnet/src/libxutil/fd_stream.c deleted file mode 100644 index 428f0a5ff0f..00000000000 --- a/vnet/src/libxutil/fd_stream.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * An IOStream implementation using fds. - */ -#ifndef __KERNEL__ - -#include -#include -#include -#include -#include -#include "allocate.h" -#include "fd_stream.h" - -#define MODULE_NAME "fd_stream" -#define DEBUG 1 -//#undef DEBUG -#include "debug.h" - -static int fd_read(IOStream *s, void *buf, size_t n); -static int fd_write(IOStream *s, const void *buf, size_t n); -static int fd_error(IOStream *s); -static int fd_close(IOStream *s); -static void fd_free(IOStream *s); -static int fd_flush(IOStream *s); - -/** Methods used by a fd IOStream. */ -static const IOMethods fd_methods = { - read: fd_read, - write: fd_write, - error: fd_error, - close: fd_close, - free: fd_free, - flush: fd_flush, -}; - -/** Get the fd data. - * - * @param io fd stream - * @return data - */ -static inline FDData * fd_data(IOStream *io){ - return (FDData *)io->data; -} - -/** Test if a stream is a fd stream. - * - * @param io stream - * @return 0 if a fd stream, -EINVAL if not - */ -int fd_stream_check(IOStream *io){ - return (io && io->methods == &fd_methods ? 0 : -EINVAL); -} - -/** Get the data for a fd stream. - * - * @param io stream - * @param data return value for the data - * @return 0 if a fd stream, -EINVAL if not - */ -int fd_stream_data(IOStream *io, FDData **data){ - int err = fd_stream_check(io); - if(err){ - *data = NULL; - } else { - *data = fd_data(io); - } - return err; -} - - -/** Write to the underlying fd. - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to write - * @return number of bytes written - */ -static int fd_write(IOStream *s, const void *buf, size_t n){ - FDData *data = fd_data(s); - int k; - k = write(data->fd, buf, n); - return k; -} - -/** Read from the underlying stream; - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to read - * @return number of bytes read - */ -static int fd_read(IOStream *s, void *buf, size_t n){ - FDData *data = fd_data(s); - int k; - k = read(data->fd, buf, n); - //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k); - return k; -} - -/** Flush the fd (no-op). - * - * @param s fd stream - * @return 0 on success, error code otherwise - */ -static int fd_flush(IOStream *s){ - return 0; -} - -/** Check if a fd stream has an error (no-op). - * - * @param s fd stream - * @return 1 if has an error, 0 otherwise - */ -static int fd_error(IOStream *s){ - return 0; -} - -/** Close a fd stream. - * - * @param s fd stream to close - * @return result of the close - */ -static int fd_close(IOStream *s){ - FDData *data = fd_data(s); - return close(data->fd); -} - -/** Free a fd stream. - * - * @param s fd stream - */ -static void fd_free(IOStream *s){ - FDData *data = fd_data(s); - deallocate(data); -} - -/** Create an IOStream for a fd. - * - * @param fd fd to wtap - * @return new IOStream using fd for i/o - */ -IOStream *fd_stream_new(int fd){ - int err = -ENOMEM; - IOStream *io = NULL; - FDData *data = NULL; - - io = ALLOCATE(IOStream); - if(!io) goto exit; - io->methods = &fd_methods; - data = ALLOCATE(FDData); - if(!data) goto exit; - io->data = data; - data->fd = fd; - err = 0; - exit: - if(err){ - if(io){ - if(data) deallocate(data); - deallocate(io); - io = NULL; - } - } - return io; -} - -#endif diff --git a/vnet/src/libxutil/fd_stream.h b/vnet/src/libxutil/fd_stream.h deleted file mode 100644 index b37a6863e29..00000000000 --- a/vnet/src/libxutil/fd_stream.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XMC_FD_STREAM_H_ -#define _XMC_FD_STREAM_H_ - -#ifndef __KERNEL__ -#include "iostream.h" - -/** Data associated with a fd stream. */ -typedef struct FDData { - /** The socket file descriptor. */ - int fd; -} FDData; - -extern IOStream *fd_stream_new(int fd); -extern int fd_stream_data(IOStream *io, FDData **data); -extern int fd_stream_check(IOStream *io); - -#endif -#endif /* !_XMC_FD_STREAM_H_ */ diff --git a/vnet/src/libxutil/file_stream.c b/vnet/src/libxutil/file_stream.c deleted file mode 100644 index 188e647f8f2..00000000000 --- a/vnet/src/libxutil/file_stream.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * An IOStream implementation using FILE*. - */ -#ifndef __KERNEL__ -#include -#include -#include -#include "allocate.h" -#include "file_stream.h" - -static int file_read(IOStream *s, void *buf, size_t n); -static int file_write(IOStream *s, const void *buf, size_t n); -static int file_error(IOStream *s); -static int file_close(IOStream *s); -static void file_free(IOStream *s); -static int file_flush(IOStream *s); - -/** Methods used by a FILE* IOStream. */ -static const IOMethods file_methods = { - read: file_read, - write: file_write, - error: file_error, - close: file_close, - free: file_free, - flush: file_flush, -}; - -/** IOStream for stdin. */ -static IOStream _iostdin = { - methods: &file_methods, - data: (void*)1, - nofree: 1, -}; - -/** IOStream for stdout. */ -static IOStream _iostdout = { - methods: &file_methods, - data: (void*)2, - nofree: 1, -}; - -/** IOStream for stderr. */ -static IOStream _iostderr = { - methods: &file_methods, - data: (void*)3, - nofree: 1, -}; - -/** IOStream for stdin. */ -IOStream *iostdin = &_iostdin; - -/** IOStream for stdout. */ -IOStream *iostdout = &_iostdout; - -/** IOStream for stderr. */ -IOStream *iostderr = &_iostderr; - -/* Get the underlying FILE*. - * - * @param s file stream - * @return the stream s wraps - */ -static inline FILE *get_file(IOStream *s){ - FILE *data = NULL; - switch((long)s->data){ - case 1: - data = stdin; - break; - case 2: - data = stdout; - break; - case 3: - data = stderr; - break; - default: - data = (FILE*)s->data; - break; - } - return data; -} - -/** Control buffering on the underlying stream, like setvbuf(). - * - * @param io file stream - * @param buf buffer - * @param mode buffering mode (see man setvbuf()) - * @param size buffer size - * @return 0 on success, non-zero otherwise - */ -int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){ - return setvbuf(get_file(io), buf, mode, size); -} - -/** Write to the underlying stream using fwrite(); - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to write - * @return number of bytes written - */ -static int file_write(IOStream *s, const void *buf, size_t n){ - int cnt = 0; - unsigned char *ptr = (unsigned char*)buf; - while (n) { - if ((cnt = fwrite((const void *)(ptr), sizeof(unsigned char), n, get_file(s))) < 0) { - if (errno == EINTR) - continue; - else - return -1; - } - n -= cnt; - ptr += cnt; - } - - return n; -} - -/** Read from the underlying stream using fread(); - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to read - * @return number of bytes read - */ -static int file_read(IOStream *s, void *buf, size_t n){ - return fread(buf, 1, n, get_file(s)); -} - -/** Fush the underlying stream using fflush(). - * - * @param s file stream - * @return 0 on success, error code otherwise - */ -static int file_flush(IOStream *s){ - return fflush(get_file(s)); -} - -/** Check if a stream has an error. - * - * @param s file stream - * @return 1 if has an error, 0 otherwise - */ -static int file_error(IOStream *s){ - return ferror(get_file(s)); -} - -/** Close a file stream. - * - * @param s file stream to close - * @return result of the close - */ -static int file_close(IOStream *s){ - int result = 0; - result = fclose(get_file(s)); - return result; -} - -/** Free a file stream. - * - * @param s file stream - */ -static void file_free(IOStream *s){ - // Nothing extra to do - close did it all. -} - -/** Create an IOStream for a stream. - * - * @param f stream to wrap - * @return new IOStream using f for i/o - */ -IOStream *file_stream_new(FILE *f){ - IOStream *io = ALLOCATE(IOStream); - if(io){ - io->methods = &file_methods; - io->data = (void*)f; - } - return io; -} - -/** IOStream version of fopen(). - * - * @param file name of the file to open - * @param flags giving the mode to open in (as for fopen()) - * @return new stream for the open file, or 0 if failed - */ -IOStream *file_stream_fopen(const char *file, const char *flags){ - IOStream *io = 0; - FILE *fin = fopen(file, flags); - if(fin){ - io = file_stream_new(fin); - if(!io){ - fclose(fin); - } - } - return io; -} - -/** IOStream version of fdopen(). - * - * @param fd file descriptor - * @param flags giving the mode to open in (as for fdopen()) - * @return new stream for the open file, or 0 if failed. Always takes - * ownership of fd. - */ -IOStream *file_stream_fdopen(int fd, const char *flags){ - IOStream *io = 0; - FILE *fin = fdopen(fd, flags); - if(fin){ - io = file_stream_new(fin); - if(!io){ - fclose(fin); - } - } - return io; -} -#endif diff --git a/vnet/src/libxutil/file_stream.h b/vnet/src/libxutil/file_stream.h deleted file mode 100644 index f717656c240..00000000000 --- a/vnet/src/libxutil/file_stream.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_FILE_STREAM_H_ -#define _XUTIL_FILE_STREAM_H_ - -#ifndef __KERNEL__ -#include "iostream.h" -#include - -extern IOStream *file_stream_new(FILE *f); -extern IOStream *file_stream_fopen(const char *file, const char *flags); -extern IOStream *file_stream_fdopen(int fd, const char *flags); -extern IOStream get_stream_stdout(void); -extern IOStream get_stream_stderr(void); -extern IOStream get_stream_stdin(void); - -extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size); -#endif -#endif /* !_XUTIL_FILE_STREAM_H_ */ diff --git a/vnet/src/libxutil/gzip_stream.c b/vnet/src/libxutil/gzip_stream.c deleted file mode 100644 index ea14b825807..00000000000 --- a/vnet/src/libxutil/gzip_stream.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2003 Hewlett-Packard Company. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * An IOStream implementation using zlib gzFile to provide - * compression and decompression. - */ -#ifndef __KERNEL__ - -#include -#include - -#include "zlib.h" - -#include "allocate.h" -#include "gzip_stream.h" - -static int gzip_read(IOStream *s, void *buf, size_t n); -static int gzip_write(IOStream *s, const void *buf, size_t n); -static int gzip_error(IOStream *s); -static int gzip_close(IOStream *s); -static void gzip_free(IOStream *s); -static int gzip_flush(IOStream *s); - -/** Methods used by a gzFile* IOStream. */ -static const IOMethods gzip_methods = { - read: gzip_read, - write: gzip_write, - error: gzip_error, - close: gzip_close, - free: gzip_free, - flush: gzip_flush, -}; - -/** Get the underlying gzFile*. - * - * @param s gzip stream - * @return the stream s wraps - */ -static inline gzFile get_gzfile(IOStream *s){ - return (gzFile)s->data; -} - -/** Write to the underlying stream. - * - * @param stream destination - * @param buf data - * @param n number of bytes to write - * @return number of bytes written - */ -static int gzip_write(IOStream *s, const void *buf, size_t n){ - return gzwrite(get_gzfile(s), (void*)buf, n); -} - -/** Read from the underlying stream. - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to read - * @return number of bytes read - */ -static int gzip_read(IOStream *s, void *buf, size_t n){ - return gzread(get_gzfile(s), buf, n); -} - -/** Flush the underlying stream. - * - * @param s gzip stream - * @return 0 on success, error code otherwise - */ -static int gzip_flush(IOStream *s){ - //return gzflush(get_gzfile(s), Z_NO_FLUSH); - return gzflush(get_gzfile(s), Z_SYNC_FLUSH); - //return gzflush(get_gzfile(s), Z_FULL_FLUSH); -} - -/** Check if a stream has an error. - * - * @param s gzip stream - * @return 1 if has an error, 0 otherwise - */ -static int gzip_error(IOStream *s){ - int err; - gzFile *gz = get_gzfile(s); - gzerror(gz, &err); - return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err); -} - -/** Close a gzip stream. - * - * @param s gzip stream to close - * @return result of the close - */ -static int gzip_close(IOStream *s){ - int result = 0; - result = gzclose(get_gzfile(s)); - return result; -} - -/** Free a gzip stream. - * - * @param s gzip stream - */ -static void gzip_free(IOStream *s){ - // Nothing to do - close did it all. -} - -/** Create an IOStream for a gzip stream. - * - * @param f stream to wrap - * @return new IOStream using f for i/o - */ -IOStream *gzip_stream_new(gzFile *f){ - IOStream *io = ALLOCATE(IOStream); - if(io){ - io->methods = &gzip_methods; - io->data = (void*)f; - } - return io; -} - -/** IOStream version of fopen(). - * - * @param file name of the file to open - * @param flags giving the mode to open in (as for fopen()) - * @return new stream for the open file, or NULL if failed - */ -IOStream *gzip_stream_fopen(const char *file, const char *flags){ - IOStream *io = NULL; - gzFile *fgz; - fgz = gzopen(file, flags); - if(fgz){ - io = gzip_stream_new(fgz); - if(!io){ - gzclose(fgz); - } - } - return io; -} - -/** IOStream version of fdopen(). - * - * @param fd file descriptor - * @param flags giving the mode to open in (as for fdopen()) - * @return new stream for the open file, or NULL if failed. Always takes - * ownership of fd. - */ -IOStream *gzip_stream_fdopen(int fd, const char *flags){ - IOStream *io = NULL; - gzFile *fgz; - fgz = gzdopen(fd, flags); - if(fgz){ - io = gzip_stream_new(fgz); - if(!io) - gzclose(fgz); - } - return io; -} -#endif diff --git a/vnet/src/libxutil/gzip_stream.h b/vnet/src/libxutil/gzip_stream.h deleted file mode 100644 index fd28e39575a..00000000000 --- a/vnet/src/libxutil/gzip_stream.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2003 Hewlett-Packard Company. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_GZIP_STREAM_H_ -#define _XUTIL_GZIP_STREAM_H_ - -#ifndef __KERNEL__ -#include "iostream.h" -#include "zlib.h" - -extern IOStream *gzip_stream_new(gzFile *f); -extern IOStream *gzip_stream_fopen(const char *file, const char *flags); -extern IOStream *gzip_stream_fdopen(int fd, const char *flags); -#endif -#endif /* !_XUTIL_GZIP_STREAM_H_ */ diff --git a/vnet/src/libxutil/hash_table.c b/vnet/src/libxutil/hash_table.c deleted file mode 100644 index 1e2af26bb0c..00000000000 --- a/vnet/src/libxutil/hash_table.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) 2001 - 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __KERNEL__ -# include -# include -# include -# include -#else -# include -# include -#endif - -#include "allocate.h" -#include "hash_table.h" - -/** @file - * Base support for hashtables. - * - * Hash codes are reduced modulo the number of buckets to index tables, - * so there is no need for hash functions to limit the range of hashcodes. - * In fact it is assumed that hashcodes do not change when the number of - * buckets in the table changes. - */ - -/*============================================================================*/ -/* --------------------------------------------------------------------- -lookup2.c, by Bob Jenkins, December 1996, Public Domain. -You can use this free for any purpose. It has no warranty. --------------------------------------------------------------------- -*/ - -#define hashsize(n) ((ub4)1<<(n)) -#define hashmask(n) (hashsize(n)-1) - -/* --------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. -For every delta with one or two bit set, and the deltas of all three - high bits or all three low bits, whether the original value of a,b,c - is almost all zero or is uniformly distributed, -* If mix() is run forward or backward, at least 32 bits in a,b,c - have at least 1/4 probability of changing. -* If mix() is run forward, every bit of c will change between 1/3 and - 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) -mix() was built out of 36 single-cycle latency instructions in a - structure that could supported 2x parallelism, like so: - a -= b; - a -= c; x = (c>>13); - b -= c; a ^= x; - b -= a; x = (a<<8); - c -= a; b ^= x; - c -= b; x = (b>>13); - ... - Unfortunately, superscalar Pentiums and Sparcs can't take advantage - of that parallelism. They've also turned some of those single-cycle - latency instructions into multi-cycle latency instructions. Still, - this is the fastest good hash I could find. There were about 2^^68 - to choose from. I only looked at a billion or so. --------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ -} - -/* --------------------------------------------------------------------- -hash() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - len : the length of the key, counting by bytes - level : can be any 4-byte value -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Every 1-bit and 2-bit delta achieves avalanche. -About 36+6len instructions. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (ub1 **)k, do it like this: - for (i=0, h=0; i= 12) - { - a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24)); - b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24)); - c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24)); - mix(a,b,c); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch(len) /* all the case statements fall through */ - { - case 11: c+=((ub4)k[10]<<24); - case 10: c+=((ub4)k[9]<<16); - case 9 : c+=((ub4)k[8]<<8); - /* the first byte of c is reserved for the length */ - case 8 : b+=((ub4)k[7]<<24); - case 7 : b+=((ub4)k[6]<<16); - case 6 : b+=((ub4)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((ub4)k[3]<<24); - case 3 : a+=((ub4)k[2]<<16); - case 2 : a+=((ub4)k[1]<<8); - case 1 : a+=k[0]; - /* case 0: nothing left to add */ - } - mix(a,b,c); - /*-------------------------------------------- report the result */ - return c; -} - -ub4 hash(const ub1 *k, ub4 length, ub4 initval){ - return _hash(k, length, initval); -} - -/*============================================================================*/ - -/** Get the bucket for a hashcode in a hash table. - * - * @param table to get bucket from - * @param hashcode to get bucket for - * @return bucket - */ -inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){ - return table->buckets + (hashcode % table->buckets_n); -} - -/** Initialize a hash table. - * - * @param table to initialize - */ -static void HashTable_init(HashTable *table){ - int i; - - for(i = 0; i < table->buckets_n; i++){ - HTBucket *bucket = get_bucket(table, i); - bucket->head = NULL; - bucket->count = 0; - } - table->entry_count = 0; -} - -/** Allocate a new hashtable. - * If the number of buckets is not positive the default is used. - * - * @param buckets_n number of buckets - * @return new hashtable or null - */ -HashTable *HashTable_new(int buckets_n){ - HashTable *z = ALLOCATE(HashTable); - if(!z) goto exit; - if(buckets_n <= 0){ - buckets_n = HT_BUCKETS_N; - } - z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); - if(!z->buckets){ - deallocate(z); - z = NULL; - goto exit; - } - z->buckets_n = buckets_n; - HashTable_init(z); - exit: - return z; -} - -/** Free a hashtable. - * Any entries are removed and freed. - * - * @param h hashtable (ignored if null) - */ -void HashTable_free(HashTable *h){ - if(h){ - HashTable_clear(h); - deallocate(h->buckets); - deallocate(h); - } -} - -/** Push an entry on the list in the bucket for a given hashcode. - * - * @param table to add entry to - * @param hashcode for the entry - * @param entry to add - */ -static inline void push_on_bucket(HashTable *table, Hashcode hashcode, - HTEntry *entry){ - HTBucket *bucket; - HTEntry *old_head; - - bucket = get_bucket(table, hashcode); - old_head = bucket->head; - bucket->count++; - bucket->head = entry; - entry->next = old_head; -} - -/** Change the number of buckets in a hashtable. - * No-op if the number of buckets is not positive. - * Existing entries are reallocated to buckets based on their hashcodes. - * The table is unmodified if the number of buckets cannot be changed. - * - * @param table hashtable - * @param buckets_n new number of buckets - * @return 0 on success, error code otherwise - */ -int HashTable_set_buckets_n(HashTable *table, int buckets_n){ - int err = 0; - HTBucket *old_buckets = table->buckets; - int old_buckets_n = table->buckets_n; - int i; - - if(buckets_n <= 0){ - err = -EINVAL; - goto exit; - } - table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket)); - if(!table->buckets){ - err = -ENOMEM; - table->buckets = old_buckets; - goto exit; - } - table->buckets_n = buckets_n; - for(i=0; i < old_buckets_n; i++){ - HTBucket *bucket = old_buckets + i; - HTEntry *entry, *next; - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - push_on_bucket(table, entry->hashcode, entry); - } - } - deallocate(old_buckets); - exit: - return err; -} - -/** Adjust the number of buckets so the table is neither too full nor too empty. - * The table is unmodified if adjusting fails. - * - * @param table hash table - * @param buckets_min minimum number of buckets (use default if 0 or negative) - * @return 0 on success, error code otherwise - */ -int HashTable_adjust(HashTable *table, int buckets_min){ - int buckets_n = 0; - int err = 0; - if(buckets_min <= 0) buckets_min = HT_BUCKETS_N; - if(table->entry_count >= table->buckets_n){ - // The table is dense - expand it. - buckets_n = 2 * table->buckets_n; - } else if((table->buckets_n > buckets_min) && - (4 * table->entry_count < table->buckets_n)){ - // The table is more than minimum size and sparse - shrink it. - buckets_n = 2 * table->entry_count; - if(buckets_n < buckets_min) buckets_n = buckets_min; - } - if(buckets_n){ - err = HashTable_set_buckets_n(table, buckets_n); - } - return err; -} - -/** Allocate a new entry for a given value. - * - * @param value to put in the entry - * @return entry, or 0 on failure - */ -HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){ - HTEntry *z = ALLOCATE(HTEntry); - if(z){ - z->hashcode = hashcode; - z->key = key; - z->value = value; - } - return z; -} - -/** Free an entry. - * - * @param z entry to free - */ -inline void HTEntry_free(HTEntry *z){ - if(z){ - deallocate(z); - } -} - -/** Free an entry in a hashtable. - * The table's entry_free_fn is used is defined, otherwise - * the HTEntry itself is freed. - * - * @param table hashtable - * @param entry to free - */ -inline void HashTable_free_entry(HashTable *table, HTEntry *entry){ - if(!entry) return; - if(table && table->entry_free_fn){ - table->entry_free_fn(table, entry); - } else { - HTEntry_free(entry); - } -} - -/** Get the first entry satisfying a test from the bucket for the - * given hashcode. - * - * @param table to look in - * @param hashcode indicates the bucket - * @param test_fn test to apply to elements - * @param arg first argument to calls to test_fn - * @return entry found, or 0 - */ -inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, - TableTestFn *test_fn, TableArg arg){ - HTBucket *bucket; - HTEntry *entry = NULL; - HTEntry *next; - - bucket = get_bucket(table, hashcode); - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - if(test_fn(arg, table, entry)){ - break; - } - } - return entry; -} - -/** Test hashtable keys for equality. - * Uses the table's key_equal_fn if defined, otherwise pointer equality. - * - * @param key1 key to compare - * @param key2 key to compare - * @return 1 if equal, 0 otherwise - */ -inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){ - if(table->key_size){ - return memcmp(key1, key2, table->key_size) == 0; - } - return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == key2); -} - -/** Compute the hashcode of a hashtable key. - * The table's key_hash_fn is used if defined, otherwise the address of - * the key is hashed. - * - * @param table hashtable - * @param key to hash - * @return hashcode - */ -inline Hashcode HashTable_key_hash(HashTable *table, void *key){ - if(table->key_size){ - return _hash(key, table->key_size, 0); - } - return (table->key_hash_fn - ? table->key_hash_fn(key) - : hash_hvoid(0, &key, sizeof(key))); -} - -/** Test if an entry has a given key. - * - * @param arg containing key to test for - * @param table the entry is in - * @param entry to test - * @return 1 if the entry has the key, 0 otherwise - */ -static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){ - return HashTable_key_equal(table, arg.ptr, entry->key); -} - -/** Get an entry with a given key. - * - * @param table to search - * @param key to look for - * @return entry if found, null otherwise - */ -inline HTEntry * HashTable_get_entry(HashTable *table, void *key){ - Hashcode hashcode; - HTBucket *bucket; - HTEntry *entry = NULL; - HTEntry *next; - - hashcode = HashTable_key_hash(table, key); - bucket = get_bucket(table, hashcode); - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - if(HashTable_key_equal(table, key, entry->key)){ - break; - } - } - return entry; -} - -/** Get the value of an entry with a given key. - * - * @param table to search - * @param key to look for - * @return value if an entry was found, null otherwise - */ -inline void * HashTable_get(HashTable *table, void *key){ - HTEntry *entry = HashTable_get_entry(table, key); - return (entry ? entry->value : 0); -} - -/** Print the buckets in a table. - * - * @param table to print - */ -void show_buckets(HashTable *table, IOStream *io){ - int i,j ; - IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n); - for(i=0; i < table->buckets_n; i++){ - if(0 || table->buckets[i].count>0){ - IOStream_print(io, "bucket %3d %3d %10p ", i, - table->buckets[i].count, - table->buckets[i].head); - for(j = table->buckets[i].count; j>0; j--){ - IOStream_print(io, "+"); - } - IOStream_print(io, "\n"); - } - } - HashTable_print(table, io); -} - -/** Print an entry in a table. - * - * @param entry to print - * @param arg a pointer to an IOStream to print to - * @return 0 - */ -static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){ - IOStream *io = (IOStream*)arg.ptr; - IOStream_print(io, " b=%4lx h=%08lx |-> e=%8p k=%8p v=%8p\n", - entry->hashcode % table->buckets_n, - entry->hashcode, - entry, entry->key, entry->value); - return 0; -} - -/** Print a hash table. - * - * @param table to print - */ -void HashTable_print(HashTable *table, IOStream *io){ - IOStream_print(io, "{\n"); - HashTable_map(table, print_entry, (TableArg){ ptr: io }); - IOStream_print(io, "}\n"); -} -/*==========================================================================*/ - -/** Add an entry to the bucket for the - * given hashcode. - * - * @param table to insert in - * @param hashcode indicates the bucket - * @param key to add an entry for - * @param value to add an entry for - * @return entry on success, 0 on failure - */ -inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){ - HTEntry *entry = HTEntry_new(hashcode, key, value); - if(entry){ - push_on_bucket(table, hashcode, entry); - table->entry_count++; - } - return entry; -} - -/** Move the front entry for a bucket to the correct point in the bucket order as - * defined by the order function. If this is called every time a new entry is added - * the bucket will be maintained in sorted order. - * - * @param table to modify - * @param hashcode indicates the bucket - * @param order entry comparison function - * @return 0 if an entry was moved, 1 if not - */ -int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){ - HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL; - HTBucket *bucket; - int err = 1; - - bucket = get_bucket(table, hashcode); - new_entry = bucket->head; - if(!new_entry || !new_entry->next) goto exit; - for(entry = new_entry->next; entry; prev = entry, entry = entry->next){ - if(order(new_entry, entry) <= 0) break; - } - if(prev){ - err = 0; - bucket->head = new_entry->next; - new_entry->next = entry; - prev->next = new_entry; - } - exit: - return err; -} - -/** Add an entry to a hashtable. - * The entry is added to the bucket for its key's hashcode. - * - * @param table to insert in - * @param key to add an entry for - * @param value to add an entry for - * @return entry on success, 0 on failure - */ -inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){ - return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value); -} - -/** Remove entries satisfying a test from the bucket for the - * given hashcode. - * - * @param table to remove from - * @param hashcode indicates the bucket - * @param test_fn test to apply to elements - * @param arg first argument to calls to test_fn - * @return number of entries removed - */ -inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode, - TableTestFn *test_fn, TableArg arg){ - HTBucket *bucket; - HTEntry *entry, *prev = NULL, *next; - int removed_count = 0; - - bucket = get_bucket(table, hashcode); - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - if(test_fn(arg, table, entry)){ - if(prev){ - prev->next = next; - } else { - bucket->head = next; - } - bucket->count--; - table->entry_count--; - removed_count++; - HashTable_free_entry(table, entry); - entry = NULL; - } - prev = entry; - } - return removed_count; -} - -/** Remove entries with a given key. - * - * @param table to remove from - * @param key of entries to remove - * @return number of entries removed - */ -inline int HashTable_remove(HashTable *table, void *key){ - Hashcode hashcode; - HTBucket *bucket; - HTEntry *entry, *prev = NULL, *next; - int removed_count = 0; - - hashcode = HashTable_key_hash(table, key); - bucket = get_bucket(table, hashcode); - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - if(HashTable_key_equal(table, key, entry->key)){ - if(prev){ - prev->next = next; - } else { - bucket->head = next; - } - bucket->count--; - table->entry_count--; - removed_count++; - HashTable_free_entry(table, entry); - entry = NULL; - } - prev = entry; - } - return removed_count; -} - -/** Remove (and free) all the entries in a bucket. - * - * @param bucket to clear - */ -static inline void bucket_clear(HashTable *table, HTBucket *bucket){ - HTEntry *entry, *next; - - for(entry = bucket->head; entry; entry = next){ - next = entry->next; - HashTable_free_entry(table, entry); - } - bucket->head = NULL; - table->entry_count -= bucket->count; - bucket->count = 0; -} - -/** Remove (and free) all the entries in a table. - * - * @param table to clear - */ -void HashTable_clear(HashTable *table){ - int i, n = table->buckets_n; - - for(i = 0; i < n; i++){ - bucket_clear(table, table->buckets + i); - } -} diff --git a/vnet/src/libxutil/hash_table.h b/vnet/src/libxutil/hash_table.h deleted file mode 100644 index beae2fb05e1..00000000000 --- a/vnet/src/libxutil/hash_table.h +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (C) 2001 - 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_HASH_TABLE_H_ -#define _XUTIL_HASH_TABLE_H_ - -#include "iostream.h" -#include "sys_string.h" - -typedef unsigned long Hashcode; - -/** Type used to pass parameters to table functions. */ -typedef union TableArg { - unsigned long ul; - void *ptr; -} TableArg; - -/** An entry in a bucket list. */ -typedef struct HTEntry { - /** Hashcode of the entry's key. */ - Hashcode hashcode; - /** The key for this entry. */ - void *key; - /** The value in this entry. */ - void *value; - /** The next entry in the list. */ - struct HTEntry *next; -} HTEntry; - -/** A bucket in a rule table. */ -typedef struct HTBucket { - /** Number of entries in the bucket. */ - int count; - /** First entry in the bucket (may be null). */ - HTEntry *head; -} HTBucket; - -/** Default number of buckets in a hash table. - * You want enough buckets so the lists in the buckets will typically be short. - * If the hash function is good it doesn't matter whether the number of - * buckets is prime or not. - */ -//#define HT_BUCKETS_N 1 -//#define HT_BUCKETS_N 3 -//#define HT_BUCKETS_N 7 -//#define HT_BUCKETS_N 17 -//#define HT_BUCKETS_N 97 -//#define HT_BUCKETS_N 211 -//#define HT_BUCKETS_N 401 -#define HT_BUCKETS_N 1021 - -typedef struct HashTable HashTable; - -/** Type for a function used to select table entries. */ -typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry); - -/** Type for a function to map over table entries. */ -typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry); - -/** Type for a function to free table entries. */ -typedef void TableFreeFn(HashTable *table, HTEntry *entry); - -/** Type for a function to hash table keys. */ -typedef Hashcode TableHashFn(void *key); - -/** Type for a function to test table keys for equality. */ -typedef int TableEqualFn(void *key1, void *key2); - -/** Type for a function to order table entries. */ -typedef int TableOrderFn(HTEntry *e1, HTEntry *e2); - -/** General hash table. - * A hash table with a list in each bucket. - * Functions can be supplied for freeing entries, hashing keys, and comparing keys. - * These all default to 0, when default behaviour treating keys as integers is used. - */ -struct HashTable { - /** Array of buckets, each with its own list. */ - HTBucket *buckets; - /** Number of buckets in the bucket array. */ - int buckets_n; - /** Number of entries in the table. */ - int entry_count; - unsigned long key_size; - /** Function to free keys and values in entries. */ - TableFreeFn *entry_free_fn; - /** Function to hash keys. */ - TableHashFn *key_hash_fn; - /** Function to compare keys for equality. */ - TableEqualFn *key_equal_fn; - /** Place for the user of the table to hang extra data. */ - void *user_data; -}; - -extern HashTable *HashTable_new(int bucket_n); -extern void HashTable_free(HashTable *table); -extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value); -extern void HTEntry_free(HTEntry *entry); -extern int HashTable_set_bucket_n(HashTable *table, int bucket_n); -extern void HashTable_clear(HashTable *table); -extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value); -extern HTEntry * HashTable_get_entry(HashTable *table, void *key); -extern HTEntry * HashTable_add(HashTable *table, void *key, void *value); -extern void * HashTable_get(HashTable *table, void *key); -extern int HashTable_remove(HashTable *table, void *key); -extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode, - TableTestFn *test_fn, TableArg arg); -extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode, - TableTestFn *test_fn, TableArg arg); -extern void HashTable_print(HashTable *table, IOStream *out); -extern int HashTable_set_buckets_n(HashTable *table, int buckets_n); -extern int HashTable_adjust(HashTable *table, int buckets_min); - -extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order); - -typedef unsigned long ub4; -typedef unsigned char ub1; - -extern ub4 hash(const ub1 *k, ub4 length, ub4 initval); - -/** Hash some bytes starting with a given hashcode. - * - * @param h initial hashcode - use 0, a previous hash, or an arbitrary value - * @param b bytes to hash - * @param b_n number of bytes to hash - * @return hashcode - */ -static inline Hashcode hash_hvoid(Hashcode h, const void *b, unsigned b_n){ - return hash(b, b_n, h); -} - -/** Hash a string (null-terminated). - * - * @param s input to hash - * @return hashcode - */ -static inline Hashcode hash_string(char *s){ - return (s ? hash_hvoid(0, s, strlen(s)) : 0); -} - -/** Macro to declare variables for HashTable_for_each() to use. - * - * @param entry variable that is set to entries in the table - */ -#define HashTable_for_decl(entry) \ - HashTable *_var_table; \ - HTBucket *_var_bucket; \ - HTBucket *_var_end; \ - HTEntry *_var_next; \ - HTEntry *entry - -/** Macro to iterate over the entries in a hashtable. - * Must be in a scope where HashTable_for_decl() has been used to declare - * variables for it to use. - * The variable 'entry' is iterated over entries in the table. - * The code produced is syntactically a loop, so it must be followed by - * a loop body, typically some statements in braces: - * HashTable_for_each(entry, table){ ...loop body... } - * - * HashTable_for_each() and HashTable_for_decl() cannot be used for nested - * loops as variables will clash. - * - * @note The simplest way to code a direct loop over the entries in a hashtable - * is to use a loop over the buckets, with a nested loop over the entries - * in a bucket. Using this approach in a macro means the macro contains - * an opening brace, and calls to it must be followed by 2 braces! - * To avoid this the code has been restructured so that it is a for loop. - * So that statements could be used in the test expression of the for loop, - * we have used the gcc statement expression extension ({ ... }). - * - * @param entry variable to iterate over the entries - * @param table to iterate over (non-null) - */ -#define HashTable_for_each(entry, table) \ - _var_table = table; \ - _var_bucket = _var_table->buckets; \ - _var_end = _var_bucket + _var_table->buckets_n; \ - for(entry=0, _var_next=0; \ - ({ if(_var_next){ \ - entry = _var_next; \ - _var_next = entry->next; \ - } else { \ - while(_var_bucket < _var_end){ \ - entry = _var_bucket->head; \ - _var_bucket++; \ - if(entry){ \ - _var_next = entry->next; \ - break; \ - } \ - } \ - }; \ - entry; }); \ - entry = _var_next ) - -/** Map a function over the entries in a table. - * Mapping stops when the function returns a non-zero value. - * Uses the gcc statement expression extension ({ ... }). - * - * @param table to map over - * @param fn function to apply to entries - * @param arg first argument to call the function with - * @return 0 if fn always returned 0, first non-zero value otherwise - */ -#define HashTable_map(table, fn, arg) \ - ({ HashTable_for_decl(_var_entry); \ - TableArg _var_arg = arg; \ - int _var_value = 0; \ - HashTable_for_each(_var_entry, table){ \ - if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \ - } \ - _var_value; }) - -/** Cast x to the type for a key or value in a hash table. - * This avoids compiler warnings when using short integers - * as keys or values (especially on 64-bit platforms). - */ -#define HKEY(x) ((void*)(unsigned long)(x)) - -/** Cast x from the type for a key or value in a hash table. - * to an unsigned long. This avoids compiler warnings when using - * short integers as keys or values (especially on 64-bit platforms). - */ -#define HVAL(x) ((unsigned long)(x)) - -#endif /* !_XUTIL_HASH_TABLE_H_ */ diff --git a/vnet/src/libxutil/iostream.c b/vnet/src/libxutil/iostream.c deleted file mode 100644 index 39a62173ad6..00000000000 --- a/vnet/src/libxutil/iostream.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "iostream.h" -#include "sys_string.h" - -/** Print on a stream, like vfprintf(). - * - * @param stream to print to - * @param format for the print (as fprintf()) - * @param args arguments to print - * @return result code from the print - */ -int IOStream_vprint(IOStream *stream, const char *format, va_list args){ - char buffer[1024]; - int k = sizeof(buffer), n; - - n = vsnprintf(buffer, k, (char*)format, args); - if(n < 0 || n > k ){ - n = k; - } - n = IOStream_write(stream, buffer, n); - return n; -} - -/** Print on a stream, like fprintf(). - * - * @param stream to print to - * @param format for the print (as fprintf()) - * @return result code from the print - */ -int IOStream_print(IOStream *stream, const char *format, ...){ - va_list args; - int result = -1; - - va_start(args, format); - result = IOStream_vprint(stream, format, args); - va_end(args); - return result; -} diff --git a/vnet/src/libxutil/iostream.h b/vnet/src/libxutil/iostream.h deleted file mode 100644 index f41ca56629f..00000000000 --- a/vnet/src/libxutil/iostream.h +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_IOSTREAM_H_ -#define _XUTIL_IOSTREAM_H_ - -#include - -#ifdef __KERNEL__ -#include -#include -#include -#else -#include -#include -#include -#endif - -#include "allocate.h" - -/** End of input return value (for getc). */ -#define IOSTREAM_EOF -1 - -/** An input/output abstraction. - */ -typedef struct IOStream IOStream; - -/** Record of the functions to use for operations on an - * IOStream implementation. - */ -typedef struct IOMethods { - /** Read function. Called with the user data, buffer to read into - * and number of bytes to read. Must return number of bytes read - * on success, less than zero on error. - */ - int (*read)(IOStream *stream, void *buf, size_t n); - - /** Write function. Called with user data, buffer to write and - * number of bytes to write. Must return number of bytes written on - * success, less than zero otherwise. - */ - int (*write)(IOStream *stream, const void *buf, size_t n); - - int (*flush)(IOStream *s); - - int (*error)(IOStream *s); - - int (*close)(IOStream *s); - - void (*free)(IOStream *s); - - void (*lock)(IOStream *s); - void (*unlock)(IOStream *s); - -} IOMethods; - -/** Abstract i/o object. - */ -struct IOStream { - /** Methods to use to implement operations. */ - const IOMethods *methods; - /** Private state for the implementation. */ - const void *data; - /** Flag indicating whether the stream is closed. */ - int closed; - /** Number of bytes written. */ - int written; - /** Number of bytes read. */ - int read; - /** Flag indicating whether not to free when closed. */ - int nofree; -}; - - -/** IOStream version of stdin. */ -extern IOStream *iostdin; - -/** IOStream version of stdout, */ -extern IOStream *iostdout; - -/** IOStream version of stderr. */ -extern IOStream *iostderr; - -extern int IOStream_print(IOStream *io, const char *format, ...); -extern int IOStream_vprint(IOStream *io, const char *format, va_list args); - -/** Read from a stream. - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to read - * @return if ok, number of bytes read, otherwise negative error code - */ -static inline int IOStream_read(IOStream *stream, void *buf, size_t n){ - int result; - if(stream->closed){ - result = -EIO; - goto exit; - } - if(!stream->methods || !stream->methods->read){ - result = -EINVAL; - goto exit; - } - result = (stream->methods->read)(stream, buf, n); - if(result > 0){ - stream->read += result; - } - exit: - return result; -} - -/** Write to a stream. - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to write - * @return if ok, number of bytes written, otherwise negative error code - */ -static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){ - int result; - if(stream->closed){ - result = -EIO; - goto exit; - } - if(!stream->methods || !stream->methods->write){ - result = -EINVAL; - goto exit; - } - result = (stream->methods->write)(stream, buf, n); - if(result > 0){ - stream->written += result; - } - exit: - return result; -} - -/** Flush the stream. - * - * @param stream stream - * @return 0 on success, negative error code otherwise - */ -static inline int IOStream_flush(IOStream *stream){ - int result = 0; - if(stream->closed){ - result = -EIO; - } else if(stream->methods->flush){ - result = (stream->methods->flush)(stream); - } - return result; -} - -/** Check whether the stream has an error. - * - * @param stream to check - * @return 1 for error, 0 otherwise - */ -static inline int IOStream_error(IOStream *stream){ - int err = 0; - if(stream->methods && stream->methods->error){ - err = (stream->methods->error)(stream); - } - return err; -} - -/** Close the stream. - * - * @param stream to close - * @return 0 on success, negative error code otherwise - */ -static inline int IOStream_close(IOStream *stream){ - int err = 0; - if(!stream || stream->closed){ - err = -EIO; - goto exit; - } - if(stream->methods && stream->methods->close){ - err = (stream->methods->close)(stream); - stream->closed = 1; - } - if(stream->nofree) goto exit; - if(stream->methods && stream->methods->free){ - (stream->methods->free)(stream); - } - *stream = (IOStream){}; - deallocate(stream); - exit: - return err; -} - -/** Test if the stream has been closed. - * - * @param stream to check - * @return 1 if closed, 0 otherwise - */ -static inline int IOStream_is_closed(IOStream *stream){ - return stream->closed; -} - -/** Print a character to a stream, like fputc(). - * - * @param stream to print to - * @param c character to print - * @return result code from the print - */ -static inline int IOStream_putc(IOStream *stream, int c){ - int err; - unsigned char b = (unsigned char)c; - err = IOStream_write(stream, &b, 1); - if(err < 1){ - err = IOSTREAM_EOF; - } else { - err = b; - } - return err; -} - -/** Read from a stream, like fgetc(). - * - * @param stream to read from - * @return IOSTREAM_EOF on error, character read otherwise - */ -static inline int IOStream_getc(IOStream *stream){ - int err, rc; - unsigned char b; - - err = IOStream_read(stream, &b, 1); - if(err < 1){ - rc = IOSTREAM_EOF; - } else { - rc = b; - } - return rc; -} - -/** Get number of bytes read. - * - * @param stream to get from - * @return number of bytes read - */ -static inline int IOStream_get_read(IOStream *stream){ - return stream->read; -} - -/** Get number of bytes written. - * - * @param stream to get from - * @return number of bytes written - */ -static inline int IOStream_get_written(IOStream *stream){ - return stream->written; -} - - -#endif /* ! _XUTIL_IOSTREAM_H_ */ diff --git a/vnet/src/libxutil/kernel_stream.c b/vnet/src/libxutil/kernel_stream.c deleted file mode 100644 index 3c6b55223db..00000000000 --- a/vnet/src/libxutil/kernel_stream.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * An IOStream implementation using printk() for output. - * Input is not implemented. - */ -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include -#include - -#include "kernel_stream.h" -#include "allocate.h" - -/** Number of characters in the output buffer. - * The kernel uses 1024 for printk, so that should suffice. - */ -#define BUF_N 1024 - -/** State for a kernel stream. */ -typedef struct KernelData { - /** Stream lock. We need a lock to serialize access to the stream. */ - spinlock_t lock; - /** Saved flags for locking. */ - unsigned long flags; - /** Size of the output buffer. */ - int buf_n; - /** Output buffer. */ - char buf[BUF_N]; -} KernelData; - -static int kernel_write(IOStream *s, const void *msg, size_t n); -static void kernel_free(IOStream *s); -static void kernel_stream_lock(IOStream *s); -static void kernel_stream_unlock(IOStream *s); - -/** Methods for a kernel stream. Output only. */ -static const IOMethods kernel_methods = { - write: kernel_write, - free: kernel_free, - lock: kernel_stream_lock, - unlock: kernel_stream_unlock, -}; - -/** Shared state for kernel streams. - * All implementations write using printk, so we can use - * shared state and avoid allocating it. - */ -static const KernelData kernel_data = { - lock: SPIN_LOCK_UNLOCKED, - flags: 0, - buf_n: BUF_N, -}; - -/** Stream for kernel printk. */ -static IOStream iokernel = { - methods: &kernel_methods, - data: &kernel_data, - nofree: 1, -}; - -/** Stream for kernel printk. */ -IOStream *iostdout = &iokernel; - -/** Stream for kernel printk. */ -IOStream *iostdin = &iokernel; - -/** Stream for kernel printk. */ -IOStream *iostderr = &iokernel; - -/** Get an output-only stream implementation using - * printk(). The stream uses static storage, and must not be freed. - * - * @return kernel stream - */ -IOStream get_stream_kernel(void){ - return iokernel; -} - -/** Obtain the lock on the stream state. - * - * @param kdata stream state - */ -static inline void KernelData_lock(KernelData *kdata){ - spin_lock_irqsave(&kdata->lock, kdata->flags); -} - -/** Release the lock on the stream state. - * - * @param kdata stream state - */ -static inline void KernelData_unlock(KernelData *kdata){ - spin_unlock_irqrestore(&kdata->lock, kdata->flags); -} - -/** Get the stream state. - * - * @param s kernel stream - * @return stream state - */ -static inline KernelData *get_kernel_data(IOStream *s){ - return (KernelData*)s->data; -} - -/** Obtain the lock on the stream state. - * - * @param s stream - */ -void kernel_stream_lock(IOStream *s){ - KernelData_lock(get_kernel_data(s)); -} - -/** Release the lock on the stream state. - * - * @param s stream - */ -void kernel_stream_unlock(IOStream *s){ - KernelData_unlock(get_kernel_data(s)); -} - -/** Write to a kernel stream. - * - * @param stream kernel stream - * @param format print format - * @param args print arguments - * @return result of the print - */ -static int kernel_write(IOStream *stream, const void *buf, size_t n){ - KernelData *kdata = get_kernel_data(stream); - int k; - k = kdata->buf_n - 1; - if(n < k) k = n; - memcpy(kdata->buf, buf, k); - kdata->buf[k] = '\0'; - printk(kdata->buf); - return k; -} - -/** Free a kernel stream. - * Frees the internal state of the stream. - * Do not call this unless the stream was dynamically allocated. - * Do not call this on a stream returned from get_stream_kernel(). - * - * @param io stream to free - */ -static void kernel_free(IOStream *io){ - KernelData *kdata; - if(io == &iokernel) return; - kdata = get_kernel_data(io); - memset(kdata, 0, sizeof(*kdata)); - deallocate(kdata); -} -#endif /* __KERNEL__ */ - - - - diff --git a/vnet/src/libxutil/kernel_stream.h b/vnet/src/libxutil/kernel_stream.h deleted file mode 100644 index 0f18058d59a..00000000000 --- a/vnet/src/libxutil/kernel_stream.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_KERNEL_STREAM_H_ -#define _XUTIL_KERNEL_STREAM_H_ - -#ifdef __KERNEL__ -#include "iostream.h" - -extern IOStream get_stream_kernel(void); -#define get_stream_stdout get_stream_kernel - -#endif /* __KERNEL__ */ -#endif /* !_XUTIL_KERNEL_STREAM_H_ */ diff --git a/vnet/src/libxutil/lexis.c b/vnet/src/libxutil/lexis.c deleted file mode 100644 index d3441f0c381..00000000000 --- a/vnet/src/libxutil/lexis.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * Lexical analysis. - */ - -#include "sys_string.h" -#include "lexis.h" -#include - -/** Check if a value lies in a (closed) range. - * - * @param x value to test - * @param lo low end of the range - * @param hi high end of the range - * @return 1 if x is in the interval [lo, hi], 0 otherwise - */ -inline static int in_range(int x, int lo, int hi){ - return (lo <= x) && (x <= hi); -} - -/** Determine if a string is an (unsigned) decimal number. - * - * @param s pointer to characters to test - * @param n length of string - * @return 1 if s is a decimal number, 0 otherwise. - */ -int is_decimal_number(const char *s, int n){ - int i; - if(n <= 0)return 0; - for(i = 0; i < n; i++){ - if(!in_decimal_digit_class(s[i])) return 0; - } - return 1; -} - -/** Determine if a string is a hex number. - * Hex numbers are 0, or start with 0x or 0X followed - * by a non-zero number of hex digits (0-9,a-f,A-F). - * - * @param s pointer to characters to test - * @param n length of string - * @return 1 if s is a hex number, 0 otherwise. - */ -int is_hex_number(const char *s, int n){ - int i; - if(n <= 0) return 0; - if(n == 1){ - return s[0]=='0'; - } - if(n <= 3) return 0; - if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0; - for(i = 2; i < n; i++){ - if(!in_hex_digit_class(s[i])) return 0; - } - return 1; -} - -/** Test if a string matches a keyword. - * The comparison is case-insensitive. - * The comparison fails if either argument is null. - * - * @param s string - * @param k keyword - * @return 1 if they match, 0 otherwise - */ -int is_keyword(const char *s, const char *k){ - return s && k && !strcasecmp(s, k); -} - -/** Test if a string matches a character. - * - * @param s string - * @param c character (non-null) - * @return 1 if s contains exactly c, 0 otherwise - */ -int is_keychar(const char *s, char c){ - return c && (s[0] == c) && !s[1]; -} diff --git a/vnet/src/libxutil/lexis.h b/vnet/src/libxutil/lexis.h deleted file mode 100644 index d49a3547d67..00000000000 --- a/vnet/src/libxutil/lexis.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_LEXIS_H_ -#define _XUTIL_LEXIS_H_ - -#include "sys_string.h" - -#ifdef __KERNEL__ -# include -#else -# include -#endif - -/** @file - * Lexical analysis. - */ - -/** Class of characters treated as space. */ -#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 }) - -/** Class of separator characters. */ -#define sep_class "{}()<>[]!;\"'" - -#define comment_class "#" - -/** Determine if a character is in a given class. - * - * @param c character to test - * @param s null-terminated string of characters in the class - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_class(int c, const char *s){ - return s && (strchr(s, c) != 0); -} - -/** Determine if a character is in the space class. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_space_class(int c){ - return in_class(c, space_class); -} - -static inline int in_comment_class(int c){ - return in_class(c, comment_class); -} - -/** Determine if a character is in the separator class. - * Separator characters terminate tokens, and do not need space - * to separate them. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_sep_class(int c){ - return in_class(c, sep_class); -} - -/** Determine if a character is in the alpha class. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_alpha_class(int c){ - return isalpha(c); -} - -/** Determine if a character is in the octal digit class. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_octal_digit_class(int c){ - return '0' <= c && c <= '7'; -} - -/** Determine if a character is in the decimal digit class. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_decimal_digit_class(int c){ - return isdigit(c); -} - -/** Determine if a character is in the hex digit class. - * - * @param c character to test - * @return 1 if c is in the class, 0 otherwise. - */ -static inline int in_hex_digit_class(int c){ - return isdigit(c) || in_class(c, "abcdefABCDEF"); -} - - -static inline int in_string_quote_class(int c){ - return in_class(c, "'\""); -} - -static inline int in_printable_class(int c){ - return ('A' <= c && c <= 'Z') - || ('a' <= c && c <= 'z') - || ('0' <= c && c <= '9') - || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~"); -} - -extern int is_decimal_number(const char *s, int n); -extern int is_hex_number(const char *s, int n); -extern int is_keyword(const char *s, const char *k); -extern int is_keychar(const char *s, char c); - -#endif /* !_XUTIL_LEXIS_H_ */ diff --git a/vnet/src/libxutil/mem_stream.c b/vnet/src/libxutil/mem_stream.c deleted file mode 100644 index 0a846a19e5a..00000000000 --- a/vnet/src/libxutil/mem_stream.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * IOStream subtype for input and output to memory. - * Usable from user or kernel code (with __KERNEL__ defined). - */ - -#include "sys_string.h" -#include "mem_stream.h" -#include "allocate.h" - -/** Internal state for a memory stream. - * - * The memory stream buffer is treated as a circular buffer. - * The lo and hi markers indicate positions in the buffer, but - * are not reduced modulo the buffer size. This avoids the ambiguity - * between a full and empty buffer when using reduced values. - * - * If x is a marker, then buf + (x % buf_n) is the corresponding - * pointer into the buffer. When the buffer is empty, lo == hi, - * and the corresponding pointers are equal. When the buffer is - * full, hi == lo + buf_n, and the corresponding pointers - * are also equal. - * - * Data is written after the high pointer and read from the lo pointer. - * The value hi - lo is the number of bytes in the buffer. - */ -typedef struct MemData { - /** Data buffer. */ - char *buf; - /** Low marker - start of readable area. */ - unsigned long lo; - /** High marker - end of readable area, start of writeable area. */ - unsigned long hi; - /** Size of the buffer. */ - unsigned int buf_n; - /** Maximum size the buffer can grow to. */ - unsigned int buf_max; - /** Error code. */ - int err; -} MemData; - -/** Get number of bytes available to read. - * - * @param data mem stream - * @return bytes - */ -static inline int mem_len(struct MemData *data){ - return data->hi - data->lo; -} - -/** Get available space left in the buffer. - * - * @param data mem stream - * @return bytes - */ -static inline int mem_room(struct MemData *data){ - return data->buf_n - mem_len(data); -} - -/** Get a pointer to the start of the data in the buffer. - * - * @param data mem stream - * @return lo pointer - */ -static inline char * mem_lo(struct MemData *data){ - return data->buf + (data->lo % data->buf_n); -} - -/** Get a pointer to the end of the data in the buffer. - * - * @param data mem stream - * @return hi pointer - */ -static inline char * mem_hi(struct MemData *data){ - return data->buf + (data->hi % data->buf_n); -} - -/** Get a pointer to the end of the buffer. - * - * @param data mem stream - * @return end pointer - */ -static inline char * mem_end(struct MemData *data){ - return data->buf + data->buf_n; -} - -static int mem_error(IOStream *io); -static int mem_close(IOStream *io); -static void mem_free(IOStream *io); -static int mem_write(IOStream *io, const void *msg, size_t n); -static int mem_read(IOStream *io, void *buf, size_t n); - -/** Minimum delta used to increment the buffer. */ -static int delta_min = 256; - -/** Methods for a memory stream. */ -static IOMethods mem_methods = { - read: mem_read, - write: mem_write, - error: mem_error, - close: mem_close, - free: mem_free, -}; - -/** Get the memory stream state. - * - * @param io memory stream - * @return state - */ -static inline MemData *get_mem_data(IOStream *io){ - return (MemData*)io->data; -} - -/** Get the number of bytes available to read. - * - * @param io memory stream - * @return number of bytes - */ -int mem_stream_avail(IOStream *io){ - MemData *data = get_mem_data(io); - return (data->err ? -data->err : mem_len(data)); -} - -/** Copy bytes from a memory stream into a buffer. - * - * @param data mem stream - * @param buf buffer - * @param n number of bytes to copy - */ -static void mem_get(MemData *data, char *buf, size_t n){ - char *start = mem_lo(data); - char *end = mem_end(data); - if (start + n < end) { - memcpy(buf, start, n); - } else { - int k = end - start; - memcpy(buf, start, k); - memcpy(buf + k, data->buf, n - k); - } -} - -/** Copy bytes from a buffer into a memory stream. - * - * @param data mem stream - * @param buf buffer - * @param n number of bytes to copy - */ -static void mem_put(MemData *data, const char *buf, size_t n){ - char *start = mem_hi(data); - char *end = mem_end(data); - if(start + n < end){ - memcpy(start, buf, n); - } else { - int k = end - start; - memcpy(start, buf, k); - memcpy(data->buf, buf + k, n - k); - } -} - -/** Expand the buffer used by a memory stream. - * - * @param data mem stream - * @param extra number of bytes to expand by - * @return 0 on success, negative error otherwise - */ -static int mem_expand(MemData *data, size_t extra){ - int err = -ENOMEM; - int delta = (extra < delta_min ? delta_min : extra); - int buf_n; - char *buf; - if(data->buf_max > 0){ - int delta_max = data->buf_max - data->buf_n; - if(delta > delta_max){ - delta = extra; - if(delta > delta_max) goto exit; - } - } - buf_n = data->buf_n + delta; - buf = allocate(buf_n); - if(!buf) goto exit; - mem_get(data, buf, mem_len(data)); - data->hi = mem_len(data); - data->lo = 0; - deallocate(data->buf); - data->buf = buf; - data->buf_n = buf_n; - err = 0; - exit: - if(err){ - data->err = -err; - } - return err; -} - -/** Write bytes from a buffer into a memory stream. - * The internal buffer is expanded as needed to hold the data, - * up to the stream maximum (if specified). If the buffer cannot - * be expanded -ENOMEM is returned. - * - * @param io mem stream - * @param buf buffer - * @param n number of bytes to write - * @return number of bytes written on success, negative error code otherwise - */ -static int mem_write(IOStream *io, const void *msg, size_t n){ - int room; - MemData *data = get_mem_data(io); - if(data->err) return -data->err; - room = mem_room(data); - if(n > room){ - int err = mem_expand(data, n - room); - if(err) return err; - } - mem_put(data, msg, n); - data->hi += n; - return n; -} - -/** Read bytes from a memory stream into a buffer. - * - * @param io mem stream - * @param buf buffer - * @param n maximum number of bytes to read - * @return number of bytes read on success, negative error code otherwise - */ -static int mem_read(IOStream *io, void *buf, size_t n){ - int k; - MemData *data = get_mem_data(io); - if(data->err) return -data->err; - k = mem_len(data); - if(n > k){ - n = k; - } - mem_get(data, buf, n); - data->lo += n; - return n; -} - -/** Test if a memory stream has an error. - * - * @param io mem stream - * @return 0 if ok, error code otherwise - */ -static int mem_error(IOStream *io){ - MemData *data = get_mem_data(io); - return data->err; -} - -/** Close a memory stream. - * - * @param io mem stream - * @return 0 - */ -static int mem_close(IOStream *io){ - MemData *data = get_mem_data(io); - if(!data->err){ - data->err = ENOTCONN; - } - return 0; -} - -/** Free a memory stream. - * - * @param io mem stream - */ -static void mem_free(IOStream *io){ - MemData *data = get_mem_data(io); - deallocate(data->buf); - memzero(data, sizeof(*data)); - deallocate(data); -} - -/** Allocate and initialise a memory stream. - * - * @param buf_n initial buffer size (0 means default) - * @param buf_max maximum buffer size (0 means no max) - * @return new stream (free using IOStream_close) - */ -IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max){ - int err = -ENOMEM; - MemData *data = ALLOCATE(MemData); - IOStream *io = NULL; - if(!data) goto exit; - io = ALLOCATE(IOStream); - if(!io) goto exit; - if(buf_n <= delta_min){ - buf_n = delta_min; - } - if(buf_max > 0 && buf_max < buf_n){ - buf_max = buf_n; - } - data->buf = allocate(buf_n); - if(!data->buf) goto exit; - data->buf_n = buf_n; - data->buf_max = buf_max; - io->methods = &mem_methods; - io->data = data; - io->nofree = 0; - err = 0; - exit: - if(err){ - deallocate(data); - deallocate(io); - io = NULL; - } - return io; -} diff --git a/vnet/src/libxutil/mem_stream.h b/vnet/src/libxutil/mem_stream.h deleted file mode 100644 index 01089665972..00000000000 --- a/vnet/src/libxutil/mem_stream.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_MEM_STREAM_H_ -#define _XUTIL_MEM_STREAM_H_ - -#include "iostream.h" - -extern IOStream *mem_stream_new_size(size_t buf_n, size_t buf_max); - -extern int mem_stream_avail(IOStream *io); - -static inline IOStream *mem_stream_new(void){ - return mem_stream_new_size(0, 0); -} - -#endif /* !_XUTIL_MEM_STREAM_H_ */ diff --git a/vnet/src/libxutil/socket_stream.c b/vnet/src/libxutil/socket_stream.c deleted file mode 100644 index 9e90b4e06eb..00000000000 --- a/vnet/src/libxutil/socket_stream.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * An IOStream implementation using sockets. - */ -#ifndef __KERNEL__ - -#include -#include -#include -#include -#include -#include "allocate.h" -#include "socket_stream.h" - -#define MODULE_NAME "sock" -#define DEBUG 0 -//#undef DEBUG -#include "debug.h" - -static int socket_read(IOStream *s, void *buf, size_t n); -static int socket_write(IOStream *s, const void *buf, size_t n); -static int socket_error(IOStream *s); -static int socket_close(IOStream *s); -static void socket_free(IOStream *s); -static int socket_flush(IOStream *s); - -/** Methods used by a socket IOStream. */ -static const IOMethods socket_methods = { - read: socket_read, - write: socket_write, - error: socket_error, - close: socket_close, - free: socket_free, - flush: socket_flush, -}; - -/** Get the socket data. - * - * @param io socket stream - * @return data - */ -static inline SocketData * socket_data(IOStream *io){ - return (SocketData *)io->data; -} - -/** Test if a stream is a socket stream. - * - * @param io stream - * @return 0 if a socket stream, -EINVAL if not - */ -int socket_stream_check(IOStream *io){ - return (io && io->methods == &socket_methods ? 0 : -EINVAL); -} - -/** Get the data for a socket stream. - * - * @param io stream - * @param data return value for the data - * @return 0 if a socket stream, -EINVAL if not - */ -int socket_stream_data(IOStream *io, SocketData **data){ - int err = socket_stream_check(io); - if(err){ - *data = NULL; - } else { - *data = socket_data(io); - } - return err; -} - -/** Set the destination address for a socket stream. - * - * @param io stream - * @param addr address - * @return 0 if a socket stream, -EINVAL if not - */ -int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){ - int err = 0; - SocketData *data = NULL; - err = socket_stream_data(io, &data); - if(!err){ - data->daddr = *addr; - } - return err; -} - -/** Set the send flags for a socket stream. - * - * @param io stream - * @param flags flags - * @return 0 if a socket stream, -EINVAL if not - */ -int socket_stream_set_flags(IOStream *io, int flags){ - int err = 0; - SocketData *data = NULL; - err = socket_stream_data(io, &data); - if(!err){ - data->flags = flags; - } - return err; -} - -/** Write to the underlying socket using sendto. - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to write - * @return number of bytes written - */ -static int socket_write(IOStream *s, const void *buf, size_t n){ - SocketData *data = socket_data(s); - struct sockaddr *daddr = (struct sockaddr *)&data->daddr; - socklen_t daddr_n = sizeof(data->daddr); - int k; - dprintf("> sock=%d addr=%s:%d n=%d\n", - data->fd, inet_ntoa(data->daddr.sin_addr), ntohs(data->daddr.sin_port), n); - if(0){ - struct sockaddr_in self = {}; - socklen_t self_n; - getsockname(data->fd, (struct sockaddr *)&self, &self_n); - dprintf("> sockname sock=%d %s:%d\n", - data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port)); - } - k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n); - dprintf("> sendto=%d\n", k); - return k; -} - -/** Read from the underlying stream using recv(); - * - * @param stream input - * @param buf where to put input - * @param n number of bytes to read - * @return number of bytes read - */ -static int socket_read(IOStream *s, void *buf, size_t n){ - SocketData *data = socket_data(s); - int k; - struct sockaddr *saddr = (struct sockaddr *)&data->saddr; - socklen_t saddr_n = sizeof(data->saddr); - k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n); - return k; -} - -/** Flush the socket (no-op). - * - * @param s socket stream - * @return 0 on success, error code otherwise - */ -static int socket_flush(IOStream *s){ - return 0; -} - -/** Check if a socket stream has an error (no-op). - * - * @param s socket stream - * @return 1 if has an error, 0 otherwise - */ -static int socket_error(IOStream *s){ - // Read SOL_SOCKET/SO_ERROR ? - return 0; -} - -/** Close a socket stream. - * - * @param s socket stream to close - * @return result of the close - */ -static int socket_close(IOStream *s){ - SocketData *data = socket_data(s); - return close(data->fd); -} - -/** Free a socket stream. - * - * @param s socket stream - */ -static void socket_free(IOStream *s){ - SocketData *data = socket_data(s); - deallocate(data); -} - -/** Create an IOStream for a socket. - * - * @param fd socket to wtap - * @return new IOStream using fd for i/o - */ -IOStream *socket_stream_new(int fd){ - int err = -ENOMEM; - IOStream *io = NULL; - SocketData *data = NULL; - - io = ALLOCATE(IOStream); - if(!io) goto exit; - io->methods = &socket_methods; - data = ALLOCATE(SocketData); - if(!data) goto exit; - io->data = data; - data->fd = fd; - data->buf_n = sizeof(data->buf); - err = 0; - exit: - if(err){ - if(io){ - if(data) deallocate(data); - deallocate(io); - io = NULL; - } - } - return io; -} - -#endif diff --git a/vnet/src/libxutil/socket_stream.h b/vnet/src/libxutil/socket_stream.h deleted file mode 100644 index 9da23e9f01e..00000000000 --- a/vnet/src/libxutil/socket_stream.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XEN_LIB_SOCKET_STREAM_H_ -#define _XEN_LIB_SOCKET_STREAM_H_ - -#ifndef __KERNEL__ -#include "iostream.h" -#include - -#include -#include -#include - -/** Data associated with a socket stream. */ -typedef struct SocketData { - /** The socket file descriptor. */ - int fd; - /** Source address from last read (recvfrom). */ - struct sockaddr_in saddr; - /** Destination address for writes (sendto). */ - struct sockaddr_in daddr; - /** Write flags (sendto). */ - int flags; - /** Buffer size. */ - int buf_n; - /** Buffer for formatted printing. */ - char buf[1024]; -} SocketData; - -extern IOStream *socket_stream_new(int fd); -extern int socket_stream_data(IOStream *io, SocketData **data); -extern int socket_stream_check(IOStream *io); -extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr); -extern int socket_stream_set_flags(IOStream *io, int flags); - -#endif -#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */ diff --git a/vnet/src/libxutil/string_stream.c b/vnet/src/libxutil/string_stream.c deleted file mode 100644 index 907e7d70ee5..00000000000 --- a/vnet/src/libxutil/string_stream.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** @file - * IOStream subtype for input and output to strings. - * Usable from user or kernel code (with __KERNEL__ defined). - */ - -#include "sys_string.h" -#include "string_stream.h" -#include "allocate.h" - -static int string_error(IOStream *io); -static int string_close(IOStream *io); -static void string_free(IOStream *io); -static int string_write(IOStream *io, const void *msg, size_t n); -static int string_read(IOStream *io, void *buf, size_t n); - -/** Methods for a string stream. */ -static IOMethods string_methods = { - read: string_read, - write: string_write, - error: string_error, - close: string_close, - free: string_free, -}; - -/** Get the string stream state. - * - * @param io string stream - * @return state - */ -static inline StringData *get_string_data(IOStream *io){ - return (StringData*)io->data; -} - -static int string_write(IOStream *io, const void *msg, size_t n){ - StringData *data = get_string_data(io); - int k; - - k = data->end - data->out; - if(n > k) n = k; - memcpy(data->out, msg, n); - data->out += n; - return n; -} - -static int string_read(IOStream *io, void *buf, size_t n){ - StringData *data = get_string_data(io); - int k; - - k = data->end - data->in; - if(n > k) n = k; - memcpy(buf, data->in, k); - data->in += n; - return n; -} - -/** Test if a string stream has an error. - * - * @param io string stream - * @return 0 if ok, error code otherwise - */ -static int string_error(IOStream *io){ - StringData *data = get_string_data(io); - return data->out == NULL; -} - -/** Close a string stream. - * - * @param io string stream - * @return 0 - */ -static int string_close(IOStream *io){ - StringData *data = get_string_data(io); - data->in = NULL; - data->out = NULL; - return 0; -} - -/** Free a string stream. - * The stream state is freed, but the underlying string is not. - * - * @param io string stream - */ -static void string_free(IOStream *io){ - StringData *data = get_string_data(io); - memzero(data, sizeof(*data)); - deallocate(data); -} - -/** Get the methods to use for a string stream. - * - * @return methods - */ -IOMethods *string_stream_get_methods(void){ - return &string_methods; -} - -/** Initialise a string stream, usually from static data. - * If the stream and StringData should be freed when - * the stream is closed, unset io->nofree. - * The string is not freed on close. - * - * @param io address of IOStream to fill in - * @param data address of StringData to fill in - * @param s string to use - * @param n length of the string - */ -void string_stream_init(IOStream *io, StringData *data, char *s, int n){ - if(data && io){ - memzero(data, sizeof(*data)); - data->string = (char*)s; - data->in = data->string; - data->out = data->string; - data->size = n; - data->end = data->string + n; - memzero(io, sizeof(*io)); - io->methods = &string_methods; - io->data = data; - io->nofree = 1; - } -} - -/** Allocate and initialise a string stream. - * The stream is freed on close, but the string is not. - * - * @param s string to use - * @param n length of the string - * @return new stream (free using IOStream_free) - */ -IOStream *string_stream_new(char *s, int n){ - int ok = 0; - StringData *data = ALLOCATE(StringData); - IOStream *io = ALLOCATE(IOStream); - if(data && io){ - ok = 1; - string_stream_init(io, data, s, n); - io->nofree = 0; - } - if(!ok){ - deallocate(data); - deallocate(io); - io = NULL; - } - return io; -} diff --git a/vnet/src/libxutil/string_stream.h b/vnet/src/libxutil/string_stream.h deleted file mode 100644 index 246e63d2fe8..00000000000 --- a/vnet/src/libxutil/string_stream.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_STRING_STREAM_H_ -#define _XUTIL_STRING_STREAM_H_ - -#include "iostream.h" - -/** Internal state for a string stream. - * Exposed here so that string streams can be statically created, using - * string_stream_init(). - */ -typedef struct { - /** The string used for input and ouput. */ - char *string; - /** Output pointer. */ - char *out; - /** Input pointer. */ - char *in; - /** Length of string. */ - int size; - /** End marker. */ - char *end; -} StringData; - -extern IOMethods *string_stream_get_methods(void); -extern IOStream *string_stream_new(char *s, int n); -extern void string_stream_init(IOStream *stream, StringData *data, char *s, int n); - -#endif /* !_XUTIL_STRING_STREAM_H_ */ diff --git a/vnet/src/libxutil/sxpr.c b/vnet/src/libxutil/sxpr.c deleted file mode 100644 index e107b9b8b37..00000000000 --- a/vnet/src/libxutil/sxpr.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "sys_string.h" -#include "lexis.h" -#include "sys_net.h" -#include "hash_table.h" -#include "sxpr.h" - -#ifdef __KERNEL__ -#include -#else -#include -#endif - -#ifdef __KERNEL__ -#include - -int rand(void){ - int v; - get_random_bytes(&v, sizeof(v)); - return v; -} - -#else -#include -#endif - -#undef free - -/** @file - * General representation of sxprs. - * Includes print, equal, and free functions for the sxpr types. - * - * Zero memory containing an Sxpr will have the value ONONE - this is intentional. - * When a function returning an sxpr cannot allocate memory we return ONOMEM. - * - */ - -static int atom_print(IOStream *io, Sxpr obj, unsigned flags); -static int atom_equal(Sxpr x, Sxpr y); -static void atom_free(Sxpr obj); -static Sxpr atom_copy(Sxpr obj); - -static int string_print(IOStream *io, Sxpr obj, unsigned flags); -static int string_equal(Sxpr x, Sxpr y); -static void string_free(Sxpr obj); -static Sxpr string_copy(Sxpr obj); - -static int cons_print(IOStream *io, Sxpr obj, unsigned flags); -static int cons_equal(Sxpr x, Sxpr y); -static void cons_free(Sxpr obj); -static Sxpr cons_copy(Sxpr obj); - -static int null_print(IOStream *io, Sxpr obj, unsigned flags); -static int none_print(IOStream *io, Sxpr obj, unsigned flags); -static int int_print(IOStream *io, Sxpr obj, unsigned flags); -static int bool_print(IOStream *io, Sxpr obj, unsigned flags); -static int err_print(IOStream *io, Sxpr obj, unsigned flags); -static int nomem_print(IOStream *io, Sxpr obj, unsigned flags); - -/** Type definitions. */ -static SxprType types[1024] = { - [T_NONE] { .type= T_NONE, .name= "none", .print= none_print }, - [T_NULL] { .type= T_NULL, .name= "null", .print= null_print }, - [T_UINT] { .type= T_UINT, .name= "int", .print= int_print, }, - [T_BOOL] { .type= T_BOOL, .name= "bool", .print= bool_print, }, - [T_ERR] { .type= T_ERR, .name= "err", .print= err_print, }, - [T_NOMEM] { .type= T_ERR, .name= "nomem", .print= nomem_print, }, - [T_ATOM] { .type= T_ATOM, .name= "atom", .print= atom_print, - .pointer= TRUE, - .free= atom_free, - .equal= atom_equal, - .copy= atom_copy, - }, - [T_STRING] { .type= T_STRING, .name= "string", .print= string_print, - .pointer= TRUE, - .free= string_free, - .equal= string_equal, - .copy= string_copy, - }, - [T_CONS] { .type= T_CONS, .name= "cons", .print= cons_print, - .pointer= TRUE, - .free= cons_free, - .equal= cons_equal, - .copy= cons_copy, - }, -}; - -/** Number of entries in the types array. */ -static int type_sup = sizeof(types)/sizeof(types[0]); - -/** Define a type. - * The tydef must have a non-zero type code. - * It is an error if the type code is out of range or already defined. - * - * @param tydef type definition - * @return 0 on success, error code otherwise - */ -int def_sxpr_type(SxprType *tydef){ - int err = 0; - int ty = tydef->type; - if(ty < 0 || ty >= type_sup){ - err = -EINVAL; - goto exit; - } - if(types[ty].type){ - err = -EEXIST; - goto exit; - } - types[ty] = *tydef; - exit: - return err; - -} - -/** Get the type definition for a given type code. - * - * @param ty type code - * @return type definition or null - */ -SxprType *get_sxpr_type(int ty){ - if(0 <= ty && ty < type_sup){ - return types+ty; - } - return NULL; -} - -/** The default print function. - * - * @param io stream to print to - * @param x sxpr to print - * @param flags print flags - * @return number of bytes written on success - */ -int default_print(IOStream *io, Sxpr x, unsigned flags){ - return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x)); -} - -/** The default equal function. - * Uses eq(). - * - * @param x sxpr to compare - * @param y sxpr to compare - * @return 1 if equal, 0 otherwise - */ -int default_equal(Sxpr x, Sxpr y){ - return eq(x, y); -} - -/** General sxpr print function. - * Prints an sxpr on a stream using the print function for the sxpr type. - * Printing is controlled by flags from the PrintFlags enum. - * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr - * (for debugging). - * - * @param io stream to print to - * @param x sxpr to print - * @param flags print flags - * @return number of bytes written - */ -int objprint(IOStream *io, Sxpr x, unsigned flags){ - SxprType *def = get_sxpr_type(get_type(x)); - ObjPrintFn *print_fn = (def && def->print ? def->print : default_print); - int k = 0; - if(!io) return k; - if(flags & PRINT_TYPE){ - k += IOStream_print(io, "%s:", def->name); - } - if(def->pointer && (flags & PRINT_ADDR)){ - k += IOStream_print(io, "<%p>", get_ptr(x)); - } - k += print_fn(io, x, flags); - return k; -} - -Sxpr objcopy(Sxpr x){ - SxprType *def = get_sxpr_type(get_type(x)); - ObjCopyFn *copy_fn = (def ? def->copy : NULL); - Sxpr v; - if(copy_fn){ - v = copy_fn(x); - } else if(def->pointer){ - v = ONOMEM; - } else { - v = x; - } - return v; -} - -/** General sxpr free function. - * Frees an sxpr using the free function for its type. - * Free functions must recursively free any subsxprs. - * If no function is defined then the default is to - * free sxprs whose type has pointer true. - * Sxprs must not be used after freeing. - * - * @param x sxpr to free - */ -void objfree(Sxpr x){ - SxprType *def = get_sxpr_type(get_type(x)); - - if(def){ - if(def->free){ - def->free(x); - } else if (def->pointer){ - hfree(x); - } - } -} - -/** General sxpr equality function. - * Compares x and y using the equal function for x. - * Uses default_equal() if x has no equal function. - * - * @param x sxpr to compare - * @param y sxpr to compare - * @return 1 if equal, 0 otherwise - */ -int objequal(Sxpr x, Sxpr y){ - SxprType *def = get_sxpr_type(get_type(x)); - ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal); - return equal_fn(x, y); -} - -/** Search for a key in an alist. - * An alist is a list of conses, where the cars - * of the conses are the keys. Compares keys using equality. - * - * @param k key - * @param l alist to search - * @return first element of l with car k, or ONULL - */ -Sxpr assoc(Sxpr k, Sxpr l){ - for( ; CONSP(l) ; l = CDR(l)){ - Sxpr x = CAR(l); - if(CONSP(x) && objequal(k, CAR(x))){ - return x; - } - } - return ONULL; -} - -/** Search for a key in an alist. - * An alist is a list of conses, where the cars - * of the conses are the keys. Compares keys using eq. - * - * @param k key - * @param l alist to search - * @return first element of l with car k, or ONULL - */ -Sxpr assocq(Sxpr k, Sxpr l){ - for( ; CONSP(l); l = CDR(l)){ - Sxpr x = CAR(l); - if(CONSP(x) && eq(k, CAR(x))){ - return x; - } - } - return ONULL; -} - -/** Add a new key and value to an alist. - * - * @param k key - * @param l value - * @param l alist - * @return l with the new cell added to the front - */ -Sxpr acons(Sxpr k, Sxpr v, Sxpr l){ - Sxpr x, y; - x = cons_new(k, v); - if(NOMEMP(x)) return x; - y = cons_new(x, l); - if(NOMEMP(y)) cons_free_cells(x); - return y; -} - -/** Test if a list contains an element. - * Uses sxpr equality. - * - * @param l list - * @param x element to look for - * @return a tail of l with x as car, or ONULL - */ -Sxpr cons_member(Sxpr l, Sxpr x){ - for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){} - return l; -} - -/** Test if a list contains an element satisfying a test. - * The test function is called with v and an element of the list. - * - * @param l list - * @param test_fn test function to use - * @param v value for first argument to the test - * @return a tail of l with car satisfying the test, or 0 - */ -Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){ - for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ } - return l; -} - -/** Test if the elements of list 't' are a subset of the elements - * of list 's'. Element order is not significant. - * - * @param s element list to check subset of - * @param t element list to check if is a subset - * @return 1 if is a subset, 0 otherwise - */ -int cons_subset(Sxpr s, Sxpr t){ - for( ; CONSP(t); t = CDR(t)){ - if(!CONSP(cons_member(s, CAR(t)))){ - return 0; - } - } - return 1; -} - -/** Test if two lists have equal sets of elements. - * Element order is not significant. - * - * @param s list to check - * @param t list to check - * @return 1 if equal, 0 otherwise - */ -int cons_set_equal(Sxpr s, Sxpr t){ - return cons_subset(s, t) && cons_subset(t, s); -} - -#ifdef USE_GC -/*============================================================================*/ -/* The functions inside this ifdef are only safe if GC is used. - * Otherwise they may leak memory. - */ - -/** Remove an element from a list (GC only). - * Uses sxpr equality and removes all instances, even - * if there are more than one. - * - * @param l list to remove elements from - * @param x element to remove - * @return modified input list - */ -Sxpr cons_remove(Sxpr l, Sxpr x){ - return cons_remove_if(l, eq, x); -} - -/** Remove elements satisfying a test (GC only). - * The test function is called with v and an element of the set. - * - * @param l list to remove elements from - * @param test_fn function to use to decide if an element should be removed - * @return modified input list - */ -Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){ - Sxpr prev = ONULL, elt, next; - - for(elt = l; CONSP(elt); elt = next){ - next = CDR(elt); - if(test_fn(v, CAR(elt))){ - if(NULLP(prev)){ - l = next; - } else { - CDR(prev) = next; - } - } - } - return l; -} - -/** Set the value for a key in an alist (GC only). - * If the key is present, changes the value, otherwise - * adds a new cell. - * - * @param k key - * @param v value - * @param l alist - * @return modified or extended list - */ -Sxpr setf(Sxpr k, Sxpr v, Sxpr l){ - Sxpr e = assoc(k, l); - if(NULLP(e)){ - l = acons(k, v, l); - } else { - CAR(CDR(e)) = v; - } - return l; -} -/*============================================================================*/ -#endif /* USE_GC */ - -/** Create a new atom with the given name. - * - * @param name the name - * @return new atom - */ -Sxpr atom_new(char *name){ - Sxpr n, obj = ONOMEM; - long v; - - // Don't always want to do this. - if(0 && convert_atol(name, &v) == 0){ - obj = OINT(v); - } else { - n = string_new(name); - if(NOMEMP(n)) goto exit; - obj = HALLOC(ObjAtom, T_ATOM); - if(NOMEMP(obj)){ - string_free(n); - goto exit; - } - OBJ_ATOM(obj)->name = n; - } - exit: - return obj; -} - -/** Free an atom. - * - * @param obj to free - */ -void atom_free(Sxpr obj){ - // Interned atoms are shared, so do not free. - if(OBJ_ATOM(obj)->interned) return; - objfree(OBJ_ATOM(obj)->name); - hfree(obj); -} - -/** Copy an atom. - * - * @param obj to copy - */ -Sxpr atom_copy(Sxpr obj){ - Sxpr v; - if(OBJ_ATOM(obj)->interned){ - v = obj; - } else { - v = atom_new(atom_name(obj)); - } - return v; -} - -/** Print an atom. Prints the atom name. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes printed - */ -int atom_print(IOStream *io, Sxpr obj, unsigned flags){ - return objprint(io, OBJ_ATOM(obj)->name, flags); -} - -/** Atom equality. - * - * @param x to compare - * @param y to compare - * @return 1 if equal, 0 otherwise - */ -int atom_equal(Sxpr x, Sxpr y){ - int ok; - ok = eq(x, y); - if(ok) goto exit; - ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name); - if(ok) goto exit; - ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y); - exit: - return ok; -} - -/** Get the name of an atom. - * - * @param obj atom - * @return name - */ -char * atom_name(Sxpr obj){ - return string_string(OBJ_ATOM(obj)->name); -} - -int atom_length(Sxpr obj){ - return string_length(OBJ_ATOM(obj)->name); -} - -/** Get the C string from a string sxpr. - * - * @param obj string sxpr - * @return string - */ -char * string_string(Sxpr obj){ - return OBJ_STRING(obj)->data; -} - -/** Get the length of a string. - * - * @param obj string - * @return length - */ -int string_length(Sxpr obj){ - return OBJ_STRING(obj)->len; -} - -/** Create a new string. The input string is copied, - * and must be null-terminated. - * - * @param s characters to put in the string - * @return new sxpr - */ -Sxpr string_new(char *s){ - int n = (s ? strlen(s) : 0); - return string_new_n(s, n); -} - -/** Create a new string. The input string is copied, - * and need not be null-terminated. - * - * @param s characters to put in the string (may be null) - * @param n string length - * @return new sxpr - */ -Sxpr string_new_n(char *s, int n){ - Sxpr obj; - obj = halloc(sizeof(ObjString) + n + 1, T_STRING); - if(!NOMEMP(obj)){ - char *str = OBJ_STRING(obj)->data; - OBJ_STRING(obj)->len = n; - if(s){ - memcpy(str, s, n); - str[n] = '\0'; - } else { - memset(str, 0, n + 1); - } - } - return obj; -} - -/** Free a string. - * - * @param obj to free - */ -void string_free(Sxpr obj){ - hfree(obj); -} - -/** Copy a string. - * - * @param obj to copy - */ -Sxpr string_copy(Sxpr obj){ - return string_new_n(string_string(obj), string_length(obj)); -} - -/** Determine if a string needs escapes when printed - * using the given flags. - * - * @param str string to check - * @param n string length - * @param flags print flags - * @return 1 if needs escapes, 0 otherwise - */ -int needs_escapes(char *str, int n, unsigned flags){ - char *c; - int i; - int val = 0; - - if(str){ - for(i=0, c=str; i> 16) & 0xff; - if('a' <= c && c <= 'z') break; - } - return c; -} - -int string_contains(char *s, int s_n, char *k, int k_n){ - int i, n = s_n - k_n; - for(i=0; i < n; i++){ - if(!memcmp(s+i, k, k_n)) return 1; - } - return 0; -} - -int string_delim(char *s, int s_n, char *d, int d_n){ - int i; - if(d_n < 4) return -1; - memset(d, 0, d_n+1); - for(i=0; i<3; i++){ - d[i] = randchar(); - } - for( ; i < d_n; i++){ - if(!string_contains(s, s_n, d, i)){ - return i; - } - d[i] = randchar(); - } - return -1; -} - -/** Print the bytes in a string as-is. - * - * @param io stream - * @param str string - * @param n length - * @return bytes written or error code - */ -int _string_print_raw(IOStream *io, char *str, int n){ - int k = 0; - k = IOStream_write(io, str, n); - return k; -} - -/** Print a string in counted data format. - * - * @param io stream - * @param str string - * @param n length - * @return bytes written or error code - */ -int _string_print_counted(IOStream *io, char *str, int n){ - int k = 0; - k += IOStream_print(io, "%c%c%d%c", - c_data_open, c_data_count, n, c_data_count); - k += IOStream_write(io, str, n); - return k; -} - -/** Print a string in quoted data format. - * - * @param io stream - * @param str string - * @param n length - * @return bytes written or error code - */ -int _string_print_quoted(IOStream *io, char *str, int n){ - int k = 0; - char d[10]; - int d_n; - d_n = string_delim(str, n, d, sizeof(d) - 1); - k += IOStream_print(io, "%c%c%s%c", - c_data_open, c_data_quote, d, c_data_quote); - k += IOStream_write(io, str, n); - k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote); - return k; -} - -/** Print a string as a quoted string. - * - * @param io stream - * @param str string - * @param n length - * @return bytes written or error code - */ -int _string_print_string(IOStream *io, char *str, int n){ - int k = 0; - - k += IOStream_print(io, "\""); - if(str){ - char *s, *t; - for(s = str, t = str + n; s < t; s++){ - if(*s < ' ' || *s >= 127 ){ - switch(*s){ - case '\a': k += IOStream_print(io, "\\a"); break; - case '\b': k += IOStream_print(io, "\\b"); break; - case '\f': k += IOStream_print(io, "\\f"); break; - case '\n': k += IOStream_print(io, "\\n"); break; - case '\r': k += IOStream_print(io, "\\r"); break; - case '\t': k += IOStream_print(io, "\\t"); break; - case '\v': k += IOStream_print(io, "\\v"); break; - default: - // Octal escape; - k += IOStream_print(io, "\\%o", *s); - break; - } - } else if(*s == c_double_quote || - *s == c_single_quote || - *s == c_escape){ - k += IOStream_print(io, "\\%c", *s); - } else { - k+= IOStream_print(io, "%c", *s); - } - } - } - k += IOStream_print(io, "\""); - return k; -} - -/** Print a string to a stream, with escapes if necessary. - * - * @param io stream to print to - * @param str string - * @param n string length - * @param flags print flags - * @return number of bytes written - */ -int _string_print(IOStream *io, char *str, int n, unsigned flags){ - int k = 0; - if((flags & PRINT_COUNTED)){ - k = _string_print_counted(io, str, n); - } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){ - k = _string_print_raw(io, str, n); - } else if(n > 50){ - k = _string_print_quoted(io, str, n); - } else { - k = _string_print_string(io, str, n); - } - return k; -} - -/** Print a string to a stream, with escapes if necessary. - * - * @param io stream to print to - * @param obj string - * @param flags print flags - * @return number of bytes written - */ -int string_print(IOStream *io, Sxpr obj, unsigned flags){ - return _string_print(io, - OBJ_STRING(obj)->data, - OBJ_STRING(obj)->len, - flags); -} - -int string_eq(char *s, int s_n, char *t, int t_n){ - return (s_n == t_n) && (memcmp(s, t, s_n) == 0); -} - -/** Compare an sxpr with a string for equality. - * - * @param x string to compare with - * @param y sxpr to compare - * @return 1 if equal, 0 otherwise - */ -int string_equal(Sxpr x, Sxpr y){ - int ok = 0; - ok = eq(x,y); - if(ok) goto exit; - ok = has_type(y, T_STRING) && - string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, - OBJ_STRING(y)->data, OBJ_STRING(y)->len); - if(ok) goto exit; - ok = has_type(y, T_ATOM) && - string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len, - atom_name(y), atom_length(y)); - exit: - return ok; -} - -/** Create a new cons cell. - * The cell is ONOMEM if either argument is. - * - * @param car sxpr for the car - * @param cdr sxpr for the cdr - * @return new cons - */ -Sxpr cons_new(Sxpr car, Sxpr cdr){ - Sxpr obj; - if(NOMEMP(car) || NOMEMP(cdr)){ - obj = ONOMEM; - } else { - obj = HALLOC(ObjCons, T_CONS); - if(!NOMEMP(obj)){ - ObjCons *z = OBJ_CONS(obj); - z->car = car; - z->cdr = cdr; - } - } - return obj; -} - -/** Push a new element onto a list. - * - * @param list list to add to - * @param elt element to add - * @return 0 if successful, error code otherwise - */ -int cons_push(Sxpr *list, Sxpr elt){ - Sxpr l; - l = cons_new(elt, *list); - if(NOMEMP(l)) return -ENOMEM; - *list = l; - return 0; -} - -/** Free a cons. Recursively frees the car and cdr. - * - * @param obj to free - */ -void cons_free(Sxpr obj){ - Sxpr next; - for(; CONSP(obj); obj = next){ - next = CDR(obj); - objfree(CAR(obj)); - hfree(obj); - } - if(!NULLP(obj)){ - objfree(obj); - } -} - -/** Copy a cons. Recursively copies the car and cdr. - * - * @param obj to copy - */ -Sxpr cons_copy(Sxpr obj){ - Sxpr v = ONULL; - Sxpr l = ONULL, x = ONONE; - for(l = obj; CONSP(l); l = CDR(l)){ - x = objcopy(CAR(l)); - if(NOMEMP(x)) goto exit; - x = cons_new(x, v); - if(NOMEMP(x)) goto exit; - v = x; - } - v = nrev(v); - exit: - if(NOMEMP(x)){ - objfree(v); - v = ONOMEM; - } - return v; -} - -/** Free a cons and its cdr cells, but not the car sxprs. - * Does nothing if called on something that is not a cons. - * - * @param obj to free - */ -void cons_free_cells(Sxpr obj){ - Sxpr next; - for(; CONSP(obj); obj = next){ - next = CDR(obj); - hfree(obj); - } -} - -/** Print a cons. - * Prints the cons in list format if the cdrs are conses. - * uses pair (dot) format if the last cdr is not a cons (or null). - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -int cons_print(IOStream *io, Sxpr obj, unsigned flags){ - int first = 1; - int k = 0; - k += IOStream_print(io, "("); - for( ; CONSP(obj) ; obj = CDR(obj)){ - if(first){ - first = 0; - } else { - k += IOStream_print(io, " "); - } - k += objprint(io, CAR(obj), flags); - } - if(!NULLP(obj)){ - k += IOStream_print(io, " . "); - k += objprint(io, obj, flags); - } - k += IOStream_print(io, ")"); - return (IOStream_error(io) ? -1 : k); -} - -/** Compare a cons with another sxpr for equality. - * If y is a cons, compares the cars and cdrs recursively. - * - * @param x cons to compare - * @param y sxpr to compare - * @return 1 if equal, 0 otherwise - */ -int cons_equal(Sxpr x, Sxpr y){ - return CONSP(y) && - objequal(CAR(x), CAR(y)) && - objequal(CDR(x), CDR(y)); -} - -/** Return the length of a cons list. - * - * @param obj list - * @return length - */ -int cons_length(Sxpr obj){ - int count = 0; - for( ; CONSP(obj); obj = CDR(obj)){ - count++; - } - return count; -} - -/** Destructively reverse a cons list in-place. - * If the argument is not a cons it is returned unchanged. - * - * @param l to reverse - * @return reversed list - */ -Sxpr nrev(Sxpr l){ - if(CONSP(l)){ - // Iterate down the cells in the list making the cdr of - // each cell point to the previous cell. The last cell - // is the head of the reversed list. - Sxpr prev = ONULL; - Sxpr cell = l; - Sxpr next; - - while(1){ - next = CDR(cell); - CDR(cell) = prev; - if(!CONSP(next)) break; - prev = cell; - cell = next; - } - l = cell; - } - return l; -} - -/** Print the null sxpr. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int null_print(IOStream *io, Sxpr obj, unsigned flags){ - return IOStream_print(io, "()"); -} - -/** Print the `unspecified' sxpr none. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int none_print(IOStream *io, Sxpr obj, unsigned flags){ - return IOStream_print(io, ""); -} - -/** Print an integer. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int int_print(IOStream *io, Sxpr obj, unsigned flags){ - return IOStream_print(io, "%d", OBJ_INT(obj)); -} - -/** Print a boolean. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int bool_print(IOStream *io, Sxpr obj, unsigned flags){ - return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false)); -} - -/** Print an error. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int err_print(IOStream *io, Sxpr obj, unsigned flags){ - int err = OBJ_INT(obj); - if(err < 0) err = -err; - return IOStream_print(io, "[error:%d:%s]", err, strerror(err)); -} - -/** Print the 'nomem' sxpr. - * - * @param io stream to print to - * @param obj to print - * @param flags print flags - * @return number of bytes written - */ -static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){ - return IOStream_print(io, "[ENOMEM]"); -} - -int sxprp(Sxpr obj, Sxpr name){ - return CONSP(obj) && objequal(CAR(obj), name); -} - -/** Get the name of an element. - * - * @param obj element - * @return name - */ -Sxpr sxpr_name(Sxpr obj){ - Sxpr val = ONONE; - if(CONSP(obj)){ - val = CAR(obj); - } else if(STRINGP(obj) || ATOMP(obj)){ - val = obj; - } - return val; -} - -int sxpr_is(Sxpr obj, char *s){ - if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s)); - if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s)); - return 0; -} - -int sxpr_elementp(Sxpr obj, Sxpr name){ - int ok = 0; - ok = CONSP(obj) && objequal(CAR(obj), name); - return ok; -} - -/** Get the attributes of an sxpr. - * - * @param obj sxpr - * @return attributes - */ -Sxpr sxpr_attributes(Sxpr obj){ - Sxpr val = ONULL; - if(CONSP(obj)){ - obj = CDR(obj); - if(CONSP(obj)){ - obj = CAR(obj); - if(sxprp(obj, intern("@"))){ - val = CDR(obj); - } - } - } - return val; -} - -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){ - Sxpr val = ONONE; - val = assoc(sxpr_attributes(obj), key); - if(CONSP(val) && CONSP(CDR(val))){ - val = CADR(def); - } else { - val = def; - } - return val; -} - -/** Get the children of an sxpr. - * - * @param obj sxpr - * @return children - */ -Sxpr sxpr_children(Sxpr obj){ - Sxpr val = ONULL; - if(CONSP(obj)){ - val = CDR(obj); - if(CONSP(val) && sxprp(CAR(val), intern("@"))){ - val = CDR(val); - } - } - return val; -} - -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){ - Sxpr val = ONONE; - Sxpr l; - for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){ - if(sxprp(CAR(l), name)){ - val = CAR(l); - break; - } - } - if(NONEP(val)) val = def; - return val; -} - -Sxpr sxpr_child0(Sxpr obj, Sxpr def){ - Sxpr val = ONONE; - Sxpr l = sxpr_children(obj); - if(CONSP(l)){ - val = CAR(l); - } else { - val = def; - } - return val; -} - -Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def){ - Sxpr val = def; - Sxpr l; - int i; - for (i = 0, l = sxpr_children(obj); CONSP(l); i++, l = CDR(l)){ - if(i == n){ - val = CAR(l); - break; - } - } - return val; -} - -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){ - Sxpr val = ONONE; - val = sxpr_child(obj, name, ONONE); - if(NONEP(val)){ - val = def; - } else { - val = sxpr_child0(val, def); - } - return val; -} - -/** Table of interned symbols. Indexed by symbol name. */ -static HashTable *symbols = NULL; - -/** Hash function for entries in the symbol table. - * - * @param key to hash - * @return hashcode - */ -static Hashcode sym_hash_fn(void *key){ - return hash_string((char*)key); -} - -/** Key equality function for the symbol table. - * - * @param x to compare - * @param y to compare - * @return 1 if equal, 0 otherwise - */ -static int sym_equal_fn(void *x, void *y){ - return !strcmp((char*)x, (char*)y); -} - -/** Entry free function for the symbol table. - * - * @param table the entry is in - * @param entry being freed - */ -static void sym_free_fn(HashTable *table, HTEntry *entry){ - if(entry){ - objfree(((ObjAtom*)entry->value)->name); - HTEntry_free(entry); - } -} - -/** Initialize the symbol table. - * - * @return 0 on sucess, error code otherwise - */ -static int init_symbols(void){ - symbols = HashTable_new(100); - if(symbols){ - symbols->key_hash_fn = sym_hash_fn; - symbols->key_equal_fn = sym_equal_fn; - symbols->entry_free_fn = sym_free_fn; - return 0; - } - return -1; -} - -/** Cleanup the symbol table. Frees the table and all its symbols. - */ -void cleanup_symbols(void){ - HashTable_free(symbols); - symbols = NULL; -} - -/** Get the interned symbol with the given name. - * No new symbol is created. - * - * @return symbol or null - */ -Sxpr get_symbol(char *sym){ - HTEntry *entry; - if(!symbols){ - if(init_symbols()) return ONOMEM; - return ONULL; - } - entry = HashTable_get_entry(symbols, sym); - if(entry){ - return OBJP(T_ATOM, entry->value); - } else { - return ONULL; - } -} - -/** Get the interned symbol with the given name. - * Creates a new symbol if necessary. - * - * @return symbol - */ -Sxpr intern(char *sym){ - Sxpr symbol = get_symbol(sym); - if(NULLP(symbol)){ - if(!symbols) return ONOMEM; - symbol = atom_new(sym); - if(!NOMEMP(symbol)){ - OBJ_ATOM(symbol)->interned = TRUE; - HashTable_add(symbols, atom_name(symbol), get_ptr(symbol)); - } - } - return symbol; -} diff --git a/vnet/src/libxutil/sxpr.h b/vnet/src/libxutil/sxpr.h deleted file mode 100644 index decb6961dcd..00000000000 --- a/vnet/src/libxutil/sxpr.h +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _XUTIL_SXPR_H_ -#define _XUTIL_SXPR_H_ - -#ifdef __KERNEL__ -#include -#include -#else -#include -#endif - -#include "hash_table.h" -#include "iostream.h" -#include "allocate.h" - -/** @file - * Definitions for rules and sxprs. - */ - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/** Sxpr type. */ -typedef int16_t TypeCode; - -/** A typed sxpr handle.*/ -typedef struct Sxpr { - /** Sxpr type. */ - TypeCode type; - union { - /** Sxpr value. */ - unsigned long ul; - /** Pointer. */ - void *ptr; - } v; -} Sxpr; - -/** Get the integer value from an sxpr. - * - * @param obj sxpr - * @return value - */ -static inline unsigned long get_ul(Sxpr obj){ - return obj.v.ul; -} - -/** Get the pointer value from an sxpr. - * - * @param obj sxpr - * @return value - */ -static inline void * get_ptr(Sxpr obj){ - return obj.v.ptr; -} - -/** Create an sxpr containing a pointer. - * - * @param ty typecode - * @param val pointer - * @return sxpr - */ -static inline Sxpr obj_ptr(TypeCode ty, void *val){ - return (Sxpr){ .type= ty, .v= { .ptr= val } }; -} - -/** Create an sxpr containing an integer. - * - * @param ty typecode - * @param val integer - * @return sxpr - */ -static inline Sxpr obj_ul(TypeCode ty, unsigned long val){ - return (Sxpr){ .type= ty, .v= { .ul= val } }; -} - -/** Get the type of an sxpr. - * - * @param obj sxpr - * @return type - */ -static inline TypeCode get_type(Sxpr obj){ - return obj.type; -} - -/** Check the type of an sxpr. - * - * @param obj sxpr - * @param type to check - * @return 1 if has the type, 0 otherwise - */ -static inline int has_type(Sxpr obj, TypeCode type){ - return get_type(obj) == type; -} - -/** Compare sxprs for literal equality of type and value. - * - * @param x sxpr to compare - * @param y sxpr to compare - * @return 1 if equal, 0 otherwise - */ -static inline int eq(Sxpr x, Sxpr y){ - return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y))); -} - -/** The 'unspecified' sxpr. */ -#define T_NONE ((TypeCode)0) -/** The empty list. */ -#define T_NULL ((TypeCode)1) -/** Unsigned integer. */ -#define T_UINT ((TypeCode)2) -/** A string. */ -#define T_STRING ((TypeCode)3) -/** An atom. */ -#define T_ATOM ((TypeCode)4) -/** A boolean. */ -#define T_BOOL ((TypeCode)5) - -/** A cons (pair or list). */ -#define T_CONS ((TypeCode)10) - -/** An error. */ -#define T_ERR ((TypeCode)40) -/** Sxpr type to indicate out of memory. */ -#define T_NOMEM ((TypeCode)41) - -typedef struct ObjString { - int len; - char data[0]; -} ObjString; - -/** An atom. */ -typedef struct ObjAtom { - Sxpr name; - Hashcode hashcode; - int interned; -} ObjAtom; - -/** A cons (pair). */ -typedef struct ObjCons { - Sxpr car; - Sxpr cdr; -} ObjCons; - -/** Flags for sxpr printing. */ -enum PrintFlags { - PRINT_RAW = 0x001, - PRINT_TYPE = 0x002, - PRINT_PRETTY = 0x004, - PRINT_COUNTED = 0x008, - PRINT_ADDR = 0x010, -}; - -extern int _string_print(IOStream *io, char *str, int n, unsigned flags); -extern int _string_print_raw(IOStream *io, char *str, int n); -extern int _string_print_counted(IOStream *io, char *str, int n); -extern int _string_print_quoted(IOStream *io, char *str, int n); -extern int _string_print_string(IOStream *io, char *str, int n); - -/** An integer sxpr. - * - * @param ty type - * @param val integer value - */ -#define OBJI(ty, val) obj_ul(ty, val) - -/** Make an integer sxpr. - * @param x value - */ -#define OINT(x) OBJI(T_UINT, x) - -/** Make an error sxpr. - * - * @param x value - */ -#define OERR(x) OBJI(T_ERR, x) - -/** Out of memory constant. */ -#define ONOMEM OBJI(T_NOMEM, 0) - -/** The `unspecified' constant. */ -#define ONONE OBJI(T_NONE, 0) - -/** Empty list constant. */ -#define ONULL OBJI(T_NULL, 0) - -/** False constant. */ -#define OFALSE OBJI(T_BOOL, 0) - -/** True constant. */ -#define OTRUE OBJI(T_BOOL, 1) - -/** A pointer sxpr. - * If the pointer is non-null, returns an sxpr containing it. - * If the pointer is null, returns ONOMEM. - * - * @param ty type - * @param val pointer - */ -static inline Sxpr OBJP(int ty, void *val){ - return (val ? obj_ptr(ty, val) : ONOMEM); -} - -/** Make an integer sxpr containing a pointer. - * - * @param val pointer - */ -static inline Sxpr PTR(void *val){ - return OBJP(T_UINT, (void*)(val)); -} - -/** Allocate some memory and return an sxpr containing it. - * Returns ONOMEM if allocation failed. - * - * @param n number of bytes to allocate - * @param ty typecode - * @return sxpr - */ -static inline Sxpr halloc(int n, int ty){ - return OBJP(ty, allocate(n)); -} - -/** Allocate an sxpr containing a pointer to the given type. - * - * @param _ctype type (uses sizeof to determine how many bytes to allocate) - * @param _tycode typecode - * @return sxpr, ONOMEM if allocation failed - */ -#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode) - -/* Recognizers for the various sxpr types. */ -#define ATOMP(obj) has_type(obj, T_ATOM) -#define BOOLP(obj) has_type(obj, T_BOOL) -#define CONSP(obj) has_type(obj, T_CONS) -#define ERRP(obj) has_type(obj, T_ERR) -#define INTP(obj) has_type(obj, T_UINT) -#define NOMEMP(obj) has_type(obj, T_NOMEM) -#define NONEP(obj) has_type(obj, T_NONE) -#define NULLP(obj) has_type(obj, T_NULL) -#define STRINGP(obj) has_type(obj, T_STRING) - -#define TRUEP(obj) get_ul(obj) - -/** Convert an sxpr to an unsigned integer. */ -#define OBJ_UINT(x) get_ul(x) -/** Convert an sxpr to an integer. */ -#define OBJ_INT(x) (int)get_ul(x) - -/* Conversions of sxprs to their values. - * No checking is done. - */ -#define OBJ_STRING(x) ((ObjString*)get_ptr(x)) -#define OBJ_CONS(x) ((ObjCons*)get_ptr(x)) -#define OBJ_ATOM(x) ((ObjAtom*)get_ptr(x)) -#define OBJ_SET(x) ((ObjSet*)get_ptr(x)) -#define CAR(x) (OBJ_CONS(x)->car) -#define CDR(x) (OBJ_CONS(x)->cdr) - -#define CAAR(x) (CAR(CAR(x))) -#define CADR(x) (CAR(CDR(x))) -#define CDAR(x) (CDR(CAR(x))) -#define CDDR(x) (CDR(CDR(x))) - -/** Checked version of CAR - * - * @param x sxpr - * @return CAR if a cons, x otherwise - */ -static inline Sxpr car(Sxpr x){ - return (CONSP(x) ? CAR(x) : x); -} - -/** Checked version of CDR. - * - * @param x sxpr - * @return CDR if a cons, null otherwise - */ -static inline Sxpr cdr(Sxpr x){ - return (CONSP(x) ? CDR(x) : ONULL); -} - -typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags); -typedef int ObjEqualFn(Sxpr obj, Sxpr other); -typedef void ObjFreeFn(Sxpr obj); -typedef Sxpr ObjCopyFn(Sxpr obj); - -/** An sxpr type definition. */ -typedef struct SxprType { - TypeCode type; - char *name; - int pointer; - ObjPrintFn *print; - ObjEqualFn *equal; - ObjFreeFn *free; - ObjCopyFn *copy; -} SxprType; - -extern int def_sxpr_type(SxprType *tydef); -extern SxprType *get_sxpr_type(int ty); - -/** Free the pointer in an sxpr. - * - * @param x sxpr containing a pointer - */ -static inline void hfree(Sxpr x){ - deallocate(get_ptr(x)); -} - -extern int objprint(IOStream *io, Sxpr x, unsigned flags); -extern int objequal(Sxpr x, Sxpr y); -extern void objfree(Sxpr x); -extern Sxpr objcopy(Sxpr x); - -extern void cons_free_cells(Sxpr obj); -extern Sxpr intern(char *s); - -extern Sxpr assoc(Sxpr k, Sxpr l); -extern Sxpr assocq(Sxpr k, Sxpr l); -extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l); -extern Sxpr nrev(Sxpr l); -extern Sxpr cons_member(Sxpr l, Sxpr x); -extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v); -extern int cons_subset(Sxpr s, Sxpr t); -extern int cons_set_equal(Sxpr s, Sxpr t); - -#ifdef USE_GC -extern Sxpr cons_remove(Sxpr l, Sxpr x); -extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v); -#endif - -extern Sxpr atom_new(char *name); -extern char * atom_name(Sxpr obj); -extern int atom_length(Sxpr obj); - -extern Sxpr string_new(char *s); -extern Sxpr string_new_n(char *s, int n); -extern char * string_string(Sxpr obj); -extern int string_length(Sxpr obj); - -extern Sxpr cons_new(Sxpr car, Sxpr cdr); -extern int cons_push(Sxpr *list, Sxpr elt); -extern int cons_length(Sxpr obj); - -Sxpr sxpr_name(Sxpr obj); -int sxpr_is(Sxpr obj, char *s); -int sxpr_elementp(Sxpr obj, Sxpr name); -Sxpr sxpr_attributes(Sxpr obj); -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def); -Sxpr sxpr_children(Sxpr obj); -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def); -Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def); -Sxpr sxpr_child0(Sxpr obj, Sxpr def); -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def); - -/** Create a new atom. - * - * @param s atom name - * @return new atom - */ -static inline Sxpr mkatom(char *s){ - return atom_new(s); -} - -/** Create a new string sxpr. - * - * @param s string bytes (copied) - * @return new string - */ -static inline Sxpr mkstring(char *s){ - return string_new(s); -} - -/** Create an integer sxpr. - * - * @param i value - * @return sxpr - */ -static inline Sxpr mkint(int i){ - return OBJI(T_UINT, i); -} - -/** Create a boolean sxpr. - * - * @param b value - * @return sxpr - */ -static inline Sxpr mkbool(int b){ - return OBJI(T_BOOL, (b ? 1 : 0)); -} - -/* Constants used in parsing and printing. */ -#define k_list_open "(" -#define c_list_open '(' -#define k_list_close ")" -#define c_list_close ')' -#define k_true "true" -#define k_false "false" - -#define c_escape '\\' -#define c_single_quote '\'' -#define c_double_quote '"' -#define c_string_open c_double_quote -#define c_string_close c_double_quote - -#define c_data_open '<' -#define c_data_quote '<' -#define c_data_count '*' -//#define c_data_open '[' -//#define c_data_close ']' -//#define c_binary '*' - -#define c_var '$' -#define c_eval '!' -#define c_concat_open '{' -#define c_concat_close '}' - -#endif /* ! _XUTIL_SXPR_H_ */ diff --git a/vnet/src/libxutil/sxpr_parser.c b/vnet/src/libxutil/sxpr_parser.c deleted file mode 100644 index 4c807d2ed35..00000000000 --- a/vnet/src/libxutil/sxpr_parser.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* - * Copyright (C) 2001 - 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __KERNEL__ -# include -# include -# include -# include -# include -#else -# include -# include -#endif - -#include "sys_net.h" - -#include "iostream.h" -#include "lexis.h" -#include "sxpr_parser.h" -#include "sys_string.h" -#include "enum.h" - -/** @file - * Sxpr parsing. - * - * So that the parser does not leak memory, all sxprs constructed by - * the parser must be freed on error. On successful parse the sxpr - * returned becomes the responsibility of the caller. - * - * @author Mike Wray - */ - -#ifdef DEBUG -#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args) -#else -#define dprintf(fmt, args...) do{ }while(0) -#endif - -#undef printf -#define printf(fmt, args...) IOStream_print(iostdout, fmt, ##args) - -static int state_start(Parser *p, char c); -static int begin_start(Parser *p, char c); - -#if 0 -/** Print a parse error. - * - * @param in parser - * @param msg format followed by printf arguments - */ -static void eprintf(Parser *in, char *msg, ...){ - va_list args; - if(in->error_out){ - va_start(args, msg); - IOStream_vprint(in->error_out, msg, args); - va_end(args); - } -} - -/** Print a parse warning. - * - * @param in parser - * @param msg format followed by printf arguments - */ -static void wprintf(Parser *in, char *msg, ...){ - va_list args; - if(in->error_out){ - va_start(args, msg); - IOStream_vprint(in->error_out, msg, args); - va_end(args); - } -} -#endif - - -/*============================================================================*/ - -/** Record defining the message for a parse error. */ -typedef struct { - ParseErrorId id; - char *message; -} ParseError; - -/** Format for printing parse error messages. */ -#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s" - -/** Message catalog for the parse error codes. */ -static ParseError catalog[] = { - { PARSE_ERR_UNSPECIFIED, "unspecified error" }, - { PARSE_ERR_NOMEM, "out of memory" }, - { PARSE_ERR_UNEXPECTED_EOF, "unexpected end of input" }, - { PARSE_ERR_TOKEN_TOO_LONG, "token too long" }, - { PARSE_ERR_INVALID_SYNTAX, "syntax error" }, - { PARSE_ERR_INVALID_ESCAPE, "invalid escape" }, - { 0, NULL } -}; - -/** Number of entries in the message catalog. */ -const static int catalog_n = sizeof(catalog)/sizeof(ParseError); - -/** Set the parser error stream. - * Parse errors are reported on the the error stream if it is non-null. - * - * @param z parser - * @param error_out error stream - */ -void Parser_set_error_stream(Parser *z, IOStream *error_out){ - z->error_out = error_out; -} - -/** Get the parser error message for an error code. - * - * @param id error code - * @return error message (empty string if the code is unknown) - */ -static char *get_message(ParseErrorId id){ - int i; - for(i = 0; i < catalog_n; i++){ - if(id == catalog[i].id){ - return catalog[i].message; - } - } - return ""; -} - -#if 0 -/** Get the line number. - * - * @param in parser - */ -static int get_line(Parser *in){ - return in->line_no; -} - -/** Get the column number. - * - * @param in parser - */ -static int get_column(Parser *in){ - return in->char_no; -} -#endif - -/** Get the line number the current token started on. - * - * @param in parser - */ -static int get_tok_line(Parser *in){ - return in->tok_begin_line; -} - -/** Get the column number the current token started on. - * - * @param in parser - */ -static int get_tok_column(Parser *in){ - return in->tok_begin_char; -} - -/** Return the current token. - * The return value points at the internal buffer, so - * it must not be modified (or freed). Use copy_token() if you need a copy. - * - * @param p parser - * @return token - */ -char *peek_token(Parser *p){ - return p->tok; -} - -int token_len(Parser *p){ - return p->tok_end - p->tok; -} - -/** Return a copy of the current token. - * The returned value should be freed when finished with. - * - * @param p parser - * @return copy of token - */ -char *copy_token(Parser *p){ - int n = token_len(p); - char *buf = allocate(n + 1); - if(buf){ - memcpy(buf, peek_token(p), n); - buf[n] = '\0'; - } - return buf; -} - -void new_token(Parser *p){ - memset(p->buf, 0, p->buf_end - p->buf); - p->tok = p->buf; - p->tok_end = p->tok; - p->tok_begin_line = p->line_no; - p->tok_begin_char = p->char_no; -} - -/** Report a parse error. - * Does nothing if the error stream is null or there is no error. - * - * @param in parser - */ -static void report_error(Parser *in){ - if(in->error_out && in->err){ - char *msg = get_message(in->err); - char *tok = peek_token(in); - IOStream_print(in->error_out, PARSE_ERR_FMT, - get_tok_line(in), get_tok_column(in), msg); - if(tok && tok[0]){ - IOStream_print(in->error_out, " '%s'", tok); - } - IOStream_print(in->error_out, "\n"); - } -} - -/** Get the error message for the current parse error code. - * Does nothing if there is no error. - * - * @param in parser - * @param buf where to place the message - * @param n maximum number of characters to place in buf - * @return current error code (zero for no error) - */ -int Parser_error_message(Parser *in, char *buf, int n){ - if(in->err){ - char *msg = get_message(in->err); - snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), - get_tok_column(in), msg); - } - return in->err; -} - -/** Flag a parse error. All subsequent reads will fail. - * Does not change the parser error code if it is already set. - * - * @param in parser - * @param id error code - */ -int Parser_error_id(Parser *in, ParseErrorId id){ - if(!in->err){ - in->err = id; - report_error(in); - } - return -EINVAL; -} - -/** Flag an unspecified parse error. - * - * @param in parser - */ -int Parser_error(Parser *in){ - return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX); -} - -/** Test if the parser's error flag is set. - * - * @param in parser - * @return 1 if set, 0 otherwise - */ -int Parser_has_error(Parser *in){ - return (in->err > 0); -} - -/** Test if the parser is at end of input. - * - * @param in parser - * @return 1 if at EOF, 0 otherwise - */ -int Parser_at_eof(Parser *p){ - return p->eof; -} - -void ParserState_free(ParserState *z){ - if(!z) return; - objfree(z->val); - deallocate(z); -} - -int ParserState_new(ParserStateFn *fn, char *name, - ParserState *parent, ParserState **val){ - int err = -ENOMEM; - ParserState *z; - z = ALLOCATE(ParserState); - if(!z) goto exit; - z->name = name; - z->fn = fn; - z->parent = parent; - z->val = ONULL; - err = 0; - exit: - *val = (err ? NULL : z); - return err; -} - -void Parser_pop(Parser *p){ - ParserState *s = p->state; - if(!s) return; - dprintf("Parser_pop> %s\n", s->name); - p->state = s->parent; - if (p->start_state == s) { - p->start_state = NULL; - } - ParserState_free(s); -} - -/** Free a parser. - * No-op if the parser is null. - * - * @param z parser - */ -void Parser_free(Parser *z){ - if(!z) return; - // Hmmm. Need to free states, but careful about double free of values. - while(z->state){ - objfree(z->state->val); - Parser_pop(z); - } - if(z->buf) deallocate(z->buf); - objfree(z->val); - z->val = ONONE; - deallocate(z); -} - -int Parser_push(Parser *p, ParserStateFn *fn, char *name){ - dprintf("Parser_push> %s\n", name); - return ParserState_new(fn, name, p->state, &p->state); -} - -int Parser_return(Parser *p){ - int err = 0; - Sxpr val = ONONE; - if(!p->state){ - err = -EINVAL; - goto exit; - } - val = p->state->val; - p->state->val = ONONE; - Parser_pop(p); - if(p->state){ - err = cons_push(&p->state->val, val); - } else { - val = nrev(val); - p->val = val; - } - exit: - if(err){ - objfree(val); - } - return err; -} - -/** Reset the fields of a parser to initial values. - * - * @param z parser - */ -static void reset(Parser *z){ - // leave flags - // leave error_out - while(z->state){ - Parser_pop(z); - } - z->val = ONONE; - z->eof = 0; - z->err = 0; - z->line_no = 1; - z->char_no = 0; - memset(z->buf, 0, z->buf_end - z->buf); - z->tok = z->buf; - z->tok_end = z->tok; - z->tok_begin_line = 0; - z->tok_begin_char = 0; - z->start_state = NULL; -} - -/** Create a new parser. The error stream defaults to null. - */ -Parser * Parser_new(void){ - Parser *z = ALLOCATE(Parser); - int n = PARSER_BUF_SIZE; - int err = -ENOMEM; - - if(!z) goto exit; - z->buf = allocate(n); - if(!z->buf) goto exit; - err = 0; - z->buf_end = z->buf + n; - z->begin = begin_start; - reset(z); - exit: - if(err){ - Parser_free(z); - z = NULL; - } - return z; -} - -/** Get the next character. - * Records the character read in the parser, - * and sets the line and character counts. - * - * @param p parser - * @return error flag: 0 on success, non-zero on error - */ -static int input_char(Parser *p, char c){ - int err = 0; - if(c=='\n'){ - p->line_no++; - p->char_no = 0; - } else { - p->char_no++; - } - return err; -} - -int save_char(Parser *p, char c){ - int err = 0; - if(p->tok_end >= p->buf_end){ - int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT; - char *buf = allocate(buf_n); - if(!buf){ - err = -ENOMEM; - goto exit; - } - memcpy(buf, p->buf, p->tok_end - p->buf); - p->buf_end = buf + buf_n; - p->tok = buf + (p->tok - p->buf); - p->tok_end = buf + (p->tok_end - p->buf); - deallocate(p->buf); - p->buf = buf; - } - *p->tok_end++ = c; - exit: - return err; -} - -/** Determine if a character is a separator. - * - * @param p parser - * @param c character to test - * @return 1 if a separator, 0 otherwise - */ -static int is_separator(Parser *p, char c){ - return in_sep_class(c); -} - -int Parser_set_value(Parser *p, Sxpr obj){ - int err = 0; - if(NOMEMP(obj)){ - err = -ENOMEM; - } else { - p->state->val = obj; - } - return err; -} - -int Parser_intern(Parser *p){ - Sxpr obj = intern(peek_token(p)); - return Parser_set_value(p, obj); -} - -int Parser_atom(Parser *p){ - Sxpr obj; - long v; - if(Parser_flags(p, PARSE_INT) && - convert_atol(peek_token(p), &v) == 0){ - obj = OINT(v); - } else { - obj = atom_new(peek_token(p)); - } - return Parser_set_value(p, obj); -} - -int Parser_string(Parser *p){ - Sxpr obj = string_new_n(peek_token(p), token_len(p)); - return Parser_set_value(p, obj); -} - -int Parser_data(Parser *p){ - Sxpr obj = string_new_n(peek_token(p), token_len(p)); - return Parser_set_value(p, obj); -} - -int Parser_uint(Parser *p){ - unsigned int x = htonl(*(unsigned int *)peek_token(p)); - return Parser_set_value(p, OINT(x)); -} - -static int get_escape(char c, char *d){ - int err = 0; - switch(c){ - case 'a': *d = '\a'; break; - case 'b': *d = '\b'; break; - case 'f': *d = '\f'; break; - case 'n': *d = '\n'; break; - case 'r': *d = '\r'; break; - case 't': *d = '\t'; break; - case 'v': *d = '\v'; break; - case c_escape: *d = c_escape; break; - case c_single_quote: *d = c_single_quote; break; - case c_double_quote: *d = c_double_quote; break; - default: - err = -EINVAL; - } - return err; -} - -int Parser_ready(Parser *p){ - return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val)); -} - -Sxpr Parser_get_val(Parser *p){ - Sxpr v = ONONE, w = ONONE; - if(CONSP(p->val)){ - } else if (p->start_state && CONSP(p->start_state->val)){ - p->val = p->start_state->val; - p->val = nrev(p->val); - p->start_state->val = ONULL; - } else { - goto exit; - } - w = p->val; - v = CAR(w); - p->val = CDR(w); - hfree(w); - exit: - return v; -} - -Sxpr Parser_get_all(Parser *p){ - Sxpr v = ONULL; - if(CONSP(p->val)){ - v = p->val; - p->val = ONONE; - } else if(p->start_state && CONSP(p->start_state->val)){ - v = p->start_state->val; - p->start_state->val = ONULL; - v = nrev(v); - } - return v; -} - -static int state_comment(Parser *p, char c){ - int err = 0; - if(c == '\n' || Parser_at_eof(p)){ - Parser_pop(p); - } else { - err = input_char(p, c); - } - return err; -} - -static int begin_comment(Parser *p, char c){ - int err = 0; - err = Parser_push(p, state_comment, "comment"); - if(err) goto exit; - err = input_char(p, c); - exit: - return err; -} - -static int end_string(Parser *p){ - int err = 0; - err = Parser_string(p); - if(err) goto exit; - err = Parser_return(p); - exit: - return err; -} - -static int octaldone(Parser *p){ - int err = 0; - char d = (char)(p->state->ival & 0xff); - Parser_pop(p); - err = Parser_input_char(p, d); - return err; -} - -static int octaldigit(Parser *p, int d){ - int err = 0; - p->state->ival *= 8; - p->state->ival += d; - p->state->count++; - if(err) goto exit; - if(p->state->ival < 0 || p->state->ival > 0xff){ - err = Parser_error(p); - goto exit; - } - if(p->state->count == 3){ - err = octaldone(p); - } - exit: - return err; -} - -static int state_octal(Parser *p, char c){ - int err = 0; - if(Parser_at_eof(p)){ - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); - goto exit; - } else if('0' <= c && c <= '7'){ - err = octaldigit(p, c - '0'); - } else { - err = octaldone(p); - if(err) goto exit; - Parser_input_char(p, c); - } - exit: - return err; -} - -static int hexdone(Parser *p){ - int err = 0; - char d = (char)(p->state->ival & 0xff); - Parser_pop(p); - err = Parser_input_char(p, d); - return err; -} - -static int hexdigit(Parser *p, int d){ - int err = 0; - p->state->ival *= 16; - p->state->ival += d; - p->state->count++; - if(err) goto exit; - if(p->state->ival < 0 || p->state->ival > 0xff){ - err = Parser_error(p); - goto exit; - } - if(p->state->count == 2){ - err = hexdone(p); - } - exit: - return err; -} - -static int state_hex(Parser *p, char c){ - int err = 0; - if(Parser_at_eof(p)){ - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); - goto exit; - } else if('0' <= c && c <= '9'){ - err = hexdigit(p, c - '0'); - } else if('A' <= c && c <= 'F'){ - err = hexdigit(p, c - 'A' + 10); - } else if('a' <= c && c <= 'f'){ - err = hexdigit(p, c - 'a' + 10); - } else if(p->state->count){ - err = hexdone(p); - if(err) goto exit; - Parser_input_char(p, c); - } - exit: - return err; -} - -static int state_escape(Parser *p, char c){ - int err = 0; - char d; - if(Parser_at_eof(p)){ - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); - goto exit; - } - if(get_escape(c, &d) == 0){ - err = save_char(p, d); - if(err) goto exit; - Parser_pop(p); - } else if(c == 'x'){ - p->state->fn = state_hex; - p->state->ival = 0; - p->state->count = 0; - } else { - p->state->fn = state_octal; - p->state->ival = 0; - p->state->count = 0; - err = Parser_input_char(p, c); - } - exit: - return err; -} - -static int state_string(Parser *p, char c){ - int err = 0; - if(Parser_at_eof(p)){ - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); - } else if(c == p->state->delim){ - err = end_string(p); - } else if(c == '\\'){ - err = Parser_push(p, state_escape, "escape"); - } else { - err = save_char(p, c); - } - return err; -} - -static int begin_string(Parser *p, char c){ - int err = 0; - err = Parser_push(p, state_string, "string"); - if(err) goto exit; - new_token(p); - p->state->delim = c; - exit: - return err; -} - -static int end_atom(Parser *p){ - int err = 0; - err = Parser_atom(p); - if(err) goto exit; - err = Parser_return(p); - exit: - return err; -} - -static int state_atom(Parser *p, char c){ - int err = 0; - if(Parser_at_eof(p)){ - err = end_atom(p); - } else if(is_separator(p, c) || - in_space_class(c) || - in_comment_class(c)){ - err = end_atom(p); - if(err) goto exit; - err = Parser_input_char(p, c); - } else { - err = save_char(p, c); - } - exit: - return err; -} - -static int begin_atom(Parser *p, char c){ - int err = 0; - err = Parser_push(p, state_atom, "atom"); - if(err) goto exit; - new_token(p); - err = save_char(p, c); - exit: - return err; -} - -static int end_data(Parser *p){ - int err = 0; - err = Parser_data(p); - if(err) goto exit; - err = Parser_return(p); - exit: - return err; -} - -static int counted_data(Parser *p, char c){ - int err = 0; - err = save_char(p, c); - if(err) goto exit; - if(token_len(p) == p->state->count){ - err = end_data(p); - } - exit: - return err; -} - -static int counted_data_count(Parser *p, char c){ - int err = 0; - if(c == p->state->delim){ - new_token(p); - p->state->count = p->state->ival; - p->state->fn = counted_data; - } else if('0' <= c && c <= '9'){ - p->state->ival *= 10; - p->state->ival += c - '0'; - } else { - err = -EINVAL; - } - return err; -} - -static int quoted_data(Parser *p, char c){ - int err = 0; - int count = p->state->count; - err = save_char(p, c); - if(err) goto exit; - // Check that buf is longer than delim and - // ends with delim. If so, trim delim off and return. - if((token_len(p) >= count) && - !memcmp(p->tok_end - count, p->buf, count)){ - p->tok_end -= count; - end_data(p); - } - exit: - return err; -} - -static int quoted_data_delim(Parser *p, char c){ - // Saves the delim in the token buffer. - int err = 0; - err = save_char(p, c); - if(err) goto exit; - if(c == p->state->delim){ - p->state->fn = quoted_data; - p->state->count = token_len(p); - // Advance the token pointer past the delim. - p->tok = p->tok_end; - } - exit: - return err; -} - -static int state_data(Parser *p, char c){ - // Quoted data: - // <state->delim = c; - p->state->fn = counted_data_count; - p->state->ival = 0; - new_token(p); - break; - case c_data_quote: - p->state->delim = c; - p->state->fn = quoted_data_delim; - new_token(p); - err = save_char(p, c); - break; - default: - err = Parser_error(p); - break; - } - return err; -} - -static int begin_data(Parser *p, char c){ - int err = 0; - err = Parser_push(p, state_data, "data"); - if(err) goto exit; - new_token(p); - exit: - return err; -} - -static int state_list(Parser *p, char c){ - int err = 0; - dprintf(">\n"); - if(Parser_at_eof(p)){ - err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF); - } else if(c == c_list_close){ - p->state->val = nrev(p->state->val); - err = Parser_return(p); - } else { - err = state_start(p, c); - } - dprintf("< err=%d\n", err); - return err; - -} - -static int begin_list(Parser *p, char c){ - return Parser_push(p, state_list, "list"); -} - -static int state_start(Parser *p, char c){ - int err = 0; - dprintf(">\n"); - if(Parser_at_eof(p)){ - err = Parser_return(p); - } else if(in_space_class(c)){ - //skip - } else if(in_comment_class(c)){ - begin_comment(p, c); - } else if(c == c_list_open){ - begin_list(p, c); - } else if(c == c_list_close){ - err = Parser_error(p); - } else if(in_string_quote_class(c)){ - begin_string(p, c); - } else if(c == c_data_open){ - begin_data(p, c); - } else if(in_printable_class(c)){ - begin_atom(p, c); - } else if(c == 0x04){ - //ctrl-D, EOT: end-of-text. - Parser_input_eof(p); - } else { - err = Parser_error(p); - } - dprintf("< err=%d\n", err); - return err; -} - -int begin_start(Parser *p, char c){ - int err = 0; - dprintf(">\n"); - err = Parser_push(p, state_start, "start"); - if(err) goto exit; - p->start_state = p->state; - exit: - dprintf("< err=%d\n", err); - return err; -} - -int Parser_input_char(Parser *p, char c){ - int err = 0; - if(Parser_at_eof(p)){ - //skip; - } else { - input_char(p, c); - } - if(!p->state){ - err = p->begin(p, c); - if(err) goto exit; - } - err = p->state->fn(p, c); - exit: - return err; -} - -int Parser_input_eof(Parser *p){ - int err = 0; - p->eof = 1; - err = Parser_input_char(p, IOSTREAM_EOF); - return err; -} - -int Parser_input(Parser *p, char *buf, int buf_n){ - int err = 0; - int i = 0; - dprintf("> buf_n=%d\n", buf_n); - if(buf_n <= 0){ - buf_n = 0; - err = Parser_input_eof(p); - goto exit; - } - dprintf("> buf=|%*s|\n", buf_n, buf); - for(i = 0; i < buf_n; i++){ - err = Parser_input_char(p, buf[i]); - if(err) goto exit; - } - exit: - err = (err < 0 ? err : buf_n); - dprintf("< err=%d\n", err); - return err; -} - -#ifdef SXPR_PARSER_MAIN -/* Stuff for standalone testing. */ - -#include "file_stream.h" -//#include "string_stream.h" - -/** Main program for testing. - * Parses input and prints it. - * - * @param argc number of arguments - * @param argv arguments - * @return error code - */ -int main(int argc, char *argv[]){ - Parser *pin; - int err = 0; - char buf[1024]; - int k; - Sxpr obj; - int i = 0; - - pin = Parser_new(); - Parser_set_error_stream(pin, iostdout); - dprintf("> parse...\n"); - while(1){ - k = fread(buf, 1, 100, stdin); - if(k>=0){ - buf[k+1] = '\0'; - } - err = Parser_input(pin, buf, k); - while(Parser_ready(pin)){ - obj = Parser_get_val(pin); - printf("obj %d\n", i++); - objprint(iostdout, obj, 0); printf("\n"); - } - if(k <= 0) break; - } - dprintf("> err=%d\n", err); - return 0; -} -#endif diff --git a/vnet/src/libxutil/sxpr_parser.h b/vnet/src/libxutil/sxpr_parser.h deleted file mode 100644 index 68efcc8ed2f..00000000000 --- a/vnet/src/libxutil/sxpr_parser.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2001 - 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_SXPR_PARSER_H_ -#define _XUTIL_SXPR_PARSER_H_ - -#include "sxpr.h" -#include "iostream.h" - -/** @file - * Sxpr parsing definitions. - */ - -/** Initial size of a parser input buffer. - */ -#define PARSER_BUF_SIZE 512 - -/** Input buffer size increment (when it's full). - */ -#define PARSER_BUF_INCREMENT 512 - -struct Parser; -typedef int ParserStateFn(struct Parser *, char c); - -typedef struct ParserState { - struct ParserState *parent; - Sxpr val; - int ival; - int count; - char delim; - ParserStateFn *fn; - char *name; -} ParserState; - -typedef struct Parser { - /** Initial state function. */ - ParserStateFn *begin; - /** Parse value. */ - Sxpr val; - /** Error reporting stream (null for no reports). */ - IOStream *error_out; - /** End-of-file flag, */ - int eof; - /** Error flag. Non-zero if there has been a read error. */ - int err; - /** Line number on input (from 1). */ - int line_no; - /** Column number of input (reset on new line). */ - int char_no; - /** Buffer for reading tokens. */ - char *buf; - char *buf_end; - char *tok; - char *tok_end; - /** Line the last token started on. */ - int tok_begin_line; - /** Character number the last token started on. */ - int tok_begin_char; - /** Parsing flags. */ - int flags; - ParserState *state; - ParserState *start_state; -} Parser; - -/** Parser error codes. */ -typedef enum { - PARSE_ERR_NONE=0, - PARSE_ERR_UNSPECIFIED, - PARSE_ERR_NOMEM, - PARSE_ERR_UNEXPECTED_EOF, - PARSE_ERR_TOKEN_TOO_LONG, - PARSE_ERR_INVALID_SYNTAX, - PARSE_ERR_INVALID_ESCAPE, -} ParseErrorId; - - -/** Parser flags. */ -enum { - /** Convert integer atoms to ints. */ - PARSE_INT=1, -}; - -/** Raise some parser flags. - * - * @param in parser - * @param flags flags mask - */ -static inline void Parser_flags_raise(Parser *in, int flags){ - in->flags |= flags; -} - -/** Lower some parser flags. - * - * @param in parser - * @param flags flags mask - */ -static inline void Parser_flags_lower(Parser *in, int flags){ - in->flags &= ~flags; -} - -/** Clear all parser flags. - * - * @param in parser - */ -static inline void Parser_flags_clear(Parser *in){ - in->flags = 0; -} - -static inline int Parser_flags(Parser *in, int flags){ - return in->flags & flags; -} - -extern void Parser_free(Parser *z); -extern Parser * Parser_new(void); -extern int Parser_input(Parser *p, char *buf, int buf_n); -extern int Parser_input_eof(Parser *p); -extern int Parser_input_char(Parser *p, char c); -extern void Parser_set_error_stream(Parser *z, IOStream *error_out); - -extern int Parser_error_message(Parser *in, char *buf, int n); -extern int Parser_has_error(Parser *in); -extern int Parser_at_eof(Parser *in); - -extern int Parser_ready(Parser *p); -extern Sxpr Parser_get_val(Parser *p); -extern Sxpr Parser_get_all(Parser *p); - -/* Internal parser api. */ -void Parser_pop(Parser *p); -int Parser_push(Parser *p, ParserStateFn *fn, char *name); -int Parser_return(Parser *p); -int Parser_at_eof(Parser *p); -int Parser_error(Parser *in); -int Parser_set_value(Parser *p, Sxpr val); -int Parser_intern(Parser *p); -int Parser_string(Parser *p); -int Parser_data(Parser *p); -int Parser_uint(Parser *p); - -char *peek_token(Parser *p); -char *copy_token(Parser *p); -void new_token(Parser *p); -int save_char(Parser *p, char c); -int token_len(Parser *p); - -#endif /* ! _XUTIL_SXPR_PARSER_H_ */ diff --git a/vnet/src/libxutil/sys_net.c b/vnet/src/libxutil/sys_net.c deleted file mode 100644 index ba7194f4954..00000000000 --- a/vnet/src/libxutil/sys_net.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sys_net.h" -#include "sys_string.h" - -#ifdef __KERNEL__ -# include -#else -# include -#endif - -/** @file - * All network data are kept in network order and only converted to - * host order for display. Network data includes IP addresses, port numbers and - * network masks. - */ - -/** Maximum value for a port. */ -#define PORT_MAX 0xffff - -/** Convert a number of bits to a network mask - * for IP addresses. The number of bits must - * be in the range 1-31. - * - * @param n number of bits to set in the mask - * @return value with n high bits set (in network order) - */ -unsigned long bits_to_mask(int n){ - unsigned long mask = (n ? (1 << 31) : 0); - int i; - for(i=1; i> 1); - } - return htonl(mask); -} - -/** Convert a network mask to a number of bits. - * - * @param mask network mask in network order - * @return number of bits in mask - */ -int mask_to_bits(unsigned long mask){ - // Start with n set to the number of bits in the mask. Then reduce n by - // the number of low zero bits in the mask. - int n = 32; - for(mask = ntohl(mask); - (mask & 1)==0 && n>0; - mask >>= 1){ - n--; - } - return n; -} - -/** Get the index of the first occurrence of a character in a string. - * Stops at end of string or after n characters. - * - * @param s input string - * @param n maximum number of charactes to search - * @param c character to look for - * @return index of first occurrence, -1 if not found - */ -inline static int indexof(const char *s, int n, char c){ - int i; - for(i=0; i= sizeof(buf)){ - goto exit; - } - for(i=0; i < WORD_BYTES; i++){ - int idx = indexof(s, n, dot); - idx = (idx < 0 ? strlen(s) : idx); - strncpy(buf, s, idx); buf[idx]='\0'; - if(convert_atoul(buf, &v)){ - goto exit; - } - if(v < 0 || v > ADDR_MAX){ - goto exit; - } - addr |= (v << shift); - if(idx == n) break; - shift -= BYTE_BITS; - s += idx+1; - } - err = 0; - exit: - addr = htonl(addr); - *address = (err ? 0 : addr); - return err; -} - -#ifdef __KERNEL__ -/** Convert an address in network order to IPv4 dot notation. - * The return value is a static buffer which is overwritten on each call. - * - * @param inaddr address (in network order) - * @return address in dot notation - */ -char *inet_ntoa(struct in_addr inaddr){ - static char address[16] = {}; - uint32_t addr = ntohl(inaddr.s_addr); - snprintf(address, sizeof(address), "%d.%d.%d.%d", - (unsigned)((addr >> 24) & 0xff), - (unsigned)((addr >> 16) & 0xff), - (unsigned)((addr >> 8) & 0xff), - (unsigned)((addr ) & 0xff)); - return address; -} - - -/** Convert a string in IPv4 dot notation to an int in network order. - * - * @param address address in dot notation - * @param inp result of conversion (in network order) - * @return 0 on success, error code on error - */ -int inet_aton(const char *address, struct in_addr *inp){ - int err = 0; - unsigned long addr; - - err = get_inet_addr(address, &addr); - if(err) goto exit; - inp->s_addr = addr; - exit: - return err; -} -#endif - -/** Convert a hostname or IPv4 address string to an address in network order. - * - * @param name input hostname or address string - * @param address where to put the address - * @return 0 if address found OK, nonzero otherwise - */ -int get_host_address(const char *name, unsigned long *address){ -#ifdef __KERNEL__ - return get_inet_addr(name, address); -#else - struct hostent *host = gethostbyname(name); - if(!host){ - return -ENOENT; - } - *address = ((struct in_addr *)(host->h_addr))->s_addr; - return 0; -#endif -} - -/** Convert a service name to a port (in network order). - * - * @param name service name - * @param port where to put the port - * @return 0 if service port found OK, negative otherwise - */ -int get_service_port(const char *name, unsigned long *port){ -#ifdef __KERNEL__ - return -ENOSYS; -#else - struct servent *service; - service = getservbyname(name, 0); - if(!service){ - return -EINVAL; - } - *port = service->s_port; - return 0; -#endif -} - -/** Convert a port number (in network order) to a service name. - * - * @param port the port number - * @return service name if found OK, NULL otherwise - */ -char *get_port_service(unsigned long port){ -#ifdef __KERNEL__ - return NULL; -#else - struct servent *service = getservbyport(port, 0); - return (service ? service->s_name : NULL); -#endif -} - -/** Convert a decimal integer or service name to a port (in network order). - * - * @param s input to convert - * @param port where to put the port - * @return 0 if port found OK, -1 otherwise - */ -int convert_service_to_port(const char *s, unsigned long *port){ - int err = 0; - unsigned long value; - if(convert_atoul(s, &value) == 0){ - int ok = (0 <= value) && (value <= PORT_MAX); - if(ok){ - value = htons((unsigned short)value); - } else { - err = -EINVAL; - } - } else { - err = get_service_port(s, &value); - } - *port = (err ? 0: value); - return err; -} - -#define MAC_ELEMENT_N 6 // Number of elements in a MAC address. -#define MAC_DIGIT_N 2 // Number of digits in an element in a MAC address. -#define MAC_LENGTH 17 //((MAC_ELEMENT_N * MAC_DIGIT_N) + MAC_ELEMENT_N - 1) - -/** Convert a mac address from a string of the form - * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars). - * Each X denotes a hex digit: 0..9, a..f, A..F. - * Also supports using '-' as the separator instead of ':'. - * - * @param mac_in string to convert - * @param mac destination for the value - * @return 0 on success, -1 on error - */ -int mac_aton(const char *mac_in, unsigned char *mac){ - int err = 0; - int i, j; - const char *p; - char sep = 0; - unsigned char d; - if(!mac_in || strlen(mac_in) != MAC_LENGTH){ - err = -1; - goto exit; - } - for(i = 0, p = mac_in; i < MAC_ELEMENT_N; i++){ - d = 0; - if(i){ - if(!sep){ - if(*p == ':' || *p == '-') sep = *p; - } - if(sep && *p == sep){ - p++; - } else { - err = -1; - goto exit; - } - } - for(j = 0; j < MAC_DIGIT_N; j++, p++){ - if(j) d <<= 4; - if(*p >= '0' && *p <= '9'){ - d += (*p - '0'); - } else if(*p >= 'A' && *p <= 'F'){ - d += (*p - 'A') + 10; - } else if(*p >= 'a' && *p <= 'f'){ - d += (*p - 'a') + 10; - } else { - err = -1; - goto exit; - } - } - mac[i] = d; - } - exit: - return err; -} - -/** Convert a MAC address from numerical form to a string. - * - * @param mac address to convert - * @return static string value - */ -char *mac_ntoa(const unsigned char *mac){ - static char buf[MAC_LENGTH + 1]; - int buf_n = sizeof(buf); - - memset(buf, 0, buf_n); - snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x", - mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5]); - buf[buf_n - 1] = '\0'; - return buf; -} diff --git a/vnet/src/libxutil/sys_net.h b/vnet/src/libxutil/sys_net.h deleted file mode 100644 index 61754940f2e..00000000000 --- a/vnet/src/libxutil/sys_net.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_SYS_NET_H_ -#define _XUTIL_SYS_NET_H_ -/** @file - * - * Replacement for standard network includes. - * Works in user or kernel code. - */ - -extern int get_inet_addr(const char *s, unsigned long *address); -extern unsigned long bits_to_mask(int n); -extern int mask_to_bits(unsigned long mask); -extern int get_host_address(const char *name, unsigned long *address); -extern int get_service_port(const char *name, unsigned long *port); -extern char *get_port_service(unsigned long port); -extern int convert_service_to_port(const char *s, unsigned long *port); - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include - -#ifndef htonl -#define htonl(x) __constant_htonl(x) -#endif - -#ifndef ntohl -#define ntohl(x) __constant_ntohl(x) -#endif - -#ifndef htons -#define htons(x) __constant_htons(x) -#endif - -#ifndef ntohs -#define ntohs(x) __constant_ntohs(x) -#endif - -#include -extern char *inet_ntoa(struct in_addr inaddr); -extern int inet_aton(const char *address, struct in_addr *inp); - -#else - -#include -#include -#include -#include -#include - -#endif - -extern char *mac_ntoa(const unsigned char *macaddr); -extern int mac_aton(const char *addr, unsigned char *macaddr); - -#endif /* !_XUTIL_SYS_NET_H_ */ - - - diff --git a/vnet/src/libxutil/sys_string.c b/vnet/src/libxutil/sys_string.c deleted file mode 100644 index 46db2a3226d..00000000000 --- a/vnet/src/libxutil/sys_string.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef __KERNEL__ -# include -# include -# include -# include -#else -# include -#endif - -#include "allocate.h" -#include "sys_string.h" - -#ifdef __KERNEL__ - -#define deferr(_err) case _err: return #_err - -extern char *strerror(int err) -{ - switch(err){ - deferr(EPERM); - deferr(ENOENT); - deferr(ESRCH); - deferr(EINTR); - deferr(EIO); - deferr(EINVAL); - deferr(ENOMEM); - deferr(EACCES); - deferr(EFAULT); - deferr(EBUSY); - - default: - return "ERROR"; - } -} - -#endif - -/** Set the base to use for converting a string to a number. Base is - * hex if starts with 0x, otherwise decimal. - * - * @param s input string - * @param base where to put the base - * @return rest of s to parse as a number - */ -inline static const char * convert_set_base(const char *s, int *base){ - *base = 10; - if(s){ - if(*s=='0'){ - s++; - if(*s=='x' || *s=='X'){ - *base = 16; - s++; - } - } - } - return s; -} - -/** Set the sign to use for converting a string to a number. - * Value is 1 for positive, -1 for negative. - * - * @param s input string - * @param sign where to put the sign - * @return rest of s to parse as a number - */ -inline static const char * convert_set_sign(const char *s, int *sign){ - *sign = 1; - if(s){ - if(*s == '+'){ - *sign = 1; - s++; - } else if (*s == '-'){ - *sign = -1; - s++; - } - } - return s; -} - -/** Get the numerical value of a digit in the given base. - * - * @param c digit character - * @param base to use - * @return numerical value of digit in range 0..base-1 or - * -1 if not in range for the base - */ -inline static int convert_get_digit(char c, int base){ - int d; - - if('0'<=c && c<='9'){ - d = c - '0'; - } else if('a'<=c && c<='f'){ - d = c - 'a' + 10; - } else if('A'<=c && c<='F'){ - d = c - 'A' + 10; - } else { - d = -1; - } - return (d < base ? d : -1); -} - -/** Convert a string to an unsigned long by parsing it as a number. - * Will accept hex or decimal in usual C syntax. - * - * @param str input string - * @param val where to put the result - * @return 0 if converted OK, negative otherwise - */ -int convert_atoul(const char *str, unsigned long *val){ - int err = 0; - unsigned long v = 0; - int base; - const char *s = str; - - if(!s) { - err = -EINVAL; - goto exit; - } - s = convert_set_base(s, &base); - for( ; !err && *s; s++){ - int digit = convert_get_digit(*s, base); - if(digit<0){ - err = -EINVAL; - goto exit; - } - v *= base; - v += digit; - } - exit: - *val = (err ? 0 : v); - return err; -} - -/** Convert a string to a long by parsing it as a number. - * Will accept hex or decimal in usual C syntax. - * - * @param str input string - * @param val where to put the result - * @return 0 if converted OK, negative otherwise - */ -int convert_atol(const char *str, long *val){ - int err = 0; - unsigned long v = 0; - int base, sign = 1; - const char *s = str; - - if(!s) { - err = -EINVAL; - goto exit; - } - s = convert_set_sign(s, &sign); - s = convert_set_base(s, &base); - for( ; !err && *s; s++){ - int digit = convert_get_digit(*s, base); - if(digit<0){ - err = -EINVAL; - goto exit; - } - v *= base; - v += digit; - } - if(sign < 0) v = -v; - exit: - *val = (err ? 0 : v); - return err; -} - -/** Combine a directory path with a relative path to produce - * a new path. - * - * @param s directory path - * @param t relative path - * @return new combined path s/t - */ -int path_concat(char *s, char *t, char **val){ - int err = 0; - int sn, tn, vn; - char *v; - sn = strlen(s); - if(sn > 0 && s[sn-1] == '/'){ - sn--; - } - tn = strlen(t); - if(tn > 0 && t[0] == '/'){ - tn--; - } - vn = sn+tn+1; - v = (char*)allocate(vn+1); - if(!v){ - err = -ENOMEM; - goto exit; - } - strncpy(v, s, sn); - v[sn] = '/'; - strncpy(v+sn+1, t, tn); - v[vn] = '\0'; - exit: - *val = (err ? NULL : v); - return err; -} diff --git a/vnet/src/libxutil/sys_string.h b/vnet/src/libxutil/sys_string.h deleted file mode 100644 index c66fded4018..00000000000 --- a/vnet/src/libxutil/sys_string.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2001 - 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XUTIL_SYS_STRING_H_ -#define _XUTIL_SYS_STRING_H_ -/** @file - * Replacement for standard string includes. - * Works in user or kernel code. - */ -/*============================================================================*/ -#define _GNU_SOURCE -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include "allocate.h" - -extern char *strerror(int err); - -#if 0 -static inline int tolower(int c){ - return (c>='A' && c<='Z' ? (c-'A')+'a' : c); -} -#endif - -static inline int isalpha(int c){ - return (c>='A' && c<='Z') || (c>='a' && c<='z'); -} - -static inline int isdigit(int c){ - return (c>='0' && c<='9'); -} - -#if 0 -static inline int strcasecmp(const char *s1, const char *s2){ - int c1, c2; - - do { - c1 = tolower(*s1++); - c2 = tolower(*s2++); - } while (c1 && c1 == c2); - return c1 - c2; -} -#endif - -static inline char * strdup(const char *s){ - int n = (s ? 1+strlen(s) : 0); - char *copy = (n ? allocate(n) : NULL); - if(copy){ - strcpy(copy, s); - } - return copy; -} - -/*============================================================================*/ -#else -#include -#include - -#ifndef _GNU_SOURCE -static inline size_t strnlen(const char *s, size_t n){ - int k = 0; - if(s){ - for(k=0; *s && k. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sys_net.h" -#include "sys_string.h" - -#ifndef __KERNEL__ -# include -# include -#endif - -#include "util.h" - - -/** @file Various utility functions. - */ - -/** Print an address (in network order) as an IPv4 address string - * in dot notation. - * - * @param io where to print address - * @param address to print (in network order) - * @return bytes printed - */ -int print_address(IOStream *io, unsigned long address){ -#ifdef __KERNEL__ - address = ntohl(address); - return IOStream_print(io, "%u.%u.%u.%u", - (unsigned)((address >> 24) & 0xff), - (unsigned)((address >> 16) & 0xff), - (unsigned)((address >> 8) & 0xff), - (unsigned)((address ) & 0xff)); -#else - struct in_addr inaddr = { s_addr: address }; - return IOStream_print(io, inet_ntoa(inaddr)); -#endif -} - -/** Get the protocol number for a protocol. - * - * @param name protocol name - * @param protocol where to put the protocol number - * @return 0 if OK, error otherwise - */ -int get_protocol_number(char *name, unsigned long *protocol){ -#ifdef __KERNEL__ - return -1; -#else - struct protoent *proto = getprotobyname(name); - if(!proto){ - return -1; - } - *protocol = proto->p_proto; - return 0; -#endif -} - -/** Get the protocol name for a protocol number. - * - * @param protocol number - * @return name or null - */ -char *get_protocol_name(unsigned long protocol){ -#ifdef __KERNEL__ - return 0; -#else - struct protoent *proto = getprotobynumber(protocol); - if(!proto){ - return 0; - } - return proto->p_name; -#endif -} - -/** Get the host name for an address. - * - * @param addr address - * @return host name or null - */ -char *get_host_name(unsigned long addr){ -#ifdef __KERNEL__ - return 0; -#else - struct in_addr inaddr; - struct hostent *host = 0; - - inaddr.s_addr = addr; - host = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET); - if(!host) return NULL; - return host->h_name; -#endif -} diff --git a/vnet/src/libxutil/util.h b/vnet/src/libxutil/util.h deleted file mode 100644 index b4a170512f5..00000000000 --- a/vnet/src/libxutil/util.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2002 - 2004 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _XEN_LIB_UTIL_H_ -#define _XEN_LIB_UTIL_H_ - -#include "iostream.h" - -extern int print_address(IOStream *io, unsigned long address); -extern int get_protocol_number(char *name, unsigned long *protocol); -extern char *get_protocol_name(unsigned long protocol); -extern char *get_host_name(unsigned long addr); - -#endif /* ! _XEN_LIB_UTIL_H_ */ diff --git a/vnet/src/scripts/Makefile b/vnet/src/scripts/Makefile deleted file mode 100644 index 22910a4432a..00000000000 --- a/vnet/src/scripts/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/Rules.mk - -.PHONY: all -all: - -.PHONY: install -install: - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) vn $(DESTDIR)$(SBINDIR) - -.PHONY: clean -clean: diff --git a/vnet/src/scripts/vn b/vnet/src/scripts/vn deleted file mode 100644 index c7f19ec7103..00000000000 --- a/vnet/src/scripts/vn +++ /dev/null @@ -1,904 +0,0 @@ -#!/usr/bin/env python2.4 -# -*- mode: python; -*- -#============================================================================ -# Copyright (C) 2005, 2006 Mike Wray -# -# This library is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -# Vnet (network virtualization) control utility. - -import os -import os.path -import re -import socket -import sys -from getopt import getopt, GetoptError - -sys.path.append('/usr/lib/python') -sys.path.append('/usr/lib64/python') - -from xen.xend import sxp -from xen.xend.PrettyPrint import prettyprint - -# Path of unix-domain socket to vnetd. -VNETD_PATH = "/tmp/vnetd" - -def vnetd_running(): - return os.path.exists(VNETD_PATH) - -def vnetd_open(): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(VNETD_PATH) - fi = sock.makefile('r', 0) - fo = sock.makefile('w', 0) - return (fi, fo) - -os.defpath += ':/sbin:/usr/sbin:/usr/local/sbin' -CMD_IFCONFIG = 'ifconfig' -CMD_BRCTL = 'brctl' - -opts = None - -class Opts: - - def __init__(self, **kwds): - for (k, v) in kwds.items(): - setattr(self, k, v) - -opts = Opts(verbose=False, dryrun=False) - -def set_opts(val): - global opts - opts = val - return opts - -def cmd(prog, *args): - """Execute command 'prog' with 'args', optionally printing the command. - """ - global opts - command = " ".join([ prog ] + map(str, args)) - if opts.verbose: - print command - if not opts.dryrun: - os.system(command) - -def vif_bridge_add(bridge, vif): - """Add a network interface to a bridge. - """ - cmd(CMD_BRCTL, 'addif', bridge, vif) - -def vif_bridge_rem(bridge, vif): - """Remove a network interface from a bridge. - """ - cmd(CMD_BRCTL, 'delif', bridge, vif) - -def bridge_create(bridge, **kwd): - """Create a bridge. - Defaults hello time to 0, forward delay to 0 and stp off. - """ - cmd(CMD_BRCTL, 'addbr', bridge) - if kwd.get('hello', None) is None: - kwd['hello'] = 0 - if kwd.get('fd', None) is None: - kwd['fd'] = 0 - if kwd.get('stp', None) is None: - kwd['stp'] = 'off' - bridge_set(bridge, **kwd) - cmd(CMD_IFCONFIG, bridge, "up") - -def bridge_set(bridge, hello=None, fd=None, stp=None): - """Set bridge parameters. - """ - if hello is not None: - cmd(CMD_BRCTL, 'sethello', bridge, hello) - if fd is not None: - cmd(CMD_BRCTL, 'setfd', bridge, fd) - if stp is not None: - cmd(CMD_BRCTL, 'stp', bridge, stp) - -def bridge_del(bridge): - """Delete a bridge. - """ - cmd(CMD_IFCONFIG, bridge, 'down') - cmd(CMD_BRCTL, 'delbr', bridge) - -class Bridge: - # Network interfaces are at /sys/class/net/*. - # A bridge interface has ./bridge dir, ./brif is dir of bridged interfaces - # (symlinks to the brport dirs). - # If an interface is bridged ./brport is bridged port info, - # brport/bridge is a symlink to the bridge. - - INTERFACE_DIR = "/sys/class/net" - - def isBridge(klass, dev): - """Test if a network interface is a bridge. - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - brdir = os.path.join(devdir, "bridge") - try: - os.stat(brdir) - return True - except: - return False - - isBridge = classmethod(isBridge) - - def getInterfaces(klass): - """Get a list of the network interfaces. - """ - try: - v = os.listdir(klass.INTERFACE_DIR) - v.sort() - return v - except: - return [] - - getInterfaces = classmethod(getInterfaces) - - def getInterfaceAddr(klass, intf): - intfdir = os.path.join(klass.INTERFACE_DIR, intf) - addrfile = os.path.join(intfdir, "address") - try: - f = file(addrfile, "rb") - except Exception, ex: - #print ex - return None - try: - return f.readline().strip() - finally: - f.close() - - getInterfaceAddr = classmethod(getInterfaceAddr) - - def getBridges(klass): - """Get a list of the bridges. - """ - return [ dev for dev in klass.getInterfaces() if klass.isBridge(dev) ] - - getBridges = classmethod(getBridges) - - def getBridgeInterfaces(klass, dev): - """Get a list of the interfaces attached to a bridge. - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - intfdir = os.path.join(devdir, "brif") - try: - v = os.listdir(intfdir) - v.sort() - return v - except: - return [] - - getBridgeInterfaces = classmethod(getBridgeInterfaces) - - def getBridge(klass, dev): - """Get the bridge an interface is attached to (if any). - """ - devdir = os.path.join(klass.INTERFACE_DIR, dev) - brfile = os.path.join(devdir, "brport/bridge") - try: - brpath = os.readlink(brfile) - return os.path.basename(brpath) - except: - return None - - getBridge = classmethod(getBridge) - -def vnet_cmd(expr): - """Send a command expression to the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - else: - fi = None - fo = file("/proc/vnet/policy", "wb") - try: - sxp.show(expr, fo) - fo.flush() - finally: - if fi: fi.close() - if fo: fo.close() - -def varp_flush(): - """Flush the varp cache. - """ - expr = ['varp.flush'] - return vnet_cmd(expr) - -def vif_add(vnetid, vmac): - """Tell the vnet implementation to add a vif to a vnet. - """ - expr = ['vif.add', ['vnet', vnetid], ['vmac', vmac]] - return vnet_cmd(expr) - -def vif_del(vnetid, vmac): - """Tell the vnet implementation to delete a vif from a vnet. - """ - expr = ['vif.del', ['vnet', vnetid], ['vmac', vmac]] - return vnet_cmd(expr) - -def vnet_add(vnetid, vnetif=None, security=None): - """Tell the vnet implementation to add a vnet. - """ - expr = ['vnet.add', ['id', vnetid]] - if vnetif: - expr.append(['vnetif', vnetif]) - if security: - expr.append(['security', security]) - return vnet_cmd(expr) - -def peer_add(addr, port=None): - expr = ['peer.add', ['addr', addr]] - if port: - expr.append(['port', port]) - return vnet_cmd(expr) - -def peer_del(addr, port=None): - expr = ['peer.del', ['addr', addr]] - return vnet_cmd(expr) - -def vnet_del(vnetid): - """Tell the vnet implementation to delete a vnet. - """ - expr = ['vnet.del', ['id', vnetid]] - return vnet_cmd(expr) - -def vnet_create(vnetid, vnetif=None, bridge=None, security=None): - """Tell the vnet implementation to add a vnet. - If 'bridge' is non-null, create the bridge and add the vnet interface - to it. - """ - vnet_add(vnetid, vnetif=vnetif, security=security) - val = vnet_lookup(vnetid) - if not vnetif: - vnetif = sxp.child_value(val, "vnetif") - vmac = get_mac(vnetif) - emac = get_mac("eth0") or get_mac("eth1") or get_mac("eth2") - """ if emac and vmac != emac: - set_mac(vnetif, emac) """ - cmd(CMD_IFCONFIG, vnetif, 'up') - if bridge: - bridge_create(bridge) - vif_bridge_add(bridge, vnetif) - return val - -def vnet_delete(vnet, delbridge=False): - """Tell the vnet implementation to delete a vnet. - If the vnet interface is attached to a bridge, - remove it from the bridge, and if delbridge is true - delete the bridge. - """ - v = vnet_lookup(vnet) - if not v: - raise GetoptError("vnet not found: %s" % vnet) - vnetid = sxp.child_value(v, "id") - vnetif = sxp.child_value(v, "vnetif") - bridge = Bridge.getBridge(vnetif) - if bridge: - vif_bridge_rem(bridge, vnetif) - if delbridge: - bridge_del(bridge) - return vnet_del(vnetid) - -def get_mac(intf): - """Get the mac address of an interface. - """ - try: - return Bridge.getInterfaceAddr(intf) - except: - pass - - hwre = re.compile(".*\s+HWaddr\s+(?P\S*)\s+.*") - fin = os.popen("%s %s" % (CMD_IFCONFIG, intf), 'r') - try: - for x in fin: - m = hwre.match(x) - if not m: - continue - info = m.groupdict() - return info['mac'] - return None - finally: - fin.close() - -def set_mac(intf, mac): - cmd(CMD_IFCONFIG, intf, 'down') - cmd(CMD_IFCONFIG, intf, 'hw', 'ether', mac) - cmd(CMD_IFCONFIG, intf, 'up') - -def get_addr(host): - return socket.gethostbyname(host) - -def get_port(srv): - return srv - -def vnetidof(v): - """Normalise a vnet id. Adds leading 0 fields to make up 8 if - there aren't enough. Pads all fields to 4 hex digits. - """ - try: - l = v.split(":") - l = [ int(x or 0, 16) for x in l ] - l = [ 0 ] * (8 - len(l)) + l - return ":".join([ "%04x" % x for x in l ]) - except: - return None - -def vnet_lookup(vnet, vnets=None): - """Find the vnet with the given vnet id or vnet interface. - - @param vnet id or interface - @param vnets list of vnet info to use (get from implementation if None) - @return vnet info or None if not found - """ - vnetid = vnetidof(vnet) - if vnets is None: - vnets = vnet_list() - for v in vnets: - vid = sxp.child_value(v, "id") - if vid == vnet or vid == vnetid: - return v - if sxp.child_value(v, "vnetif") == vnet: - return v - return None - -def get_vnetid(vnet): - """Get the normalised vnet id of the given vnet id or vnet interface. - Raises an error if the vnet cannot be found. - """ - v = vnet_lookup(vnet) - if not v: - raise GetoptError("vnet not found: %s" % vnet) - vnetid = sxp.child_value(v, "id") - return vnetid - -def vif_list(): - """Get the list of vif info from the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['vif.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/vifs") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -def vnets_filter(vnetlist, vnets): - """Filter a list of vnet info by a list of vnet ids or interfaces. - """ - if vnets is None: - val = vnetlist - else: - val = [] - for x in vnets: - v = vnet_lookup(x, vnets=vnetlist) - if not v: - continue - val.append(v) - return val - -def vnet_list(vnets=None): - """Get the list of vnet info from the vnet implementation, - sorted by vnet id. - - @param vnets list of vnet ids or interfaces to filter the results by - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['vnet.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/vnets") - fo = None - try: - val = vnets_filter(sxp.parse(fi) or [], vnets) - val.sort(lambda x, y: - cmp(sxp.child_value(x, "id"), - sxp.child_value(y, "id"))) - return val - finally: - if fi: fi.close() - if fo: fo.close() - -def vnif_list(vnets=None): - """Get the list of vnet interface names from the vnet implementation. - - @param vnets list of vnet ids or interfaces to filter the results by - """ - vnifs = [] - for v in vnet_list(vnets=vnets): - vnetif = sxp.child_value(v, "vnetif") - if vnetif: - vnifs.append(vnetif) - return vnifs - -def varp_list(): - """Get the list of varp info from the vnet implementation. - """ - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['varp.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/varp") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -def peer_list(): - if vnetd_running(): - (fi, fo) = vnetd_open() - sxp.show(['peer.list'], fo) - fo.flush() - else: - fi = file("/proc/vnet/peers") - fo = None - try: - return sxp.parse(fi) or [] - finally: - if fi: fi.close() - if fo: fo.close() - -class Opt: - """Declares command-line options for a command. - """ - - def getopt(klass, argv, opts, args): - """Get options and args from argv. - The value opts in the return value has an attribute for - eacho option or arg. The value args in the return value - is the remaining arguments. - - @param argv arguments - @param opts option specifiers (list of Opt objects) - @param args arg specififiers (list of Arg objects) - @return (opts, args) - """ - shortopts = "".join([ x.optShort() for x in opts ]) - longopts = [ x.optLong() for x in opts ] - (ovals, oargs) = getopt(argv[1:], shortopts, longopts) - odir = Opts() - for x in opts: - x.setDefault(odir) - for (k, v) in ovals: - for x in opts: - x.setOpt(k, v, odir) - argc = len(oargs) - if len(oargs) < len(args): - raise GetoptError("insufficient arguments for %s" % argv[0]) - for (x, v) in zip(args, oargs): - x.setArg(v, odir) - return (odir, oargs[len(args): ]) - - getopt = classmethod(getopt) - - def gethelp(klass, opts, args): - l = [] - for x in opts: - l.append(x.help()) - for x in args: - l.append(x.help()) - return " ".join(l) - - gethelp = classmethod(gethelp) - - """A command=-line option. - - @param name option name (this attribute is set to value in opts) - @param short short option flag (single-character string) - @param long long option name (defaults to option name, pass "" to suppress) - @param arg argument name (option has no arg if not specified) - """ - def __init__(self, name, short=None, long=None, arg=False): - self.name = name - self.short = short - if long is None: - long = name - elif not long: - long = None - self.long = long - self.arg = arg - - def help(self): - s = self.keyShort() - l = self.keyLong() - if s and l: - return "[%s | %s]" % (s, l) - else: - return s or l - - def keyShort(self): - if self.short: - return "-%s" % self.short - else: - return None - - def keyLong(self): - if self.long: - return "--%s" % self.long - else: - return None - - def optLong(self): - if not self.long: - return None - if self.arg: - return "%s=" % self.long - else: - return self.long - - def optShort(self): - if not self.short: - return None - if self.arg: - return "%s:" % self.short - else: - return self.short - - def setDefault(self, vals): - if self.arg: - setattr(vals, self.name, None) - else: - setattr(vals, self.name, False) - - def setOpt(self, k, v, vals): - if k in [ self.keyShort(), self.keyLong() ]: - if self.arg: - setattr(vals, self.name, v) - else: - if v not in [ None, '' ]: - raise GetoptError("option %s does not take an argument" % k) - setattr(vals, self.name, True) - -class Arg: - - """A command-line parameter. Args get their values from arguments - left over after option processing and are assigned in order. - The value is accessible as the attribute called 'name' in opts. - - @param name argument name - """ - def __init__(self, name): - self.name = name - - def setArg(self, v, vals): - setattr(vals, self.name, v) - - def help(self): - return "<%s>" % self.name - -class VnMain: - - """Methods beginning with this prefix are commands. - They must all have arguments like this: - - op_foo(self, argv, args, opts) - - argv: original command-line arguments - args: arguments left after option processing - opts: option and arg values (accessible as attributes) - - Method options are specified by setting attribute - .opts on the method to a list of Option objects. - For args set .args to a list of Arg objects. - Use .use for short usage string, .help for long help. - - Each option or arg defines an attribute in opts. For example - an option with name 'foo' is accessible as 'opts.foo'. - """ - opPrefix = "op_" - - def __init__(self, argv): - if argv: - self.name = argv[0] - else: - self.name = "vn" - self.argv = argv - self.argc = len(argv) - - def error(self, v): - print >>sys.stderr, "%s: %s" % (self.name, v) - sys.exit(1) - - def getFunction(self, opname): - key = self.opPrefix + opname.replace("-", "_") - fn = getattr(self, key, None) - if not fn: - raise ValueError("unknown command: %s" % opname) - return fn - - def main(self): - if self.argc < 2: - args = ["help"] - else: - args = self.argv[1:] - try: - fn = self.getFunction(args[0]) - except ValueError, ex: - self.error(ex) - try: - fnopts = self.getOpts(fn) - fnargs = self.getArgs(fn) - (opts, parms) = Opt.getopt(args, fnopts, fnargs) - return fn(args, parms, opts) - except GetoptError, ex: - self.error(ex) - except ValueError, ex: - self.error(ex) - except Exception, ex: - import traceback; traceback.print_exc() - self.error(ex) - - def getOpts(self, meth): - return getattr(meth, "opts", []) - - def getArgs(self, meth): - return getattr(meth, "args", []) - - def getUse(self, meth): - return getattr(meth, "use", "") - - def getHelp(self, meth): - return getattr(meth, "help", "") or self.getUse(meth) - - def fnHelp(self, meth): - return Opt.gethelp(self.getOpts(meth), self.getArgs(meth)) - - def printHelp(self, fn, opt_long): - meth = getattr(self, fn) - opname = fn[len(self.opPrefix):].replace("_", "-") - if opt_long: - help = self.getHelp(meth) - print "\n %s" % opname - if help: - print "%s" % help - else: - use = self.getUse(meth) - print " %s %s" % (opname, self.fnHelp(meth)) - if use: - print "\t\t%s" % use - - def show_vnif(self, dev): - cmd(CMD_IFCONFIG, dev) - bridge = Bridge.getBridge(dev) - if bridge: - print " Bridge:", bridge - interfaces = Bridge.getBridgeInterfaces(bridge) - if dev in interfaces: - interfaces.remove(dev) - if interfaces: - print " Interfaces:", ", ".join(interfaces) - print - - def op_help(self, argv, args, opts): - if opts.long: - print '%s ' % self.name - print self.long_help - else: - print '%s:' % self.name - l = dir(self) - l.sort() - for fn in l: - if fn.startswith(self.opPrefix): - self.printHelp(fn, opts.long) - print - - op_help.opts = [ Opt('long', short='l') ] - - def op_vnets(self, argv, args, opts): - vnets = vnet_list(vnets=args or None) - for v in vnets: - prettyprint(v, width=50) - print - if not opts.long: - continue - vnif = sxp.child_value(v, "vnetif") - if not vnif: - continue - self.show_vnif(vnif) - if opts.all: - vnetids = {} - for v in vnets: - vnetids[sxp.child_value(v, "id")] = v - for v in vif_list(): - vnet = sxp.child_value(v, "vnet") - if vnet not in vnetids: - continue - prettyprint(v) - print - for v in varp_list(): - prettyprint(v) - print - - op_vnets.opts = [ Opt('all', short='a'), Opt('long', short='l') ] - - def op_vnifs(self, argv, args, opts): - vnifs = vnif_list(vnets=args or None) - for vnif in vnifs: - self.show_vnif(vnif) - - def op_vifs(self, argv, args, opts): - for v in vif_list(): - prettyprint(v) - print - - def op_varp(self, argv, args, opts): - for v in varp_list(): - prettyprint(v) - print - - def op_varp_flush(self, argv, args, opts): - varp_flush() - - def op_vnet_create(self, argv, args, opts): - return vnet_create(opts.vnet, - vnetif=opts.vnetif, - bridge=opts.bridge, - security=opts.security) - - op_vnet_create.args = [ Arg('vnet') ] - op_vnet_create.opts = [ Opt('security', short='s', arg="SECURITY"), - Opt('bridge', short='b', arg="BRIDGE"), - Opt('vnetif', short='v', arg="VNETIF") ] - - def op_vnet_delete(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - return vnet_delete(vnetid, delbridge=opts.bridge) - - op_vnet_delete.args = [ Arg('vnet') ] - op_vnet_delete.opts = [ Opt('bridge', short='b') ] - - def op_vif_add(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - if opts.interface: - vmac = get_mac(opts.vmac) - if not vmac: - raise ValueError("interface not found: %s" % opts.vmac) - else: - vmac = opts.vmac - return vif_add(vnetid, vmac) - - op_vif_add.args = [ Arg('vnet'), Arg('vmac') ] - op_vif_add.opts = [ Opt('interface', short='i') ] - - def op_vif_delete(self, argv, args, opts): - vnetid = get_vnetid(opts.vnet) - if opts.interface: - vmac = get_mac(opts.vmac) - else: - vmac = opts.vmac - return vif_del(vnetid, vmac) - - op_vif_delete.args = [ Arg('vnet'), Arg('vmac') ] - op_vif_delete.opts = [ Opt('interface', short='i') ] - - def op_peer_add(self, argv, args, opts): - addr = get_addr(opts.addr) - if(opts.port): - port = get_port(opts.port) - else: - port = None - return peer_add(addr, port) - - op_peer_add.args = [ Arg('addr') ] - op_peer_add.opts = [ Opt('port', short='p') ] - - def op_peer_delete(self, argv, args, opts): - addr = get_addr(opts.addr) - return peer_del(addr) - - op_peer_delete.args = [ Arg('addr') ] - - def op_peers(self, argv, args, opts): - for v in peer_list(): - prettyprint(v) - print - - def op_bridges(self, argv, args, opts): - if opts.long: - for bridge in Bridge.getBridges(): - cmd(CMD_IFCONFIG, bridge) - interfaces = Bridge.getBridgeInterfaces(bridge) - if interfaces: - print " Interfaces:", ", ".join(interfaces) - print - else: - for bridge in Bridge.getBridges(): - print bridge, - interfaces = Bridge.getBridgeInterfaces(bridge) - if interfaces: - print ":", ", ".join(interfaces) - else: - print - - op_bridges.opts = [ Opt('long', short='l') ] - - def op_insmod(self, argv, args, opts): - """Insert the vnet kernel module.""" - cmd("/etc/xen/scripts/vnet-insert", *args) - - long_help = """Control utility for vnets (virtual networking). -Report bugs to Mike Wray . -""" - - op_help.use = "Print help." - op_help.help = "Print help, long help if the option -l or --long is given." - - op_vnets.use = """Print vnets.""" - op_vnets.help = """Print vnet information, where options are: - -a, -all Print vnets, vifs and varp info. - -l, --long Print ifconfigs for vnet interfaces.""" - - op_vifs.use = "Print vifs." - - op_vnifs.use = "Print ifconfigs for vnet network interfaces." - - op_varp.use = "Print varp info and entries in the varp cache." - - op_varp_flush.use = "Flush the varp cache." - - op_vnet_create.use = "Create a vnet." - - op_vnet_delete.use = "Delete a vnet." - op_vnet_delete.help = """Delete a vnet. - -b, --bridge Delete the bridge the vnet interface is attached to. - """ - - op_vif_add.use = "Add a vif to a vnet." - op_vif_add.help = """Add a vif to a vnet. Not usually needed as vifs -are added automatically. - -i, --interface The vmac is the name of an interface to get the mac from.""" - - op_vif_delete.use = "Delete a vif from a vnet." - op_vif_delete.help = """Delete a vif from a vnet. Not usually needed as vifs -are removed periodically. - -i, --interface The vmac is the name of an interface to get the mac from.""" - - op_peer_add.use = "Add a peer." - op_peer_add.help = """Add a peer: -Vnets use multicast to discover interfaces, but networks are often configured -not to forward multicast. Vnets forward multicasts to peers using UDP. -Only add peers if multicasts are not working, check with - -ping -b 224.10.0.1 - -Only add peers at one machine in a subnet, otherwise you may cause forwarding -loops. -""" - - op_peer_delete.use = "Delete a peer." - op_peer_delete.help= "Delete a peer: " - - op_peers.use = "List peers." - op_peers.help = "List peers." - - op_bridges.use = "Print bridges." - - op_insmod.use = "Insert the vnet kernel module, optionally with parameters." - -if __name__ == "__main__": - vn = VnMain(sys.argv) - vn.main() - diff --git a/vnet/src/vnet-module/00README b/vnet/src/vnet-module/00README deleted file mode 100644 index 707b965f085..00000000000 --- a/vnet/src/vnet-module/00README +++ /dev/null @@ -1,39 +0,0 @@ -Vnet module for network virtualization. -Mike Wray - -*) Compiling -The vnet module can be compiled for 2.4 or 2.6 series kernels. -The makefiles use the following variables, which -can be set in your env or on the make command line: - -LINUX_SERIES: linux release to compile for: 2.4, or 2.6 (default). -XEN_ROOT: root of the xen tree containing kernel source. -KERNEL_VERSION: kernel version, default got from XEN_ROOT. -KERNEL_SRC: path to kernel source, default build-linux- - under XEN_ROOT. - -*) For 2.4 kernel - -To compile from scratch: - -make clean -make LINUX_SERIES=2.4 - -This will build vnet_module.o in the current directory. -To install the module use - -make LINUX_SERIES=2.4 install - -*) For 2.6 kernel - -To compile from scratch: - -make clean -make - -This will build vnet_module.ko in the current directory. -To install the module use - -make install - - diff --git a/vnet/src/vnet-module/Makefile b/vnet/src/vnet-module/Makefile deleted file mode 100644 index 417ce8866ce..00000000000 --- a/vnet/src/vnet-module/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -# -# Copyright (C) 2004 Mike Wray -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free software Foundation, Inc., -# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -ifndef VNET_ROOT -export VNET_ROOT = $(shell cd .. && pwd) -include $(VNET_ROOT)/Make.env -endif - -#============================================================================ -ifeq ($(src),) - -include Makefile-$(LINUX_SERIES) - -#============================================================================ -else -#============================================================================ -# This section is for the 2.6 kbuild. - -#$(warning KBUILD_EXTMOD $(KBUILD_EXTMOD)) -#$(warning src $(src)) -#$(warning obj $(obj)) - -include $(src)/Makefile.vnet - -obj-m = vnet_module.o -vnet_module-objs = $(VNET_OBJ) -vnet_module-objs += $(VNET_LIB_OBJ) - -#---------------------------------------------------------------------------- -# The fancy stuff in the kernel build defeats 'vpath %.c' so we can't -# use that to get the lib files compiled. -# Setup explicit rules for them using the kbuild C compile rule. - -# File names in the lib dir. -remote_srcs = $(foreach file,$(VNET_LIB_SRC),$(LIBXUTIL_DIR)/$(file)) - -# Equivalent file names here. -local_srcs = $(foreach file,$(VNET_LIB_SRC),$(src)/$(file)) - -# Objects for the local names. -local_objs = $(local_srcs:.c=.o) - -# Make the local objects depend on compiling the remote sources. -$(local_objs): $(src)/%.o: $(LIBXUTIL_DIR)/%.c - $(call if_changed_rule,cc_o_c) -#---------------------------------------------------------------------------- - -vpath %.h $(LIBXUTIL_DIR) -EXTRA_CFLAGS += -I $(LIBXUTIL_DIR) -EXTRA_CFLAGS += -I $(src) - -endif -#============================================================================ - diff --git a/vnet/src/vnet-module/Makefile-2.4 b/vnet/src/vnet-module/Makefile-2.4 deleted file mode 100644 index 7ece1c51f53..00000000000 --- a/vnet/src/vnet-module/Makefile-2.4 +++ /dev/null @@ -1,98 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -# -# Copyright (C) 2004 Mike Wray -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free software Foundation, Inc., -# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -#============================================================================ -# Vnet module makefile for 2.4 series kernels. - -LINUX_SERIES =2.4 -include Makefile.ver - -KERNEL_MODULE := vnet_module.o - -CONFIG_MODVERSIONS := $(shell grep 'CONFIG_MODVERSIONS=y' $(KERNEL_SRC)/.config && echo 1 || echo 0) - -include Makefile.vnet - -VNET_OBJ += $(VNET_LIB_OBJ) - -#---------------------------------------------------------------------------- - -vpath %.h $(KERNEL_SRC)/include -INCLUDES+= -I $(KERNEL_SRC)/include - -vpath %.h $(LIBXUTIL_DIR) -vpath %.c $(LIBXUTIL_DIR) -INCLUDES += -I $(LIBXUTIL_DIR) - -INCLUDES+= -I . - -#---------------------------------------------------------------------------- - -CPPFLAGS += -D__KERNEL__ -CPPFLAGS += -DMODULE - -ifeq ($(CONFIG_MODVERSIONS), 1) -CPPFLAGS += -DMODVERSIONS -CPPFLAGS += -include $(KERNEL_SRC)/include/linux/modversions.h -endif - -CPPFLAGS += $(INCLUDES) - -CFLAGS += -Wall -CFLAGS += -Wstrict-prototypes -CFLAGS += -Wno-trigraphs -CFLAGS += -Wno-unused-function -CFLAGS += -Wno-unused-parameter - -CFLAGS += -g -CFLAGS += -O2 -CFLAGS += -fno-strict-aliasing -CFLAGS += -fno-common -#CFLAGS += -fomit-frame-pointer - -# Dependencies. Gcc generates them for us. -CFLAGS += -Wp,-MD,.$(@F).d -VNET_DEP = .*.d -#---------------------------------------------------------------------------- - -.PHONY: all -all: module - -.PHONY: module modules -module modules: $(KERNEL_MODULE) - -$(KERNEL_MODULE): $(VNET_OBJ) - $(LD) -r -o $@ $^ - -.PHONY: install install-module modules_install -install install-module modules_install: module - install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR) - install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR) - -TAGS: - etags *.c *.h - -.PHONY: clean -clean: - -@$(RM) *.a *.o *.ko *~ - -@$(RM) $(VNET_DEP) .*.cmd *.mod.? - -@$(RM) -r .tmp_versions - --include $(VNET_DEP) diff --git a/vnet/src/vnet-module/Makefile-2.6 b/vnet/src/vnet-module/Makefile-2.6 deleted file mode 100644 index 7ae0f64d459..00000000000 --- a/vnet/src/vnet-module/Makefile-2.6 +++ /dev/null @@ -1,60 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -# -# Copyright (C) 2004 Mike Wray -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free software Foundation, Inc., -# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -#============================================================================ -# Vnet module makefile for 2.6 series kernels. - -LINUX_SERIES =2.6 -include Makefile.ver - -export KERNEL_MINOR=$(shell echo $(LINUX_VERSION) |cut -d"-" -f1 |cut -d"." -f3) -$(warning KERNEL_MINOR $(KERNEL_MINOR)) - -KERNEL_MODULE ?= vnet_module.ko - -#---------------------------------------------------------------------------- -#export KBUILD_VERBOSE=1 - -.PHONY: all -all: module module_version - -.PHONY: module -module modules: - $(MAKE) -C $(KERNEL_SRC) M=`pwd` modules - -.PHONY: module_version -module_version: - $(warning Module version $(shell strings $(KERNEL_MODULE) | grep vermagic)) - -.PHONY: install install-module modules_install -install install-module modules_install: module - install -m 0755 -d $(DESTDIR)$(KERNEL_MODULE_DIR) - install -m 0554 $(KERNEL_MODULE) $(DESTDIR)$(KERNEL_MODULE_DIR) - -.PHONY: clean -clean: - -@$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean - -@$(RM) *.a *.o *.ko *~ .*.d .*.cmd *.mod.? - -@$(RM) -r .tmp_versions - -.PHONY: TAGS -TAGS: - etags *.c *.h - diff --git a/vnet/src/vnet-module/Makefile.ver b/vnet/src/vnet-module/Makefile.ver deleted file mode 100644 index 58386b864ea..00000000000 --- a/vnet/src/vnet-module/Makefile.ver +++ /dev/null @@ -1,51 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -# -# Copyright (C) 2004 Mike Wray -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free software Foundation, Inc., -# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -LINUX_SERIES?=2.6 - -LINUX_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/linux-$(LINUX_SERIES).* 2>/dev/null) | \ - sed -e 's!^.*linux-\(.\+\).hg!\1!' ) - -ifeq ($(LINUX_VERSION),) -$(error Kernel source for linux $(LINUX_SERIES) not found) -endif - -KERNEL_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/build-linux-$(LINUX_VERSION)* 2>/dev/null) | \ - grep -v -m 1 -e '-xenU' | \ - sed -e 's!^.*linux-\(.\+\)!\1!' ) - -KERNEL_SRC ?= $(XEN_ROOT)/build-linux-$(KERNEL_VERSION) - -ifeq ($(KERNEL_SRC),) -$(error Kernel source for kernel $(KERNEL_VERSION) not found) -endif - -# Get the full kernel release version from its makefile, as the source path -# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release -# 2.6.12.6-xen0. -KERNEL_RELEASE?=$(shell make -s -C $(KERNEL_SRC) kernelrelease) - -KERNEL_MODULE_DIR=/lib/modules/$(KERNEL_RELEASE)/kernel - -$(warning KERNEL_SRC $(KERNEL_SRC)) -$(warning LINUX_VERSION $(LINUX_VERSION)) -$(warning KERNEL_VERSION $(KERNEL_VERSION)) -$(warning KERNEL_RELEASE $(KERNEL_RELEASE)) -$(warning KERNEL_MODULE_DIR $(KERNEL_MODULE_DIR)) diff --git a/vnet/src/vnet-module/Makefile.vnet b/vnet/src/vnet-module/Makefile.vnet deleted file mode 100644 index da4b30299c4..00000000000 --- a/vnet/src/vnet-module/Makefile.vnet +++ /dev/null @@ -1,62 +0,0 @@ -# -*- mode: Makefile; -*- -#============================================================================ -# -# Copyright (C) 2004 Mike Wray -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free software Foundation, Inc., -# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA -#============================================================================ - -ifeq ($(src),) -SRC_DIR= -else -SRC_DIR=$(src)/ -endif - -VNET_SRC := -VNET_SRC += etherip.c -VNET_SRC += random.c -VNET_SRC += sa.c -VNET_SRC += esp.c -ifeq ($(KERNEL_MINOR),18) -VNET_SRC += sa_algorithm.c -endif -VNET_SRC += skb_context.c -VNET_SRC += skb_util.c -VNET_SRC += sxpr_util.c -VNET_SRC += timer_util.c -VNET_SRC += tunnel.c -VNET_SRC += varp.c -VNET_SRC += varp_socket.c -VNET_SRC += vif.c -VNET_SRC += vnet.c -VNET_SRC += vnet_dev.c -VNET_SRC += vnet_ioctl.c -VNET_SRC += vnet_eval.c -VNET_SRC += vnet_forward.c - -VNET_LIB_SRC += allocate.c -VNET_LIB_SRC += enum.c -VNET_LIB_SRC += hash_table.c -VNET_LIB_SRC += iostream.c -VNET_LIB_SRC += kernel_stream.c -VNET_LIB_SRC += mem_stream.c -VNET_LIB_SRC += sxpr.c -VNET_LIB_SRC += sxpr_parser.c -VNET_LIB_SRC += sys_net.c -VNET_LIB_SRC += sys_string.c - -VNET_OBJ := $(VNET_SRC:.c=.o) -VNET_LIB_OBJ := $(VNET_LIB_SRC:.c=.o) - diff --git a/vnet/src/vnet-module/esp.c b/vnet/src/vnet-module/esp.c deleted file mode 100644 index 8f7ebb0b26d..00000000000 --- a/vnet/src/vnet-module/esp.c +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static const int DEBUG_ICV = 0; - -#define MODULE_NAME "IPSEC" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -#if ((LINUX_VERSION_CODE != KERNEL_VERSION(2,6,18) ) || !defined(CONFIG_CRYPTO_HMAC)) -#warning No esp transform - - -int __init esp_module_init(void){ - return 0; -} - -void __exit esp_module_exit(void){ -} - -#else - -/* Outgoing packet: [ eth | ip | data ] - * After etherip: [ eth2 | ip2 | ethip | eth | ip | data ] - * After esp : [ eth2 | ip2 | esp | {ethip | eth | ip | data} | pad | icv ] - * ^ + - * The curly braces { ... } denote encryption. - * The esp header includes the fixed esp headers and the iv (variable size). - * The point marked ^ does not move. To the left is in the header, to the right - * is in the frag. Remember that all outgoing skbs (from domains) have 1 frag. - * Data after + is added by esp, using an extra frag. - * - * Incoming as above. - * After decrypt: [ eth2 | ip2 | esp | ethip | eth | ip | data | pad | icv ] - * Trim tail: [ eth2 | ip2 | esp | ethip | eth | ip | data ] - * Drop hdr: [ eth2 | ip2 | ethip | eth | ip | data ] - * ^ - * The point marked ^ does not move. Incoming skbs are linear (no frags). - * The tail is trimmed by adjusting skb->tail and len. - * The esp hdr is dropped by using memmove to move the headers and - * adjusting the skb pointers. - * - * todo: Now this code is in linux we can't assume 1 frag for outbound skbs, - * or (maybe) that memmove is safe on inbound. - */ - -/** Round n up to a multiple of block. - * If block is less than 2 does nothing. - * Otherwise assume block is a power of 2. - * - * @param n to round up - * @param block size to round to a multiple of - * @return rounded value - */ -static inline int roundupto(int n, int block){ - if(block <= 1) return n; - block--; - return (n + block) & ~block; -} - -/** Check if n is a multiple of block. - * If block is less than 2 returns 1. - * Otherwise assumes block is a power of 2. - * - * @param n to check - * @param block block size - * @return 1 if a multiple, 0 otherwise - */ -static inline int multipleof(int n, int block){ - if(block <= 1) return 1; - block--; - return !(n & block); -} - -/** Convert from bits to bytes. - * - * @param n number of bits - * @return number of bytes - */ -static inline int bits_to_bytes(int n){ - return n / 8; -} - - -/** Insert esp padding at the end of an skb. - * Inserts padding bytes, number of padding bytes, protocol number. - * - * @param skb skb - * @param offset offset from skb end to where padding should end - * @param extra_n total amount of padding - * @param protocol protocol number (from original ip hdr) - * @return 0 on success, error code otherwise - */ -static int esp_sa_pad(struct sk_buff *skb, int offset, int extra_n, - unsigned char protocol){ - int err; - char *data; - int pad_n = extra_n - ESP_PAD_N; - int i; - char buf[extra_n]; - - data = buf; - for(i = 1; i <= pad_n; i++){ - *data++ = i; - } - *data++ = pad_n; - *data++ = protocol; - err = skb_put_bits(skb, skb->len - offset - extra_n, buf, extra_n); - return err; -} - -/** Encrypt skb. Skips esp header and iv. - * Assumes skb->data points at esp header. - * - * @param esp esp state - * @parm esph esp header - * @param skb packet - * @param head_n size of esp header and iv - * @param iv_n size of iv - * @param text_n size of ciphertext - * @return 0 on success, error code otherwise - */ -static int esp_sa_encrypt(ESPState *esp, ESPHdr *esph, struct sk_buff *skb, - int head_n, int iv_n, int text_n){ - int err = 0; - int sg_n = skb_shinfo(skb)->nr_frags + 1; - struct scatterlist sg[sg_n]; - - err = skb_scatterlist(skb, sg, &sg_n, head_n, text_n); - if(err) goto exit; - if(iv_n){ - crypto_cipher_set_iv(esp->cipher.tfm, esp->cipher.iv, iv_n); - } - crypto_cipher_encrypt(esp->cipher.tfm, sg, sg, text_n); - if(iv_n){ - memcpy(esph->data, esp->cipher.iv, iv_n); - crypto_cipher_get_iv(esp->cipher.tfm, esp->cipher.iv, iv_n); - } - exit: - return err; -} - -/** Decrypt skb. Skips esp header and iv. - * Assumes skb->data points at esp header. - * - * @param esp esp state - * @parm esph esp header - * @param skb packet - * @param head_n size of esp header and iv - * @param iv_n size of iv - * @param text_n size of ciphertext - * @return 0 on success, error code otherwise - */ -static int esp_sa_decrypt(ESPState *esp, ESPHdr *esph, struct sk_buff *skb, - int head_n, int iv_n, int text_n){ - int err = 0; - int sg_n = skb_shinfo(skb)->nr_frags + 1; - struct scatterlist sg[sg_n]; - - err = skb_scatterlist(skb, sg, &sg_n, head_n, text_n); - if(err) goto exit; - if(iv_n){ - crypto_cipher_set_iv(esp->cipher.tfm, esph->data, iv_n); - } - crypto_cipher_decrypt(esp->cipher.tfm, sg, sg, text_n); - exit: - return err; -} - -/** Compute icv. Includes esp header, iv and ciphertext. - * Assumes skb->data points at esp header. - * - * @param esp esp state - * @param skb packet - * @param digest_n number of bytes to digest - * @param icv_n size of icv - * @return 0 on success, error code otherwise - */ -static int esp_sa_digest(ESPState *esp, struct sk_buff *skb, int digest_n, int icv_n){ - int err = 0; - u8 icv[icv_n]; - - if(DEBUG_ICV){ - dprintf("> skb digest_n=%d icv_n=%d\n", digest_n, icv_n); - skb_print_bits("esp", skb, 0, digest_n); - } - memset(icv, 0, icv_n); - esp->digest.icv(esp, skb, 0, digest_n, icv); - skb_put_bits(skb, digest_n, icv, icv_n); - return err; -} - -/** Check the icv and trim it from the skb tail. - * - * @param sa sa state - * @param esp esp state - * @param esph esp header - * @param skb packet - * @return 0 on success, error code otherwise - */ -static int esp_check_icv(SAState *sa, ESPState *esp, ESPHdr *esph, struct sk_buff *skb){ - int err = 0; - int icv_n = esp->digest.icv_n; - int digest_n = skb->len - icv_n; - u8 icv_skb[icv_n]; - u8 icv_new[icv_n]; - - dprintf(">\n"); - if(DEBUG_ICV){ - dprintf("> skb len=%d digest_n=%d icv_n=%d\n", - skb->len, digest_n, icv_n); - skb_print_bits("esp", skb, 0, skb->len); - } - if(skb_copy_bits(skb, digest_n, icv_skb, icv_n)){ - wprintf("> Error getting icv from skb\n"); - goto exit; - } - esp->digest.icv(esp, skb, 0, digest_n, icv_new); - if(DEBUG_ICV){ - dprintf("> len=%d icv_n=%d", digest_n, icv_n); - printk("\nskb="); buf_print(icv_skb, icv_n); - printk("new="); buf_print(icv_new, icv_n); - } - if(unlikely(memcmp(icv_new, icv_skb, icv_n))){ - wprintf("> ICV check failed!\n"); - err = -EINVAL; - sa->counts.integrity_failures++; - goto exit; - } - skb_trim_tail(skb, icv_n); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Send a packet via an ESP SA. - * - * @param sa SA state - * @param skb packet to send - * @param tunnel underlying tunnel - * @return 0 on success, negative error code otherwise - */ -static int esp_sa_send(SAState *sa, struct sk_buff *skb, Tunnel *tunnel){ - int err = 0; - int ip_n; // Size of ip header. - int plaintext_n; // Size of plaintext. - int ciphertext_n; // Size of ciphertext (including padding). - int extra_n; // Extra bytes needed for ciphertext. - int icv_n = 0; // Size of integrity check value (icv). - int iv_n = 0; // Size of initialization vector (iv). - int head_n; // Size of esp header and iv. - int tail_n; // Size of esp trailer: padding and icv. - ESPState *esp; - ESPHdr *esph; - - dprintf(">\n"); - esp = sa->data; - ip_n = (skb->nh.iph->ihl << 2); - // Assuming skb->data points at ethernet header, exclude ethernet - // header and IP header. - plaintext_n = skb->len - ETH_HLEN - ip_n; - // Add size of padding fields. - ciphertext_n = roundupto(plaintext_n + ESP_PAD_N, esp->cipher.block_n); - if(esp->cipher.pad_n > 0){ - ciphertext_n = roundupto(ciphertext_n, esp->cipher.pad_n); - } - extra_n = ciphertext_n - plaintext_n; - iv_n = esp->cipher.iv_n; - icv_n = esp->digest.icv_n; - dprintf("> len=%d plaintext=%d ciphertext=%d extra=%d\n", - skb->len, plaintext_n, ciphertext_n, extra_n); - dprintf("> iv=%d icv=%d\n", iv_n, icv_n); - skb_print_bits("iv", skb, 0, skb->len); - - // Add headroom for esp header and iv, tailroom for the ciphertext - // and icv. - head_n = ESP_HDR_N + iv_n; - tail_n = extra_n + icv_n; - err = skb_make_room(&skb, skb, head_n, tail_n); - if(err) goto exit; - dprintf("> skb=%p\n", skb); - // Move the headers up to make space for the esp header. We can - // use memmove() since all this data fits in the skb head. - // todo: Can't assume this anymore? - dprintf("> header push...\n"); - __skb_push(skb, head_n); - if(0 && skb->mac.raw){ - dprintf("> skb->mac=%p\n", skb->mac.raw); - dprintf("> ETH header pull...\n"); - memmove(skb->data, skb->mac.raw, ETH_HLEN); - skb->mac.raw = skb->data; - skb_pull_vn(skb, ETH_HLEN); - } - dprintf("> IP header pull...\n"); - memmove(skb->data, skb->nh.raw, ip_n); - skb->nh.raw = skb->data; - skb_pull_vn(skb, ip_n); - esph = (void*)skb->data; - // Add spi and sequence number. - esph->spi = sa->ident.spi; - esph->seq = htonl(++sa->replay.send_seq); - // Insert the padding bytes: extra bytes less the pad fields - // themselves. - dprintf("> esp_sa_pad ...\n"); - esp_sa_pad(skb, icv_n, extra_n, skb->nh.iph->protocol); - if(sa->security & SA_CONF){ - dprintf("> esp_sa_encrypt...\n"); - err = esp_sa_encrypt(esp, esph, skb, head_n, iv_n, ciphertext_n); - if(err) goto exit; - } - if(icv_n){ - dprintf("> esp_sa_digest...\n"); - err = esp_sa_digest(esp, skb, head_n + ciphertext_n, icv_n); - if(err) goto exit; - } - dprintf("> IP header push...\n"); - __skb_push(skb, ip_n); - if(0 && skb->mac.raw){ - dprintf("> ETH header push...\n"); - __skb_push(skb, ETH_HLEN); - } - // Fix ip header. Adjust length field, set protocol, zero - // checksum. - { - // Total packet length (bytes). - int tot_len = ntohs(skb->nh.iph->tot_len); - tot_len += head_n; - tot_len += tail_n; - skb->nh.iph->protocol = IPPROTO_ESP; - skb->nh.iph->tot_len = htons(tot_len); - skb->nh.iph->check = 0; - } - err = Tunnel_send(tunnel, skb); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Release an skb context. - * Drops the refcount on the SA. - * - * @param context to free - */ -static void esp_context_free_fn(SkbContext *context){ - SAState *sa; - if(!context) return; - sa = context->data; - if(!sa) return; - context->data = NULL; - SAState_decref(sa); -} - -/** Receive a packet via an ESP SA. - * Does ESP receive processing (check icv, decrypt), strips - * ESP header and re-receives. - * - * If return 1 the packet has been freed. - * If return <= 0 the caller must free. - * - * @param sa SA - * @param skb packet - * @return >= 0 on success, negative protocol otherwise - */ -static int esp_sa_recv(SAState *sa, struct sk_buff *skb){ - int err = -EINVAL; - int mine = 0; - int vnet = 0; //todo: fixme - need to record skb vnet somewhere - ESPState *esp; - ESPHdr *esph; - ESPPadding *pad; - int block_n; // Cipher blocksize. - int icv_n; // Size of integrity check value (icv). - int iv_n; // Size of initialization vector (iv). - int text_n; // Size of text (ciphertext or plaintext). - int head_n; // Size of esp header and iv. - - dprintf("> skb=%p\n", skb); - // Assumes skb->data points at esp hdr. - esph = (void*)skb->data; - esp = sa->data; - block_n = crypto_tfm_alg_blocksize(esp->cipher.tfm); - icv_n = esp->digest.icv_n; - iv_n = esp->cipher.iv_n; - head_n = ESP_HDR_N + iv_n; - text_n = skb->len - head_n - icv_n; - if(text_n < ESP_PAD_N || !multipleof(text_n, block_n)){ - wprintf("> Invalid size: text_n=%d tfm:block_n=%d esp:block_n=%d\n", - text_n, block_n, esp->cipher.block_n); - goto exit; - } - if(icv_n){ - err = esp_check_icv(sa, esp, esph, skb); - if(err) goto exit; - } - mine = 1; - if(sa->security & SA_CONF){ - err = esp_sa_decrypt(esp, esph, skb, head_n, iv_n, text_n); - if(err) goto exit; - } - // Strip esp header by moving the other headers down. - //todo Maybe not safe to do this anymore. - memmove(skb->mac.raw + head_n, skb->mac.raw, (skb->data - skb->mac.raw)); - skb->mac.raw += head_n; - skb->nh.raw += head_n; - // Move skb->data back to ethernet header. - // Do in 2 moves to ensure offsets are +ve, - // since args to skb_pull/skb_push are unsigned. - skb_pull_vn(skb, head_n); - __skb_push(skb, skb->data - skb->mac.raw); - // After this esph is invalid. - esph = NULL; - // Trim padding, restore protocol in IP header. - pad = skb_trim_tail(skb, ESP_PAD_N); - text_n -= ESP_PAD_N; - if((pad->pad_n > 255) | (pad->pad_n > text_n)){ - wprintf("> Invalid padding: pad_n=%d text_n=%d\n", pad->pad_n, text_n); - goto exit; - } - skb_trim_tail(skb, pad->pad_n); - skb->nh.iph->protocol = pad->protocol; - err = skb_push_context(skb, vnet, sa->ident.addr, IPPROTO_ESP, - sa, esp_context_free_fn); - if(err) goto exit; - // Increase sa refcount now the skb context refers to it. - // Refcount is decreased by esp_context_free_fn. - SAState_incref(sa); - // Deliver skb to be received by network code. - // Not safe to refer to the skb after this. - // todo: return -skb->nh.iph->protocol instead? - netif_rx(skb); - exit: - if(mine){ - if(err < 0){ - kfree_skb(skb); - } - err = 1; - } - dprintf("< skb=%p err=%d\n", skb, err); - return err; -} - -/** Estimate the packet size for some data using ESP processing. - * - * @param sa ESP SA - * @param data_n data size - * @return size after ESP processing - */ -static u32 esp_sa_size(SAState *sa, int data_n){ - // Even in transport mode have to round up to blocksize. - // Have to add some padding for alignment even if pad_n is zero. - ESPState *esp = sa->data; - - data_n = roundupto(data_n + ESP_PAD_N, esp->cipher.block_n); - if(esp->cipher.pad_n > 0){ - data_n = roundupto(data_n, esp->cipher.pad_n); - } - data_n += esp->digest.icv_n; - //data_n += esp->cipher.iv_n; - data_n += ESP_HDR_N; - return data_n; -} - -/** Compute an icv using HMAC digest. - * - * @param esp ESP state - * @param skb packet to digest - * @param offset offset to start at - * @param len number of bytes to digest - * @param icv return parameter for ICV - * @return 0 on success, negative error code otherwise - */ -static inline void esp_hmac_digest(ESPState *esp, struct sk_buff *skb, - int offset, int len, u8 *icv){ - int err = 0; - struct crypto_tfm *digest = esp->digest.tfm; - char *icv_tmp = esp->digest.icv_tmp; - int sg_n = skb_shinfo(skb)->nr_frags + 1; - struct scatterlist sg[sg_n]; - - dprintf("> offset=%d len=%d\n", offset, len); - memset(icv, 0, esp->digest.icv_n); - if(DEBUG_ICV){ - dprintf("> key len=%d\n", esp->digest.key_n); - printk("\nkey="); - buf_print(esp->digest.key,esp->digest.key_n); - } - crypto_hmac_init(digest, esp->digest.key, &esp->digest.key_n); - err = skb_scatterlist(skb, sg, &sg_n, offset, len); - crypto_hmac_update(digest, sg, sg_n); - crypto_hmac_final(digest, esp->digest.key, &esp->digest.key_n, icv_tmp); - if(DEBUG_ICV){ - dprintf("> digest len=%d ", esp->digest.icv_n); - printk("\nval="); - buf_print(icv_tmp, esp->digest.icv_n); - } - memcpy(icv, icv_tmp, esp->digest.icv_n); - dprintf("<\n"); -} - -/** Finish up an esp state. - * Releases the digest, cipher, iv and frees the state. - * - * @parma esp state - */ -static void esp_fini(ESPState *esp){ - if(!esp) return; - if(esp->digest.tfm){ - crypto_free_tfm(esp->digest.tfm); - esp->digest.tfm = NULL; - } - if(esp->digest.icv_tmp){ - kfree(esp->digest.icv_tmp); - esp->digest.icv_tmp = NULL; - } - if(esp->cipher.tfm){ - crypto_free_tfm(esp->cipher.tfm); - esp->cipher.tfm = NULL; - } - if(esp->cipher.iv){ - kfree(esp->cipher.iv); - esp->cipher.iv = NULL; - } - kfree(esp); -} - -/** Release an ESP SA. - * - * @param sa ESO SA - */ -static void esp_sa_fini(SAState *sa){ - ESPState *esp; - if(!sa) return; - esp = sa->data; - if(!esp) return; - esp_fini(esp); - sa->data = NULL; -} - -/** Initialize the cipher for an ESP SA. - * - * @param sa ESP SA - * @param esp ESP state - * @return 0 on success, negative error code otherwise - */ -static int esp_cipher_init(SAState *sa, ESPState *esp){ - int err = 0; - SAAlgorithm *algo = NULL; - int cipher_mode = CRYPTO_TFM_MODE_CBC; - - dprintf("> sa=%p esp=%p\n", sa, esp); - dprintf("> cipher=%s\n", sa->cipher.name); - algo = sa_cipher_by_name(sa->cipher.name); - if(!algo){ - wprintf("> Cipher unavailable: %s\n", sa->cipher.name); - err = -EINVAL; - goto exit; - } - esp->cipher.key_n = roundupto(sa->cipher.bits, 8); - // If cipher is null must use ECB because CBC algo does not support blocksize 1. - if(strcmp(sa->cipher.name, "cipher_null")){ - cipher_mode = CRYPTO_TFM_MODE_ECB; - } - esp->cipher.tfm = crypto_alloc_tfm(sa->cipher.name, cipher_mode); - if(!esp->cipher.tfm){ - err = -ENOMEM; - goto exit; - } - esp->cipher.block_n = roundupto(crypto_tfm_alg_blocksize(esp->cipher.tfm), 4); - esp->cipher.iv_n = crypto_tfm_alg_ivsize(esp->cipher.tfm); - esp->cipher.pad_n = 0; - if(esp->cipher.iv_n){ - esp->cipher.iv = kmalloc(esp->cipher.iv_n, GFP_KERNEL); - get_random_bytes(esp->cipher.iv, esp->cipher.iv_n); - } - crypto_cipher_setkey(esp->cipher.tfm, esp->cipher.key, esp->cipher.key_n); - err = 0; - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Initialize the digest for an ESP SA. - * - * @param sa ESP SA - * @param esp ESP state - * @return 0 on success, negative error code otherwise - */ -static int esp_digest_init(SAState *sa, ESPState *esp){ - int err = 0; - SAAlgorithm *algo = NULL; - - dprintf(">\n"); - esp->digest.key = sa->digest.key; - esp->digest.key_n = bits_to_bytes(roundupto(sa->digest.bits, 8)); - esp->digest.tfm = crypto_alloc_tfm(sa->digest.name, 0); - if(!esp->digest.tfm){ - err = -ENOMEM; - goto exit; - } - algo = sa_digest_by_name(sa->digest.name); - if(!algo){ - wprintf("> Digest unavailable: %s\n", sa->digest.name); - err = -EINVAL; - goto exit; - } - esp->digest.icv = esp_hmac_digest; - esp->digest.icv_full_n = bits_to_bytes(algo->info.digest.icv_fullbits); - esp->digest.icv_n = bits_to_bytes(algo->info.digest.icv_truncbits); - - if(esp->digest.icv_full_n != crypto_tfm_alg_digestsize(esp->digest.tfm)){ - err = -EINVAL; - wprintf("> digest %s, size %u != %hu\n", - sa->digest.name, - crypto_tfm_alg_digestsize(esp->digest.tfm), - esp->digest.icv_full_n); - goto exit; - } - - esp->digest.icv_tmp = kmalloc(esp->digest.icv_full_n, GFP_KERNEL); - if(!esp->digest.icv_tmp){ - err = -ENOMEM; - goto exit; - } - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Initialize an ESP SA. - * - * @param sa ESP SA - * @param args arguments - * @return 0 on success, negative error code otherwise - */ -static int esp_sa_init(SAState *sa, void *args){ - int err = 0; - ESPState *esp = NULL; - - dprintf("> sa=%p\n", sa); - esp = kmalloc(sizeof(*esp), GFP_KERNEL); - if(!esp){ - err = -ENOMEM; - goto exit; - } - *esp = (ESPState){}; - err = esp_cipher_init(sa, esp); - if(err) goto exit; - err = esp_digest_init(sa, esp); - if(err) goto exit; - sa->data = esp; - exit: - if(err){ - if(esp) esp_fini(esp); - } - dprintf("< err=%d\n", err); - return err; -} - -/** SA type for ESP. - */ -static SAType esp_sa_type = { - .name = "ESP", - .protocol = IPPROTO_ESP, - .init = esp_sa_init, - .fini = esp_sa_fini, - .size = esp_sa_size, - .recv = esp_sa_recv, - .send = esp_sa_send -}; - -/** Get the ESP header from a packet. - * - * @param skb packet - * @param esph return parameter for header - * @return 0 on success, negative error code otherwise - */ -static int esp_skb_header(struct sk_buff *skb, ESPHdr **esph){ - int err = 0; - if(skb->len < ESP_HDR_N){ - err = -EINVAL; - goto exit; - } - *esph = (ESPHdr*)skb->data; - exit: - return err; -} - -/** Handle an incoming skb with ESP protocol. - * - * Lookup spi, if state found hand to the state. - * If no state, check spi, if ok, create state and pass to it. - * If spi not ok, drop. - * - * Return value convention for protocols: - * >= 0 Protocol took the packet - * < 0 A -ve protocol id the packet should be re-received as. - * - * So always return >=0 if we took the packet, even if we dropped it. - * - * @param skb packet - * @return 0 on sucess, negative protocol number otherwise - */ -static int esp_protocol_recv(struct sk_buff *skb){ - int err = 0; - const int eth_n = ETH_HLEN; - int ip_n; - ESPHdr *esph = NULL; - SAState *sa = NULL; - u32 addr; - - dprintf(">\n"); -#ifdef DEBUG - dprintf("> recv skb=\n"); - skb_print_bits("", skb, 0, skb->len); -#endif - ip_n = (skb->nh.iph->ihl << 2); - if(skb->data == skb->mac.raw){ - // skb->data points at ethernet header. - if (!pskb_may_pull(skb, eth_n + ip_n)){ - wprintf("> Malformed skb\n"); - err = -EINVAL; - goto exit; - } - skb_pull_vn(skb, eth_n + ip_n); - } - addr = skb->nh.iph->daddr; - err = esp_skb_header(skb, &esph); - if(err) goto exit; - dprintf("> spi=%08x protocol=%d addr=" IPFMT "\n", - esph->spi, IPPROTO_ESP, NIPQUAD(addr)); - sa = sa_table_lookup_spi(esph->spi, IPPROTO_ESP, addr); - if(!sa){ - err = vnet_sa_create(esph->spi, IPPROTO_ESP, addr, &sa); - if(err) goto exit; - } - //todo: Return a -ve protocol instead? See esp_sa_recv. - err = SAState_recv(sa, skb); - exit: - if(sa) SAState_decref(sa); - if(err <= 0){ - kfree_skb(skb); - err = 0; - } - dprintf("< err=%d\n", err); - return err; -} - -/** Handle an ICMP error related to ESP. - * - * @param skb ICMP error packet - * @param info - */ -static void esp_protocol_icmp_err(struct sk_buff *skb, u32 info){ - struct iphdr *iph = (struct iphdr*)skb->data; - ESPHdr *esph; - SAState *sa; - - dprintf("> ICMP error type=%d code=%d\n", - skb->h.icmph->type, skb->h.icmph->code); - if(skb->h.icmph->type != ICMP_DEST_UNREACH || - skb->h.icmph->code != ICMP_FRAG_NEEDED){ - return; - } - - //todo: need to check skb has enough len to do this. - esph = (ESPHdr*)(skb->data + (iph->ihl << 2)); - sa = sa_table_lookup_spi(esph->spi, IPPROTO_ESP, iph->daddr); - if(!sa) return; - wprintf("> ICMP unreachable on SA ESP spi=%08x addr=" IPFMT "\n", - ntohl(esph->spi), NIPQUAD(iph->daddr)); - SAState_decref(sa); -} - -//============================================================================ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -// Code for 2.6 kernel. - -/** Protocol handler for ESP. - */ -static struct net_protocol esp_protocol = { - .handler = esp_protocol_recv, - .err_handler = esp_protocol_icmp_err -}; - -static int esp_protocol_add(void){ - return inet_add_protocol(&esp_protocol, IPPROTO_ESP); -} - -static int esp_protocol_del(void){ - return inet_del_protocol(&esp_protocol, IPPROTO_ESP); -} - -//============================================================================ -#else -//============================================================================ -// Code for 2.4 kernel. - -/** Protocol handler for ESP. - */ -static struct inet_protocol esp_protocol = { - .name = "ESP", - .protocol = IPPROTO_ESP, - .handler = esp_protocol_recv, - .err_handler = esp_protocol_icmp_err -}; - -static int esp_protocol_add(void){ - inet_add_protocol(&esp_protocol); - return 0; -} - -static int esp_protocol_del(void){ - return inet_del_protocol(&esp_protocol); -} - -#endif -//============================================================================ - - -/** Initialize the ESP module. - * Registers the ESP protocol and SA type. - * - * @return 0 on success, negative error code otherwise - */ -int __init esp_module_init(void){ - int err = 0; - dprintf(">\n"); - err = SAType_add(&esp_sa_type); - if(err < 0){ - eprintf("> Error adding esp sa type\n"); - goto exit; - } - esp_protocol_add(); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Finalize the ESP module. - * Deregisters the ESP protocol and SA type. - */ -void __exit esp_module_exit(void){ - if(esp_protocol_del() < 0){ - eprintf("> Error removing esp protocol\n"); - } - if(SAType_del(&esp_sa_type) < 0){ - eprintf("> Error removing esp sa type\n"); - } -} - -#endif // CONFIG_CRYPTO_HMAC diff --git a/vnet/src/vnet-module/esp.h b/vnet/src/vnet-module/esp.h deleted file mode 100644 index f9eeb6a3fe9..00000000000 --- a/vnet/src/vnet-module/esp.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_ESP_H__ -#define __VNET_ESP_H__ - -#ifdef __KERNEL__ -#include -#include -#include - -#else - -#include "sys_kernel.h" - -struct crypto_tfm; - -#endif - -/** Header used by IPSEC ESP (Encapsulated Security Payload). */ -typedef struct ESPHdr { - /** The spi (security parameters index). */ - u32 spi; - /** Sequence number. */ - u32 seq; - /* Variable length data (depends on crypto suite). - Mind the 64 bit alignment! */ - u8 data[0]; -} ESPHdr; - -/** Padding trailer used by IPSEC ESP. - * Follows the padding itself with the padding length and the - * protocol being encapsulated. - */ -typedef struct ESPPadding { - u8 pad_n; - u8 protocol; -} ESPPadding; - -/** Size of the esp header (spi and seq). */ -static const int ESP_HDR_N = sizeof(ESPHdr); - -/** Size of the esp pad and next protocol field. */ -static const int ESP_PAD_N = sizeof(ESPPadding); - -enum { - SASTATE_VOID, - SASTATE_ACQUIRE, - SASTATE_VALID, - SASTATE_ERROR, - SASTATE_EXPIRED, - SASTATE_DEAD, -}; - -struct ESPState; - -/** A cipher instance. */ -typedef struct ESPCipher { - /** Cipher key. */ - u8 *key; - /** Key size (bytes). */ - int key_n; - /** Initialization vector (IV). */ - u8 *iv; - /** IV size (bytes). */ - int iv_n; - /** Block size for padding (bytes). */ - int pad_n; - /** Cipher block size (bytes). */ - int block_n; - /** Cipher crypto transform. */ - struct crypto_tfm *tfm; -} ESPCipher; - -/** A digest instance. */ -typedef struct ESPDigest { - /** Digest key. */ - u8 *key; - /** Key size (bytes) */ - int key_n; - /** ICV size used (bytes). */ - u8 icv_n; - /** Full ICV size when computed (bytes). */ - u8 icv_full_n; - /** Working storage for computing ICV. */ - u8 *icv_tmp; - /** Function used to compute ICV (e.g. HMAC). */ - void (*icv)(struct ESPState *esp, - struct sk_buff *skb, - int offset, - int len, - u8 *icv); - /** Digest crypto transform (e.g. SHA). */ - struct crypto_tfm *tfm; -} ESPDigest; - -typedef struct ESPState { - struct ESPCipher cipher; - struct ESPDigest digest; -} ESPState; - -extern int esp_module_init(void); -extern void esp_module_exit(void); - -#endif /* !__VNET_ESP_H__ */ diff --git a/vnet/src/vnet-module/etherip.c b/vnet/src/vnet-module/etherip.c deleted file mode 100644 index 7b5865e525c..00000000000 --- a/vnet/src/vnet-module/etherip.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#else - -#include -#include - -#include "sys_kernel.h" -#include "spinlock.h" -#include "skbuff.h" -#include -#include - -#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file Etherip implementation. - * The etherip protocol is used to transport Ethernet frames in IP packets. - */ - -/** Flag controlling whether to use etherip-in-udp encapsulation. - * If false we send etherip protocol in IP packets. - * If true we send etherip protocol in UDP packets with a vnet header. - */ -int etherip_in_udp = 1; - -/** Get the vnet label from an etherip header. - * - * @param hdr header - * @@param vnet (in net order) - */ -void etheriphdr_get_vnet(struct etheriphdr *hdr, VnetId *vnet){ -#ifdef CONFIG_ETHERIP_EXT - *vnet = *(VnetId*)hdr->vnet; -#else - *vnet = (VnetId){}; - vnet->u.vnet16[VNET_SIZE16 - 1] = (unsigned short)hdr->reserved; - -#endif -} - -/** Set the vnet label in an etherip header. - * Also sets the etherip version. - * - * @param hdr header - * @param vnet vnet label (in net order) - */ -void etheriphdr_set_vnet(struct etheriphdr *hdr, VnetId *vnet){ -#ifdef CONFIG_ETHERIP_EXT - hdr->version = ETHERIP_VERSION; - *(VnetId*)hdr->vnet = *vnet; -#else - hdr->version = ETHERIP_VERSION; - hdr->reserved = (vnet->u.vnet16[VNET_SIZE16 - 1] & 0x0fff); -#endif -} - -/** Open an etherip tunnel. - * - * @param tunnel to open - * @return 0 on success, error code otherwise - */ -static int etherip_tunnel_open(Tunnel *tunnel){ - return 0; -} - -/** Close an etherip tunnel. - * - * @param tunnel to close - */ -static void etherip_tunnel_close(Tunnel *tunnel){ -} - - -static inline int skb_make_headroom(struct sk_buff **pskb, struct sk_buff *skb, int head_n){ - int err = 0; - dprintf("> skb=%p headroom=%d head_n=%d\n", skb, skb_headroom(skb), head_n); - if(head_n > skb_headroom(skb) || skb_cloned(skb) || skb_shared(skb)){ - // Expand header the way GRE does. - struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16); - if(!new_skb){ - err = -ENOMEM; - goto exit; - } - kfree_skb(skb); - *pskb = new_skb; - } else { - *pskb = skb; - } - exit: - return err; -} - -/** Send a packet via an etherip tunnel. - * Adds etherip header and new ip header around ethernet frame. - * - * @param tunnel tunnel - * @param skb packet - * @return 0 on success, error code otherwise - */ -static int etherip_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){ - int err = 0; - const int ip_n = sizeof(struct iphdr); - const int etherip_n = sizeof(struct etheriphdr); - const int udp_n = sizeof(struct udphdr); - const int vnet_n = sizeof(struct VnetMsgHdr); - int head_n = etherip_n + ip_n /* + ETH_HLEN */; - VnetId *vnet = &tunnel->key.vnet; - struct etheriphdr *etheriph; - u32 saddr = 0; - - if(etherip_in_udp){ - head_n += vnet_n + udp_n; - } - err = skb_make_headroom(&skb, skb, head_n); - if(err) goto exit; - - // Null the pointer as we are pushing a new IP header. - skb->mac.raw = NULL; - - // Setup the etherip header. - etheriph = (void*)skb_push(skb, etherip_n); - etheriphdr_set_vnet(etheriph, vnet); - - if(etherip_in_udp){ - // Vnet header. - struct VnetMsgHdr *vhdr = (void*)skb_push(skb, vnet_n); - vhdr->id = htons(VUDP_ID); - vhdr->opcode = 0; - - // Setup the UDP header. - skb->h.raw = skb_push(skb, udp_n); - skb->h.uh->source = varp_port; // Source port. - skb->h.uh->dest = varp_port; // Destination port. - skb->h.uh->len = htons(skb->len); // Total packet length (bytes). - skb->h.uh->check = 0; - } - - // Setup the IP header. - skb->nh.raw = skb_push(skb, ip_n); - skb->nh.iph->version = 4; // Standard version. - skb->nh.iph->ihl = ip_n / 4; // IP header length (32-bit words). - skb->nh.iph->tos = 0; // No special type-of-service. - skb->nh.iph->tot_len = htons(skb->len); // Total packet length (bytes). - skb->nh.iph->id = 0; // No flow id (since no frags). - if(etherip_in_udp){ - skb->nh.iph->protocol = IPPROTO_UDP; // IP protocol number. - skb->nh.iph->frag_off = 0; - } else { - skb->nh.iph->protocol = IPPROTO_ETHERIP;// IP protocol number. - skb->nh.iph->frag_off = htons(IP_DF); // Don't fragment - can't handle frags. - } - skb->nh.iph->ttl = 64; // Linux default time-to-live. - skb->nh.iph->saddr = saddr; // Source address. - skb->nh.iph->daddr = tunnel->key.addr.u.ip4.s_addr; // Destination address. - skb->nh.iph->check = 0; // Zero the checksum. - - // Ethernet header will be filled-in by device. - err = Tunnel_send(tunnel->base, skb); - skb = NULL; - exit: - if(err && skb){ - wprintf("< err=%d\n", err); - kfree_skb(skb); - } - return err; -} - -/** Tunnel type for etherip. - */ -static TunnelType _etherip_tunnel_type = { - .name = "ETHERIP", - .open = etherip_tunnel_open, - .close = etherip_tunnel_close, - .send = etherip_tunnel_send -}; - -TunnelType *etherip_tunnel_type = &_etherip_tunnel_type; - -int etherip_tunnel_create(VnetId *vnet, VarpAddr *addr, Tunnel *base, Tunnel **tunnel){ - return Tunnel_create(etherip_tunnel_type, vnet, addr, base, tunnel); -} - -#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) -/** We need our own copy of this as it is no longer exported from the bridge module. - */ -static inline void _nf_bridge_save_header(struct sk_buff *skb){ - int header_size = 16; - - // Were using this modified to use h_proto instead of skb->protocol. - if(skb->protocol == htons(ETH_P_8021Q)){ - header_size = 18; - } - memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); -} -#endif - -/** Do etherip receive processing. - * Strips the etherip header to extract the ethernet frame, sets - * the vnet from the header and re-receives the frame. - * - * Return code 1 means we now own the packet - the caller must not free it. - * Return code < 0 means an error - caller still owns the packet. - * - * @param skb packet - * @return 1 on success, error code otherwise - */ -int etherip_protocol_recv(struct sk_buff *skb){ - int err = 0; - const int etherip_n = sizeof(struct etheriphdr); - struct etheriphdr *etheriph; - Vnet *vinfo = NULL; - VnetId vnet = {}; - u32 saddr, daddr; - char vnetbuf[VNET_ID_BUF]; - struct ethhdr *eth; - struct sk_buff *newskb; - - dprintf(">\n"); - saddr = skb->nh.iph->saddr; - daddr = skb->nh.iph->daddr; - if(MULTICAST(daddr) && (daddr != varp_mcast_addr)){ - // Ignore multicast packets not addressed to us. - wprintf("> Ignoring mcast skb: src=%u.%u.%u.%u dst=%u.%u.%u.%u" - " varp_mcast_addr=%u.%u.%u.%u\n", - NIPQUAD(saddr), NIPQUAD(daddr), NIPQUAD(varp_mcast_addr)); - goto exit; - } - if(skb->data == skb->mac.raw){ - // skb->data points at ethernet header. - //FIXME: Does this ever happen? - //dprintf("> len=%d\n", skb->len); - int ip_n = (skb->nh.iph->ihl << 2); - int pull_n = ETH_HLEN + ip_n; - if (!pskb_may_pull(skb, pull_n)){ - wprintf("> Malformed skb (eth+ip) src=%u.%u.%u.%u\n", - NIPQUAD(saddr)); - err = -EINVAL; - goto exit; - } - skb_pull_vn(skb, pull_n); - } - // Assume skb->data points at etherip header. - etheriph = (void*)skb->data; - if(etheriph->version != ETHERIP_VERSION){ - wprintf("> Bad etherip version=%d src=%u.%u.%u.%u\n", - etheriph->version, NIPQUAD(saddr)); - err = -EINVAL; - goto exit; - } - if(!pskb_may_pull(skb, etherip_n)){ - wprintf("> Malformed skb (etherip) src=%u.%u.%u.%u\n", - NIPQUAD(saddr)); - err = -EINVAL; - goto exit; - } - etheriphdr_get_vnet(etheriph, &vnet); - // If vnet is secure, context must include IPSEC ESP. - err = vnet_check_context(&vnet, SKB_CONTEXT(skb), &vinfo); - if(err){ - dprintf("> Failed security check vnet=%s src=%u.%u.%u.%u\n", - VnetId_ntoa(&vnet, vnetbuf), NIPQUAD(saddr)); - goto exit; - } - // Point at the headers in the contained ethernet frame. -#ifdef __KERNEL__ - __pskb_pull(skb, etherip_n); - skb_reset_mac_header(skb); -#else - skb->mac.raw = skb_pull_vn(skb, etherip_n); -#endif - eth = eth_hdr(skb); - - // Simulate the logic from eth_type_trans() - // to set skb->pkt_type and skb->protocol. - if(mac_is_multicast(eth->h_dest)){ - if(mac_is_broadcast(eth->h_dest)){ - skb->pkt_type = PACKET_BROADCAST; - } else { - skb->pkt_type = PACKET_MULTICAST; - } - } else { - skb->pkt_type = PACKET_HOST; - } - if(ntohs(eth->h_proto) >= 1536){ - skb->protocol = eth->h_proto; - } else { - skb->protocol = htons(ETH_P_802_2); - } - - // Assuming a standard Ethernet frame. - // Should check for protocol? Support ETH_P_8021Q too. -#ifndef __KERNEL__ - skb->nh.raw = skb_pull_vn(skb, ETH_HLEN); - skb->h.raw = skb->nh.raw + sizeof(struct iphdr); -#else - __pskb_pull(skb, ETH_HLEN); - skb_reset_network_header(skb); - skb_set_transport_header(skb, sizeof(struct iphdr)); -#endif - -#ifdef __KERNEL__ - // Fix IP options, checksum, skb dst, netfilter state. - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); -//fixme CHECKSUM_HW no longer defined - check replacing with CHECKSUM_COMPLETE. -/* if(skb->ip_summed == CHECKSUM_HW){ */ -/* skb->ip_summed = CHECKSUM_NONE; */ -/* } */ - if(skb->ip_summed == CHECKSUM_HW){ - skb->ip_summed = CHECKSUM_NONE; - } - dst_release(skb->dst); - skb->dst = NULL; - nf_reset(skb); -#ifdef CONFIG_BRIDGE_NETFILTER - if(skb->nf_bridge){ - // Stop the eth header being clobbered by nf_bridge_maybe_copy_header(). - nf_bridge_save_header(skb); - } -#endif -#endif // __KERNEL__ - - dprintf("> Unpacked srcaddr=" IPFMT " dstaddr=" IPFMT " vnet=%s srcmac=" MACFMT " dstmac=" MACFMT "\n", - NIPQUAD(skb->nh.iph->saddr), - NIPQUAD(skb->nh.iph->daddr), - VnetId_ntoa(&vnet, vnetbuf), - MAC6TUPLE(eth->h_source), - MAC6TUPLE(eth->h_dest)); - //print_skb(__FUNCTION__, 0, skb); - - { - // Know source ip, vnet, vmac, so update the varp cache. - // For this to work forwarded vnet packets must have the - // original source address. - VarpAddr addr = { .family = AF_INET }; - addr.u.ip4.s_addr = saddr; - varp_update(&vnet, eth->h_source, &addr); - } - - err = vnet_skb_recv(skb, vinfo); - exit: - if(vinfo) Vnet_decref(vinfo); - dprintf("< skb=%p err=%d\n", skb, err); - return err; -} - - -#ifdef __KERNEL__ - -/** Handle an ICMP error related to etherip. - * - * @param skb ICMP error packet - * @param info - */ -static void etherip_protocol_icmp_err(struct sk_buff *skb, u32 info){ - struct iphdr *iph = (struct iphdr*)skb->data; - - wprintf("> ICMP error type=%d code=%d addr=" IPFMT "\n", - skb->h.icmph->type, skb->h.icmph->code, NIPQUAD(iph->daddr)); - - if (skb->h.icmph->type != ICMP_DEST_UNREACH || - skb->h.icmph->code != ICMP_FRAG_NEEDED){ - return; - } - wprintf("> MTU too big addr= " IPFMT "\n", NIPQUAD(iph->daddr)); -} - -//============================================================================ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -// Code for 2.6 kernel. - -/** Etherip protocol. */ -static struct net_protocol etherip_protocol = { - .handler = etherip_protocol_recv, - .err_handler = etherip_protocol_icmp_err, -}; - -static int etherip_protocol_add(void){ - return inet_add_protocol(ðerip_protocol, IPPROTO_ETHERIP); -} - -static int etherip_protocol_del(void){ - return inet_del_protocol(ðerip_protocol, IPPROTO_ETHERIP); -} - -//============================================================================ -#else -//============================================================================ -// Code for 2.4 kernel. - -/** Etherip protocol. */ -static struct inet_protocol etherip_protocol = { - .name = "ETHERIP", - .protocol = IPPROTO_ETHERIP, - .handler = etherip_protocol_recv, - .err_handler = etherip_protocol_icmp_err, -}; - -static int etherip_protocol_add(void){ - inet_add_protocol(ðerip_protocol); - return 0; -} - -static int etherip_protocol_del(void){ - return inet_del_protocol(ðerip_protocol); -} - -#endif -//============================================================================ - - -/** Initialize the etherip module. - * Registers the etherip protocol. - * - * @return 0 on success, error code otherwise - */ -int __init etherip_module_init(void) { - int err = 0; - etherip_protocol_add(); - return err; -} - -/** Finalize the etherip module. - * Deregisters the etherip protocol. - */ -void __exit etherip_module_exit(void) { - if(etherip_protocol_del() < 0){ - printk(KERN_INFO "%s: can't remove etherip protocol\n", __FUNCTION__); - } -} - -#endif // __KERNEL__ diff --git a/vnet/src/vnet-module/etherip.h b/vnet/src/vnet-module/etherip.h deleted file mode 100644 index ef647e29698..00000000000 --- a/vnet/src/vnet-module/etherip.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_ETHERIP_H_ -#define _VNET_ETHERIP_H_ - -#include "if_etherip.h" - -#ifdef __KERNEL__ -extern int etherip_module_init(void); -extern void etherip_module_exit(void); -#endif - -extern int etherip_protocol_recv(struct sk_buff *skb); -extern int etherip_in_udp; - -struct VnetId; -struct VarpAddr; -struct Tunnel; - -extern int etherip_tunnel_create(struct VnetId *vnet, struct VarpAddr *addr, - struct Tunnel *base, struct Tunnel **tunnel); -#endif diff --git a/vnet/src/vnet-module/if_etherip.h b/vnet/src/vnet-module/if_etherip.h deleted file mode 100644 index c03a742d921..00000000000 --- a/vnet/src/vnet-module/if_etherip.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_IF_ETHERIP_H_ -#define _VNET_IF_ETHERIP_H_ - -#ifdef __KERNEL__ -#include -#else -#define __KERNEL__ -/* This include may cause a compile warning, which can be ignored. - * Can't use because it doesn't define - *__LITTLE_ENDIAN_BITFIELD or __BIG_ENDIAN_BITFIELD. - */ -#include -#undef __KERNEL__ -#endif - -#include - -#define CONFIG_ETHERIP_EXT - -#ifdef CONFIG_ETHERIP_EXT - -/* Extended header with room for a longer vnet id. */ - -#define ETHERIP_VERSION 4 - -struct etheriphdr { -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u16 reserved:12, - version:4; -#elif defined (__BIG_ENDIAN_BITFIELD) - __u16 version:4, - reserved:12; -#else -#error "Adjust your defines" -#endif - __u8 vnet[VNETID_SIZE8]; -} __attribute__ ((packed)); - -#else - -/* Original header as in Etherip RFC. */ - -#define ETHERIP_VERSION 3 - -struct etheriphdr -{ -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u16 reserved:12, - version:4; -#elif defined (__BIG_ENDIAN_BITFIELD) - __u16 version:4, - reserved:12; -#else -#error "Adjust your defines" -#endif - -}; -#endif - - -#ifndef IPPROTO_ETHERIP -#define IPPROTO_ETHERIP 97 -#endif - -#endif /* ! _VNET_IF_ETHERIP_H_ */ diff --git a/vnet/src/vnet-module/if_varp.h b/vnet/src/vnet-module/if_varp.h deleted file mode 100644 index 4ce270d9749..00000000000 --- a/vnet/src/vnet-module/if_varp.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _VNET_IF_VARP_H -#define _VNET_IF_VARP_H - -/* Need struct in_addr, struct in6_addr. */ -#ifdef __KERNEL__ - -#include -#include - -#else - -#include -#include - -#endif - -#include - -typedef struct Vmac { - unsigned char mac[ETH_ALEN]; -} Vmac; - -enum { - /* Varp protocol messages. - * Format is defined by struct VarpHdr. - */ - VARP_ID = 1, - - /* Vnet ethernet in udp messages. - * Format is uint16_t id (VUDP_ID), then - * struct etheriphdr. - */ - VUDP_ID = 2, - - /* Forwarded messages. - */ - VFWD_ID = 3, - - /* Varp request. */ - VARP_OP_REQUEST = 1, - /* Varp announce. */ - VARP_OP_ANNOUNCE = 2, -}; - -#define VNETID_SIZE8 16 -#define VNETID_SIZE16 (VNETID_SIZE8 >> 1) -#define VNETID_SIZE32 (VNETID_SIZE8 >> 2) - -typedef struct VnetId { - union { - uint8_t vnet8[VNETID_SIZE8]; - uint16_t vnet16[VNETID_SIZE16]; - uint32_t vnet32[VNETID_SIZE32]; - } u; -} __attribute__((packed)) VnetId; - -typedef struct VarpAddr { - uint8_t family; // AF_INET or AF_INET6. - union { - uint8_t raw[16]; - struct in_addr ip4; - struct in6_addr ip6; - } u; - //uint16_t port; -} __attribute__((packed)) VarpAddr; - -typedef struct VnetMsgHdr { - uint16_t id; - uint16_t opcode; -} __attribute__((packed)) VnetMsgHdr; - -typedef struct VarpHdr { - VnetMsgHdr hdr; - VnetId vnet; - Vmac vmac; - VarpAddr addr; -} __attribute__((packed)) VarpHdr; - - -/** Default address for varp/vnet broadcasts: 224.10.0.1 */ -#define VARP_MCAST_ADDR 0xe00a0001 - -/** UDP port to use for varp protocol. */ -#define VARP_PORT 1798 - -#endif /* ! _VNET_IF_VARP_H */ diff --git a/vnet/src/vnet-module/linux/pfkeyv2.h b/vnet/src/vnet-module/linux/pfkeyv2.h deleted file mode 100644 index cf3a2f16223..00000000000 --- a/vnet/src/vnet-module/linux/pfkeyv2.h +++ /dev/null @@ -1,329 +0,0 @@ -/* PF_KEY user interface, this is defined by rfc2367 so - * do not make arbitrary modifications or else this header - * file will not be compliant. - */ - -#ifndef _LINUX_PFKEY2_H -#define _LINUX_PFKEY2_H - -#include - -#define PF_KEY_V2 2 -#define PFKEYV2_REVISION 199806L - -struct sadb_msg { - uint8_t sadb_msg_version; - uint8_t sadb_msg_type; - uint8_t sadb_msg_errno; - uint8_t sadb_msg_satype; - uint16_t sadb_msg_len; - uint16_t sadb_msg_reserved; - uint32_t sadb_msg_seq; - uint32_t sadb_msg_pid; -} __attribute__((packed)); -/* sizeof(struct sadb_msg) == 16 */ - -struct sadb_ext { - uint16_t sadb_ext_len; - uint16_t sadb_ext_type; -} __attribute__((packed)); -/* sizeof(struct sadb_ext) == 4 */ - -struct sadb_sa { - uint16_t sadb_sa_len; - uint16_t sadb_sa_exttype; - uint32_t sadb_sa_spi; - uint8_t sadb_sa_replay; - uint8_t sadb_sa_state; - uint8_t sadb_sa_auth; - uint8_t sadb_sa_encrypt; - uint32_t sadb_sa_flags; -} __attribute__((packed)); -/* sizeof(struct sadb_sa) == 16 */ - -struct sadb_lifetime { - uint16_t sadb_lifetime_len; - uint16_t sadb_lifetime_exttype; - uint32_t sadb_lifetime_allocations; - uint64_t sadb_lifetime_bytes; - uint64_t sadb_lifetime_addtime; - uint64_t sadb_lifetime_usetime; -} __attribute__((packed)); -/* sizeof(struct sadb_lifetime) == 32 */ - -struct sadb_address { - uint16_t sadb_address_len; - uint16_t sadb_address_exttype; - uint8_t sadb_address_proto; - uint8_t sadb_address_prefixlen; - uint16_t sadb_address_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_address) == 8 */ - -struct sadb_key { - uint16_t sadb_key_len; - uint16_t sadb_key_exttype; - uint16_t sadb_key_bits; - uint16_t sadb_key_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_key) == 8 */ - -struct sadb_ident { - uint16_t sadb_ident_len; - uint16_t sadb_ident_exttype; - uint16_t sadb_ident_type; - uint16_t sadb_ident_reserved; - uint64_t sadb_ident_id; -} __attribute__((packed)); -/* sizeof(struct sadb_ident) == 16 */ - -struct sadb_sens { - uint16_t sadb_sens_len; - uint16_t sadb_sens_exttype; - uint32_t sadb_sens_dpd; - uint8_t sadb_sens_sens_level; - uint8_t sadb_sens_sens_len; - uint8_t sadb_sens_integ_level; - uint8_t sadb_sens_integ_len; - uint32_t sadb_sens_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_sens) == 16 */ - -/* followed by: - uint64_t sadb_sens_bitmap[sens_len]; - uint64_t sadb_integ_bitmap[integ_len]; */ - -struct sadb_prop { - uint16_t sadb_prop_len; - uint16_t sadb_prop_exttype; - uint8_t sadb_prop_replay; - uint8_t sadb_prop_reserved[3]; -} __attribute__((packed)); -/* sizeof(struct sadb_prop) == 8 */ - -/* followed by: - struct sadb_comb sadb_combs[(sadb_prop_len + - sizeof(uint64_t) - sizeof(struct sadb_prop)) / - sizeof(strut sadb_comb)]; */ - -struct sadb_comb { - uint8_t sadb_comb_auth; - uint8_t sadb_comb_encrypt; - uint16_t sadb_comb_flags; - uint16_t sadb_comb_auth_minbits; - uint16_t sadb_comb_auth_maxbits; - uint16_t sadb_comb_encrypt_minbits; - uint16_t sadb_comb_encrypt_maxbits; - uint32_t sadb_comb_reserved; - uint32_t sadb_comb_soft_allocations; - uint32_t sadb_comb_hard_allocations; - uint64_t sadb_comb_soft_bytes; - uint64_t sadb_comb_hard_bytes; - uint64_t sadb_comb_soft_addtime; - uint64_t sadb_comb_hard_addtime; - uint64_t sadb_comb_soft_usetime; - uint64_t sadb_comb_hard_usetime; -} __attribute__((packed)); -/* sizeof(struct sadb_comb) == 72 */ - -struct sadb_supported { - uint16_t sadb_supported_len; - uint16_t sadb_supported_exttype; - uint32_t sadb_supported_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_supported) == 8 */ - -/* followed by: - struct sadb_alg sadb_algs[(sadb_supported_len + - sizeof(uint64_t) - sizeof(struct sadb_supported)) / - sizeof(struct sadb_alg)]; */ - -struct sadb_alg { - uint8_t sadb_alg_id; - uint8_t sadb_alg_ivlen; - uint16_t sadb_alg_minbits; - uint16_t sadb_alg_maxbits; - uint16_t sadb_alg_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_alg) == 8 */ - -struct sadb_spirange { - uint16_t sadb_spirange_len; - uint16_t sadb_spirange_exttype; - uint32_t sadb_spirange_min; - uint32_t sadb_spirange_max; - uint32_t sadb_spirange_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_spirange) == 16 */ - -struct sadb_x_kmprivate { - uint16_t sadb_x_kmprivate_len; - uint16_t sadb_x_kmprivate_exttype; - u_int32_t sadb_x_kmprivate_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_x_kmprivate) == 8 */ - -struct sadb_x_sa2 { - uint16_t sadb_x_sa2_len; - uint16_t sadb_x_sa2_exttype; - uint8_t sadb_x_sa2_mode; - uint8_t sadb_x_sa2_reserved1; - uint16_t sadb_x_sa2_reserved2; - uint32_t sadb_x_sa2_sequence; - uint32_t sadb_x_sa2_reqid; -} __attribute__((packed)); -/* sizeof(struct sadb_x_sa2) == 16 */ - -struct sadb_x_policy { - uint16_t sadb_x_policy_len; - uint16_t sadb_x_policy_exttype; - uint16_t sadb_x_policy_type; - uint8_t sadb_x_policy_dir; - uint8_t sadb_x_policy_reserved; - uint32_t sadb_x_policy_id; - uint32_t sadb_x_policy_reserved2; -} __attribute__((packed)); -/* sizeof(struct sadb_x_policy) == 16 */ - -struct sadb_x_ipsecrequest { - uint16_t sadb_x_ipsecrequest_len; - uint16_t sadb_x_ipsecrequest_proto; - uint8_t sadb_x_ipsecrequest_mode; - uint8_t sadb_x_ipsecrequest_level; - uint16_t sadb_x_ipsecrequest_reqid; -} __attribute__((packed)); -/* sizeof(struct sadb_x_ipsecrequest) == 16 */ - -/* This defines the TYPE of Nat Traversal in use. Currently only one - * type of NAT-T is supported, draft-ietf-ipsec-udp-encaps-06 - */ -struct sadb_x_nat_t_type { - uint16_t sadb_x_nat_t_type_len; - uint16_t sadb_x_nat_t_type_exttype; - uint8_t sadb_x_nat_t_type_type; - uint8_t sadb_x_nat_t_type_reserved[3]; -} __attribute__((packed)); -/* sizeof(struct sadb_x_nat_t_type) == 8 */ - -/* Pass a NAT Traversal port (Source or Dest port) */ -struct sadb_x_nat_t_port { - uint16_t sadb_x_nat_t_port_len; - uint16_t sadb_x_nat_t_port_exttype; - uint16_t sadb_x_nat_t_port_port; - uint16_t sadb_x_nat_t_port_reserved; -} __attribute__((packed)); -/* sizeof(struct sadb_x_nat_t_port) == 8 */ - -/* Message types */ -#define SADB_RESERVED 0 -#define SADB_GETSPI 1 -#define SADB_UPDATE 2 -#define SADB_ADD 3 -#define SADB_DELETE 4 -#define SADB_GET 5 -#define SADB_ACQUIRE 6 -#define SADB_REGISTER 7 -#define SADB_EXPIRE 8 -#define SADB_FLUSH 9 -#define SADB_DUMP 10 -#define SADB_X_PROMISC 11 -#define SADB_X_PCHANGE 12 -#define SADB_X_SPDUPDATE 13 -#define SADB_X_SPDADD 14 -#define SADB_X_SPDDELETE 15 -#define SADB_X_SPDGET 16 -#define SADB_X_SPDACQUIRE 17 -#define SADB_X_SPDDUMP 18 -#define SADB_X_SPDFLUSH 19 -#define SADB_X_SPDSETIDX 20 -#define SADB_X_SPDEXPIRE 21 -#define SADB_X_SPDDELETE2 22 -#define SADB_X_NAT_T_NEW_MAPPING 23 -#define SADB_MAX 23 - -/* Security Association flags */ -#define SADB_SAFLAGS_PFS 1 - -/* Security Association states */ -#define SADB_SASTATE_LARVAL 0 -#define SADB_SASTATE_MATURE 1 -#define SADB_SASTATE_DYING 2 -#define SADB_SASTATE_DEAD 3 -#define SADB_SASTATE_MAX 3 - -/* Security Association types */ -#define SADB_SATYPE_UNSPEC 0 -#define SADB_SATYPE_AH 2 -#define SADB_SATYPE_ESP 3 -#define SADB_SATYPE_RSVP 5 -#define SADB_SATYPE_OSPFV2 6 -#define SADB_SATYPE_RIPV2 7 -#define SADB_SATYPE_MIP 8 -#define SADB_X_SATYPE_IPCOMP 9 -#define SADB_SATYPE_MAX 9 - -/* Authentication algorithms */ -#define SADB_AALG_NONE 0 -#define SADB_AALG_MD5HMAC 2 -#define SADB_AALG_SHA1HMAC 3 -#define SADB_X_AALG_SHA2_256HMAC 5 -#define SADB_X_AALG_SHA2_384HMAC 6 -#define SADB_X_AALG_SHA2_512HMAC 7 -#define SADB_X_AALG_RIPEMD160HMAC 8 -#define SADB_X_AALG_NULL 251 /* kame */ -#define SADB_AALG_MAX 251 - -/* Encryption algorithms */ -#define SADB_EALG_NONE 0 -#define SADB_EALG_DESCBC 2 -#define SADB_EALG_3DESCBC 3 -#define SADB_X_EALG_CASTCBC 6 -#define SADB_X_EALG_BLOWFISHCBC 7 -#define SADB_EALG_NULL 11 -#define SADB_X_EALG_AESCBC 12 -#define SADB_EALG_MAX 12 - -/* Compression algorithms */ -#define SADB_X_CALG_NONE 0 -#define SADB_X_CALG_OUI 1 -#define SADB_X_CALG_DEFLATE 2 -#define SADB_X_CALG_LZS 3 -#define SADB_X_CALG_LZJH 4 -#define SADB_X_CALG_MAX 4 - -/* Extension Header values */ -#define SADB_EXT_RESERVED 0 -#define SADB_EXT_SA 1 -#define SADB_EXT_LIFETIME_CURRENT 2 -#define SADB_EXT_LIFETIME_HARD 3 -#define SADB_EXT_LIFETIME_SOFT 4 -#define SADB_EXT_ADDRESS_SRC 5 -#define SADB_EXT_ADDRESS_DST 6 -#define SADB_EXT_ADDRESS_PROXY 7 -#define SADB_EXT_KEY_AUTH 8 -#define SADB_EXT_KEY_ENCRYPT 9 -#define SADB_EXT_IDENTITY_SRC 10 -#define SADB_EXT_IDENTITY_DST 11 -#define SADB_EXT_SENSITIVITY 12 -#define SADB_EXT_PROPOSAL 13 -#define SADB_EXT_SUPPORTED_AUTH 14 -#define SADB_EXT_SUPPORTED_ENCRYPT 15 -#define SADB_EXT_SPIRANGE 16 -#define SADB_X_EXT_KMPRIVATE 17 -#define SADB_X_EXT_POLICY 18 -#define SADB_X_EXT_SA2 19 -/* The next four entries are for setting up NAT Traversal */ -#define SADB_X_EXT_NAT_T_TYPE 20 -#define SADB_X_EXT_NAT_T_SPORT 21 -#define SADB_X_EXT_NAT_T_DPORT 22 -#define SADB_X_EXT_NAT_T_OA 23 -#define SADB_EXT_MAX 23 - -/* Identity Extension values */ -#define SADB_IDENTTYPE_RESERVED 0 -#define SADB_IDENTTYPE_PREFIX 1 -#define SADB_IDENTTYPE_FQDN 2 -#define SADB_IDENTTYPE_USERFQDN 3 -#define SADB_IDENTTYPE_MAX 3 - -#endif /* !(_LINUX_PFKEY2_H) */ diff --git a/vnet/src/vnet-module/random.c b/vnet/src/vnet-module/random.c deleted file mode 100644 index 835eaab6caf..00000000000 --- a/vnet/src/vnet-module/random.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include - -#include "hash_table.h" - -#define MODULE_NAME "RANDOM" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file - * Source of randomness. - * Current implementation is not enough. - * Needs to be cryptographically strong. - */ - -static unsigned long seed = 0; -static unsigned long count = 0; - -/** Contribute some random bytes. - * - * @param src bytes to contribute - * @param src_n number of bytes - */ -void add_random_bytes(const void *src, int src_n){ - ++count; - seed = hash_hvoid(seed, &count, sizeof(count)); - seed = hash_hvoid(seed, src, src_n); -} - -/** Get one random byte. - * - * @return random byte - */ -int get_random_byte(void){ - int tmp = jiffies; - add_random_bytes(&tmp, sizeof(tmp)); - return seed; -} - -#ifndef __KERNEL__ -/* Get some random bytes. - * - * @param dst destination for the bytes - * @param dst_n number of bytes to get - */ -void get_random_bytes(void *dst, int dst_n){ - int i; - char *p = (char *)dst; - for(i = 0; i < dst_n; i++){ - *p++ = get_random_byte(); - } -} -#endif - -int __init random_module_init(void){ - int dummy; - int tmp = jiffies; - seed = (unsigned long)&dummy; - add_random_bytes(&tmp, sizeof(tmp)); - return 0; -} - -void __exit random_module_exit(void){ -} - diff --git a/vnet/src/vnet-module/random.h b/vnet/src/vnet-module/random.h deleted file mode 100644 index 9c5762da615..00000000000 --- a/vnet/src/vnet-module/random.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_RANDOM_H__ -#define __VNET_RANDOM_H__ - -extern void get_random_bytes(void *dst, int dst_n); -extern void add_random_bytes(const void *src, int src_n); - -extern int random_module_init(void); -extern void random_module_exit(void); - -#endif /* ! __VNET_RANDOM_H__ */ diff --git a/vnet/src/vnet-module/sa.c b/vnet/src/vnet-module/sa.c deleted file mode 100644 index a3505ed97d1..00000000000 --- a/vnet/src/vnet-module/sa.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include - -#include -#include -#include -#include - -#include "hash_table.h" -#include "allocate.h" - -#define MODULE_NAME "IPSEC" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file IPSEC Security Association (SA). - */ - -/** Maximum number of protocols.*/ -#define INET_PROTOCOL_MAX 256 - -/** Table of SA types indexed by protocol. */ -static SAType *sa_type[INET_PROTOCOL_MAX] = {}; - -/** Hash a protocol number. - * - * @param protocol protocol number - * @return hashcode - */ -static inline unsigned char InetProtocol_hash(int protocol){ - return (protocol) & (INET_PROTOCOL_MAX - 1); -} - -/** Register an SA type. - * It is an error if an SA type is already registered for the protocol. - * - * @param type SA type - * @return 0 on success, error code otherwise - */ -int SAType_add(SAType *type){ - int err = -EINVAL; - int hash; - if(!type) goto exit; - hash = InetProtocol_hash(type->protocol); - if(sa_type[hash]) goto exit; - err = 0; - sa_type[hash] = type; - exit: - return err; -} - -/** Deregister an SA type. - * It is an error if no SA type is registered for the protocol. - * - * @param type SA type - * @return 0 on success, error code otherwise - */ -int SAType_del(SAType *type){ - int err = -EINVAL; - int hash; - if(!type) goto exit; - hash = InetProtocol_hash(type->protocol); - if(!sa_type[hash]) goto exit; - err = 0; - sa_type[hash] = NULL; - exit: - return err; -} - -int SAType_get(int protocol, SAType **type){ - int err = -ENOENT; - int hash; - hash = InetProtocol_hash(protocol); - *type = sa_type[hash]; - if(!*type) goto exit; - err = 0; - exit: - return err; -} - -/* Defeat compiler warnings about unused functions. */ -static int sa_key_check(SAKey *key, enum sa_alg_type type) __attribute__((unused)); -static u32 random_spi(void) __attribute__((unused)); -static u32 generate_key(u32 key, u32 offset, u32 spi) __attribute__((unused)); - -/** Check a key has an acceptable length for an algorithm. - * - * @param key key - * @param type algorithm - * @return 0 on success, error code otherwise - */ -static int sa_key_check(SAKey *key, enum sa_alg_type type){ - return 0; -} - -static unsigned long sa_spi_counter = 0; - -/** Mangle some input to generate output. - * This is used to derive spis and keying material from secrets, - * so it probably ought to be cryptographically strong. - * Probably ought to use a good hash (sha1) or cipher (aes). - * - * @param input input bytes - * @param n number of bytes - * @return mangled value - */ -static u32 mangle(void *input, int n){ - return hash_hvoid(0, input, n); -} - -/** Generate a random spi. - * Uses a hashed counter. - * - * @return spi - */ -static u32 random_spi(void){ - u32 spi; - do{ - spi = sa_spi_counter++; - spi = mangle(&spi, sizeof(spi)); - } while(!spi); - return spi; -} - - /** Generate a spi for a given protocol and address, using a secret key. - * The offset is used when it is necessary to generate more than one spi - * for the same protocol and address. - * - * @param key key - * @param offset offset - * @param protocol protocol - * @param addr IP address - * @return spi - */ -static u32 generate_spi(u32 key, u32 offset, u32 protocol, u32 addr){ - u32 input[] = { key, offset, protocol, addr }; - return mangle(input, sizeof(input)); -} - -/** Generate keying material for a given spi, based on a - * secret. - * - * @param key secret - * @param offset offset - * @param spi spi - * @return keying material - */ -static u32 generate_key(u32 key, u32 offset, u32 spi){ - u32 input[] = { key, offset, spi }; - return mangle(input, sizeof(input)); -} - -/** Allocate a spi. - * Want to use random ones. - * So check for ones not in use. - * - * When using static keying, both ends need to agree on key. - * How does that work? Also, will suddenly get traffic using a spi, - * and will have to create SA then. Or need to create in advance. - * But can't do that because don't know peers. - * When get message on a spi that doesn't exist - do what? - * Use a spi related to the destination addr and a secret. - * Then receiver can check if spi is ok and create SA on demand. - * Use hash of key, protocol, addr to generate. Then have to check - * for in-use because of potential collisions. Receiver can do the - * same hash and check spi is in usable range. Then derive keys from - * the spi (using another secret). - * - * @param key spi generation key - * @param protocol protocol - * @param addr IP address - * @param spip return parameter for spi - * @return 0 on success, error code otherwise - */ -int sa_spi_alloc(u32 key, u32 protocol, u32 addr, u32 *spip){ - int err = 0; - int i = 0, n = 100; - u32 spi; - for(i = 0; i < n; i++, spi++){ - spi = generate_spi(key, i, protocol, addr); - if(!spi) continue; - if(!sa_table_lookup_spi(spi, protocol, addr)){ - *spip = spi; - goto exit; - } - } - err = -ENOMEM; - exit: - return err; -} - -/** Table of SAs. Indexed by unique id and spi/protocol/addr triple. - */ -static HashTable *sa_table = NULL; - -static u32 sa_id = 1; - -/** Hash an SA id. - * - * @param id SA id - * @return hashcode - */ -static inline Hashcode sa_table_hash_id(u32 id){ - return hash_hvoid(0, &id, sizeof(id)); -} - -/** Hash SA spi/protocol/addr. - * - * @param spi spi - * @param protocol protocol - * @param addr IP address - * @return hashcode - */ -static inline Hashcode sa_table_hash_spi(u32 spi, u32 protocol, u32 addr){ - u32 a[] = { spi, protocol, addr }; - return hash_hvoid(0, a, sizeof(a)); -} - -/** Test if an SA entry has a given value. - * - * @param arg contains SA pointer - * @param table hashtable - * @param entry entry containing SA - * @return 1 if it does, 0 otherwise - */ -static int sa_table_state_fn(TableArg arg, HashTable *table, HTEntry *entry){ - return entry->value == arg.ptr; -} - -/** Test if an SA entry has a given id. - * - * @param arg contains SA id - * @param table hashtable - * @param entry entry containing SA - * @return 1 if it does, 0 otherwise - */ -static int sa_table_id_fn(TableArg arg, HashTable *table, HTEntry *entry){ - SAState *state = entry->value; - u32 id = arg.ul; - return state->ident.id == id; -} - -/** Test if an SA entry has a given spi/protocol/addr. - * - * @param arg contains SAIdent pointer - * @param table hashtable - * @param entry entry containing SA - * @return 1 if it does, 0 otherwise - */ -static int sa_table_spi_fn(TableArg arg, HashTable *table, HTEntry *entry){ - SAState *state = entry->value; - SAIdent *ident = arg.ptr; - return state->ident.spi == ident->spi - && state->ident.protocol == ident->protocol - && state->ident.addr == ident->addr; -} - -/** Free an SA entry. Decrements the SA refcount and frees the entry. - * - * @param table containing table - * @param entry to free - */ -static void sa_table_free_fn(HashTable *table, HTEntry *entry){ - if(!entry) return; - if(entry->value){ - SAState *state = entry->value; - SAState_decref(state); - } - deallocate(entry); -} - -/** Initialize the SA table. - * - * @return 0 on success, error code otherwise - */ -int sa_table_init(void){ - int err = 0; - sa_table = HashTable_new(0); - if(!sa_table){ - err = -ENOMEM; - goto exit; - } - sa_table->entry_free_fn = sa_table_free_fn; - - exit: - return err; -} - -void sa_table_exit(void){ - HashTable_free(sa_table); -} - -/** Remove an SA from the table. - * - * @param state SA - */ -int sa_table_delete(SAState *state){ - int count = 0; - Hashcode h1, h2; - TableArg arg = { .ptr = state }; - // Remove by id. - h1 = sa_table_hash_id(state->ident.id); - count += HashTable_remove_entry(sa_table, h1, sa_table_state_fn, arg); - // Remove by spi/protocol/addr if spi nonzero. - if(!state->ident.spi) goto exit; - h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, state->ident.addr); - if(h1 == h2) goto exit; - count += HashTable_remove_entry(sa_table, h2, sa_table_state_fn, arg); - exit: - return count; -} - -/** Add an SA to the table. - * The SA is indexed by id and spi/protocol/addr (if the spi is non-zero). - * - * @param state SA - * @return 0 on success, error code otherwise - */ -int sa_table_add(SAState *state){ - int err = 0; - Hashcode h1, h2; - int entries = 0; - - dprintf(">\n"); - // Index by id. - h1 = sa_table_hash_id(state->ident.id); - if(!HashTable_add_entry(sa_table, h1, HKEY(state->ident.id), state)){ - err = -ENOMEM; - goto exit; - } - entries++; - SAState_incref(state); - // Index by spi/protocol/addr if spi non-zero. - if(state->ident.spi){ - h2 = sa_table_hash_spi(state->ident.spi, state->ident.protocol, state->ident.addr); - if(h1 != h2){ - if(!HashTable_add_entry(sa_table, h2, HKEY(state->ident.id), state)){ - err = -ENOMEM; - goto exit; - } - entries++; - SAState_incref(state); - } - } - exit: - if(err && entries){ - sa_table_delete(state); - } - dprintf("< err=%d\n", err); - return err; -} - - -/** Find an SA by spi/protocol/addr. - * Increments the SA refcount on success. - * - * @param spi spi - * @param protocol protocol - * @param addr IP address - * @return SA or NULL - */ -SAState * sa_table_lookup_spi(u32 spi, u32 protocol, u32 addr){ - SAState *state = NULL; - Hashcode h; - SAIdent id = { - .spi = spi, - .protocol = protocol, - .addr = addr }; - TableArg arg = { .ptr = &id }; - HTEntry *entry = NULL; - - h = sa_table_hash_spi(spi, protocol, addr); - entry = HashTable_find_entry(sa_table, h, sa_table_spi_fn, arg); - if(entry){ - state = entry->value; - SAState_incref(state); - } - return state; -} - -/** Find an SA by unique id. - * Increments the SA refcount on success. - * - * @param id id - * @return SA or NULL - */ -SAState * sa_table_lookup_id(u32 id){ - Hashcode h; - TableArg arg = { .ul = id }; - HTEntry *entry = NULL; - SAState *state = NULL; - - dprintf("> id=%u\n", id); - h = sa_table_hash_id(id); - entry = HashTable_find_entry(sa_table, h, sa_table_id_fn, arg); - if(entry){ - state = entry->value; - SAState_incref(state); - } - dprintf("< state=%p\n", state); - return state; -} - -/** Replace an existing SA by another in the table. - * The existing SA is not removed if the new one cannot be added. - * - * @param existing SA to replace - * @param state new SA - * @return 0 on success, error code otherwise - */ -static int sa_table_replace(SAState *existing, SAState *state){ - int err = 0; - // Need check for in-use? - - dprintf(">\n"); - if(existing->keying.state != SA_STATE_ACQUIRE){ - err = -EINVAL; - goto exit; - } - // replace it. - err = sa_table_add(state); - if(err) goto exit; - sa_table_delete(existing); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Allocate an SA. - * - * @return SA or NULL - */ -SAState *SAState_alloc(void){ - SAState *state; - - dprintf(">\n"); - state = kmalloc(sizeof(SAState), GFP_ATOMIC); - if(!state) goto exit; - *state = (SAState){}; - atomic_set(&state->refcount, 1); - state->lock = SPIN_LOCK_UNLOCKED; - exit: - dprintf("< state=%p\n", state); - return state; -} - -/** Create an SA in initial state. - * It has no spi and its keying state is acquire. - * It must have a unique id, protocol and address. - * At some point it should get updated with a complete SA. - * - * @param ident SA identifier - * @param statep return parameter for new SA - * @return 0 on success, error code otherwise - */ -int SAState_init(SAIdent *ident, SAState **statep){ - int err = 0; - SAState *state = NULL; - - if(ident->spi || !ident->id){ - err = -EINVAL; - goto exit; - } - state = SAState_alloc(); - if (!state){ - err = -ENOMEM; - goto exit; - } - state->ident = *ident; - state->keying.state = SA_STATE_ACQUIRE; - exit: - return err; -} - -/** Create a complete SA, with spi and cipher suite. - * - * @param info SA parameters - * @param statep return parameter for new SA - * @return 0 on success, error code otherwise - */ -int SAState_create(SAInfo *info, SAState **statep){ - int err = 0; - SAState *state = NULL; - - dprintf(">\n"); - state = SAState_alloc(); - if (!state){ - err = -ENOMEM; - goto exit; - } - state->ident = info->ident; - state->limits = info->limits; - state->digest = info->digest; - state->cipher = info->cipher; - state->compress = info->compress; - state->security = info->security; - err = SAType_get(state->ident.protocol, &state->type); - if (err) goto exit; - err = state->type->init(state, NULL); - if (err) goto exit; - state->keying.state = SA_STATE_VALID; - exit: - if(err){ - SAState_decref(state); - state = NULL; - } - *statep = state; - dprintf("< err=%d\n", err); - return err; -} - -/** Create an SA for the given spi etc. - * For now we fix the cipher suite and the keys. - * Digest is SHA1 HMAC with a 128-bit key. - * Cipher is AES (Rijndael) in CBC mode with a 128-bit key. - * - * The cipher suite and keys should really come from policy, with the - * possibility of negotiating them with the peer (using IKE). - * Negotiation creates difficulties though - because the SA cannot - * be created immediately we have to be able to queue packets - * while the SA is being negotiated. - * - * @param spi spi - * @param protocol protocol - * @param addr address - * @param sa return parameter for SA - * @return 0 on success, error code otherwise - */ -int sa_create(int security, u32 spi, u32 protocol, u32 addr, SAState **sa){ - int err = 0; - SAInfo info = {}; - char *digest_name = "sha1"; - char *digest_key = "0123456789abcdef"; - int digest_key_n = strlen(digest_key); - char *cipher_name= "aes"; - char *cipher_key = "0123456789ABCDEF"; - int cipher_key_n = strlen(cipher_key); - - dprintf("> security=%d spi=%u protocol=%u addr=" IPFMT "\n", - security, spi, protocol, NIPQUAD(addr)); - if(!spi){ - spi = generate_spi(0, 0, protocol, addr); - } - dprintf("> info...\n"); - info.ident.id = sa_id++; - info.ident.spi = spi; - info.ident.protocol = protocol; - info.ident.addr = addr; - info.security = security; - - //sa_algorithm_probe_all(); - - dprintf("> digest name=%s key_n=%d\n", digest_name, digest_key_n); - strcpy(info.digest.name, digest_name); - info.digest.bits = digest_key_n * 8; - memcpy(info.digest.key, digest_key, digest_key_n); - - if(security & SA_CONF){ - dprintf("> cipher name=%s key_n=%d\n", cipher_name, cipher_key_n); - strcpy(info.cipher.name, cipher_name); - info.cipher.bits = cipher_key_n * 8; - memcpy(info.cipher.key, cipher_key, cipher_key_n); - } else { - dprintf("> cipher name=%s key_n=%d\n", "cipher_null", 0); - strcpy(info.cipher.name, "cipher_null"); - info.cipher.bits = 0; - memset(info.cipher.key, 0, sizeof(info.cipher.key)); - } - - err = sa_set(&info, 0, sa); - dprintf("< err=%d\n", err); - return err; -} - -/** Create or update an SA. - * The SA is added to the table. - * - * @param info SA parameters - * @param update create if zero, update otherwise - * @return 0 on success, error code otherwise - */ -int sa_set(SAInfo *info, int update, SAState **val){ - int err = 0; - SAState *state = NULL; - SAState *existing = NULL; - - dprintf("> info=%p update=%d val=%p\n", info, update, val); - existing = sa_table_lookup_id(info->ident.id); - if(update && !existing){ - err = -ENOENT; - } else if(!update && existing){ - err = -EINVAL; - } - if(err) goto exit; - err = SAState_create(info, &state); - if (err) goto exit; - if(existing){ - err = sa_table_replace(existing, state); - } else { - err = sa_table_add(state); - } - exit: - if(existing) SAState_decref(existing); - if(val && !err){ - *val = state; - } else { - SAState_decref(state); - } - dprintf("< err=%d\n", err); - return err; -} - -/** Delete an SA. Removes it from the SA table. - * It is an error if no SA with the given id exists. - * - * @param id SA id - * @return 0 on success, error code otherwise - */ -int sa_delete(int id){ - int err = 0; - SAState *state; - state = sa_table_lookup_id(id); - if (!state){ - err = -ENOENT; - goto exit; - } - sa_table_delete(state); - SAState_decref(state); - exit: - return err; -} -/** Determine ESP security mode for a new SA. - * - * @param spi incoming spi - * @param protocol incoming protocol - * @param addr source address - * @return security level or negative error code - * - * @todo Need to check spi, and do some lookup for security params. - */ -int vnet_sa_security(u32 spi, int protocol, u32 addr){ - extern int vnet_security_default; - int security = vnet_security_default; - dprintf("< security=%x\n", security); - return security; -} - -/** Create a new SA for incoming traffic. - * - * @param spi incoming spi - * @param protocol incoming protocol - * @param addr source address - * @param sa return parameter for SA - * @return 0 on success, error code otherwise - */ -int vnet_sa_create(u32 spi, int protocol, u32 addr, SAState **sa){ - int err = 0; - int security = vnet_sa_security(spi, protocol, addr); - if(security < 0){ - err = security; - goto exit; - } - err = sa_create(security, spi, protocol, addr, sa); - exit: - return err; -} -/** Open function for SA tunnels. - * - * @param tunnel to open - * @return 0 on success, error code otherwise - */ -static int sa_tunnel_open(Tunnel *tunnel){ - int err = 0; - //dprintf(">\n"); - //dprintf("< err=%d\n", err); - return err; -} - -/** Close function for SA tunnels. - * - * @param tunnel to close (OK if null) - */ -static void sa_tunnel_close(Tunnel *tunnel){ - SAState *sa; - if(!tunnel) return; - sa = tunnel->data; - if(!sa) return; - SAState_decref(sa); - tunnel->data = NULL; -} - -/** Packet send function for SA tunnels. - * - * @param tunnel to send on - * @param skb packet to send - * @return 0 on success, negative error code on error - */ -static int sa_tunnel_send(Tunnel *tunnel, struct sk_buff *skb){ - int err = -EINVAL; - SAState *sa; - if(!tunnel){ - wprintf("> Null tunnel!\n"); - goto exit; - } - sa = tunnel->data; - if(!sa){ - wprintf("> Null SA!\n"); - goto exit; - } - err = SAState_send(sa, skb, tunnel->base); - exit: - return err; -} - -/** Functions used by SA tunnels. */ -static TunnelType _sa_tunnel_type = { - .name = "SA", - .open = sa_tunnel_open, - .close = sa_tunnel_close, - .send = sa_tunnel_send -}; - -/** Functions used by SA tunnels. */ -TunnelType *sa_tunnel_type = &_sa_tunnel_type; - -int sa_tunnel_create(Vnet *info, VarpAddr *addr, Tunnel *base, Tunnel **tunnel){ - int err = 0; - SAState *sa = NULL; - //FIXME: Assuming IPv4 for now. - u32 ipaddr = addr->u.ip4.s_addr; - err = Tunnel_create(sa_tunnel_type, &info->vnet, addr, base, tunnel); - if(err) goto exit; - err = sa_create(info->security, 0, IPPROTO_ESP, ipaddr, &sa); - if(err) goto exit; - (*tunnel)->data = sa; - exit: - return err; -} diff --git a/vnet/src/vnet-module/sa.h b/vnet/src/vnet-module/sa.h deleted file mode 100644 index c0d1f7d7ba7..00000000000 --- a/vnet/src/vnet-module/sa.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_SA_H__ -#define __VNET_SA_H__ - -#ifdef __KERNEL__ -#include -#include - -#else - -#include "sys_kernel.h" - -#endif - -struct Vnet; -struct VarpAddr; -struct Tunnel; - -#ifndef CRYPTO_MAX_KEY_BYTES -#define CRYPTO_MAX_KEY_BYTES 64 -#define CRYPTO_MAX_KEY_BITS (CRYPTO_MAX_KEY_BYTES * 8) -#endif - -#ifndef CRYPTO_MAX_ALG_NAME -#define CRYPTO_MAX_ALG_NAME 64 -#endif - -typedef struct SALimits { - u64 bytes_soft; - u64 bytes_hard; - u64 packets_soft; - u64 packets_hard; -} SALimits; - -typedef struct SACounts { - u64 bytes; - u64 packets; - u32 integrity_failures; -} SACounts; - -typedef struct SAReplay { - int replay; - u32 send_seq; - u32 recv_seq; - u32 bitmap; - u32 replay_window; -} SAReplay; - -typedef struct SAKey { - char name[CRYPTO_MAX_ALG_NAME]; - int bits; - char key[CRYPTO_MAX_KEY_BYTES]; -} SAKey; - -typedef struct SAKeying { - u8 state; - u8 dying; -} SAKeying; - -typedef struct SAIdent { - u32 id; - u32 spi; - u32 addr; - u32 protocol; -} SAIdent; - -struct SAType; - -/** Security assocation (SA). */ -typedef struct SAState { - atomic_t refcount; - spinlock_t lock; - /** Identifier. */ - struct SAIdent ident; - /** Security flags. */ - int security; - /** Keying state. */ - struct SAKeying keying; - /** Byte counts etc. */ - struct SACounts counts; - /** Byte limits etc. */ - struct SALimits limits; - /** Replay protection. */ - struct SAReplay replay; - /** Digest algorithm. */ - struct SAKey digest; - /** Cipher algorithm. */ - struct SAKey cipher; - /** Compress algorith. */ - struct SAKey compress; - /** SA type (ESP, AH). */ - struct SAType *type; - /** Data for the SA type to use. */ - void *data; -} SAState; - -typedef struct SAType { - char *name; - int protocol; - int (*init)(SAState *state, void *args); - void (*fini)(SAState *state); - int (*recv)(SAState *state, struct sk_buff *skb); - int (*send)(SAState *state, struct sk_buff *skb, struct Tunnel *tunnel); - u32 (*size)(SAState *state, int size); -} SAType; - -/** Information needed to create an SA. - * Unused algorithms have zero key size. - */ -typedef struct SAInfo { - /** Identifier. */ - SAIdent ident; - /** Security flags. */ - int security; - /** Digest algorithm and key. */ - SAKey digest; - /** Cipher algorithm and key. */ - SAKey cipher; - /** Compress algorithm and key. */ - SAKey compress; - /** SA lifetime limits. */ - SALimits limits; - /** Replay protection window. */ - int replay_window; -} SAInfo; - -enum sa_alg_type { - SA_ALG_DIGEST = 1, - SA_ALG_CIPHER = 2, - SA_ALG_COMPRESS = 3, -}; - -extern int SAType_add(SAType *type); -extern int SAType_del(SAType *type); -extern int SAType_get(int protocol, SAType **type); - -extern int sa_table_init(void); -extern void sa_table_exit(void); -extern int sa_table_delete(SAState *state); -extern int sa_table_add(SAState *state); -extern SAState * sa_table_lookup_spi(u32 spi, u32 protocol, u32 addr); -extern SAState * sa_table_lookup_id(u32 id); - -/** Increment reference count. - * - * @param sa security association (may be null) - */ -static inline void SAState_incref(SAState *sa){ - if(!sa) return; - atomic_inc(&sa->refcount); -} - -/** Decrement reference count, freeing if zero. - * - * @param sa security association (may be null) - */ -static inline void SAState_decref(SAState *sa){ - if(!sa) return; - if(atomic_dec_and_test(&sa->refcount)){ - sa->type->fini(sa); - kfree(sa); - } -} - -extern SAState *SAState_alloc(void); -extern int SAState_init(SAIdent *id, SAState **statep); -extern int SAState_create(SAInfo *info, SAState **statep); - -static inline int SAState_send(SAState *sa, struct sk_buff *skb, struct Tunnel *tunnel){ - return sa->type->send(sa, skb, tunnel); -} - -static inline int SAState_recv(SAState *sa, struct sk_buff *skb){ - return sa->type->recv(sa, skb); -} - -static inline int SAState_size(SAState *sa, int n){ - return sa->type->size(sa, n); -} - -extern int sa_create(int security, u32 spi, u32 protocol, u32 addr, SAState **sa); -extern int sa_set(SAInfo *info, int update, SAState **val); -extern int sa_delete(int id); - -enum { - SA_AUTH = 1, - SA_CONF = 2 -}; - -enum { - SA_STATE_ACQUIRE = 1, - SA_STATE_VALID = 2, -}; - -extern int sa_tunnel_create(struct Vnet *info, struct VarpAddr *addr, - struct Tunnel *base, struct Tunnel **tunnel); - -#endif /* !__VNET_SA_H__ */ diff --git a/vnet/src/vnet-module/sa_algorithm.c b/vnet/src/vnet-module/sa_algorithm.c deleted file mode 100644 index d5d14181747..00000000000 --- a/vnet/src/vnet-module/sa_algorithm.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2002 James Morris - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include -//#include - -#include - -#define MODULE_NAME "IPSEC" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file Tables of supported IPSEC algorithms. - * Has tables for digests, ciphers and compression algorithms. - */ - -/* - * Algorithms supported by IPsec. These entries contain properties which - * are used in key negotiation and sa processing, and are used to verify - * that instantiated crypto transforms have correct parameters for IPsec - * purposes. - */ - -/** Digests. */ -static SAAlgorithm digest_alg[] = { - { - .name = "digest_null", - .info = { - .digest = { - .icv_truncbits = 0, - .icv_fullbits = 0, - } - }, - .alg = { - .sadb_alg_id = SADB_X_AALG_NULL, - .sadb_alg_ivlen = 0, - .sadb_alg_minbits = 0, - .sadb_alg_maxbits = 0 - } - }, - { - .name = "md5", - .info = { .digest = { - .icv_truncbits = 96, - .icv_fullbits = 128, - } }, - .alg = { - .sadb_alg_id = SADB_AALG_MD5HMAC, - .sadb_alg_ivlen = 0, - .sadb_alg_minbits = 128, - .sadb_alg_maxbits = 128 - } - }, - { - .name = "sha1", - .info = { - .digest = { - .icv_truncbits = 96, - .icv_fullbits = 160, - } - }, - .alg = { - .sadb_alg_id = SADB_AALG_SHA1HMAC, - .sadb_alg_ivlen = 0, - .sadb_alg_minbits = 160, - .sadb_alg_maxbits = 160 - } - }, - { - .name = "sha256", - .info = { - .digest = { - .icv_truncbits = 128, - .icv_fullbits = 256, - } - }, - .alg = { - .sadb_alg_id = SADB_X_AALG_SHA2_256HMAC, - .sadb_alg_ivlen = 0, - .sadb_alg_minbits = 256, - .sadb_alg_maxbits = 256 - } - }, -/* { */ -/* .name = "ripemd160", */ -/* .info = { */ -/* .digest = { */ -/* .icv_truncbits = 96, */ -/* .icv_fullbits = 160, */ -/* } */ -/* }, */ -/* .alg = { */ -/* .sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC, */ -/* .sadb_alg_ivlen = 0, */ -/* .sadb_alg_minbits = 160, */ -/* .sadb_alg_maxbits = 160 */ -/* } */ -/* }, */ - { /* Terminator */ } -}; - -/** Ciphers. */ -static SAAlgorithm cipher_alg[] = { - { - .name = "cipher_null", - .info = { - .cipher = { - .blockbits = 8, - .defkeybits = 0, - } - }, - .alg = { - .sadb_alg_id = SADB_EALG_NULL, - .sadb_alg_ivlen = 0, - .sadb_alg_minbits = 0, - .sadb_alg_maxbits = 0 - } - }, - { - .name = "des", - .info = { - .cipher = { - .blockbits = 64, - .defkeybits = 64, - } - }, - .alg = { - .sadb_alg_id = SADB_EALG_DESCBC, - .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 64, - .sadb_alg_maxbits = 64 - } - }, - { - .name = "des3_ede", - .info = { - .cipher = { - .blockbits = 64, - .defkeybits = 192, - } - }, - .alg = { - .sadb_alg_id = SADB_EALG_3DESCBC, - .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 192, - .sadb_alg_maxbits = 192 - } - }, -/* { */ -/* .name = "cast128", */ //cast5? -/* .info = { */ -/* .cipher = { */ -/* .blockbits = 64, */ -/* .defkeybits = 128, */ -/* } */ -/* }, */ -/* .alg = { */ -/* .sadb_alg_id = SADB_X_EALG_CASTCBC, */ -/* .sadb_alg_ivlen = 8, */ -/* .sadb_alg_minbits = 40, */ -/* .sadb_alg_maxbits = 128 */ -/* } */ -/* }, */ - { - .name = "blowfish", - .info = { - .cipher = { - .blockbits = 64, - .defkeybits = 128, - } - }, - .alg = { - .sadb_alg_id = SADB_X_EALG_BLOWFISHCBC, - .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 40, - .sadb_alg_maxbits = 448 - } - }, - { - .name = "aes", - .info = { - .cipher = { - .blockbits = 128, - .defkeybits = 128, - } - }, - .alg = { - .sadb_alg_id = SADB_X_EALG_AESCBC, - .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 128, - .sadb_alg_maxbits = 256 - } - }, - { /* Terminator */ } -}; - -/** Compressors. */ -static SAAlgorithm compress_alg[] = { - { - .name = "deflate", - .info = { - .compress = { - .threshold = 90, - } - }, - .alg = { .sadb_alg_id = SADB_X_CALG_DEFLATE } - }, -/* { */ -/* .name = "lzs", */ -/* .info = { */ -/* .compress = { */ -/* .threshold = 90, */ -/* } */ -/* }, */ -/* .alg = { .sadb_alg_id = SADB_X_CALG_LZS } */ -/* }, */ -/* { */ -/* .name = "lzjh", */ -/* .info = { */ -/* .compress = { */ -/* .threshold = 50, */ -/* } */ -/* }, */ -/* .alg = { .sadb_alg_id = SADB_X_CALG_LZJH } */ -/* }, */ - { /* Terminator */ } -}; - -static SAAlgorithm *sa_algorithm_by_id(SAAlgorithm *algo, int alg_id) { - for( ; algo && algo->name; algo++){ - if (algo->alg.sadb_alg_id == alg_id) { - return (algo->available ? algo : NULL); - } - } - return NULL; -} - - -static SAAlgorithm *sa_algorithm_by_name(SAAlgorithm *algo, char *name) { - if (!name) return NULL; - for( ; algo && algo->name; algo++){ - if (strcmp(name, algo->name) == 0) { - return (algo->available ? algo : NULL); - } - } - return NULL; -} - -SAAlgorithm *sa_digest_by_id(int alg_id) { - return sa_algorithm_by_id(digest_alg, alg_id); -} - -SAAlgorithm *sa_cipher_by_id(int alg_id) { - return sa_algorithm_by_id(cipher_alg, alg_id); -} - -SAAlgorithm *sa_compress_by_id(int alg_id) { - return sa_algorithm_by_id(compress_alg, alg_id); -} - -SAAlgorithm *sa_digest_by_name(char *name) { - return sa_algorithm_by_name(digest_alg, name); -} - -SAAlgorithm *sa_cipher_by_name(char *name) { - return sa_algorithm_by_name(cipher_alg, name); -} - -SAAlgorithm *sa_compress_by_name(char *name) { - return sa_algorithm_by_name(compress_alg, name); -} - -SAAlgorithm *sa_digest_by_index(unsigned int idx) { - return digest_alg + idx; -} - -SAAlgorithm *sa_cipher_by_index(unsigned int idx) { - return cipher_alg + idx; -} - -SAAlgorithm *sa_compress_by_index(unsigned int idx) { - return compress_alg + idx; -} - -static void sa_algorithm_probe(SAAlgorithm *algo){ - int status; - dprintf("> algo=%p\n", algo); - for( ; algo && algo->name; algo++){ - dprintf("> algorithm %s...\n", algo->name); - status = crypto_alg_available(algo->name, 0); - dprintf("> algorithm %s status=%d\n",algo->name, status); - if (algo->available != status){ - algo->available = status; - } - } - dprintf("<\n"); -} - -/** Crypto api is broken. When an unregistered algorithm is requested it - * tries to load a module of the same name. But not all algorithms are - * defined by modules of the same name. - */ -static char *crypto_modules[] = { - "aes", - //"arc4", - "blowfish", - //"cast5", - //"cast6", - "crypto_null", - "des", - //"md4", - "md5", - //"serpent", - "sha1", - "sha256", - //"sha512", - //"twofish", - NULL -}; - -#include - -static void sa_module_probe(char **modules){ - char **p; - dprintf(">\n"); - for(p = modules; *p; p++){ - dprintf("> %s\n", *p); - request_module(*p); - } - dprintf("<\n"); -} - -/** - * Probe for the availability of crypto algorithms, and set the available - * flag for any algorithms found on the system. This is typically called by - * pfkey during userspace SA add, update or register. - */ -void sa_algorithm_probe_all(void){ - dprintf("> \n"); - //BUG_ON(in_softirq()); - sa_module_probe(crypto_modules); - sa_algorithm_probe(digest_alg); - sa_algorithm_probe(cipher_alg); - sa_algorithm_probe(compress_alg); - dprintf("<\n"); -} diff --git a/vnet/src/vnet-module/sa_algorithm.h b/vnet/src/vnet-module/sa_algorithm.h deleted file mode 100644 index 333481bcb75..00000000000 --- a/vnet/src/vnet-module/sa_algorithm.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_SA_ALGORITHM_H__ -#define __VNET_SA_ALGORITHM_H__ - -#include -#include - -typedef struct SADigestInfo { - u16 icv_truncbits; - u16 icv_fullbits; -} SADigestInfo; - -typedef struct SACipherInfo { - u16 blockbits; - u16 defkeybits; -} SACipherInfo; - -typedef struct SACompressInfo { - u16 threshold; -} SACompressInfo; - -typedef struct SAAlgorithm { - char *name; - u8 available; - union { - SADigestInfo digest; - SACipherInfo cipher; - SACompressInfo compress; - } info; - struct sadb_alg alg; -} SAAlgorithm; - -extern SAAlgorithm *sa_digest_by_id(int alg_id); -extern SAAlgorithm *sa_cipher_by_id(int alg_id); -extern SAAlgorithm *sa_compress_by_id(int alg_id); -extern SAAlgorithm *sa_digest_by_name(char *name); -extern SAAlgorithm *sa_cipher_by_name(char *name); -extern SAAlgorithm *sa_compress_by_name(char *name); -extern SAAlgorithm *sa_digest_by_index(unsigned int idx); -extern SAAlgorithm *sa_cipher_by_index(unsigned int idx); -extern SAAlgorithm *sa_compress_by_index(unsigned int idx); -extern void sa_algorithm_probe_all(void); - -#define MAX_KEY_BITS 512 - -#endif /* ! __VNET_SA_ALGORITHM_H__ */ diff --git a/vnet/src/vnet-module/skb_context.c b/vnet/src/vnet-module/skb_context.c deleted file mode 100644 index 5a76d7ed89b..00000000000 --- a/vnet/src/vnet-module/skb_context.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include - -#include - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -SkbContext *SkbContext_create(u32 vnet, u32 addr, int protocol, void *data, - void (*free_fn)(SkbContext *)){ - SkbContext *context = NULL; - - context = kmalloc(sizeof(SkbContext), GFP_ATOMIC); - if(!context) goto exit; - context->vnet = vnet; - context->addr = addr; - context->protocol = protocol; - context->data = data; - context->free_fn = free_fn; - context->next = NULL; - atomic_set(&context ->refcount, 1); - exit: - return context; -} - -void SkbContext_free(SkbContext *context){ - if(!context) return; - if(context->next) SkbContext_decref(context->next); - if(context->free_fn) context->free_fn(context); - context->vnet = 0; - context->addr = 0; - context->protocol = 0; - context->free_fn = NULL; - context->data = NULL; - context->next = NULL; - kfree(context); -} - -int SkbContext_push(SkbContext **val, u32 vnet, u32 addr, int protocol, - void *data, void (*free_fn)(SkbContext *)){ - int err = 0; - SkbContext *context = NULL; - - dprintf("> vnet=%u addr=%u.%u.%u.%u protocol=%d\n", - vnet, NIPQUAD(addr), protocol); - context = SkbContext_create(vnet, addr, protocol, data, free_fn); - if(!context){ - err = -ENOMEM; - goto exit; - } - context->next = *val; - *val = context; - exit: - dprintf("< err=%d\n", err); - return err; -} - -int skb_push_context(struct sk_buff *skb, u32 vnet, u32 addr, int protocol, - void *data, void (*free_fn)(SkbContext *)){ - int err = 0; - //SkbContext *ctxt = SKB_CONTEXT(skb); - dprintf("> skb=%p\n", skb); - - //err = SkbContext_push(&ctxt, vnet, addr, protocol, data, free_fn); //todo fixme - //SKB_CONTEXT(skb) = ctxt;//todo fixme - dprintf("< err=%d\n", err); - return err; -} - - diff --git a/vnet/src/vnet-module/skb_context.h b/vnet/src/vnet-module/skb_context.h deleted file mode 100644 index 3f97a308d8a..00000000000 --- a/vnet/src/vnet-module/skb_context.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __VNET_SKB_CONTEXT_H__ -#define __VNET_SKB_CONTEXT_H__ - -#ifdef __KERNEL__ -#include -#include -#include -#include - -//todo: fixme -#define SKB_CONTEXT(_skb) ((SkbContext *)(&(_skb)->cb[0])) - -#else - -#include "sys_kernel.h" -#include "spinlock.h" - -//todo: fixme -#define SKB_CONTEXT(_skb) ((SkbContext *)NULL) - -#endif - -/** Structure used to record inbound processing path for skbs. - * For example, the ETHERIP protocol handler can use this to - * tell whether an inbound packet came through IPSEC ESP or not. - */ -typedef struct SkbContext { - u32 vnet; - u32 addr; - int protocol; - void *data; - void (*free_fn)(struct SkbContext *); - atomic_t refcount; - struct SkbContext *next; -} SkbContext; - -/** Decrement the reference count, freeing if zero. - * - * @param context context (may be null) - */ -static inline void SkbContext_decref(SkbContext *context){ - extern void SkbContext_free(SkbContext *context); - if(!context) return; - if(atomic_dec_and_test(&context->refcount)){ - SkbContext_free(context); - } -} - -/** Increment the reference count. - * - * @param context context (may be null) - */ -static inline void SkbContext_incref(SkbContext *context){ - if(!context) return; - atomic_inc(&context->refcount); -} - -extern SkbContext *SkbContext_create(u32 vnet, u32 addr, int protocol, void *data, - void (*free_fn)(SkbContext *)); - -extern int SkbContext_push(SkbContext **val, u32 vnet, u32 addr, int protocol, - void *data, void (*free_fn)(SkbContext *)); - -struct sk_buff; -extern int skb_push_context(struct sk_buff *skb, u32 vnet, u32 addr, int protocol, - void *data, void (*free_fn)(SkbContext *)); - -#endif /* !__VNET_SKB_CONTEXT_H__ */ diff --git a/vnet/src/vnet-module/skb_util.c b/vnet/src/vnet-module/skb_util.c deleted file mode 100644 index 5410105c081..00000000000 --- a/vnet/src/vnet-module/skb_util.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifdef __KERNEL__ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ) -#include -static inline void *kmap_skb_frag(const skb_frag_t *frag) -{ -#ifdef CONFIG_HIGHMEM - BUG_ON(in_irq()); - - local_bh_disable(); -#endif - return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ); -} - -static inline void kunmap_skb_frag(void *vaddr) -{ - kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); -#ifdef CONFIG_HIGHMEM - local_bh_enable(); -#endif -} - -#endif - - -#else - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "sys_kernel.h" -#include "skbuff.h" - -#if defined(__LITTLE_ENDIAN) -#define HIPQUAD(addr) \ - ((unsigned char *)&addr)[3], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[0] -#elif defined(__BIG_ENDIAN) -#define HIPQUAD NIPQUAD -#else -#error "Please fix asm/byteorder.h" -#endif /* __LITTLE_ENDIAN */ - -#endif - -#include -#include - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -//============================================================================ -/** Make enough room in an skb for extra header and trailer. - * - * @param pskb return parameter for expanded skb - * @param skb skb - * @param head_n required headroom - * @param tail_n required tailroom - * @return 0 on success, error code otherwise - */ -int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int head_n, int tail_n){ - int err = 0; - int has_headroom = (head_n <= skb_headroom(skb)); - int has_tailroom = (tail_n <= skb_tailroom(skb)); - int writeable = !skb_cloned(skb) && !skb_shared(skb); - - dprintf("> skb=%p headroom=%d head_n=%d tailroom=%d tail_n=%d\n", - skb, - skb_headroom(skb), head_n, - skb_tailroom(skb), tail_n); - if(writeable && has_headroom && has_tailroom){ - // There's room! Reuse it. - *pskb = skb; - } else if(writeable && has_tailroom){ - // Tailroom, no headroom. Expand header the way GRE does. - struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16); - if(!new_skb){ - err = -ENOMEM; - goto exit; - } - kfree_skb(skb); - *pskb = new_skb; - } else { - // No room. Expand. There may be more efficient ways to do - // this, but this is simple and correct. - struct sk_buff *new_skb = skb_copy_expand(skb, head_n + 16, tail_n, GFP_ATOMIC); - if(!new_skb){ - err = -ENOMEM; - goto exit; - } - kfree_skb(skb); - *pskb = new_skb; - } - dprintf("> skb=%p headroom=%d head_n=%d tailroom=%d tail_n=%d\n", - *pskb, - skb_headroom(*pskb), head_n, - skb_tailroom(*pskb), tail_n); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Copy some data bits from a kernel buffer to an skb. - * Derived in the obvious way from skb_copy_bits(). - */ -int skb_put_bits(const struct sk_buff *skb, int offset, void *src, int len) -{ - int i, copy; - int start = skb->len - skb->data_len; - - if (offset > (int)skb->len-len) - goto fault; - - /* Copy header. */ - if ((copy = start-offset) > 0) { - if (copy > len) - copy = len; - memcpy(skb->data + offset, src, copy); - if ((len -= copy) == 0) - return 0; - offset += copy; - src += copy; - } - -#ifdef __KERNEL__ - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - int end; - - BUG_TRAP(start <= offset+len); - - end = start + skb_shinfo(skb)->frags[i].size; - if ((copy = end-offset) > 0) { - u8 *vaddr; - - if (copy > len) - copy = len; - - vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); - memcpy(vaddr + skb_shinfo(skb)->frags[i].page_offset + offset - start, - src, - copy); - kunmap_skb_frag(vaddr); - - if ((len -= copy) == 0) - return 0; - offset += copy; - src += copy; - } - start = end; - } - - if (skb_shinfo(skb)->frag_list) { - struct sk_buff *list; - - for (list = skb_shinfo(skb)->frag_list; list; list=list->next) { - int end; - - BUG_TRAP(start <= offset+len); - - end = start + list->len; - if ((copy = end-offset) > 0) { - if (copy > len) - copy = len; - if (skb_put_bits(list, offset-start, src, copy)) - goto fault; - if ((len -= copy) == 0) - return 0; - offset += copy; - src += copy; - } - start = end; - } - } -#else - i=0; -#endif - - if (len == 0) - return 0; - - fault: - return -EFAULT; -} - -int skboffset(struct sk_buff *skb, unsigned char *ptr){ - if(!ptr || ptr < skb->head || ptr > skb->tail){ - return -1; - } - return (ptr - skb->head); -} - -/** Print some bits of an skb. - * - * @param skb to print - * @param offset byte offset to start printing at - * @param n number of bytes to print - */ -void skb_print_bits(const char *msg, struct sk_buff *skb, int offset, int n){ - int chunk = 16; - int i, k; - u8 buff[chunk]; - if(!skb) return; - printk("%s> tot=%d len=%d data=%d mac=%d nh=%d h=%d\n", - msg, - skb->tail - skb->head, - skb->len, - skboffset(skb, skb->data), - skboffset(skb, skb->mac.raw), - skboffset(skb, skb->nh.raw), - skboffset(skb, skb->h.raw)); - printk("%s> head=%p data=%p mac=%p nh=%p h=%p tail=%p\n", - msg, skb->head, skb->data, - skb->mac.raw, skb->nh.raw, skb->h.raw, - skb->tail); - while(n){ - k = (n > chunk ? chunk : n); - skb_copy_bits(skb, offset, buff, k); - printk("%03d ", offset); - for(i=0; itail -= n; - skb->len -= n; - return skb->tail; -} - -#ifdef __KERNEL__ - -static const int DEBUG_SCATTERLIST = 0; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#define SET_SCATTER_ADDR(sg, addr) do{} while(0) -#else -#define SET_SCATTER_ADDR(sg, addr) (sg).address = (addr) -#endif - -/** Convert a (possibly fragmented) skb into a scatter list. - * - * @param skb skb to convert - * @param sg scatterlist to set up - * @param sg_n size of sg on input, number of elements set on output - * @param offset offset into data to start at - * @param len number of bytes - * @return 0 on success, error code otherwise - */ -int skb_scatterlist(struct sk_buff *skb, struct scatterlist *sg, int *sg_n, - int offset, int len){ - int err = 0; - int start; // No. of bytes copied so far (where next copy starts). - int size; // Size of the next chunk. - int end; // Where the next chunk ends (start + size). - int copy; // Number of bytes to copy in one operation. - int sg_i = 0; // Index into sg. - int i; - - if(DEBUG_SCATTERLIST){ - dprintf("> offset=%d len=%d (end=%d), skb len=%d,\n", - offset, len, offset+len, skb->len); - } - start = 0; - size = skb_headlen(skb); - end = start + size; - copy = end - offset; - if(copy > 0){ - char *p; - if(copy > len) copy = len; - if(sg_i >= *sg_n){ - err = -EINVAL; - goto exit; - } - p = skb->data + offset; - SET_SCATTER_ADDR(sg[sg_i], NULL); - sg[sg_i].page = virt_to_page(p); - sg[sg_i].offset = ((unsigned long)p & ~PAGE_MASK); - sg[sg_i].length = copy; - if(DEBUG_SCATTERLIST){ - dprintf("> sg_i=%d .page=%p .offset=%u .length=%d\n", - sg_i, sg[sg_i].page, sg[sg_i].offset, sg[sg_i].length); - } - sg_i++; - if((len -= copy) == 0) goto exit; - offset += copy; - } - start = end; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++){ - BUG_TRAP(start <= offset + len); - size = skb_shinfo(skb)->frags[i].size; - end = start + size; - copy = end - offset; - if(copy > 0){ - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - if(copy > len) copy = len; - if(sg_i >= *sg_n){ - err = -EINVAL; - goto exit; - } - SET_SCATTER_ADDR(sg[sg_i], NULL); - sg[sg_i].page = frag->page; - sg[sg_i].offset = frag->page_offset + offset - start; - sg[sg_i].length = copy; - if(DEBUG_SCATTERLIST){ - dprintf("> sg_i=%d .page=%p .offset=%u .length=%d\n", - sg_i, sg[sg_i].page, sg[sg_i].offset, sg[sg_i].length); - } - sg_i++; - if((len -= copy) == 0) goto exit; - offset += copy; - } - start = end; - } - exit: - if(!err) *sg_n = sg_i; - if(len) wprintf("> len=%d\n", len); - if(len) BUG(); - if(err) dprintf("< err=%d sg_n=%d\n", err, *sg_n); - return err; -} - -#endif - -void print_skb_data(const char *msg, int count, struct sk_buff *skb, u8 *data, int len) -{ - static int skb_count = 1000000; - u8 *ptr, *end; - u32 src_addr, dst_addr; - // Transport layer header. - union { - struct tcphdr *th; - struct udphdr *uh; - struct icmphdr *icmph; - struct igmphdr *igmph; - struct iphdr *ipiph; - unsigned char *raw; - } h; - // Network layer header. - union { - struct iphdr *iph; - struct ipv6hdr *ipv6h; - struct arpheader *arph; - struct ipxhdr *ipxh; - unsigned char *raw; - } nh; - // Link layer header. - union { - struct ethhdr *ethernet; - unsigned char *raw; - } mac; - int protocol; - if(!count) count = ++skb_count; - if(!msg) msg = (char *)__FUNCTION__; - if(!data){ - printk("%s.%d> null data\n", msg, count); - return; - } - ptr = data; - end = data + len; - mac.raw = ptr; - ptr += sizeof(struct ethhdr); - if(ptr > end){ printk("***MAC:"); goto exit; } - protocol = ntohs(mac.ethernet->h_proto); - nh.raw = ptr; - - printk("%s.%d> type=%d protocol=0x%x\n", - msg, count, skb->pkt_type, htons(skb->protocol)); - if(1){ - printk("%s.%d> %p mac src=" MACFMT " dst=" MACFMT "\n", - msg, count, data, - MAC6TUPLE(mac.ethernet->h_source), - MAC6TUPLE(mac.ethernet->h_dest)); - } - - switch(protocol){ - case ETH_P_ARP: - ptr += sizeof(struct arpheader); - if(ptr > end){ printk("***ARP:"); goto exit; } - if(0){ - printk("%s.%d> ARP hrd=%d, pro=%d, hln=%d, pln=%d, op=%d\n", - msg, count, - nh.arph->ar_hrd, nh.arph->ar_pro, nh.arph->ar_hln, - nh.arph->ar_pln, nh.arph->ar_op); - } - memcpy(&src_addr, nh.arph->ar_sip, 4); - src_addr = ntohl(src_addr); - memcpy(&dst_addr, nh.arph->ar_tip, 4); - dst_addr = ntohl(dst_addr); - printk("%s.%d> ARP HW src=" MACFMT " dst=" MACFMT "\n", - msg, count, MAC6TUPLE(nh.arph->ar_sha), MAC6TUPLE(nh.arph->ar_tha)); - printk("%s.%d> ARP IP src=" IPFMT " dst=" IPFMT "\n", - msg, count, HIPQUAD(src_addr), HIPQUAD(dst_addr)); - break; - case ETH_P_IP: { - u16 src_port, dst_port; - if(ptr + sizeof(struct iphdr) > end){ printk("***IP:"); goto exit; } - src_addr = ntohl(nh.iph->saddr); - dst_addr = ntohl(nh.iph->daddr); - if(1){ - printk("%s.%d> IP proto=%d src=" IPFMT " dst=" IPFMT "\n", - msg, count, nh.iph->protocol, - HIPQUAD(src_addr), HIPQUAD(dst_addr)); - printk("%s.%d> IP tot_len=%u len=%d\n", - msg, count, ntohs(nh.iph->tot_len), len - ETH_HLEN); - } - ptr += (nh.iph->ihl * 4); - if(ptr > end){ printk ("***IP: len"); goto exit; } - h.raw = ptr; - switch(nh.iph->protocol){ - case IPPROTO_TCP: - ptr += sizeof(struct tcphdr); - if(ptr > end){ printk("***TCP:"); goto exit; } - src_port = ntohs(h.th->source); - dst_port = ntohs(h.th->dest); - printk("%s.%d> TCP src=" IPFMT ":%u dst=" IPFMT ":%u\n", - msg, count, - HIPQUAD(src_addr), src_port, - HIPQUAD(dst_addr), dst_port); - break; - case IPPROTO_UDP: - ptr += sizeof(struct udphdr); - if(ptr > end){ printk("***UDP:"); goto exit; } - src_port = ntohs(h.uh->source); - dst_port = ntohs(h.uh->dest); - printk("%s.%d> UDP src=" IPFMT ":%u dst=" IPFMT ":%u\n", - msg, count, - HIPQUAD(src_addr), src_port, - HIPQUAD(dst_addr), dst_port); - break; - default: - printk("%s.%d> IP %d src=" IPFMT " dst=" IPFMT "\n", - msg, count, - nh.iph->protocol, HIPQUAD(src_addr), HIPQUAD(dst_addr)); - break; - } - break; } - case ETH_P_IPV6: - printk("%s.%d> IPv6\n", msg, count); - break; - case ETH_P_IPX: - printk("%s.%d> IPX\n", msg, count); - break; - default: - printk("%s.%d> protocol=%d\n", msg, count, protocol); - break; - } - return; - exit: - printk("%s.%d> %s: skb problem\n", msg, count, __FUNCTION__); - printk("%s.%d> %s: data=%p end=%p(%d) ptr=%p(%d) eth=%d ip=%d\n", - msg, count, __FUNCTION__, - data, end, end - data, ptr, ptr - data, - sizeof(struct ethhdr), - sizeof(struct iphdr)); - return; -} - -void print_skb(const char *msg, int count, struct sk_buff *skb){ - print_skb_data(msg, count, skb, skb->mac.raw, skb->tail - skb->mac.raw); -} - -void print_ethhdr(const char *msg, struct sk_buff *skb){ - struct ethhdr *eth; - - if(!skb || skboffset(skb, skb->mac.raw) < 0) return; - eth = eth_hdr(skb); - printk("%s> ETH proto=%d src=" MACFMT " dst=" MACFMT "\n", - msg, - ntohs(eth->h_proto), - MAC6TUPLE(eth->h_source), - MAC6TUPLE(eth->h_dest)); -} - -void print_iphdr(const char *msg, struct sk_buff *skb){ - u32 src_addr, dst_addr; - - if(!skb || skboffset(skb, skb->nh.raw) < 0) return; - src_addr = ntohl(skb->nh.iph->saddr); - dst_addr = ntohl(skb->nh.iph->daddr); - printk("%s> IP proto=%d src=" IPFMT " dst=" IPFMT " tot_len=%u\n", - msg, - skb->nh.iph->protocol, - HIPQUAD(src_addr), - HIPQUAD(dst_addr), - ntohs(skb->nh.iph->tot_len)); -} - -void print_udphdr(const char *msg, struct sk_buff *skb){ - if(!skb || skboffset(skb, skb->h.raw) < 0) return; - printk("%s> UDP src=%u dst=%u len=%u\n", - msg, - ntohs(skb->h.uh->source), - ntohs(skb->h.uh->dest), - ntohs(skb->h.uh->len)); -} diff --git a/vnet/src/vnet-module/skb_util.h b/vnet/src/vnet-module/skb_util.h deleted file mode 100644 index 4c71adf8c62..00000000000 --- a/vnet/src/vnet-module/skb_util.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_SKB_UTIL_H_ -#define _VNET_SKB_UTIL_H_ - -#ifdef __KERNEL__ -#include -#include - -#else - -#include "skbuff.h" - -#endif - -struct sk_buff; - -extern int skb_make_room(struct sk_buff **pskb, struct sk_buff *skb, int head_n, int tail_n); - -extern int skb_put_bits(const struct sk_buff *skb, int offset, void *src, int len); - -extern void skb_print_bits(const char *msg, struct sk_buff *skb, int offset, int n); - -extern void buf_print(char *buf, int n); - -extern void *skb_trim_tail(struct sk_buff *skb, int n); - -extern void print_skb_data(const char *msg, int count, struct sk_buff *skb, u8 *data, int len); -extern void print_skb(const char *msg, int count, struct sk_buff *skb); - -extern void print_ethhdr(const char *msg, struct sk_buff *skb); -extern void print_iphdr(const char *msg, struct sk_buff *skb); -extern void print_udphdr(const char *msg, struct sk_buff *skb); - -/* The mac.ethernet field went away in 2.6 in favour of eth_hdr(). - */ -#ifdef __KERNEL__ -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -# define NEED_ETH_HDR -# endif -#else -# define NEED_ETH_HDR -#endif - -#ifdef NEED_ETH_HDR - -static inline struct ethhdr *eth_hdr(const struct sk_buff *skb) -{ - return (struct ethhdr *)skb->mac.raw; -} - -#endif - -/* - * It's a copy from {kernel}/include/linux/skbuff.h func '__skb_pull' and 'skb_pull' - * to aviodthe BUG_ON when pulling into the data (getting forwarded ip-frames) - */ -static inline unsigned char *__skb_pull_vn(struct sk_buff *skb, unsigned int len) -{ - skb->len -= len; - //BUG_ON(skb->len < skb->data_len); - return skb->data += len; -} -static inline unsigned char *skb_pull_vn(struct sk_buff *skb, unsigned int len) -{ - return unlikely(len > skb->len) ? NULL : __skb_pull_vn(skb, len); -} - - -#ifdef __KERNEL__ - -struct scatterlist; - -extern int skb_scatterlist(struct sk_buff *skb, struct scatterlist *sg, - int *sg_n, int offset, int len); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - -static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ - int err = 0; - struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = skb->nh.iph->daddr, - .saddr = skb->nh.iph->saddr, - .tos = skb->nh.iph->tos, - } - } - }; - - if(skb->dev){ - fl.oif = skb->dev->ifindex; - } - err = ip_route_output_key(prt, &fl); - return err; -} - -#else - -static inline int skb_route(struct sk_buff *skb, struct rtable **prt){ - int err = 0; - struct rt_key key = { }; - key.dst = skb->nh.iph->daddr; - key.src = skb->nh.iph->saddr; - key.tos = skb->nh.iph->tos; - if(skb->dev){ - key.oif = skb->dev->ifindex; - } - err = ip_route_output_key(prt, &key); - return err; -} - -#endif - -#endif /* __KERNEL__ */ - -/** Arp header struct with all the fields so we can access them. */ -struct arpheader -{ - unsigned short ar_hrd; /* format of hardware address */ - unsigned short ar_pro; /* format of protocol address */ - unsigned char ar_hln; /* length of hardware address */ - unsigned char ar_pln; /* length of protocol address */ - unsigned short ar_op; /* ARP opcode (command) */ - -#if 1 - /* - * Ethernet looks like this : This bit is variable sized however... - */ - unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */ - unsigned char ar_sip[4]; /* sender IP address */ - unsigned char ar_tha[ETH_ALEN]; /* target hardware address */ - unsigned char ar_tip[4]; /* target IP address */ -#endif - -}; - -#endif /* ! _VNET_SKB_UTIL_H_ */ diff --git a/vnet/src/vnet-module/sxpr_util.c b/vnet/src/vnet-module/sxpr_util.c deleted file mode 100644 index 38e07a870e6..00000000000 --- a/vnet/src/vnet-module/sxpr_util.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include "sys_net.h" -#include "if_varp.h" -#include "varp_util.h" -#include "sxpr_util.h" - -int stringof(Sxpr exp, char **s){ - int err = 0; - if(ATOMP(exp)){ - *s = atom_name(exp); - } else if(STRINGP(exp)){ - *s = string_string(exp); - } else { - err = -EINVAL; - *s = NULL; - } - return err; -} - -int child_string(Sxpr exp, Sxpr key, char **s){ - int err = 0; - Sxpr val = sxpr_child_value(exp, key, ONONE); - err = stringof(val, s); - return err; -} - -int intof(Sxpr exp, int *v){ - int err = 0; - char *s; - unsigned long l; - if(INTP(exp)){ - *v = OBJ_INT(exp); - } else { - err = stringof(exp, &s); - if(err) goto exit; - err = convert_atoul(s, &l); - *v = (int)l; - } - exit: - return err; -} - -int child_int(Sxpr exp, Sxpr key, int *v){ - int err = 0; - Sxpr val = sxpr_child_value(exp, key, ONONE); - err = intof(val, v); - return err; -} - -int vnetof(Sxpr exp, VnetId *v){ - int err = 0; - char *s; - err = stringof(exp, &s); - if(err) goto exit; - err = VnetId_aton(s, v); - exit: - return err; -} - -int child_vnet(Sxpr exp, Sxpr key, VnetId *v){ - int err = 0; - Sxpr val = sxpr_child_value(exp, key, ONONE); - err = vnetof(val, v); - return err; -} - -int macof(Sxpr exp, unsigned char *v){ - int err = 0; - char *s; - err = stringof(exp, &s); - if(err) goto exit; - err = mac_aton(s, v); - exit: - return err; -} - -int child_mac(Sxpr exp, Sxpr key, unsigned char *v){ - int err = 0; - Sxpr val = sxpr_child_value(exp, key, ONONE); - err = macof(val, v); - return err; -} - -int addrof(Sxpr exp, uint32_t *v){ - int err = 0; - char *s; - unsigned long w; - err = stringof(exp, &s); - if(err) goto exit; - err = get_inet_addr(s, &w); - if(err) goto exit; - *v = (uint32_t)w; - exit: - return err; -} - -int child_addr(Sxpr exp, Sxpr key, uint32_t *v){ - int err = 0; - Sxpr val = sxpr_child_value(exp, key, ONONE); - err = addrof(val, v); - return err; -} diff --git a/vnet/src/vnet-module/sxpr_util.h b/vnet/src/vnet-module/sxpr_util.h deleted file mode 100644 index 2814714dc16..00000000000 --- a/vnet/src/vnet-module/sxpr_util.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _SXPR_UTIL_H_ -#define _SXPR_UTIL__H_ - -#include "sxpr.h" -struct VnetId; - -int stringof(Sxpr exp, char **s); -int child_string(Sxpr exp, Sxpr key, char **s); -int intof(Sxpr exp, int *v); -int child_int(Sxpr exp, Sxpr key, int *v); -int vnetof(Sxpr exp, struct VnetId *v); -int child_vnet(Sxpr exp, Sxpr key, struct VnetId *v); -int macof(Sxpr exp, unsigned char *v); -int child_mac(Sxpr exp, Sxpr key, unsigned char *v); -int addrof(Sxpr exp, uint32_t *v); -int child_addr(Sxpr exp, Sxpr key, uint32_t *v); - -#endif /* ! _SXPR_UTIL_H_ */ diff --git a/vnet/src/vnet-module/timer_util.c b/vnet/src/vnet-module/timer_util.c deleted file mode 100644 index 68e343eb539..00000000000 --- a/vnet/src/vnet-module/timer_util.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#else - -#include "sys_kernel.h" -#include "spinlock.h" - -#endif - -#include "timer_util.h" - -#define MODULE_NAME "TIMER" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -#ifdef __KERNEL__ - -void timer_init(struct timer_list *timer, void (*fn)(unsigned long), void *data){ - init_timer(timer); - timer->data = (unsigned long)data; - timer->function = fn; -} - -void timer_set(struct timer_list *timer, unsigned long ttl){ - unsigned long now = jiffies; - timer->expires = now + ttl; - add_timer(timer); -} - -#else - -void timer_init(struct Timer *timer, void (*fn)(unsigned long), void *data){ - *timer = (struct Timer){}; - timer->data = (unsigned long)data; - timer->fn = fn; -} - -void timer_set(struct Timer *timer, unsigned long ttl){ - double now = time_now(); - timer->expiry = now + (double)ttl/(double)HZ; - Timer_cancel(timer); - Timer_add(timer); -} - -#endif diff --git a/vnet/src/vnet-module/timer_util.h b/vnet/src/vnet-module/timer_util.h deleted file mode 100644 index a2db1a15f60..00000000000 --- a/vnet/src/vnet-module/timer_util.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _VNET_TIMER_UTIL_H_ -#define _VNET_TIMER_UTIL_H_ - -#ifdef __KERNEL__ - -struct timer_list; -#define timer_cancel del_timer - -#else /* __KERNEL__ */ - -#include "timer.h" -#define timer_list Timer -#define HZ 1000 -#define jiffies (unsigned long)(time_now() * HZ) -#define timer_cancel Timer_cancel - -#endif /* __KERNEL__ */ - -void timer_init(struct timer_list *timer, void (*fn)(unsigned long), void *data); -void timer_set(struct timer_list *timer, unsigned long ttl); - -#endif /*! _VNET_TIMER_UTIL_H_ */ diff --git a/vnet/src/vnet-module/tunnel.c b/vnet/src/vnet-module/tunnel.c deleted file mode 100644 index 3403e3dcded..00000000000 --- a/vnet/src/vnet-module/tunnel.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -#else - -#include "sys_kernel.h" -#include "spinlock.h" -#include "skbuff.h" - -#endif - -#include -#include -#include -#include "hash_table.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** Table of tunnels, indexed by vnet and addr. */ -HashTable *tunnel_table = NULL; -rwlock_t tunnel_table_lock = RW_LOCK_UNLOCKED; - -#define tunnel_read_lock(flags) read_lock_irqsave(&tunnel_table_lock, (flags)) -#define tunnel_read_unlock(flags) read_unlock_irqrestore(&tunnel_table_lock, (flags)) -#define tunnel_write_lock(flags) write_lock_irqsave(&tunnel_table_lock, (flags)) -#define tunnel_write_unlock(flags) write_unlock_irqrestore(&tunnel_table_lock, (flags)) - -void Tunnel_free(Tunnel *tunnel){ - tunnel->type->close(tunnel); - Tunnel_decref(tunnel->base); - kfree(tunnel); -} - -void Tunnel_print(Tunnel *tunnel){ - if(tunnel){ - iprintf("Tunnel<%p base=%p ref=%02d type=%s>\n", - tunnel, - tunnel->base, - atomic_read(&tunnel->refcount), - tunnel->type->name); - if(tunnel->base){ - Tunnel_print(tunnel->base); - } - } else { - iprintf("Tunnel<%p base=%p ref=%02d type=%s>\n", - NULL, NULL, 0, "ip"); - } -} - -int Tunnel_create(TunnelType *type, VnetId *vnet, VarpAddr *addr, - Tunnel *base, Tunnel **val){ - int err = 0; - Tunnel *tunnel = NULL; - if(!type || !type->open || !type->send || !type->close){ - err = -EINVAL; - goto exit; - } - tunnel = kmalloc(sizeof(Tunnel), GFP_ATOMIC); - if(!tunnel){ - err = -ENOMEM; - goto exit; - } - atomic_set(&tunnel->refcount, 1); - tunnel->key.vnet = *vnet; - tunnel->key.addr = *addr; - tunnel->type = type; - tunnel->data = NULL; - tunnel->send_stats = (TunnelStats){}; - Tunnel_incref(base); - tunnel->base = base; - err = type->open(tunnel); - exit: - if(err && tunnel){ - Tunnel_decref(tunnel); - tunnel = NULL; - } - *val = tunnel; - dprintf("< err=%d\n", err); - return err; -} - -void TunnelStats_update(TunnelStats *stats, int len, int err){ - dprintf(">len=%d err=%d\n", len, err); - if(err){ - stats->dropped_bytes += len; - stats->dropped_packets++; - } else { - stats->bytes += len; - stats->packets++; - } - dprintf("<\n"); -} - -static inline Hashcode tunnel_table_key_hash_fn(void *k){ - return hash_hvoid(0, k, sizeof(TunnelKey)); -} - -static int tunnel_table_key_equal_fn(void *k1, void *k2){ - return memcmp(k1, k2, sizeof(TunnelKey)) == 0; -} - -static void tunnel_table_entry_free_fn(HashTable *table, HTEntry *entry){ - Tunnel *tunnel; - if(!entry) return; - tunnel = entry->value; - Tunnel_decref(tunnel); - HTEntry_free(entry); -} - -int Tunnel_init(void){ - int err = 0; - dprintf(">\n"); - tunnel_table = HashTable_new(0); - if(!tunnel_table){ - err = -ENOMEM; - goto exit; - } - tunnel_table->entry_free_fn = tunnel_table_entry_free_fn; - tunnel_table->key_size = sizeof(TunnelKey); - tunnel_table->key_hash_fn = tunnel_table_key_hash_fn; - tunnel_table->key_equal_fn = tunnel_table_key_equal_fn; - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Lookup tunnel state by vnet and destination. - * The caller must drop the tunnel reference when done. - * - * @param vnet vnet - * @param addr destination address - * @return 0 on success - */ -int Tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){ - unsigned long flags; - TunnelKey key = { .vnet = *vnet, .addr = *addr }; - dprintf(">\n"); - tunnel_read_lock(flags); - *tunnel = HashTable_get(tunnel_table, &key); - tunnel_read_unlock(flags); - Tunnel_incref(*tunnel); - dprintf("< tunnel=%p\n", *tunnel); - return (*tunnel ? 0 : -ENOENT); -} - -/** Get a tunnel to a given vnet and destination, creating - * a tunnel if necessary. - * The caller must drop the tunnel reference when done. - * - * @param vnet vnet - * @param addr destination address - * @param ctor tunnel constructor - * @parma ptunnel return parameter for the tunnel - * @return 0 on success - */ -int Tunnel_open(VnetId *vnet, VarpAddr *addr, - int (*ctor)(VnetId *vnet, VarpAddr *addr, Tunnel **ptunnel), - Tunnel **ptunnel){ - int err = 0; - Tunnel *tunnel = NULL; - unsigned long flags; - TunnelKey key = { .vnet = *vnet, .addr = *addr }; - - tunnel_write_lock(flags); - tunnel = HashTable_get(tunnel_table, &key); - if(!tunnel){ - err = ctor(vnet, addr, &tunnel); - if(err) goto exit; - if(!HashTable_add(tunnel_table, tunnel, tunnel)){ - err = -ENOMEM; - goto exit; - } - } - exit: - tunnel_write_unlock(flags); - if(err){ - Tunnel_decref(tunnel); - *ptunnel = NULL; - } else { - Tunnel_incref(tunnel); - *ptunnel = tunnel; - } - return err; -} - -int Tunnel_add(Tunnel *tunnel){ - int err = 0; - unsigned long flags; - dprintf(">\n"); - tunnel_write_lock(flags); - if(HashTable_add(tunnel_table, tunnel, tunnel)){ - Tunnel_incref(tunnel); - } else { - err = -ENOMEM; - } - tunnel_write_unlock(flags); - dprintf("< err=%d\n", err); - return err; -} - -int Tunnel_del(Tunnel *tunnel){ - int err; - unsigned long flags; - tunnel_write_lock(flags); - err = HashTable_remove(tunnel_table, tunnel); - tunnel_write_unlock(flags); - return err; -} - -/** Do tunnel send processing on a packet. - * - * @param tunnel tunnel state - * @param skb packet - * @return 0 on success, error code otherwise - */ -int Tunnel_send(Tunnel *tunnel, struct sk_buff *skb){ - int err = 0; - dprintf("> tunnel=%p skb=%p\n", tunnel, skb); - if(tunnel){ - int len = skb->len; - dprintf("> type=%s type->send...\n", tunnel->type->name); - // Must not refer to skb after sending - might have been freed. - err = tunnel->type->send(tunnel, skb); - TunnelStats_update(&tunnel->send_stats, len, err); - } else { - err = skb_xmit(skb); - } - dprintf("< err=%d\n", err); - return err; -} - -int __init tunnel_module_init(void){ - return Tunnel_init(); -} - -void __exit tunnel_module_exit(void){ - unsigned long flags; - tunnel_write_lock(flags); - if(tunnel_table){ - HashTable_free(tunnel_table); - tunnel_table = NULL; - } - tunnel_write_unlock(flags); -} diff --git a/vnet/src/vnet-module/tunnel.h b/vnet/src/vnet-module/tunnel.h deleted file mode 100644 index c363eca51ab..00000000000 --- a/vnet/src/vnet-module/tunnel.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_TUNNEL_H__ -#define __VNET_TUNNEL_H__ - -#ifdef __KERNEL__ -#include -#include - -#else - -//#include -#include "sys_kernel.h" -#include "spinlock.h" - -#endif - -#include - -struct sk_buff; -struct Tunnel; - -typedef struct TunnelType { - const char *name; - int (*open)(struct Tunnel *tunnel); - int (*send)(struct Tunnel *tunnel, struct sk_buff *skb); - void (*close)(struct Tunnel *tunnel); -} TunnelType; - -typedef struct TunnelStats { - int bytes; - int packets; - int dropped_bytes; - int dropped_packets; -} TunnelStats; - -typedef struct TunnelKey { - struct VnetId vnet; - struct VarpAddr addr; -} TunnelKey; - -typedef struct Tunnel { - /** Key identifying the tunnel. Must be first. */ - struct TunnelKey key; - /** Reference count. */ - atomic_t refcount; - /** Tunnel type. */ - struct TunnelType *type; - /** Statistics. */ - struct TunnelStats send_stats; - /** Type-dependent state. */ - void *data; - /** Underlying tunnel (may be null). */ - struct Tunnel *base; -} Tunnel; - -extern void Tunnel_free(struct Tunnel *tunnel); - -/** Decrement the reference count, freeing if zero. - * - * @param tunnel tunnel (may be null) - */ -static inline void Tunnel_decref(struct Tunnel *tunnel){ - if(!tunnel) return; - if(atomic_dec_and_test(&tunnel->refcount)){ - Tunnel_free(tunnel); - } -} - -/** Increment the reference count. - * - * @param tunnel tunnel (may be null) - */ -static inline void Tunnel_incref(struct Tunnel *tunnel){ - if(!tunnel) return; - atomic_inc(&tunnel->refcount); -} - -extern int Tunnel_init(void); -extern int Tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr, struct Tunnel **tunnel); -extern int Tunnel_open(struct VnetId *vnet, struct VarpAddr *addr, - int (*ctor)(struct VnetId *vnet, - struct VarpAddr *addr, - struct Tunnel **ptunnel), - struct Tunnel **ptunnel); -extern int Tunnel_add(struct Tunnel *tunnel); -extern int Tunnel_del(struct Tunnel *tunnel); -extern void Tunnel_print(struct Tunnel *tunnel); -extern int Tunnel_send(struct Tunnel *tunnel, struct sk_buff *skb); - -extern int Tunnel_create(struct TunnelType *type, struct VnetId *vnet, struct VarpAddr *addr, - struct Tunnel *base, struct Tunnel **tunnelp); - -extern int tunnel_module_init(void); -extern void tunnel_module_exit(void); - -#endif /* !__VNET_TUNNEL_H__ */ diff --git a/vnet/src/vnet-module/varp.c b/vnet/src/vnet-module/varp.c deleted file mode 100644 index 7f677b8f418..00000000000 --- a/vnet/src/vnet-module/varp.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#else - -#include "sys_kernel.h" -#include -#include -#include -#include -#include "spinlock.h" -#include "skbuff.h" - -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "allocate.h" -#include "iostream.h" -#include "hash_table.h" -#include "sys_net.h" -#include "sys_string.h" -#include "skb_util.h" -#include "timer_util.h" - -#define MODULE_NAME "VARP" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file VARP: Virtual ARP. - * - * Handles virtual ARP requests for vnet/vmac. - */ - -/* - -Varp uses UDP on port 1798. - -on domain up: ? - send varp.announce { id, vmac, vnet, coa } for each vif - that haven't announced before, or has changed. - install vif entries in local table. - -on varp.announce{ id, vmac, vnet, coa }: - update VARP entry for vmac x vnet if have one, reset ttl. - -on varp.request { id, vmac, vnet }: - if have a vif for the requested vmac/vnet, - reply with varp.announce{ id, vmac, vnet, coa } - -on timer: - traverse VARP table, flush old entries. - -on probe timer: - probe again if not out of tries. - if out of tries invalidate entry. - -*/ - -/** Time-to-live of varp entries (in jiffies).*/ -#define VARP_ENTRY_TTL (60*HZ) - -/** Maximum number of varp probes to make. */ -#define VARP_PROBE_MAX 5 - -/** Interval between varp probes (in jiffies). */ -#define VARP_PROBE_INTERVAL (3*HZ) - -/** Maximum number of queued skbs for a varp entry. */ -#define VARP_QUEUE_MAX 16 - -/** Number of buckets in the varp table (must be prime). */ -#define VARP_TABLE_BUCKETS 3001 - -/** Varp entry states. */ -enum { - VARP_STATE_INCOMPLETE = 1, - VARP_STATE_REACHABLE = 2, - VARP_STATE_FAILED = 3, -}; - -/** Varp entry flags. */ -enum { - VARP_FLAG_PROBING = 1, - VARP_FLAG_PERMANENT = 2, -}; - -/** Key for varp entries. */ -typedef struct VarpKey { - /** Vnet id (network order). */ - VnetId vnet; - /** Virtual MAC address. */ - Vmac vmac; -} VarpKey; - -/** An entry in the varp cache. */ -typedef struct VarpEntry { - /** Key for the entry. */ - VarpKey key; - /** Care-of address for the key. */ - VarpAddr addr; - /** Last-updated timestamp. */ - unsigned long timestamp; - /** State. */ - short state; - /** Flags. */ - short flags; - /** Reference count. */ - atomic_t refcount; - /** Lock. */ - rwlock_t lock; - unsigned long lflags; - - /** How many probes have been made. */ - atomic_t probes; - /** Probe timer. */ - struct timer_list timer; - void (*error)(struct VarpEntry *ventry, struct sk_buff *skb); - /** Outbound skb queue. */ - struct sk_buff_head queue; - /** Maximum size of the queue. */ - int queue_max; - atomic_t deleted; -} VarpEntry; - -/** The varp cache. Varp entries indexed by VarpKey. */ -typedef struct VarpTable { - - HashTable *table; - - /** Sweep timer. */ - struct timer_list timer; - - rwlock_t lock; - struct semaphore mutex; - - int entry_ttl; - int probe_max; - int probe_interval; - int queue_max; - -} VarpTable; - -/** The varp cache. */ -static VarpTable *varp_table = NULL; - -/** Module parameter for the multicast address. */ -static char *varp_mcaddr = NULL; - -/** Multicast address (network order). */ -u32 varp_mcast_addr = 0; - -/** UDP port (network order). */ -u16 varp_port = 0; - -char *varp_device = "xen-br0"; - -#define VarpTable_read_lock(vtable, flags) \ - do{ read_lock_irqsave(&(vtable)->lock, (flags)); } while(0) - -#define VarpTable_read_unlock(vtable, flags) \ - do{ read_unlock_irqrestore(&(vtable)->lock, (flags)); } while(0) - -#define VarpTable_write_lock(vtable, flags) \ - do{ write_lock_irqsave(&(vtable)->lock, (flags)); } while(0) - -#define VarpTable_write_unlock(vtable, flags) \ - do{ write_unlock_irqrestore(&(vtable)->lock, (flags)); } while(0) - -#define VarpEntry_lock(ventry, flags) \ - do{ write_lock_irqsave(&(ventry)->lock, (flags)); (ventry)->lflags = (flags); } while(0) - -#define VarpEntry_unlock(ventry, flags) \ - do{ (flags) = (ventry)->lflags; write_unlock_irqrestore(&(ventry)->lock, (flags)); } while(0) - -void VarpTable_sweep(VarpTable *vtable); -void VarpTable_flush(VarpTable *vtable); -void VarpTable_print(VarpTable *vtable, IOStream *io); -int VarpEntry_output(VarpEntry *ventry, struct sk_buff *skb); - -#include "./varp_util.c" - -/** Print the varp cache (if debug on). - */ -void varp_dprint(void){ -#ifdef DEBUG - VarpTable_print(varp_table, iostdout); -#endif -} - -/** Flush the varp cache. - */ -void varp_flush(void){ - VarpTable_flush(varp_table); -} - -#ifdef __KERNEL__ -static int device_ucast_addr(const char *device, uint32_t *addr) -{ - int err; - struct net_device *dev = NULL; - - err = vnet_get_device(device, &dev); - if(err) goto exit; - err = vnet_get_device_address(dev, addr); - exit: - if(err){ - *addr = 0; - } - return err; -} - -/** Get the unicast address of the varp device. - */ -int varp_ucast_addr(uint32_t *addr) -{ - int err = -ENODEV; - const char *devices[] = { varp_device, "eth0", "eth1", "eth2", NULL }; - const char **p; - for(p = devices; err && *p; p++){ - err = device_ucast_addr(*p, addr); - } - return err; -} - -/** Lookup a network device by name. - * - * @param name device name - * @param dev return parameter for the device - * @return 0 on success, error code otherwise - */ -int vnet_get_device(const char *name, struct net_device **dev){ - int err = 0; - *dev = dev_get_by_name(name); - if(!*dev){ - err = -ENETDOWN; - } - return err; -} - -/** Get the source address from a device. - * - * @param dev device - * @param addr return parameter for address - * @return 0 on success, error code otherwise - */ -int vnet_get_device_address(struct net_device *dev, u32 *addr){ - int err = 0; - struct in_device *in_dev; - - in_dev = in_dev_get(dev); - if(!in_dev){ - err = -ENODEV; - goto exit; - } - *addr = in_dev->ifa_list->ifa_address; - in_dev_put(in_dev); - exit: - return err; -} - -#else - -int varp_ucast_addr(uint32_t *addr) -{ - return 0; -} - -#endif - -/** Print varp info and the varp cache. - */ -void varp_print(IOStream *io){ - uint32_t addr = 0; - varp_ucast_addr(&addr); - - IOStream_print(io, "(varp \n"); - IOStream_print(io, " (device %s)\n", varp_device); - IOStream_print(io, " (mcast_addr " IPFMT ")\n", NIPQUAD(varp_mcast_addr)); - IOStream_print(io, " (ucast_addr " IPFMT ")\n", NIPQUAD(addr)); - IOStream_print(io, " (port %d)\n", ntohs(varp_port)); - IOStream_print(io, " (encapsulation %s)\n", - (etherip_in_udp ? "etherip_in_udp" : "etherip")); - IOStream_print(io, " (entry_ttl %lu)\n", varp_table->entry_ttl); - IOStream_print(io, ")\n"); - VarpTable_print(varp_table, io); -} - -#ifdef __KERNEL__ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) - -static inline int addr_route(u32 daddr, struct rtable **prt){ - int err = 0; - struct flowi fl = { - .nl_u = { - .ip4_u = { - .daddr = daddr, - } - } - }; - - err = ip_route_output_key(prt, &fl); - return err; -} - -#else - -static inline int addr_route(u32 daddr, struct rtable **prt){ - int err = 0; - struct rt_key key = { .dst = daddr }; - err = ip_route_output_key(prt, &key); - return err; -} - -#endif // LINUX_VERSION_CODE - -#ifndef LL_RESERVED_SPACE -#define HH_DATA_MOD 16 -#define LL_RESERVED_SPACE(dev) \ - ((dev->hard_header_len & ~(HH_DATA_MOD - 1)) + HH_DATA_MOD) - -#endif // LL_RESERVED_SPACE - -#else // __KERNEL__ - -#define ip_eth_mc_map(daddr, dmac) do{ }while(0) - -#endif // __KERNEL__ - -/** Send a varp protocol message. - * - * @param opcode varp opcode (host order) - * @param dev device (may be null) - * @param skb skb being replied to (may be null) - * @param vnet vnet id (in network order) - * @param vmac vmac (in network order) - * @return 0 on success, error code otherwise - */ -int varp_send(u16 opcode, struct net_device *dev, struct sk_buff *skbin, - VnetId *vnet, Vmac *vmac){ - int err = 0; - int link_n = 0; - int ip_n = sizeof(struct iphdr); - int udp_n = sizeof(struct udphdr); - int varp_n = sizeof(VarpHdr); - struct sk_buff *skbout = NULL; - VarpHdr *varph = NULL; - u8 smacbuf[6] = {}, dmacbuf[6] = {}; - u8 *smac = smacbuf, *dmac = dmacbuf; - u32 saddr = 0, daddr = 0; - u16 sport = 0, dport = 0; -#if defined(DEBUG) - char vnetbuf[VNET_ID_BUF]; -#endif - - dprintf("> opcode=%d vnet= %s vmac=" MACFMT "\n", - opcode, VnetId_ntoa(vnet, vnetbuf), MAC6TUPLE(vmac->mac)); - - dport = varp_port; - if(skbin){ - daddr = skbin->nh.iph->saddr; - dmac = eth_hdr(skbin)->h_source; - sport = skbin->h.uh->dest; - } else { - if(MULTICAST(varp_mcast_addr)){ - daddr = varp_mcast_addr; - ip_eth_mc_map(daddr, dmac); - } else { - daddr = INADDR_BROADCAST; - } - sport = varp_port; - } - -#ifdef __KERNEL__ - { - struct in_device *in_dev = NULL; - if(!dev){ - struct rtable *rt = NULL; - err = addr_route(daddr, &rt); - if(err) goto exit; - dev = rt->u.dst.dev; - } - - in_dev = in_dev_get(dev); - if(!in_dev){ - err = -ENODEV; - goto exit; - } - link_n = LL_RESERVED_SPACE(dev); - saddr = in_dev->ifa_list->ifa_address; - smac = dev->dev_addr; - if(daddr == INADDR_BROADCAST){ - daddr = in_dev->ifa_list->ifa_broadcast; - dmac = dev->broadcast; - } - in_dev_put(in_dev); - } -#else - { - extern uint32_t vnetd_addr(void); - saddr = vnetd_addr(); - } -#endif // __KERNEL__ - - dprintf("> dev=%s\n", (dev ? dev->name : "")); - dprintf("> smac=" MACFMT " dmac=" MACFMT "\n", MAC6TUPLE(smac), MAC6TUPLE(dmac)); - dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n", NIPQUAD(saddr), NIPQUAD(daddr)); - dprintf("> sport=%u dport=%u\n", ntohs(sport), ntohs(dport)); - - skbout = alloc_skb(link_n + ip_n + udp_n + varp_n, GFP_ATOMIC); - if (!skbout){ - err = -ENOMEM; - goto exit; - } - skbout->dev = dev; - skb_reserve(skbout, link_n); - skbout->protocol = htons(ETH_P_IP); - -#ifdef __KERNEL__ - // Device header. Pushes device header on front of skb. - if (dev->hard_header){ - err = dev->hard_header(skbout, dev, ETH_P_IP, dmac, smac, skbout->len); - if(err < 0) goto exit; - //skbout->mac.raw = skbout->data; - skb_reset_mac_header(skbout); - } -#else - smac = smac; // Defeat unused variable warning. -#endif // __KERNEL__ - - // IP header. - skbout->nh.raw = skb_put(skbout, ip_n); - skbout->nh.iph->version = 4; - skbout->nh.iph->ihl = ip_n / 4; - skbout->nh.iph->tos = 0; - skbout->nh.iph->tot_len = htons(ip_n + udp_n + varp_n); - skbout->nh.iph->id = 0; - skbout->nh.iph->frag_off = 0; - skbout->nh.iph->ttl = 64; - skbout->nh.iph->protocol = IPPROTO_UDP; - skbout->nh.iph->saddr = saddr; - skbout->nh.iph->daddr = daddr; - skbout->nh.iph->check = 0; - - // UDP header. - skbout->h.raw = skb_put(skbout, udp_n); - skbout->h.uh->source = sport; - skbout->h.uh->dest = dport; - skbout->h.uh->len = htons(udp_n + varp_n); - skbout->h.uh->check = 0; - - // Varp header. - varph = (void*)skb_put(skbout, varp_n); - *varph = (VarpHdr){}; - varph->hdr.id = htons(VARP_ID); - varph->hdr.opcode = htons(opcode); - varph->vnet = *vnet; - varph->vmac = *vmac; - varph->addr.family = AF_INET; - varph->addr.u.ip4.s_addr = saddr; - - err = skb_xmit(skbout); - - exit: - if(err && skbout) kfree_skb(skbout); - dprintf("< err=%d\n", err); - return err; -} - - -/** Send a varp request for the vnet and destination mac of a packet. - * Assumes the ventry is locked. - * - * @param skb packet - * @param vnet vnet (in network order) - * @return 0 on success, error code otherwise - */ -int varp_solicit(VnetId *vnet, Vmac *vmac){ - return varp_send(VARP_OP_REQUEST, NULL, NULL, vnet, vmac); -} - -/* Test some flags. - * - * @param ventry varp entry - * @param flags to test - * @return nonzero if flags set - */ -int VarpEntry_get_flags(VarpEntry *ventry, int flags){ - return ventry->flags & flags; -} - -/** Set some flags. - * - * @param ventry varp entry - * @param flags to set - * @param set set flags on if nonzero, off if zero - * @return new flags value - */ -int VarpEntry_set_flags(VarpEntry *ventry, int flags, int set){ - if(set){ - ventry->flags |= flags; - } else { - ventry->flags &= ~flags; - } - return ventry->flags; -} - -/** Print a varp entry. - * - * @param ventry varp entry - */ -void VarpEntry_print(VarpEntry *ventry, IOStream *io){ - IOStream_print(io, "(ventry \n"); - if(ventry){ - unsigned long now = jiffies; - char *state, *flags; - char vnetbuf[VNET_ID_BUF]; - char addrbuf[VARP_ADDR_BUF]; - - switch(ventry->state){ - case VARP_STATE_INCOMPLETE: state = "incomplete"; break; - case VARP_STATE_REACHABLE: state = "reachable"; break; - case VARP_STATE_FAILED: state = "failed"; break; - default: state = "unknown"; break; - } - flags = (VarpEntry_get_flags(ventry, VARP_FLAG_PROBING) ? "P" : "-"); - - IOStream_print(io, " (ref %d)\n", atomic_read(&ventry->refcount)); - IOStream_print(io, " (state %s)\n", state); - IOStream_print(io, " (flags %s)\n", flags); - IOStream_print(io, " (addr %s)\n", VarpAddr_ntoa(&ventry->addr, addrbuf)); - IOStream_print(io, " (queue %d)\n", skb_queue_len(&ventry->queue)); - IOStream_print(io, " (age %lu)\n", now - ventry->timestamp); - IOStream_print(io, " (vmac " MACFMT ")\n", MAC6TUPLE(ventry->key.vmac.mac)); - IOStream_print(io, " (vnet %s)\n", VnetId_ntoa(&ventry->key.vnet, vnetbuf)); - } - IOStream_print(io, ")\n"); -} - -/** Free a varp entry. - * - * @param ventry varp entry - */ -static void VarpEntry_free(VarpEntry *ventry){ - if(!ventry) return; - deallocate(ventry); -} - -/** Increment reference count. - * - * @param ventry varp entry (may be null) - */ -void VarpEntry_incref(VarpEntry *ventry){ - if(!ventry) return; - atomic_inc(&ventry->refcount); -} - -/** Decrement reference count, freeing if zero. - * - * @param ventry varp entry (may be null) - */ -void VarpEntry_decref(VarpEntry *ventry){ - if(!ventry) return; - if(atomic_dec_and_test(&ventry->refcount)){ - VarpEntry_free(ventry); - } -} - -/** Call the error handler. - * - * @param ventry varp entry - */ -void VarpEntry_error(VarpEntry *ventry){ - struct sk_buff *skb; - skb = skb_peek(&ventry->queue); - if(!skb) return; - if(ventry->error) ventry->error(ventry, skb); - skb_queue_purge(&ventry->queue); -} - -/** Schedule the varp entry timer. - * Must increment the reference count before doing - * this the first time, so the ventry won't be freed - * before the timer goes off. - * - * @param ventry varp entry - */ -void VarpEntry_schedule(VarpEntry *ventry){ - timer_set(&ventry->timer, VARP_PROBE_INTERVAL); -} - -/** Function called when a varp entry timer goes off. - * If the entry is still incomplete, carries on probing. - * Otherwise stops probing. - * - * @param arg ventry - */ -static void varp_timer_fn(unsigned long arg){ - unsigned long flags; - VarpEntry *ventry = (VarpEntry *)arg; - struct sk_buff *skb = NULL; - int probing = 0; - - dprintf(">\n"); - VarpEntry_lock(ventry, flags); - if(!atomic_read(&ventry->deleted)){ - switch(ventry->state){ - case VARP_STATE_REACHABLE: - case VARP_STATE_FAILED: - break; - case VARP_STATE_INCOMPLETE: - // Probe if haven't run out of tries, otherwise fail. - if(atomic_read(&ventry->probes) < VARP_PROBE_MAX){ - unsigned long qflags; - VnetId vnet; - Vmac vmac; - - probing = 1; - spin_lock_irqsave(&ventry->queue.lock, qflags); - skb = skb_peek(&ventry->queue); - if(skb){ - vmac = *(Vmac*)eth_hdr(skb)->h_dest; - } - spin_unlock_irqrestore(&ventry->queue.lock, qflags); - if(skb){ - dprintf("> skbs in queue - solicit\n"); - vnet = ventry->key.vnet; - atomic_inc(&ventry->probes); - VarpEntry_unlock(ventry, flags); - varp_solicit(&vnet, &vmac); - VarpEntry_lock(ventry, flags); - } else { - dprintf("> empty queue.\n"); - } - VarpEntry_schedule(ventry); - } else { - VarpEntry_error(ventry); - ventry->state = VARP_STATE_FAILED; - } - break; - } - } - VarpEntry_set_flags(ventry, VARP_FLAG_PROBING, probing); - VarpEntry_unlock(ventry, flags); - if(!probing) VarpEntry_decref(ventry); - dprintf("<\n"); -} - -/** Default error function for varp entries. - * - * @param ventry varp entry - * @param skb packet dropped because of error - */ -static void varp_error_fn(VarpEntry *ventry, struct sk_buff *skb){ -} - -/** Create a varp entry. Initializes the internal state. - * - * @param vnet vnet id - * @param vmac virtual MAC address (copied) - * @return ventry or null - */ -VarpEntry * VarpEntry_new(VnetId *vnet, Vmac *vmac){ - VarpEntry *ventry = ALLOCATE(VarpEntry); - if(ventry){ - unsigned long now = jiffies; - - atomic_set(&ventry->refcount, 1); - atomic_set(&ventry->probes, 0); - atomic_set(&ventry->deleted, 0); - ventry->lock = RW_LOCK_UNLOCKED; - ventry->state = VARP_STATE_INCOMPLETE; - ventry->queue_max = VARP_QUEUE_MAX; - skb_queue_head_init(&ventry->queue); - timer_init(&ventry->timer, varp_timer_fn, ventry); - ventry->timestamp = now; - ventry->error = varp_error_fn; - - ventry->key.vnet = *vnet; - ventry->key.vmac = *vmac; - } - return ventry; -} - -/** Hash function for keys in the varp cache. - * Hashes the vnet id and mac. - * - * @param k key (VarpKey) - * @return hashcode - */ -static Hashcode varp_key_hash_fn(void *k){ - return hash_hvoid(0, k, sizeof(VarpKey)); -} - -/** Test equality for keys in the varp cache. - * Compares vnet and mac. - * - * @param k1 key to compare (VarpKey) - * @param k2 key to compare (VarpKey) - * @return 1 if equal, 0 otherwise - */ -static int varp_key_equal_fn(void *k1, void *k2){ - return memcmp(k1, k2, sizeof(VarpKey)) == 0; -} - -/** Free an entry in the varp cache. - * - * @param table containing table - * @param entry entry to free - */ -static void varp_entry_free_fn(HashTable *table, HTEntry *entry){ - VarpEntry *ventry; - if(!entry) return; - ventry = entry->value; - if(ventry) VarpEntry_decref(ventry); - HTEntry_free(entry); -} - -/** Free the whole varp cache. - * Dangerous. - * - * @param vtable varp cache - */ -void VarpTable_free(VarpTable *vtable){ - unsigned long vtflags; - dprintf(">\n"); - if(!vtable) return; - VarpTable_write_lock(vtable, vtflags); - timer_cancel(&vtable->timer); - vtable->timer.data = 0; - if(vtable->table){ - HashTable *table = vtable->table; - HashTable_for_decl(entry); - - vtable->table = NULL; - HashTable_for_each(entry, table){ - VarpEntry *ventry = entry->value; - unsigned long flags; - VarpEntry_lock(ventry, flags); - atomic_set(&ventry->deleted, 1); - if(VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){ - timer_cancel(&ventry->timer); - ventry->timer.data = 0; - VarpEntry_decref(ventry); - } - VarpEntry_unlock(ventry, flags); - } - HashTable_free(table); - } - VarpTable_write_unlock(vtable, vtflags); - deallocate(vtable); -} - -/** Schedule the varp table timer. - * - * @param vtable varp table - */ -void VarpTable_schedule(VarpTable *vtable){ - timer_set(&vtable->timer, vtable->entry_ttl); -} - -/** Function called when the varp table timer goes off. - * Sweeps old varp cache entries and reschedules itself. - * - * @param arg varp table - */ -static void varp_table_timer_fn(unsigned long arg){ - VarpTable *vtable = (VarpTable *)arg; - if(vtable){ - VarpTable_sweep(vtable); - VarpTable_schedule(vtable); - } -} - -/** Print a varp table. - * - * @param vtable table - */ -void VarpTable_print(VarpTable *vtable, IOStream *io){ - HashTable_for_decl(entry); - VarpEntry *ventry; - unsigned long vtflags, flags; - - VarpTable_read_lock(vtable, vtflags); - HashTable_for_each(entry, vtable->table){ - ventry = entry->value; - VarpEntry_lock(ventry, flags); - VarpEntry_print(ventry, io); - VarpEntry_unlock(ventry, flags); - } - VarpTable_read_unlock(vtable, vtflags); -} - -/** Create a varp table. - * - * @return new table or null - */ -VarpTable * VarpTable_new(void){ - int err = -ENOMEM; - VarpTable *vtable = NULL; - - vtable = ALLOCATE(VarpTable); - if(!vtable) goto exit; - vtable->table = HashTable_new(VARP_TABLE_BUCKETS); - if(!vtable->table) goto exit; - vtable->table->key_size = sizeof(VarpKey); - vtable->table->key_equal_fn = varp_key_equal_fn; - vtable->table->key_hash_fn = varp_key_hash_fn; - vtable->table->entry_free_fn = varp_entry_free_fn; - - vtable->entry_ttl = VARP_ENTRY_TTL; - vtable->probe_max = VARP_PROBE_MAX; - vtable->probe_interval = VARP_PROBE_INTERVAL; - vtable->queue_max = VARP_QUEUE_MAX; - - init_MUTEX(&vtable->mutex); - vtable->lock = RW_LOCK_UNLOCKED; - timer_init(&vtable->timer, varp_table_timer_fn, vtable); - err = 0; - exit: - if(err){ - VarpTable_free(vtable); - vtable = NULL; - } - return vtable; -} - -/** Add a new entry to the varp table. - * - * @param vtable table - * @param vnet vnet id - * @param vmac virtual MAC address (copied) - * @return new entry or null - */ -VarpEntry * VarpTable_add(VarpTable *vtable, VnetId *vnet, Vmac *vmac){ - int err = 0; - VarpKey key = { .vnet = *vnet, .vmac = *vmac}; - VarpEntry *ventry = NULL; - HTEntry *entry = NULL; - unsigned long vtflags; - - VarpTable_write_lock(vtable, vtflags); - ventry = HashTable_get(vtable->table, &key); - if(ventry){ - VarpEntry_incref(ventry); - goto exit; - } - err = -ENOMEM; - ventry = VarpEntry_new(vnet, vmac); - if(!ventry) goto exit; - entry = HashTable_add(vtable->table, ventry, ventry); - if(!entry){ - VarpEntry_decref(ventry); - ventry = NULL; - goto exit; - } - err = 0; - VarpEntry_incref(ventry); - exit: - VarpTable_write_unlock(vtable, vtflags); - return ventry; -} - -/** Remove an entry from the varp table. - * - * @param vtable table - * @param ventry entry to remove - * @return removed count - */ -int VarpTable_remove(VarpTable *vtable, VarpEntry *ventry){ - //TODO: Could send a varp announce with null addr for the entry - // vnet and vmac to notify others, so they will resolve the addr - // instead of sending traffic to us. - atomic_set(&ventry->deleted, 1); - skb_queue_purge(&ventry->queue); - return HashTable_remove(vtable->table, ventry); -} - -/** Remove all entries using a vnet. - * Caller must hold the table lock. - * - * @param vtable table - * @param vnet vnet - * @return removed count - */ -int VarpTable_remove_vnet(VarpTable *vtable, VnetId *vnet){ - int count = 0; - HashTable_for_decl(entry); - - HashTable_for_each(entry, vtable->table){ - VarpEntry *ventry = entry->value; - if(VnetId_eq(&ventry->key.vnet, vnet)){ - count += VarpTable_remove(vtable, ventry); - } - } - return count; -} - -/** Remove all entries using a vnet from the varp table. - * - * @param vnet vnet - * @return removed count - */ -int varp_remove_vnet(VnetId *vnet){ - int count = 0; - unsigned long vtflags; - - VarpTable_write_lock(varp_table, vtflags); - count = VarpTable_remove_vnet(varp_table, vnet); - VarpTable_write_unlock(varp_table, vtflags); - return count; -} - -/** Lookup an entry in the varp table. - * - * @param vtable table - * @param vnet vnet id - * @param vmac virtual MAC address - * @param create create a new entry if needed if true - * @return entry found or null - */ -VarpEntry * VarpTable_lookup(VarpTable *vtable, VnetId *vnet, Vmac *vmac, int create){ - VarpKey key = { .vnet = *vnet, .vmac = *vmac }; - VarpEntry *ventry = NULL; - unsigned long vtflags; - - VarpTable_read_lock(vtable, vtflags); - ventry = HashTable_get(vtable->table, &key); - if(ventry) VarpEntry_incref(ventry); - VarpTable_read_unlock(vtable, vtflags); - - if(!ventry && create){ - ventry = VarpTable_add(vtable, vnet, vmac); - } - return ventry; -} - -/** Handle output for a reachable ventry. - * Send the skb using the tunnel to the care-of address. - * Assumes the ventry lock is held. - * - * @param ventry varp entry - * @param skb skb to send - * @return 0 on success, error code otherwise - */ -int VarpEntry_send(VarpEntry *ventry, struct sk_buff *skb){ - int err = 0; - unsigned long flags = 0; - VarpAddr addr; - VnetId vnet; - - dprintf("> skb=%p\n", skb); - vnet = ventry->key.vnet; - addr = ventry->addr; - VarpEntry_unlock(ventry, flags); - err = vnet_tunnel_send(&vnet, &addr, skb); - VarpEntry_lock(ventry, flags); - dprintf("< err=%d\n", err); - return err; -} - -/** Handle output for a non-reachable ventry. Send messages to complete it. - * If the entry is still incomplete, queue the skb, otherwise - * send it. If the queue is full, dequeue and free an old skb to - * make room for the new one. - * Assumes the ventry lock is held. - * - * @param ventry varp entry - * @param skb skb to send - * @return 0 on success, error code otherwise - */ -int VarpEntry_resolve(VarpEntry *ventry, struct sk_buff *skb){ - int err = 0; - unsigned long flags = 0; - VnetId vnet; - Vmac vmac; - - dprintf("> skb=%p\n", skb); - ventry->state = VARP_STATE_INCOMPLETE; - atomic_set(&ventry->probes, 1); - if(!VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)){ - VarpEntry_set_flags(ventry, VARP_FLAG_PROBING, 1); - VarpEntry_incref(ventry); - VarpEntry_schedule(ventry); - } - vnet = ventry->key.vnet; - vmac = *(Vmac*)eth_hdr(skb)->h_dest; - VarpEntry_unlock(ventry, flags); - varp_solicit(&vnet, &vmac); - VarpEntry_lock(ventry, flags); - - if(ventry->state == VARP_STATE_INCOMPLETE){ - while(skb_queue_len(&ventry->queue) >= ventry->queue_max){ - struct sk_buff *oldskb; - oldskb = skb_dequeue(&ventry->queue); - //oldskb = ventry->queue.next; - //__skb_unlink(oldskb, &ventry->queue); - if(!oldskb) break; - dprintf("> dropping skb=%p\n", oldskb); - kfree_skb(oldskb); - } - skb_queue_tail(&ventry->queue, skb); - } else { - err = VarpEntry_send(ventry, skb); - } - dprintf("< err=%d\n", err); - return err; -} - -/** Process the output queue for a ventry. Sends the queued skbs if - * the ventry is reachable, otherwise drops them. - * - * @param ventry varp entry - */ -void VarpEntry_process_queue(VarpEntry *ventry){ - struct sk_buff *skb; - for( ; ; ){ - if(ventry->state != VARP_STATE_REACHABLE) break; - skb = skb_dequeue(&ventry->queue); - if(!skb) break; - VarpEntry_send(ventry, skb); - } - skb_queue_purge(&ventry->queue); -} - -/** Multicast an skb on a vnet. - * - * @param vnet vnet id - * @param skb skb to send - * @return 0 on success, error code otherwise - */ -static int varp_multicast(VnetId *vnet, struct sk_buff *skb){ - VarpAddr addr = { .family = AF_INET }; - addr.u.ip4.s_addr = varp_mcast_addr; - return vnet_tunnel_send(vnet, &addr, skb); -} - -/** Handle output for a ventry. Resolves the ventry - * if necessary. - * - * @param ventry varp entry - * @param skb skb to send - * @return 0 on success, error code otherwise - */ -int VarpEntry_output(VarpEntry *ventry, struct sk_buff *skb){ - int err = 0; - unsigned long flags; - - VarpEntry_lock(ventry, flags); - switch(ventry->state){ - case VARP_STATE_REACHABLE: - if(skb_queue_len(&ventry->queue) > 0){ - VarpEntry_process_queue(ventry); - } - err = VarpEntry_send(ventry, skb); - break; - default: - if(0){ - err = VarpEntry_resolve(ventry, skb); - } else { - // Multicast the skb if the entry is not reachable. - VnetId vnet = ventry->key.vnet; - VarpEntry_unlock(ventry, flags); - err = varp_multicast(&vnet, skb); - VarpEntry_lock(ventry, flags); - } - break; - } - VarpEntry_unlock(ventry, flags); - return err; -} - -/** Update a ventry. Sets the address and state to those given - * and sets the timestamp to 'now'. - * - * @param ventry varp entry - * @param addr care-of address - * @param state state - * @return 0 on success, error code otherwise - */ -int VarpEntry_update(VarpEntry *ventry, VarpAddr *addr, int state, int vflags){ - int err = 0; - unsigned long now = jiffies; - unsigned long flags; - - VarpEntry_lock(ventry, flags); - //if(atomic_read(&ventry->deleted)) goto exit; - if(VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT)) goto exit; - ventry->addr = *addr; - ventry->timestamp = now; - ventry->state = state; - // Can't process the queue while atomic as it calls schedule(), - // and that's bad. - //if(0 && (vflags & VARP_UPDATE_QUEUE) && !in_atomic()){ - // VarpEntry_process_queue(ventry); - //} - exit: - VarpEntry_unlock(ventry, flags); - dprintf("< err=%d\n", err); - return err; -} - -/** Update the entry for a vnet. - * - * @param vtable varp table - * @param vnet vnet id - * @param vmac mac address - * @param addr care-of-address - * @param state state - * @param flags update flags - * @return 0 on success, error code otherwise - */ -int VarpTable_update(VarpTable *vtable, VnetId *vnet, Vmac *vmac, VarpAddr *addr, - int state, int flags){ - int err = 0; - VarpEntry *ventry; -#ifdef DEBUG - char vnetbuf[VNET_ID_BUF]; - char addrbuf[VARP_ADDR_BUF]; - - dprintf("> vnet=%s mac=" MACFMT " addr=%s state=%d flags=%x\n", - VnetId_ntoa(vnet, vnetbuf), - MAC6TUPLE(vmac->mac), - VarpAddr_ntoa(addr, addrbuf), - state, - flags); -#endif - ventry = VarpTable_lookup(vtable, vnet, vmac, (flags & VARP_UPDATE_CREATE)); - if(!ventry){ - err = -ENOENT; - goto exit; - } - err = VarpEntry_update(ventry, addr, state, flags); - VarpEntry_decref(ventry); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Update the entry for a vnet: make it reachable and create an entry - * if needed. - * - * @param vnet vnet id - * @param vmac mac address - * @param addr care-of-address - * @return 0 on success, error code otherwise - */ -int varp_update(VnetId *vnet, unsigned char *vmac, VarpAddr *addr){ - int err = 0; - if(!varp_table){ - err = -ENOSYS; - } else { - err = VarpTable_update(varp_table, vnet, (Vmac*)vmac, addr, - VARP_STATE_REACHABLE, VARP_UPDATE_CREATE); - } - return err; -} - -static inline int VarpEntry_sweepable(VarpEntry *ventry){ - return !VarpEntry_get_flags(ventry, (VARP_FLAG_PERMANENT | VARP_FLAG_PROBING)); -} - -static inline int VarpTable_old(VarpTable *vtable, VarpEntry *ventry, unsigned long now){ - return now - ventry->timestamp > vtable->entry_ttl; -} - -/** Sweep old varp entries. - * Doesn't affect entries that are probing or permanent. - * - * @param vtable table - */ -void VarpTable_sweep(VarpTable *vtable){ - HashTable_for_decl(entry); - VarpEntry *ventry; - unsigned long now = jiffies; - unsigned long vtflags, flags; - int sweep, swept = 0; - - if(!vtable) return; - VarpTable_write_lock(vtable, vtflags); - HashTable_for_each(entry, vtable->table){ - ventry = entry->value; - VarpEntry_lock(ventry, flags); - sweep = VarpEntry_sweepable(ventry) && VarpTable_old(vtable, ventry, now); - if(sweep){ - swept++; - //iprintf("> Sweeping:\n"); - //VarpEntry_print(ventry, iostdout); - //VarpEntry_process_queue(ventry); - ventry->state = VARP_STATE_INCOMPLETE; - } - VarpEntry_unlock(ventry, flags); - if(sweep){ - VarpTable_remove(vtable, ventry); - } - } - VarpTable_write_unlock(vtable, vtflags); - if(swept){ - iprintf(">\n"); - varp_print(iostdout); - } -} - -/** Flush the varp table. - * - * @param vtable table - */ -void VarpTable_flush(VarpTable *vtable){ - HashTable_for_decl(entry); - VarpEntry *ventry; - unsigned long vtflags, flags; - int flush; - - VarpTable_write_lock(vtable, vtflags); - HashTable_for_each(entry, vtable->table){ - ventry = entry->value; - VarpEntry_lock(ventry, flags); - flush = (!VarpEntry_get_flags(ventry, VARP_FLAG_PERMANENT) && - !VarpEntry_get_flags(ventry, VARP_FLAG_PROBING)); - if(flush){ - iprintf("> Flushing:\n"); - VarpEntry_print(ventry, iostdout); - } - VarpEntry_unlock(ventry, flags); - if(flush){ - VarpTable_remove(vtable, ventry); - } - } - VarpTable_write_unlock(vtable, vtflags); -} - -/** Handle a varp request. Look for a vif with the requested - * vnet and vmac. If find one, reply with the vnet, vmac and our - * address. Otherwise do nothing. - * - * @param skb incoming message - * @param varph varp message - * @return 0 if ok, -ENOENT if no matching vif, or error code - */ -int varp_handle_request(struct sk_buff *skb, VarpHdr *varph){ - int err = -ENOENT; - VnetId *vnet; - Vmac *vmac; - Vif *vif = NULL; - - dprintf(">\n"); - vnet = &varph->vnet; - vmac = &varph->vmac; - if(vif_lookup(vnet, vmac, &vif)) goto exit; - varp_send(VARP_OP_ANNOUNCE, skb->dev, skb, vnet, vmac); - vif_decref(vif); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Announce the vnet and vmac of a vif (gratuitous varp). - * - * @param dev device to send on (may be null) - * @param vif vif - * @return 0 on success, error code otherwise - */ -int varp_announce_vif(struct net_device *dev, Vif *vif){ - int err = 0; - dprintf(">\n"); - if(!varp_table){ - err = -ENOSYS; - goto exit; - } - err = varp_send(VARP_OP_ANNOUNCE, dev, NULL, &vif->vnet, &vif->vmac); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Handle a varp announce message. - * Update the matching ventry if we have one. - * - * @param skb incoming message - * @param varp message - * @return 0 if OK, -ENOENT if no matching entry - */ -int varp_handle_announce(struct sk_buff *skb, VarpHdr *varph){ - int err = 0; - - dprintf(">\n"); - err = VarpTable_update(varp_table, - &varph->vnet, &varph->vmac, &varph->addr, - VARP_STATE_REACHABLE, - (VARP_UPDATE_CREATE | VARP_UPDATE_QUEUE)); - dprintf("< err=%d\n", err); - return err; -} - -/** Handle an incoming varp message. - * - * @param skb incoming message - * @return 0 if OK, error code otherwise - */ -int varp_handle_message(struct sk_buff *skb){ - // Assume nh, h set, skb->data points at udp hdr (h). - int err = -EINVAL; - VarpHdr *varph; // = (void*)(skb->h.uh + 1); - - dprintf("> skb=%p saddr=" IPFMT " daddr=" IPFMT " head=%p tail=%p data=%p len=%d data_len=%d users=%d\n", - skb, - NIPQUAD(skb->nh.iph->saddr), - NIPQUAD(skb->nh.iph->daddr), - skb->head, skb->tail, skb->data,skb->len, skb->data_len, - atomic_read(&skb->users)); - - if(!varp_table){ - err = -ENOSYS; - return err; - } -#ifdef __KERNEL__ - if (skb_is_nonlinear(skb) && skb_linearize(skb) != 0) { - err = -ENOMEM; - goto exit; - } -#endif - if(MULTICAST(skb->nh.iph->daddr)){ - if(skb->nh.iph->daddr != varp_mcast_addr){ - // Ignore multicast packets not addressed to us. - err = 0; - dprintf("> Ignoring daddr=" IPFMT " mcaddr=" IPFMT "\n", - NIPQUAD(skb->nh.iph->daddr), NIPQUAD(varp_mcast_addr)); - goto exit; - } - } -#ifdef __KERNEL__ - varph = (void*) __pskb_pull(skb, sizeof(struct udphdr)); -#else - varph = (void*)skb_pull_vn(skb, sizeof(struct udphdr)); -#endif - - - if(skb->len < sizeof(struct VnetMsgHdr)){ - wprintf("> Varp msg too short: %d < %ld\n", skb->len, sizeof(struct VnetMsgHdr)); - goto exit; - } - - if (! varph || ! skb->data) { - err = -EINVAL; - goto exit; - } - - switch(ntohs(varph->hdr.id)){ - case VARP_ID: // Varp message. Handled below. - if(skb->len < sizeof(*varph)){ - wprintf("> Varp msg too short: %d < %ld\n", skb->len, sizeof(*varph)); - goto exit; - } - break; - case VUDP_ID: // Etherip-in-udp packet. - skb_pull_vn(skb, sizeof(struct VnetMsgHdr)); - err = etherip_protocol_recv(skb); - goto exit; - case VFWD_ID: // Forwarded. - skb_pull_vn(skb, sizeof(struct VnetMsgHdr)); - err = vnet_forward_recv(skb); - goto exit; - default: - // It's not varp at all - ignore it. - wprintf("> Invalid varp id: %d\n", ntohs(varph->hdr.id)); - print_skb("INVALID", 0, skb); - goto exit; - } -#ifdef DEBUG - { - char vnetbuf[VNET_ID_BUF]; - char addrbuf[VARP_ADDR_BUF]; - dprintf("> saddr=" IPFMT " daddr=" IPFMT "\n", - NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr)); - dprintf("> sport=%u dport=%u\n", ntohs(skb->h.uh->source), ntohs(skb->h.uh->dest)); - dprintf("> opcode=%d vnet=%s vmac=" MACFMT " addr=%s\n", - ntohs(varph->hdr.opcode), - VnetId_ntoa(&varph->vnet, vnetbuf), - MAC6TUPLE(varph->vmac.mac), - VarpAddr_ntoa(&varph->addr, addrbuf)); - varp_dprint(); - } -#endif - switch(ntohs(varph->hdr.opcode)){ - case VARP_OP_REQUEST: - err = varp_handle_request(skb, varph); - break; - case VARP_OP_ANNOUNCE: - err = varp_handle_announce(skb, varph); - break; - default: - wprintf("> Unknown opcode: %d \n", ntohs(varph->hdr.opcode)); - break; - } - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Send an outgoing packet on the appropriate vnet tunnel. - * - * @param skb outgoing message - * @param vnet vnet (network order) - * @return 0 on success, error code otherwise - */ -int varp_output(struct sk_buff *skb, VnetId *vnet){ - int err = 0; - unsigned char *mac = NULL; - Vmac *vmac = NULL; - VarpEntry *ventry = NULL; -#if defined(DEBUG) - char vnetbuf[VNET_ID_BUF]; -#endif - - dprintf("> vnet=%s\n", VnetId_ntoa(vnet, vnetbuf)); - if(!varp_table){ - err = -ENOSYS; - goto exit; - } - if(!skb->mac.raw){ - wprintf("> No ethhdr in skb!\n"); - err = -EINVAL; - goto exit; - } - mac = eth_hdr(skb)->h_dest; - vmac = (Vmac*)mac; - if(mac_is_multicast(mac)){ - err = varp_multicast(vnet, skb); - } else { - ventry = VarpTable_lookup(varp_table, vnet, vmac, 1); - if(ventry){ - err = VarpEntry_output(ventry, skb); - VarpEntry_decref(ventry); - } else { - err = -ENOMEM; - } - } - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Set the varp multicast address (after initialization). - * - * @param addr address (network order) - * @return 0 on success, error code otherwise - */ -int varp_set_mcast_addr(uint32_t addr){ - int err = 0; - varp_close(); - varp_mcast_addr = addr; - err = varp_open(varp_mcast_addr, varp_port); - return err; -} - -/** Initialize the varp multicast address from a module parameter. - * - * @param s address in IPv4 notation - * @return 0 on success, error code otherwise - */ -static void varp_init_mcast_addr(char *s){ - unsigned long v = 0; - - dprintf("> %s\n", s); - if(s && (get_inet_addr(s, &v) >= 0)){ - varp_mcast_addr = (u32)v; - } else { - varp_mcast_addr = htonl(VARP_MCAST_ADDR); - } -} - -/** Initialize the varp cache. - * - * @return 0 on success, error code otherwise - */ -int varp_init(void){ - int err = 0; - - dprintf(">\n"); - varp_table = VarpTable_new(); - if(!varp_table){ - err = -ENOMEM; - goto exit; - } - VarpTable_schedule(varp_table); - varp_init_mcast_addr(varp_mcaddr); - varp_port = htons(VARP_PORT); - - err = varp_open(varp_mcast_addr, varp_port); - exit: - dprintf("< err=%d\n", err); - return err; -} - -/** Close the varp cache. - */ -void varp_exit(void){ - dprintf(">\n"); - varp_close(); - if(varp_table){ - VarpTable *vtable = varp_table; - varp_table = NULL; - VarpTable_free(vtable); - } - dprintf("<\n"); -} - -module_param(varp_mcaddr, charp, 0644); -module_param(varp_device, charp, 0644); -MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address"); -MODULE_PARM_DESC(varp_device, "VARP network device"); diff --git a/vnet/src/vnet-module/varp.h b/vnet/src/vnet-module/varp.h deleted file mode 100644 index 0223fb7df73..00000000000 --- a/vnet/src/vnet-module/varp.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef _VNET_VARP_H -#define _VNET_VARP_H - -#ifdef __KERNEL__ - -#else - -#include "sys_kernel.h" - -#endif - -#include "hash_table.h" -#include "if_varp.h" -#include "varp_util.h" - -#define CONFIG_VARP_GRATUITOUS 1 - -struct net_device; -struct sk_buff; -struct Vif; - -enum { - VARP_UPDATE_CREATE = 1, - VARP_UPDATE_QUEUE = 2, -}; - -extern int vnet_get_device(const char *name, struct net_device **dev); -extern int vnet_get_device_address(struct net_device *dev, u32 *addr); - -extern int varp_remove_vnet(struct VnetId *vnet); -extern int varp_handle_message(struct sk_buff *skb); -extern int varp_output(struct sk_buff *skb, struct VnetId *vnet); -extern int varp_update(struct VnetId *vnet, unsigned char *vmac, - struct VarpAddr *addr); - -extern int varp_init(void); -extern void varp_exit(void); - -extern int varp_open(u32 mcaddr, u16 port); -extern void varp_close(void); -extern int varp_set_mcast_addr(u32 addr); - -extern void varp_print(struct IOStream *io); -extern void varp_flush(void); - -extern int varp_announce_vif(struct net_device *dev, struct Vif *vif); - -extern u32 varp_mcast_addr; -extern u16 varp_port; - -/* MAC broadcast addr is ff-ff-ff-ff-ff-ff (all 1's). - * MAC multicast addr has low bit 1, i.e. 01-00-00-00-00-00. - */ - -/** Test if a MAC address is a multicast or broadcast address. - * - * @param mac address - * @return 1 if it is, 0 if not - */ -static inline int mac_is_multicast(u8 mac[ETH_ALEN]){ - return mac[0] & 1; -} - -/** Test if a MAC address is the broadcast address. - * - * @param mac address - * @return 1 if it is, 0 if not - */ -static inline int mac_is_broadcast(u8 mac[ETH_ALEN]){ - u8 mac_bcast_val[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - return memcmp(mac, mac_bcast_val, ETH_ALEN) == 0; -} - -/** Test if a MAC address is the all-zero address. - * - * @param mac address - * @return 1 if it is, 0 if not - */ -static inline int mac_is_zero(u8 mac[ETH_ALEN]){ - u8 mac_zero_val[ETH_ALEN] = {}; - return memcmp(mac, mac_zero_val, ETH_ALEN) == 0; -} - -/** Print format for a mac address. */ -#define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" - -#define MAC6TUPLE(_mac) (_mac)[0], (_mac)[1], (_mac)[2], (_mac)[3], (_mac)[4], (_mac)[5] - -/** Get the subnet defined by a netmask and addr. - * - * @param netmask subnet netmask - * @param addr subnet address - * @return subnet - */ -static inline u32 subnet_net(u32 netmask, u32 addr){ - return netmask & addr; -} - -/** Get the address within a subnet. - * - * @param netmask subnet netmask - * @param addr address - * @return address within the subnet - */ -static inline u32 subnet_addr(u32 netmask, u32 addr){ - return ~netmask & addr; -} - -/** Get the broadcast address for a subnet. - * - * @param netmask subnet netmask - * @param netaddr subnet address - * @return subnet broadcast address - */ -static inline u32 subnet_broadcast_addr(u32 netmask, u32 netaddr){ - return subnet_net(netmask, netaddr) | ~netmask; -} - -/** Test if an address corresponds to a subnet broadcast. - * True if the address within the subnet is all 1's (in binary). - * (even if the address is not in the subnet). - * - * @param netmask subnet mask - * @param add address - * @return 1 if it does, 0 otherwise - */ -static inline int subnet_broadcast(u32 netmask, u32 addr){ - return subnet_addr(netmask, INADDR_ANY) == subnet_addr(netmask, addr); -} - -/** Test if an address is in a subnet. - * - * @param netmask subnet mask - * @param netaddr subnet address - * @param addr address - * @return 1 if it is, 0 otherwise - */ -static inline int subnet_local(u32 netmask, u32 netaddr, u32 addr){ - return subnet_net(netmask, netaddr) == subnet_net(netmask, addr); -} - -#endif /* ! _VNET_VARP_H */ diff --git a/vnet/src/vnet-module/varp_socket.c b/vnet/src/vnet-module/varp_socket.c deleted file mode 100644 index 144c12b397a..00000000000 --- a/vnet/src/vnet-module/varp_socket.c +++ /dev/null @@ -1,901 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Get macros needed to define system calls as functions in the kernel. */ -#define __KERNEL_SYSCALLS__ -int errno=0; -#define _GNU_SOURCE - -#include -#include - -#define MODULE_NAME "VARP" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file - * Support for the VARP udp sockets. - */ - -extern int syscall(int number, ...); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - -/* Compensate for struct sock fields having 'sk_' added to them in 2.6. */ -#define sk_receive_queue receive_queue -#define sk_sleep sleep - -/* Here because inline in 'socket.c' (2.4, in net.h for 2.6). */ -#define sockfd_put(sock) fput((sock)->file) - -#endif - -static inline mm_segment_t change_fs(mm_segment_t fs){ - mm_segment_t oldfs = get_fs(); - set_fs(fs); - return oldfs; -} - -/** Define the fcntl() syscall. */ -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) ) -static inline _syscall3(int, fcntl, - unsigned int, fd, - unsigned int, cmd, - unsigned long, arg) -#endif -/* Replicate the user-space socket API. - * The parts we need anyway. - * - * Some architectures use socketcall() to multiplex the socket-related calls, - * but others define individual syscalls instead. - * Architectures using socketcall() define __ARCH_WANT_SYS_SOCKETCALL. - * NB. x86_64 architecture asserts __ARCH_WANT_SYS_SOCKETCALL in error. - */ - -#if defined(__ARCH_WANT_SYS_SOCKETCALL) && !defined(__x86_64__) - -/* Define the socketcall() syscall. - * Multiplexes all the socket-related calls. - * - * @param call socket call id - * @param args arguments (upto 6) - * @return call-dependent value - */ -static inline _syscall2(int, socketcall, - int, call, - unsigned long *, args) - -int socket(int family, int type, int protocol){ - unsigned long args[6]; - - args[0] = (unsigned long)family; - args[1] = (unsigned long)type; - args[2] = (unsigned long)protocol; - return socketcall(SYS_SOCKET, args); -} - -int bind(int fd, struct sockaddr *umyaddr, int addrlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)umyaddr; - args[2] = (unsigned long)addrlen; - return socketcall(SYS_BIND, args); -} - -int connect(int fd, struct sockaddr *uservaddr, int addrlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)uservaddr; - args[2] = (unsigned long)addrlen; - return socketcall(SYS_CONNECT, args); -} - -int sendto(int fd, void * buff, size_t len, - unsigned flags, struct sockaddr *addr, - int addr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)buff; - args[2] = (unsigned long)len; - args[3] = (unsigned long)flags; - args[4] = (unsigned long)addr; - args[5] = (unsigned long)addr_len; - return socketcall(SYS_SENDTO, args); -} - -int recvfrom(int fd, void * ubuf, size_t size, - unsigned flags, struct sockaddr *addr, - int *addr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)ubuf; - args[2] = (unsigned long)size; - args[3] = (unsigned long)flags; - args[4] = (unsigned long)addr; - args[5] = (unsigned long)addr_len; - return socketcall(SYS_RECVFROM, args); -} - -int setsockopt(int fd, int level, int optname, void *optval, int optlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)level; - args[2] = (unsigned long)optname; - args[3] = (unsigned long)optval; - args[4] = (unsigned long)optlen; - return socketcall(SYS_SETSOCKOPT, args); -} - -int getsockopt(int fd, int level, int optname, void *optval, int *optlen){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)level; - args[2] = (unsigned long)optname; - args[3] = (unsigned long)optval; - args[4] = (unsigned long)optlen; - return socketcall(SYS_GETSOCKOPT, args); -} - -int shutdown(int fd, int how){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)how; - return socketcall(SYS_SHUTDOWN, args); -} - -int getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len){ - unsigned long args[6]; - - args[0] = (unsigned long)fd; - args[1] = (unsigned long)usockaddr; - args[2] = (unsigned long)usockaddr_len; - return socketcall(SYS_GETSOCKNAME, args); -} - -#elif defined(__x86_64__) - - -int socket(int family, int type, int protocol){ - struct socket* sock; - int err; - int err2; - - err = sock_create_kern(family, type, protocol, &sock); - if (err < 0) goto exit; - dprintf("sock_create err=%d\n",err); - err = sock_map_fd(sock); - if ((sock = sockfd_lookup(err, &err2 )) == NULL) - dprintf("sock_create lookup err\n"); - -exit: - return err; -} - -int bind(int fd, struct sockaddr *address, int addrlen){ - struct socket *sock; - int err; - - if((sock = sockfd_lookup(fd, &err))!=NULL) - { - err = sock->ops->bind (sock, (struct sockaddr *)address,addrlen); - } - - return err; -} - -int connect(int fd, struct sockaddr *address, int addrlen){ - struct socket *sock; - int err; - - sock = sockfd_lookup(fd, &err); - if (!sock) - goto out; - - err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, - sock->file->f_flags); -out: - return err; - -} - - -int setsockopt(int fd, int level, int optname, void *optval, int optlen){ - int err; - struct socket *sock; - - if (optlen < 0) - return -EINVAL; - - if ((sock = sockfd_lookup(fd, &err)) != NULL) - { - if (level == SOL_SOCKET) - err=sock_setsockopt(sock,level,optname,optval,optlen); - else - err=sock->ops->setsockopt(sock, level, optname, optval, optlen); - } - return err; - -} - - -int shutdown(int fd, int how){ - int err; -#if 1 - struct socket *sock; - //for multicast sockets, shutdown returns ENOTCONN - if ((sock = sockfd_lookup(fd, &err)) !=NULL) - { - err = sock->ops->shutdown(sock, how); - sock_release(sock); - } -#endif - err=sys_close(fd); - return err; - -} - -#if 0 -int sendto(int fd, void * buff, size_t len, - unsigned flags, struct sockaddr *addr, - int addr_len){ - return syscall(__NR_sendto, fd, buff, len, flags, addr, addr_len); -} - -int recvfrom(int fd, void * ubuf, size_t size, - unsigned flags, struct sockaddr *addr, - int *addr_len){ - return syscall(__NR_recvfrom, fd, ubuf, size, flags, addr, addr_len); -} -int getsockopt(int fd, int level, int optname, void *optval, int *optlen){ - return syscall(__NR_getsockopt, fd, level, optname, optval, optlen); -} - -int getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len){ - return syscall(__NR_getsockname, fd, usockaddr, usockaddr_len); -} -#endif - -#else /* !__ARCH_WANT_SYS_SOCKETCALL */ - -/* No socketcall - define the individual syscalls. */ - -static inline _syscall3(int, socket, - int, family, - int, type, - int, protocol); - -static inline _syscall3(int, bind, - int, fd, - struct sockaddr *, umyaddr, - int, addrlen); - -static inline _syscall3(int, connect, - int, fd, - struct sockaddr *, uservaddr, - int, addrlen); - -static inline _syscall6(int, sendto, - int, fd, - void *, buff, - size_t, len, - unsigned, flags, - struct sockaddr *, addr, - int, addr_len); - -static inline _syscall6(int, recvfrom, - int, fd, - void *, ubuf, - size_t, size, - unsigned, flags, - struct sockaddr *, addr, - int *, addr_len); - -static inline _syscall5(int, setsockopt, - int, fd, - int, level, - int, optname, - void *, optval, - int, optlen); - -static inline _syscall5(int, getsockopt, - int, fd, - int, level, - int, optname, - void *, optval, - int *, optlen); - -static inline _syscall2(int, shutdown, - int, fd, - int, how); - -static inline _syscall3(int, getsockname, - int, fd, - struct sockaddr *, usockaddr, - int *, usockaddr_len); - -#endif /* __ARCH_WANT_SYS_SOCKETCALL */ - -/*============================================================================*/ -/** Socket flags. */ -enum VsockFlag { - VSOCK_REUSE = 1, - VSOCK_BIND = 2, - VSOCK_CONNECT = 4, - VSOCK_BROADCAST = 8, - VSOCK_MULTICAST = 16, - VSOCK_NONBLOCK = 32, - }; - -/** Convert socket flags to a string. - * - * @param flags flags - * @return static string - */ -char * socket_flags(int flags){ - static char s[7]; - int i = 0; - s[i++] = (flags & VSOCK_CONNECT ? 'c' : '-'); - s[i++] = (flags & VSOCK_BIND ? 'b' : '-'); - s[i++] = (flags & VSOCK_REUSE ? 'r' : '-'); - s[i++] = (flags & VSOCK_BROADCAST ? 'B' : '-'); - s[i++] = (flags & VSOCK_MULTICAST ? 'M' : '-'); - s[i++] = (flags & VSOCK_NONBLOCK ? 'N' : '-'); - s[i++] = '\0'; - return s; -} - -/** Control flag for whether varp should be running. - * If this is set 0 then the varp thread will notice and - * (eventually) exit. - */ -atomic_t varp_run = ATOMIC_INIT(0); - -enum { - VARP_STATE_EXITED = 2, - VARP_STATE_RUNNING = 1, - VARP_STATE_NONE = 0, - VARP_STATE_ERROR = -1, -}; - -/** State indicating whether the varp thread is running. */ -atomic_t varp_state = ATOMIC_INIT(VARP_STATE_NONE); - -int varp_thread_err = 0; - -/** The varp multicast socket. */ -int varp_mcast_sock = -1; - -/** The varp unicast socket. */ -int varp_ucast_sock = -1; - -/** Set socket option to reuse address. - * - * @param sock socket - * @param reuse flag - * @return 0 on success, error code otherwise - */ -int setsock_reuse(int sock, int reuse){ - int err = 0; - err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); - if(err < 0){ - eprintf("> setsockopt SO_REUSEADDR: %d %d\n", err, errno); - } - return err; -} - -/** Set socket broadcast option. - * - * @param sock socket - * @param bcast flag - * @return 0 on success, error code otherwise - */ -int setsock_broadcast(int sock, int bcast){ - int err = 0; - err = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)); - if(err < 0){ - eprintf("> setsockopt SO_BROADCAST: %d %d\n", err, errno); - } - return err; -} - -/** Join a socket to a multicast group. - * - * @param sock socket - * @param saddr multicast address - * @return 0 on success, error code otherwise - */ -int setsock_multicast(int sock, uint32_t saddr){ - int err = 0; - struct ip_mreqn mreq = {}; - int mloop = 0; - - // See 'man 7 ip' for these options. - mreq.imr_multiaddr.s_addr = saddr; // IP multicast address. - mreq.imr_address.s_addr = INADDR_ANY; // Interface IP address. - mreq.imr_ifindex = 0; // Interface index (0 means any). - err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop)); - if(err < 0){ - eprintf("> setsockopt IP_MULTICAST_LOOP: %d %d\n", err, errno); - goto exit; - } - err = setsockopt(sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); - if(err < 0){ - eprintf("> setsockopt IP_ADD_MEMBERSHIP: %d %d\n", err, errno); - goto exit; - } - exit: - return err; -} - -/** Set a socket's multicast ttl (default is 1). - * @param sock socket - * @param ttl ttl - * @return 0 on success, error code otherwise - */ -int setsock_multicast_ttl(int sock, uint8_t ttl){ - int err = 0; - err = setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); - return err; -} - -/** Create a socket. - * The flags can include values from enum VsockFlag. - * - * @param socktype socket type - * @param saddr address - * @param port port - * @param flags flags - * @param val return value for the socket connection - * @return 0 on success, error code otherwise - */ -int create_socket(int socktype, uint32_t saddr, uint32_t port, int flags, int *val){ - int err = 0; - int sock; - struct sockaddr_in addr_in; - struct sockaddr *addr = (struct sockaddr *)&addr_in; - int addr_n = sizeof(addr_in); - int sockproto = 0; - - dprintf(">\n"); - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = saddr; - addr_in.sin_port = port; - dprintf("> flags=%s addr=%u.%u.%u.%u port=%d\n", - socket_flags(flags), - NIPQUAD(saddr), ntohs(port)); - - switch(socktype){ - case SOCK_DGRAM: sockproto = IPPROTO_UDP; break; - case SOCK_STREAM: sockproto = IPPROTO_TCP; break; - } - sock = socket(AF_INET, socktype, sockproto); - if(sock < 0) goto exit; - if(flags & VSOCK_REUSE){ - err = setsock_reuse(sock, 1); - if(err < 0) goto exit; - } - if(flags & VSOCK_BROADCAST){ - err = setsock_broadcast(sock, 1); - if(err < 0) goto exit; - } - if(flags & VSOCK_MULTICAST){ - err = setsock_multicast(sock, saddr); - if(err < 0) goto exit; - } - if(flags & VSOCK_CONNECT){ - err = connect(sock, addr, addr_n); - if(err < 0) goto exit; - } - if(flags & VSOCK_BIND){ - err = bind(sock, addr, addr_n); - if(err < 0) goto exit; - } -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) ) - if(flags & VSOCK_NONBLOCK){ - err = fcntl(sock, F_SETFL, O_NONBLOCK); - if(err < 0) goto exit; - } -#endif - exit: - *val = (err ? -1 : sock); - if(err) eprintf("> err=%d errno=%d\n", err, errno); - return err; -} - -/** Open the varp multicast socket. - * - * @param mcaddr multicast address - * @param port port - * @param val return parameter for the socket - * @return 0 on success, error code otherwise - */ -int varp_mcast_open(uint32_t mcaddr, uint16_t port, int *val){ - int err = 0; - int flags = VSOCK_REUSE; - int sock = 0; - - dprintf(">\n"); - flags |= VSOCK_MULTICAST; - flags |= VSOCK_BROADCAST; - - err = create_socket(SOCK_DGRAM, mcaddr, port, flags, &sock); - if(err < 0) goto exit; - if(MULTICAST(mcaddr)){ - err = setsock_multicast_ttl(sock, 2); - if(err < 0) goto exit; - } - exit: - if(err){ - shutdown(sock, 2); - } - *val = (err ? -1 : sock); - dprintf("< err=%d val=%d\n", err, *val); - return err; -} - -/** Open the varp unicast socket. - * - * @param addr address - * @param port port - * @param val return parameter for the socket - * @return 0 on success, error code otherwise - */ -int varp_ucast_open(uint32_t addr, u16 port, int *val){ - int err = 0; - int flags = (VSOCK_BIND | VSOCK_REUSE); - dprintf(">\n"); - err = create_socket(SOCK_DGRAM, addr, port, flags, val); - dprintf("< err=%d val=%d\n", err, *val); - return err; -} - -/** - * Return code > 0 means the handler owns the packet. - * Return code <= 0 means we still own it, with < 0 meaning - * an error. - */ -static int handle_varp_skb(struct sk_buff *skb){ - int err = 0; - switch(skb->pkt_type){ - case PACKET_BROADCAST: - case PACKET_MULTICAST: - vnet_forward_send(skb); - /* Fall through. */ - case PACKET_HOST: - err = varp_handle_message(skb); - break; - case PACKET_OTHERHOST: - dprintf("> PACKET_OTHERHOST\n"); - break; - case PACKET_OUTGOING: - dprintf("> PACKET_OUTGOING\n"); - break; - case PACKET_FASTROUTE: - dprintf("> PACKET_FASTROUTE\n"); - break; - case PACKET_LOOPBACK: - // Outbound mcast/bcast are echoed with this type. Drop. - dprintf("> LOOP src=" IPFMT " dst=" IPFMT " dev=%s\n", - NIPQUAD(skb->nh.iph->saddr), - NIPQUAD(skb->nh.iph->daddr), - (skb->dev ? skb->dev->name : "??")); - default: - // Drop. - break; - } - if(err <= 0){ - kfree_skb(skb); - } - return (err < 0 ? err : 0); -} - -/** Handle some skbs on a varp socket (if any). - * - * @param fd socket file descriptor - * @param n maximum number of skbs to handle - * @return number of skbs handled - */ -static int handle_varp_sock(int fd, int n){ - int ret = 0; - int err = 0; - struct sk_buff *skb; - struct socket *sock = NULL; - - sock = sockfd_lookup(fd, &err); - if (!sock){ - wprintf("> no sock for fd=%d\n", fd); - goto exit; - } - for( ; ret < n; ret++){ - if(!sock->sk) break; - skb = skb_dequeue(&sock->sk->sk_receive_queue); - if(!skb) break; - // Call the skb destructor so it isn't charged to the socket anymore. - // An skb from a socket receive queue is charged to the socket - // by skb_set_owner_r() until its destructor is called. - // If the destructor is not called the socket will run out of - // receive queue space and be unable to accept incoming skbs. - // The destructor used is sock_rfree(), see 'include/net/sock.h'. - // Other destructors: sock_wfree, sk_stream_rfree. - skb_orphan(skb); - handle_varp_skb(skb); - } - sockfd_put(sock); - exit: - dprintf("< ret=%d\n", ret); - return ret; -} - -/** Add a wait queue to a socket. - * - * @param fd socket file descriptor - * @param waitq queue - * @return 0 on success, error code otherwise - */ -int sock_add_wait_queue(int fd, wait_queue_t *waitq){ - int err = -EINVAL; - struct socket *sock = NULL; - - if(fd < 0) goto exit; - sock = sockfd_lookup(fd, &err); - if (!sock) goto exit; - add_wait_queue(sock->sk->sk_sleep, waitq); - sockfd_put(sock); - err = 0; - exit: - return err; -} - -/** Remove a wait queue from a socket. - * - * @param fd socket file descriptor - * @param waitq queue - * @return 0 on success, error code otherwise - */ -int sock_remove_wait_queue(int fd, wait_queue_t *waitq){ - int err = -EINVAL; - struct socket *sock = NULL; - - if(fd < 0) goto exit; - sock = sockfd_lookup(fd, &err); - if (!sock) goto exit; - remove_wait_queue(sock->sk->sk_sleep, waitq); - sockfd_put(sock); - err = 0; - exit: - return err; -} - -#if 0 -// Default data ready function on a socket. -static void sock_def_readable(struct sock *sk, int len) -{ - read_lock(&sk->sk_callback_lock); - if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) - wake_up_interruptible(sk->sk_sleep); - sk_wake_async(sk,1,POLL_IN); - read_unlock(&sk->sk_callback_lock); -} -#endif - -static void sock_data_ready(struct sock *sk, int len){ - struct sk_buff *skb; - //read_lock(&sk->sk_callback_lock); - skb = skb_dequeue(&sk->sk_receive_queue); - if(skb){ - skb_orphan(skb); - } - //read_unlock(&sk->sk_callback_lock); - if(skb){ - handle_varp_skb(skb); - } -} - -/** Set the data ready callback on a socket. - */ -int sock_set_callback(int fd){ - int err = -EINVAL; - struct socket *sock = NULL; - - if(fd < 0) goto exit; - sock = sockfd_lookup(fd, &err); - if (!sock) goto exit; - sock->sk->sk_data_ready = sock_data_ready; - sockfd_put(sock); - err = 0; - exit: - return err; -} - -/** Open the sockets. */ -int varp_sockets_open(u32 mcaddr, u16 port){ - int err = 0; - mm_segment_t oldfs; - - dprintf("> mcaddr=%u.%u.%u.%u port=%u\n", NIPQUAD(mcaddr), ntohs(port)); - oldfs = change_fs(KERNEL_DS); - err = varp_mcast_open(mcaddr, port, &varp_mcast_sock); - if(err < 0 ) goto exit; - err = varp_ucast_open(INADDR_ANY, port, &varp_ucast_sock); - if(err < 0 ) goto exit; - sock_set_callback(varp_ucast_sock); - sock_set_callback(varp_mcast_sock); - exit: - set_fs(oldfs); - dprintf("< err=%d\n", err); - return err; -} - -/** Close the sockets. */ -void varp_sockets_close(void){ - mm_segment_t oldfs; - int err; - struct ip_mreqn mreq = {}; - - oldfs = change_fs(KERNEL_DS); - if(varp_mcast_sock >= 0){ - mreq.imr_multiaddr.s_addr = htonl(VARP_MCAST_ADDR); - mreq.imr_address.s_addr = INADDR_ANY; - mreq.imr_ifindex = 0; - err =setsockopt(varp_mcast_sock, SOL_IP,IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); - if(err < 0){ - eprintf("> setsockopt IP_MULTICAST_DROP: %d %d\n", err, errno); - } - shutdown(varp_mcast_sock, 2); - varp_mcast_sock = -1; - } - if(varp_ucast_sock >= 0){ - err=shutdown(varp_ucast_sock, 2); - if(err){ - eprintf("> ucast sock shutdown err=%d\n", err); - } - varp_ucast_sock = -1; - } - set_fs(oldfs); -} - -/** Loop handling the varp sockets. - * We use kernel API for this (waitqueue, schedule_timeout) instead - * of select because the select syscall was returning EFAULT. Oh well. - * - * @param arg arguments - * @return exit code - */ -int varp_main(void *arg){ - int err = 0; - long timeout = 1 * HZ; - int count = 0; - DECLARE_WAITQUEUE(mcast_wait, current); - DECLARE_WAITQUEUE(ucast_wait, current); - - dprintf("> start\n"); - //snprintf(current->comm, sizeof(TASK_COMM_LEN), "vnet_varp"); - - err = varp_sockets_open(htonl(VARP_MCAST_ADDR), htons(VARP_PORT)); - if(err) goto exit; - - err = sock_add_wait_queue(varp_mcast_sock, &mcast_wait); - if(err) goto exit_mcast_sock; - err = sock_add_wait_queue(varp_ucast_sock, &ucast_wait); - if(err) goto exit_ucast_sock; - atomic_set(&varp_state, VARP_STATE_RUNNING); - for( ; atomic_read(&varp_run); ){ - count = 0; - count += handle_varp_sock(varp_mcast_sock, 1); - count += handle_varp_sock(varp_ucast_sock, 16); - if(!count){ - if(!atomic_read(&varp_run)) break; - // No skbs were handled, go to sleep. - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); - __set_current_state(TASK_RUNNING); - } - } - exit_ucast_sock: - sock_remove_wait_queue(varp_ucast_sock, &ucast_wait); - exit_mcast_sock: - sock_remove_wait_queue(varp_mcast_sock, &mcast_wait); - varp_sockets_close(); - exit: - if(err){ - eprintf("%s< err=%d\n", __FUNCTION__, err); - } - varp_thread_err = err; - atomic_set(&varp_state, VARP_STATE_EXITED); - //MOD_DEC_USE_COUNT; - return err; -} - -/** Close the varp sockets and stop the thread handling them. - */ -void varp_close(void){ - int tries = 10; - dprintf(">\n"); - // Tell the varp thread to stop and wait a while for it. - atomic_set(&varp_run, 0); - while(atomic_read(&varp_state) == VARP_STATE_RUNNING && tries-- > 0){ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 2); - __set_current_state(TASK_RUNNING); - } - //MOD_DEC_USE_COUNT; - dprintf("<\n"); -} - -/** Open the varp sockets and start the thread handling them. - * - * @param mcaddr multicast address - * @param port port - * @return 0 on success, error code otherwise - */ -int varp_open(u32 mcaddr, u16 port){ - int err = 0; - struct task_struct* task; - - //MOD_INC_USE_COUNT; - dprintf(">\n"); - atomic_set(&varp_run, 1); - atomic_set(&varp_state, VARP_STATE_NONE); -#if 1 - task = kthread_run(varp_main, (void*)NULL, "vnet_varpd"); - if (IS_ERR(task) < 0) { - eprintf("> Unable to start varp main thread\n"); - goto exit; - } -#endif -#if 0 - while(atomic_read(&varp_state) == VARP_STATE_NONE){ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1 * HZ); - __set_current_state(TASK_RUNNING); - } - err = varp_thread_err; -#endif - exit: - if(err){ - wprintf("> err=%d\n", err); - } - return err; -} diff --git a/vnet/src/vnet-module/varp_util.c b/vnet/src/vnet-module/varp_util.c deleted file mode 100644 index 66a0d344439..00000000000 --- a/vnet/src/vnet-module/varp_util.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -static int hex16(char *s, uint16_t *val) -{ - int err = -EINVAL; - uint16_t v = 0; - - for( ; *s; s++){ - v <<= 4; - if('0' <= *s && *s <= '9'){ - v |= *s - '0'; - } else if('A' <= *s && *s <= 'F'){ - v |= *s - 'A' + 10; - } else if('a' <= *s && *s <= 'f'){ - v |= *s - 'a' + 10; - } else { - goto exit; - } - } - err = 0; - exit: - *val = (err ? 0 : v); - return err; -} - -int VnetId_aton(const char *s, VnetId *vnet){ - int err = -EINVAL; - const char *p, *q; - uint16_t v; - char buf[5]; - int buf_n = sizeof(buf) - 1; - int i, n; - const int elts_n = VNETID_SIZE16; - - q = s; - p = strchr(q, ':'); - i = (p ? 0 : elts_n - 1); - do { - if(!p){ - if(i < elts_n - 1) goto exit; - p = s + strlen(s); - } - n = p - q; - if(n > buf_n) goto exit; - memcpy(buf, q, n); - buf[n] = '\0'; - err = hex16(buf, &v); - if(err) goto exit; - vnet->u.vnet16[i] = htons(v); - q = p+1; - p = strchr(q, ':'); - i++; - } while(i < elts_n); - err = 0; - exit: - if(err){ - *vnet = (VnetId){}; - } - return err; -} diff --git a/vnet/src/vnet-module/varp_util.h b/vnet/src/vnet-module/varp_util.h deleted file mode 100644 index 13b3a433e44..00000000000 --- a/vnet/src/vnet-module/varp_util.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_VARP_UTIL_H -#define _VNET_VARP_UTIL_H - -#include "hash_table.h" - -/** Size of a string buffer to store a varp address. */ -#define VARP_ADDR_BUF 56 - -/** Size of a string buffer to store a vnet id. */ -#define VNET_ID_BUF 56 - -#ifndef NIPQUAD -#define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] -#endif - -#ifndef NIP6 -#define NIP6(addr) \ - ntohs((addr).s6_addr16[0]), \ - ntohs((addr).s6_addr16[1]), \ - ntohs((addr).s6_addr16[2]), \ - ntohs((addr).s6_addr16[3]), \ - ntohs((addr).s6_addr16[4]), \ - ntohs((addr).s6_addr16[5]), \ - ntohs((addr).s6_addr16[6]), \ - ntohs((addr).s6_addr16[7]) -#endif - - -static inline const char *VarpAddr_ntoa(VarpAddr *addr, char buf[VARP_ADDR_BUF]) -{ - switch(addr->family){ - default: - case AF_INET: - snprintf(buf, VARP_ADDR_BUF-1, "%u.%u.%u.%u", - NIPQUAD(addr->u.ip4)); - break; - case AF_INET6: - snprintf(buf, VARP_ADDR_BUF-1,"%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", - NIP6(addr->u.ip6)); - break; - } - return buf; -} - -static inline const char *VnetId_ntoa(VnetId *vnet, char buf[VNET_ID_BUF]) -{ - snprintf(buf, VNET_ID_BUF-1, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", - ntohs(vnet->u.vnet16[0]), \ - ntohs(vnet->u.vnet16[1]), \ - ntohs(vnet->u.vnet16[2]), \ - ntohs(vnet->u.vnet16[3]), \ - ntohs(vnet->u.vnet16[4]), \ - ntohs(vnet->u.vnet16[5]), \ - ntohs(vnet->u.vnet16[6]), \ - ntohs(vnet->u.vnet16[7])); - return buf; -} - -extern int VnetId_aton(const char *s, VnetId *vnet); - -/** Convert an unsigned in host order to a vnet id. - */ -static inline struct VnetId toVnetId(uint32_t vnetid){ - struct VnetId vnet = {}; - vnet.u.vnet32[VNETID_SIZE32 - 1] = htonl(vnetid); - return vnet; -} - -static inline int VnetId_eq(VnetId *id1, VnetId *id2){ - return memcmp(id1, id2, sizeof(VnetId)) == 0; -} - -#endif /* _VNET_VARP_UTIL_H */ diff --git a/vnet/src/vnet-module/vif.c b/vnet/src/vnet-module/vif.c deleted file mode 100644 index 98605c20963..00000000000 --- a/vnet/src/vnet-module/vif.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include - -#else - -#include "sys_kernel.h" -#include "spinlock.h" -#include "skbuff.h" - -#endif - -#include -#include -#include - -#include "allocate.h" -#include "iostream.h" -#include "hash_table.h" -#include "timer_util.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** Vif table ttl - interval between sweeps of old vifs. */ -#define VIF_TABLE_TTL (60*HZ) - -/** Vif entry ttl - a vif entry older than this is removed. */ -#define VIF_ENTRY_TTL (60*HZ) - -/** Table of vifs indexed by VifKey. */ -HashTable *vif_table = NULL; -rwlock_t vif_table_lock = RW_LOCK_UNLOCKED; -struct timer_list vif_table_timer = {}; -int vif_table_sweeps = 0; - -#define vif_read_lock(flags) read_lock_irqsave(&vif_table_lock, (flags)) -#define vif_read_unlock(flags) read_unlock_irqrestore(&vif_table_lock, (flags)) -#define vif_write_lock(flags) write_lock_irqsave(&vif_table_lock, (flags)) -#define vif_write_unlock(flags) write_unlock_irqrestore(&vif_table_lock, (flags)) - -void vif_entry_print(Vif *vif, IOStream *io){ - char vnetbuf[VNET_ID_BUF]; - unsigned long now = jiffies; - - IOStream_print(io, "(vif\n"); - IOStream_print(io, " (vnet %s)\n", VnetId_ntoa(&vif->vnet, vnetbuf)); - IOStream_print(io, " (vmac " MACFMT ")\n", MAC6TUPLE(vif->vmac.mac)); - IOStream_print(io, " (age %u)\n", now - vif->timestamp); - IOStream_print(io, ")\n"); -} - -void vif_print(IOStream *io){ - HashTable_for_decl(entry); - Vif *vif; - unsigned long flags; - - vif_read_lock(flags); - IOStream_print(io, "(viftable\n"); - IOStream_print(io, " (table_ttl %u)\n", VIF_TABLE_TTL); - IOStream_print(io, " (entry_ttl %u)\n", VIF_ENTRY_TTL); - IOStream_print(io, " (sweeps %d)\n", vif_table_sweeps); - IOStream_print(io, ")\n"); - - HashTable_for_each(entry, vif_table){ - vif = entry->value; - vif_entry_print(vif, io); - } - vif_read_unlock(flags); -} - -void vif_decref(Vif *vif){ - if(!vif) return; - if(atomic_dec_and_test(&vif->refcount)){ - kfree(vif); - } -} - -void vif_incref(Vif *vif){ - if(!vif) return; - atomic_inc(&vif->refcount); -} - -/** Hash function for keys in the vif table. - * Hashes the vnet id and mac. - * - * @param k key (VifKey) - * @return hashcode - */ -static Hashcode vif_key_hash_fn(void *k){ - return hash_hvoid(0, k, sizeof(VifKey)); -} - -/** Test equality for keys in the vif table. - * Compares vnet and mac. - * - * @param k1 key to compare (VifKey) - * @param k2 key to compare (VifKey) - * @return 1 if equal, 0 otherwise - */ -static int vif_key_equal_fn(void *k1, void *k2){ - return memcmp(k1, k2, sizeof(VifKey)) == 0; -} - -/** Free an entry in the vif table. - * - * @param table containing table - * @param entry entry to free - */ -static void vif_entry_free_fn(HashTable *table, HTEntry *entry){ - Vif *vif; - if(!entry) return; - vif = entry->value; - if(vif){ - vif_decref(vif); - } - HTEntry_free(entry); -} - -/** Lookup a vif. - * Caller must hold vif lock. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, -ENOENT otherwise - */ -static int _vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){ - int err = 0; - VifKey key = { .vnet = *vnet, .vmac = *vmac }; - HTEntry *entry = NULL; - - entry = HashTable_get_entry(vif_table, &key); - if(entry){ - *vif = entry->value; - vif_incref(*vif); - } else { - *vif = NULL; - err = -ENOENT; - } - return err; -} - -/** Lookup a vif. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, -ENOENT otherwise - */ -int vif_lookup(VnetId *vnet, Vmac *vmac, Vif **vif){ - unsigned long flags; - int err; - - vif_read_lock(flags); - err = _vif_lookup(vnet, vmac, vif); - vif_read_unlock(flags); - return err; -} - -/** Create a new vif. - * Entry must not exist. - * Caller must hold vif lock. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, negative error code otherwise - */ -static int _vif_add(VnetId *vnet, Vmac *vmac, Vif **val){ - int err = 0; - Vif *vif = NULL; - HTEntry *entry; - unsigned long now = jiffies; - - vif = ALLOCATE(Vif); - if(!vif){ - err = -ENOMEM; - goto exit; - } - atomic_set(&vif->refcount, 1); - vif->vnet = *vnet; - vif->vmac = *vmac; - vif->timestamp = now; - entry = HashTable_add(vif_table, vif, vif); - if(!entry){ - err = -ENOMEM; - deallocate(vif); - vif = NULL; - goto exit; - } - vif_incref(vif); - exit: - *val = (err ? NULL : vif); - return err; -} - -/** Delete a vif entry. - * - * @param vnet vnet id - * @param mac MAC address - * @return number of entries deleted, or negative error code - */ -int vif_remove(VnetId *vnet, Vmac *vmac){ - int err = 0; - VifKey key = { .vnet = *vnet, .vmac = *vmac }; - unsigned long flags; - - vif_write_lock(flags); - err = HashTable_remove(vif_table, &key); - vif_write_unlock(flags); - return err; -} - -/** Delete all vifs on a vnet. - * - * @param vnet vnet id - * @return number of entries deleted - */ -int vif_remove_vnet(VnetId *vnet){ - int count = 0; - unsigned long flags; - HashTable_for_decl(entry); - - - vif_write_lock(flags); - HashTable_for_each(entry, vif_table){ - Vif *vif = entry->value; - if(VnetId_eq(&vif->vnet, vnet)){ - count += HashTable_remove(vif_table, vif); - } - } - vif_write_unlock(flags); - return count; -} - -/** Purge the vif table. - */ -void vif_purge(void){ - unsigned long flags; - vif_write_lock(flags); - HashTable_clear(vif_table); - vif_write_unlock(flags); -} - -/** Sweep old vif entries from the vif table. - */ -void vif_sweep(void){ - HashTable_for_decl(entry); - Vif *vif; - int vif_count = 0; - unsigned long now = jiffies; - unsigned long old = VIF_ENTRY_TTL; - unsigned long flags; - - vif_write_lock(flags); - vif_table_sweeps++; - HashTable_for_each(entry, vif_table){ - vif = entry->value; - vif_count++; - if(!(vif->flags & VIF_FLAG_PERSISTENT) - && (now - vif->timestamp > old)){ - iprintf("> Sweeping:\n"); - vif_entry_print(vif, iostdout); - HashTable_remove(vif_table, entry->key); - } - } - vif_write_unlock(flags); -} - -/** Create a new vif if it does not exist. - * Caller must hold vif lock. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, negative error code otherwise - */ -int _vif_create(VnetId *vnet, Vmac *vmac, Vif **vif){ - int err = 0; - - if(_vif_lookup(vnet, vmac, vif) == 0){ - goto exit; - } - err = _vif_add(vnet, vmac, vif); - exit: - return err; -} - -/** Create a new vif if it does not exist. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, negative error code otherwise - */ -int vif_create(VnetId *vnet, Vmac *vmac, int vflags, Vif **vif){ - int err = 0; - unsigned long flags; - - vif_write_lock(flags); - err = _vif_create(vnet, vmac, vif); - if(!err && *vif){ - (*vif)->flags = vflags; - } - vif_write_unlock(flags); - return err; -} - -/** Update the timestamp for a vif. - * - * @param vnet vnet id - * @param mac MAC address - * @return 0 on success, negative error code otherwise - */ -int vif_update(VnetId *vnet, Vmac *vmac){ - Vif *vif = NULL; - int err = 0; - unsigned long now = jiffies; - unsigned long flags; - - vif_write_lock(flags); - err = _vif_create(vnet, vmac, &vif); - if(err) goto exit; - vif->timestamp = now; - vif_decref(vif); - exit: - vif_write_unlock(flags); - return err; -} - -static void vif_table_timer_fn(unsigned long arg){ - if(!vif_table) return; - vif_sweep(); - timer_set(&vif_table_timer, VIF_TABLE_TTL); -} - -/** Initialize the vif table. - * - * @return 0 on success, error code otherwise - */ -int vif_init(void){ - int err = 0; - vif_table = HashTable_new(0); - if(!vif_table){ - err = -ENOMEM; - goto exit; - } - vif_table->entry_free_fn = vif_entry_free_fn; - vif_table->key_size = sizeof(VifKey); - vif_table->key_hash_fn = vif_key_hash_fn; - vif_table->key_equal_fn = vif_key_equal_fn; - - timer_init(&vif_table_timer, vif_table_timer_fn, 0); - timer_set(&vif_table_timer, VIF_TABLE_TTL); - - exit: - if(err < 0){ - eprintf("> vif_init err=%d\n", err); - } - return err; -} - -void vif_exit(void){ - timer_cancel(&vif_table_timer); - HashTable_free(vif_table); - vif_table = NULL; -} diff --git a/vnet/src/vnet-module/vif.h b/vnet/src/vnet-module/vif.h deleted file mode 100644 index c2e2fa8f9cc..00000000000 --- a/vnet/src/vnet-module/vif.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_VIF_H_ -#define _VNET_VIF_H_ - -#ifdef __KERNEL__ -#include -#else -#include "spinlock.h" -#endif - -#include -struct IOStream; - -/** Key for entries in the vif table. */ -typedef struct VifKey { - struct VnetId vnet; - struct Vmac vmac; -} VifKey; - -typedef struct Vif { - struct VnetId vnet; - struct Vmac vmac; - atomic_t refcount; - unsigned long timestamp; - int flags; -} Vif; - -enum { - VIF_FLAG_PERSISTENT = 1, -}; - -extern void vif_print(struct IOStream *io); - -extern void vif_decref(struct Vif *vif); -extern void vif_incref(struct Vif *vif); - -extern int vif_create(struct VnetId *vnet, struct Vmac *vmac, int flags, struct Vif **vif); -extern int vif_lookup(struct VnetId *vnet, struct Vmac *vmac, struct Vif **vif); -extern int vif_update(struct VnetId *vnet, struct Vmac *vmac); -extern int vif_remove(struct VnetId *vnet, struct Vmac *vmac); -extern void vif_purge(void); -extern int vif_remove_vnet(struct VnetId *vnet); - -extern int vif_init(void); -extern void vif_exit(void); - -#endif diff --git a/vnet/src/vnet-module/vnet.c b/vnet/src/vnet-module/vnet.c deleted file mode 100644 index c87210a93b3..00000000000 --- a/vnet/src/vnet-module/vnet.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef __KERNEL__ -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -#else - -#include -#include - -#include "sys_kernel.h" -#include "spinlock.h" -#include "skbuff.h" - -#include // For struct iphdr. - -extern int netif_rx(struct sk_buff *skb); - -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef __KERNEL__ -#include -#endif - -#include "allocate.h" -#include "iostream.h" -#include "hash_table.h" -#include "sys_net.h" -#include "sys_string.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** Default vnet security level. - */ -#ifdef __KERNEL__ -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) ) -int vnet_security_default = SA_AUTH ; //| SA_CONF; -#else -int vnet_security_default = 0; -#endif -#else -int vnet_security_default = 0; -#endif - -/** The physical vnet. */ -Vnet *vnet_physical = NULL; - -/** Table of vnets indexed by id. */ -HashTable *vnet_table = NULL; - -rwlock_t vnet_lock = RW_LOCK_UNLOCKED; - -#define vnet_table_read_lock(flags) read_lock_irqsave(&vnet_lock, flags) -#define vnet_table_read_unlock(flags) read_unlock_irqrestore(&vnet_lock, flags) -#define vnet_table_write_lock(flags) write_lock_irqsave(&vnet_lock, flags) -#define vnet_table_write_unlock(flags) write_unlock_irqrestore(&vnet_lock, flags) - -/** Decrement reference count, freeing if zero. - * - * @param info vnet (OK if null) - */ -void Vnet_decref(Vnet *info){ - if(!info) return; - if(atomic_dec_and_test(&info->refcount)){ - deallocate(info); - } -} - -/** Increment reference count. - * - * @param info vnet (OK if null) - */ -void Vnet_incref(Vnet *info){ - if(!info) return; - atomic_inc(&info->refcount); -} - -void Vnet_print(Vnet *info, IOStream *io) -{ - char vnetbuf[VNET_ID_BUF]; - char *security; - - if(info->security & SA_CONF){ - security = "conf"; - } else if(info->security & SA_AUTH){ - security = "auth"; - } else { - security = "none"; - } - - IOStream_print(io, "(vnet"); - IOStream_print(io, " (id %s)", VnetId_ntoa(&info->vnet, vnetbuf)); - IOStream_print(io, " (vnetif %s)", info->device); - IOStream_print(io, " (security %s)", security); - IOStream_print(io, " (header %d)", info->header_n); - IOStream_print(io, ")"); -} - -void vnet_print(IOStream *io) -{ - HashTable_for_decl(entry); - Vnet *info; - unsigned long flags; - - vnet_table_read_lock(flags); - HashTable_for_each(entry, vnet_table){ - info = entry->value; - Vnet_print(info, io); - IOStream_print(io, "\n"); - } - vnet_table_read_unlock(flags); -} - -/** Allocate a vnet, setting reference count to 1. - * - * @param info return parameter for vnet - * @return 0 on success, error code otherwise - */ -int Vnet_alloc(Vnet **info){ - int err = 0; - *info = ALLOCATE(Vnet); - if(*info){ - atomic_set(&(*info)->refcount, 1); - } else { - err = -ENOMEM; - } - return err; -} - -/** Create the virtual interface for a vnet. - * - * @param info vnet - * @return 0 on success, error code otherwise - */ -int Vnet_create(Vnet *info){ - int err = 0; - - err = vnet_dev_add(info); - if(err) goto exit; - err = Vnet_add(info); - exit: - return err; -} - -/** Add a vnet to the table under its vnet id. - * - * @param info vnet to add - * @return 0 on success, error code otherwise - */ -int Vnet_add(Vnet *info){ - int err = 0; - HTEntry *entry = NULL; - unsigned long flags; - - if(Vnet_lookup(&info->vnet, NULL) == 0){ - //todo: Delete existing vnet info? - err = -EEXIST; - goto exit; - } - Vnet_incref(info); - vnet_table_write_lock(flags); - entry = HashTable_add(vnet_table, &info->vnet, info); - vnet_table_write_unlock(flags); - if(!entry){ - err = -ENOMEM; - vnet_dev_remove(info); - Vnet_decref(info); - } - exit: - return err; -} - -/** Remove a vnet from the table. - * Also removes all vifs and varp entries for the vnet. - * - * @param vnet id of vnet to remove - * @return number of vnets removed - */ -int Vnet_del(VnetId *vnet){ - int count; - unsigned long flags; - Vnet *info; - - vnet_table_write_lock(flags); - info = HashTable_get(vnet_table, vnet); - count = HashTable_remove(vnet_table, vnet); - vnet_table_write_unlock(flags); - - varp_remove_vnet(vnet); - vif_remove_vnet(vnet); - - if(info){ - // Can't do this in the hashtable entry free function because it runs - // while we hold the vnet table lock, and the vnet tidy up calls - // vnet_dev_remove(), which calls unregister_netdev(), which schedules. - vnet_dev_remove(info); - Vnet_decref(info); - } - return count; -} - -/** Lookup a vnet by id. - * References the vnet on success - the caller must decref. - * - * @param vnet vnet id - * @param pinfo return parameter for vnet (or NULL) - * @return 0 on sucess, -ENOENT if no vnet found - */ -int Vnet_lookup(VnetId *vnet, Vnet **pinfo){ - int err = 0; - unsigned long flags; - Vnet *info; - - vnet_table_read_lock(flags); - info = HashTable_get(vnet_table, vnet); - if(info){ - if(pinfo){ - Vnet_incref(info); - } - } else { - err = -ENOENT; - } - vnet_table_read_unlock(flags); - - if(pinfo){ - *pinfo = (err ? NULL : info); - } - return err; -} - -static int vnet_key_equal_fn(void *k1, void *k2){ - return memcmp(k1, k2, sizeof(VnetId)) == 0; -} - -static Hashcode vnet_key_hash_fn(void *k){ - return hash_hvoid(0, k, sizeof(VnetId)); -} - -/** Free an entry in the vnet table. - * - * @param table containing table - * @param entry to free - */ -static void vnet_entry_free_fn(HashTable *table, HTEntry *entry){ - if(!entry) return; - HTEntry_free(entry); -} - -void vnet_table_free(void){ - HashTable *vnt; - HashTable_for_decl(entry); - - vnt = vnet_table; - if(!vnt) return; - vnet_table = NULL; - HashTable_for_each(entry, vnt){ - Vnet *info = entry->value; - vnet_dev_remove(info); - Vnet_decref(info); - } - HashTable_free(vnt); -} - -int vnet_table_init(void){ - int err = 0; - vnet_table = HashTable_new(0); - if(!vnet_table){ - err = -ENOMEM; - goto exit; - } - vnet_table->key_size = sizeof(VnetId); - vnet_table->key_equal_fn = vnet_key_equal_fn; - vnet_table->key_hash_fn = vnet_key_hash_fn; - vnet_table->entry_free_fn = vnet_entry_free_fn; - - err = Vnet_alloc(&vnet_physical); - if(err) goto exit; - vnet_physical->vnet = toVnetId(VNET_PHYS); - vnet_physical->security = 0; - err = Vnet_add(vnet_physical); - - exit: - if(err){ - vnet_table_free(); - } - return err; -} - -/** Setup some vnet entries (for testing). - * Vnet 1 is physical, vnets 2 to 10 are insecure, vnets above - * 10 are secure. - * - * @return 0 on success, negative error code otherwise - */ -static int vnet_setup(void){ - int err = 0; - int i, n = 3; - int security = vnet_security_default; - uint32_t vnetid; - Vnet *vnet; - - for(i=0; ivnet = toVnetId(vnetid); - snprintf(vnet->device, 16, "vnif%04x", vnetid); - vnet->security = (vnetid > 10 ? security : 0); - err = Vnet_create(vnet); - Vnet_decref(vnet); - if(err) break; - } - return err; -} - -/** Initialize the vnet table and the physical vnet. - * - * @return 0 on success, error code otherwise - */ -int vnet_init(void){ - int err = 0; - - err = vnet_forward_init(); - if(err) goto exit; - err = vnet_table_init(); - if(err) goto exit; - err = vif_init(); - if(err) goto exit; - err = varp_init(); - if(err) goto exit; - err = vnet_setup(); - exit: - return err; -} - -void vnet_exit(void){ - varp_exit(); - vif_exit(); - vnet_table_free(); - vnet_forward_exit(); -} - -#ifdef __KERNEL__ -inline int _skb_xmit(struct sk_buff *skb, uint32_t saddr){ - int err = 0; - struct rtable *rt = NULL; - - dprintf("> src=%u.%u.%u.%u dst=%u.%u.%u.%u\n", - NIPQUAD(skb->nh.iph->saddr), - NIPQUAD(skb->nh.iph->daddr)); - skb->protocol = htons(ETH_P_IP); - if(saddr){ - skb->nh.iph->saddr = 0; - } - err = skb_route(skb, &rt); - if(err){ - wprintf("> skb_route=%d\n", err); - wprintf("> dev=%s idx=%d src=%u.%u.%u.%u dst=%u.%u.%u.%u tos=%d\n", - (skb->dev ? skb->dev->name : "???"), - (skb->dev ? skb->dev->ifindex : -1), - NIPQUAD(skb->nh.iph->saddr), - NIPQUAD(skb->nh.iph->daddr), - skb->nh.iph->tos); - - goto exit; - } - dst_release(skb->dst); - skb->dst = &rt->u.dst; - if(!skb->dev){ - skb->dev = rt->u.dst.dev; - } - - ip_select_ident(skb->nh.iph, &rt->u.dst, NULL); - - if(saddr){ - skb->nh.iph->saddr = saddr; - } else { - if(!skb->nh.iph->saddr){ - skb->nh.iph->saddr = rt->rt_src; - } - } - - ip_send_check(skb->nh.iph); - -#if 1 - // Output to skb destination. Will use ip_output(), which fragments. - // Slightly slower than neigh_compat_output() (marginal - 1%). - err = dst_output(skb); -#else - // Sends direct to device via dev_queue_xmit(). No fragmentation? - err = neigh_compat_output(skb); -#endif - -#if 0 - if(needs_frags){ - err = ip_fragment(skb, ip_finish_output); - } else { - err = ip_finish_output(skb); - } -#endif - - exit: - dprintf("< err=%d\n", err); - return err; -} - -#else - -extern int _skb_xmit(struct sk_buff *skb, uint32_t saddr); - -#endif - -int skb_xmit(struct sk_buff *skb){ - if(MULTICAST(skb->nh.iph->daddr)){ - vnet_forward_send(skb); - } - return _skb_xmit(skb, 0); -} - -/** Called when a vif sends a packet to the network. - * Encapsulates the packet for its vnet and forwards it. - * - * @param skb packet - * @return 0 on success, error code otherwise - * - */ -int vnet_skb_send(struct sk_buff *skb, VnetId *vnet){ - VnetId vnet_phys = toVnetId(VNET_PHYS); - int err = 0; - - //dprintf(">\n"); - skb->dev = NULL; - if(!vnet || VnetId_eq(vnet, &vnet_phys)){ - // No vnet or physical vnet, send direct to the network. - skb_xmit(skb); - } else { - // Update the vif table with the source MAC. - vif_update(vnet, (Vmac*)eth_hdr(skb)->h_source); - err = varp_output(skb, vnet); - } - //dprintf("< err=%d\n", err); - return err; -} - -/** Receive an skb for a vnet. - * We make the skb come out of the vif for the vnet, and - * let ethernet bridging forward it to related interfaces. - * - * The packet must have skb->mac.raw set and skb->data must point - * after the device (ethernet) header. - * - * Return code 1 means we now own the packet - the caller must not free it. - * Return code < 0 means an error - caller still owns the packet. - * - * @param skb packet - * @param vnet packet vnet - */ -int vnet_skb_recv(struct sk_buff *skb, Vnet *vnet){ - int err = 1; - - if(!vnet->dev){ - // No device for the vnet. - err = -ENOTCONN; - goto exit; - } - skb->dev = vnet->dev; - vnet->stats.rx_packets++; - vnet->stats.rx_bytes += skb->len; - netif_rx(skb); - exit: - return err; -} - - -/** Check that a context has the correct properties w.r.t. a vnet. - * The context must be secure if the vnet requires security. - * - * @param vnet vnet id - * @param context context - * @return 0 on success, error code otherwise - * - * @todo Need to check that the sa provides the correct security level. - */ -int vnet_check_context(VnetId *vnet, SkbContext *context, Vnet **val){ - int err = 0; - Vnet *info = NULL; - SAState *sa = NULL; - - err = Vnet_lookup(vnet, &info); - if(err){ - goto exit; - } - if(!info->security) goto exit; - err = -EINVAL; - if(!context){ - wprintf("> No security context\n"); - goto exit; - } - if(context->protocol != IPPROTO_ESP){ - wprintf("> Invalid protocol: wanted %d, got %d\n", - IPPROTO_ESP, context->protocol); - goto exit; - } - sa = context->data; - //todo: Check security properties of the SA are correct w.r.t. the vnet. - //Something like sa->security == info->security; - err = 0; - exit: - *val = info; - return err; -} - - -/** Create a tunnel for a vnet to a given address. - * - * @param vnet vnet id - * @param addr destination address - * @param tunnel return parameter - * @return 0 on success, error code otherwise - */ -static int vnet_tunnel_create(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){ - int err = 0; - Vnet *info = NULL; - Tunnel *base = NULL; - Tunnel *sa_tunnel = NULL; - Tunnel *eth_tunnel = NULL; - - err = Vnet_lookup(vnet, &info); - if(err) goto exit; - - if(info->security){ - err = sa_tunnel_create(info, addr, base, &sa_tunnel); - if(err) goto exit; - base = sa_tunnel; - } - err = etherip_tunnel_create(vnet, addr, base, ð_tunnel); - exit: - Tunnel_decref(sa_tunnel); - Vnet_decref(info); - *tunnel = (err ? NULL : eth_tunnel); - return err; -} - -/** Lookup a tunnel for a vnet to a given address. - * Uses an existing tunnel if there is one. - * - * @param vnet vnet id - * @param addr care-of address - * @param tunnel return parameter - * @return 0 on success, error code otherwise - */ -int vnet_tunnel_lookup(VnetId *vnet, VarpAddr *addr, Tunnel **tunnel){ - int err = 0; - err = Tunnel_lookup(vnet, addr, tunnel); - if(err){ - err = Tunnel_open(vnet, addr, vnet_tunnel_create, tunnel); - } - return err; -} - -/** Send a packet on the appropriate tunnel. - * - * @param vnet vnet - * @param addr tunnel endpoint - * @param skb packet - * @return 0 on success, error code otherwise - */ -int vnet_tunnel_send(VnetId *vnet, VarpAddr *addr, struct sk_buff *skb){ - int err = 0; - Tunnel *tunnel = NULL; - - err = vnet_tunnel_lookup(vnet, addr, &tunnel); - if(err) { - char vnetbuf[VNET_ID_BUF]; - char addrbuf[VARP_ADDR_BUF]; - wprintf("No tunnel: skb=%p vnet=%s addr=%s\n", - skb, - VnetId_ntoa(vnet, vnetbuf), - VarpAddr_ntoa(addr, addrbuf)); - goto exit; - } - err = Tunnel_send(tunnel, skb); - Tunnel_decref(tunnel); - exit: - return err; -} - -#ifdef __KERNEL__ - -/** Module parameter for vnet encapsulation. */ -static char *vnet_encaps = NULL; - -static void __exit vnet_module_exit(void){ - ProcFS_exit(); - sa_table_exit(); - vnet_exit(); - esp_module_exit(); - etherip_module_exit(); - tunnel_module_exit(); - random_module_exit(); -} - -/** Initialize the vnet module. - * Failure is fatal. - * - * @return 0 on success, error code otherwise - */ -static int __init vnet_module_init(void){ - int err = 0; - - if(vnet_encaps && !strcmp(vnet_encaps, "udp")){ - etherip_in_udp = 1; - } - dprintf(">\n"); - err = random_module_init(); - if(err) wprintf("> random_module_init err=%d\n", err); - if(err) goto exit; - err = tunnel_module_init(); - if(err) wprintf("> tunnel_module_init err=%d\n", err); - if(err) goto exit; - err = etherip_module_init(); - if(err) wprintf("> etherip_module_init err=%d\n", err); - if(err) goto exit; - err = esp_module_init(); - if(err) wprintf("> esp_module_init err=%d\n", err); - if(err) goto exit; - err = vnet_init(); - if(err) wprintf("> vnet_init err=%d\n", err); - if(err) goto exit; -#ifdef __KERNEL__ -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) ) - sa_algorithm_probe_all(); -#endif -#endif - err = sa_table_init(); - if(err) wprintf("> sa_table_init err=%d\n", err); - if(err) goto exit; - ProcFS_init(); - exit: - if(err < 0){ - vnet_module_exit(); - wprintf("< err=%d\n", err); - } - return err; -} - -module_init(vnet_module_init); -module_exit(vnet_module_exit); -MODULE_LICENSE("GPL"); - -module_param(vnet_encaps, charp, 0644); -MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp."); - -#endif diff --git a/vnet/src/vnet-module/vnet.h b/vnet/src/vnet-module/vnet.h deleted file mode 100644 index 025b7035e0e..00000000000 --- a/vnet/src/vnet-module/vnet.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VNET_VNET_H__ -#define __VNET_VNET_H__ - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -#else - -#include // struct net_device_stats - -struct net_device { - char name[IFNAMSIZ]; - char tap[255]; - int tapfd; -}; - -#endif - -#include - -struct sk_buff; - -struct IOStream; -struct Vmac; -struct Vif; -struct SkbContext; -struct VarpAddr; -struct Tunnel; -struct SAState; - -/** Vnet property record. */ -typedef struct Vnet { - /** Vnet id. */ - struct VnetId vnet; - /** Reference count. */ - atomic_t refcount; - /** Security flag. If true the vnet requires ESP. */ - int security; - char device[IFNAMSIZ]; - - struct net_device *dev; - - /** Max size of the header. */ - int header_n; - int mtu; - /** Statistics. */ - struct net_device_stats stats; - int recursion; -} Vnet; - -extern void vnet_print(struct IOStream *io); -extern void Vnet_print(struct Vnet *info, struct IOStream *io); - -extern int Vnet_lookup(struct VnetId *vnet, struct Vnet **info); -extern int Vnet_create(struct Vnet *info); -extern int Vnet_add(struct Vnet *info); -extern int Vnet_del(struct VnetId *vnet); -extern void Vnet_incref(struct Vnet *info); -extern void Vnet_decref(struct Vnet *info); -extern int Vnet_alloc(struct Vnet **info); -extern struct Vnet *vnet_physical; - -extern int skb_xmit(struct sk_buff *skb); -extern int skb_xmit_fwd(struct sk_buff *skb); -extern int vnet_skb_send(struct sk_buff *skb, struct VnetId *vnet); -extern int vnet_skb_recv(struct sk_buff *skb, struct Vnet *vnet); - -extern int vnet_check_context(struct VnetId *vnet, struct SkbContext *context, struct Vnet **vinfo); - -extern int vnet_tunnel_open(struct VnetId *vnet, struct VarpAddr *addr, struct Tunnel **tunnel); -extern int vnet_tunnel_lookup(struct VnetId *vnet, struct VarpAddr *addr, struct Tunnel **tunnel); -extern int vnet_tunnel_send(struct VnetId *vnet, struct VarpAddr *addr, struct sk_buff *skb); - -extern int vnet_init(void); - -extern int vnet_sa_security(u32 spi, int protocol, u32 addr); -extern int vnet_sa_create(u32 spi, int protocol, u32 addr, struct SAState **sa); - -enum { - VNET_PHYS = 1, - VNET_VIF = 2, -}; - -extern struct HashTable *vnet_table; - -#endif /* !__VNET_VNET_H__ */ diff --git a/vnet/src/vnet-module/vnet_dev.c b/vnet/src/vnet-module/vnet_dev.c deleted file mode 100644 index 6f79efdb5fc..00000000000 --- a/vnet/src/vnet-module/vnet_dev.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -#if !defined(CONFIG_BRIDGE) && !defined(CONFIG_BRIDGE_MODULE) -#warning Should configure Ethernet Bridging in kernel Network Options -#endif - -#ifndef CONFIG_BRIDGE_NETFILTER -#warning Should configure CONFIG_BRIDGE_NETFILTER in kernel -#endif - -static void vnet_dev_destructor(struct net_device *dev){ - Vnet *vnet = dev->priv; - if(vnet){ - if(vnet->dev == dev){ - vnet->dev = NULL; - } - dev->priv = NULL; - Vnet_decref(vnet); - } - free_netdev(dev); -} - -static struct net_device_stats *vnet_dev_get_stats(struct net_device *dev){ - static struct net_device_stats stats = {}; - Vnet *vnet = dev->priv; - return (vnet ? &vnet->stats : &stats); -} - -static int vnet_dev_change_mtu(struct net_device *dev, int mtu){ - int err = 0; - Vnet *vnet = dev->priv; - if (mtu < 68 || mtu > (vnet ? vnet->mtu : 1500)){ - err = -EINVAL; - goto exit; - } - dev->mtu = mtu; - exit: - return err; -} - -/** Remove the net device for a vnet. - * Safe to call if the vnet or its dev are null. - * - * @param vnet vnet - */ -void vnet_dev_remove(Vnet *vnet){ - if(vnet && vnet->dev){ - iprintf("> Removing vnet device %s\n", vnet->dev->name); - unregister_netdev(vnet->dev); - } -} - -static int vnet_dev_open(struct net_device *dev){ - int err = 0; - - netif_start_queue(dev); - return err; -} - -static int vnet_dev_stop(struct net_device *dev){ - int err = 0; - - netif_stop_queue(dev); - return err; -} - -static int vnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev){ - int err = 0; - Vnet *vnet = dev->priv; - int len = 0; - - if(!skb){ - wprintf("> skb NULL!\n"); - return -EINVAL; - } - if(!vnet){ - return -ENOTCONN; - } - if(vnet->recursion++) { - extern void print_skb(const char *msg, int count, struct sk_buff *skb); - char vnetbuf[VNET_ID_BUF]; - - vnet->stats.collisions++; - vnet->stats.tx_errors++; - wprintf("> recursion! vnet=%s\n", VnetId_ntoa(&vnet->vnet, vnetbuf)); - print_skb("RECURSION", 0, skb); - varp_print(iostdout); - kfree_skb(skb); - goto exit; - } - if(!skb->mac.raw){ - skb->mac.raw = skb->data; - } - len = skb->len; - // Must not use skb pointer after vnet_skb_send(). - err = vnet_skb_send(skb, &vnet->vnet); - if(err < 0){ - vnet->stats.tx_errors++; - } else { - vnet->stats.tx_packets++; - vnet->stats.tx_bytes += len; - } - exit: - vnet->recursion--; - return 0; -} - -void vnet_dev_set_multicast_list(struct net_device *dev){ -} - -#if 0 -static int vnet_dev_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){ - int err = 0; - - return err; -} - -void vnet_dev_tx_timeout(struct net_device *dev){ - //dev->trans_start = jiffies; - //netif_wake_queue(dev); -} - -static int (*eth_hard_header)(struct sk_buff *skb, - struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) = NULL; - -static int vnet_dev_hard_header(struct sk_buff *skb, - struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len){ - int err = 0; - - err = eth_hard_header(skb, dev, type, daddr, saddr, len); - if(err) goto exit; - skb->mac.raw = skb->data; - exit: - return err; -} -#endif - -int vnet_device_mac(const char *device, unsigned char *mac){ - int err; - struct net_device *dev; - - err = vnet_get_device(device, &dev); - if(err) goto exit; - memcpy(mac, dev->dev_addr, ETH_ALEN); - dev_put(dev); - exit: - return err; -} - -void vnet_dev_mac(unsigned char *mac){ - mac[0] = 0xAA; - mac[1] = 0xFF; - get_random_bytes(mac + 2, 4); -} - -/** Initial setup of the device for a vnet. - */ -static void vnet_dev_init(struct net_device *dev){ - ether_setup(dev); - -#if 0 - if(!eth_hard_header){ - eth_hard_header = dev->hard_header; - } - dev->hard_header = vnet_dev_hard_header; - //dev->do_ioctl = vnet_dev_do_ioctl; - //dev->tx_timeout = vnet_dev_tx_timeout; - //dev->watchdog_timeo = TX_TIMEOUT; - -#endif - - dev->open = vnet_dev_open; - dev->stop = vnet_dev_stop; - dev->destructor = vnet_dev_destructor; - dev->hard_start_xmit = vnet_dev_hard_start_xmit; - dev->get_stats = vnet_dev_get_stats; - dev->change_mtu = vnet_dev_change_mtu; - dev->set_multicast_list = vnet_dev_set_multicast_list; - - dev->flags |= IFF_DEBUG; - dev->flags |= IFF_PROMISC; - dev->flags |= IFF_ALLMULTI; - - vnet_dev_mac(dev->dev_addr); -} - -/** Complete the setup of the device for a vnet. - * Associate the device and the vnet and set mtu etc. - */ -static int vnet_dev_setup(Vnet *vnet, struct net_device *dev){ - int err; - - Vnet_incref(vnet); - dev->priv = vnet; - vnet->dev = dev; - dev->hard_header_len += vnet->header_n; - if(!etherip_in_udp){ - dev->mtu -= vnet->header_n; - } - vnet->mtu = dev->mtu; - iprintf("> Adding vnet device %s\n", dev->name); - err = register_netdev(dev); - if(err){ - eprintf("> register_netdev(%s) = %d\n", dev->name, err); - vnet_dev_destructor(dev); - } - return err; -} - -static inline int roundupto(int n, int k){ - return k * ((n + k - 1) / k); -} - -/** Add the interface (net device) for a vnet. - * Sets the dev field of the vnet on success. - * Does nothing if the vnet already has an interface. - * - * @param vnet vnet - * @return 0 on success, error code otherwise - */ -int vnet_dev_add(Vnet *vnet){ - int err = 0; - struct net_device *dev = NULL; - - if(vnet->dev) goto exit; - vnet->header_n = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct etheriphdr); - if(etherip_in_udp){ - vnet->header_n += sizeof(struct VnetMsgHdr); - vnet->header_n += sizeof(struct udphdr); - } - vnet->header_n = roundupto(vnet->header_n, 4); - dev = alloc_netdev(0, vnet->device, vnet_dev_init); - if(!dev){ - err = -ENOMEM; - goto exit; - } - err = vnet_dev_setup(vnet, dev); - if(err) goto exit; - rtnl_lock(); - dev_open(dev); - rtnl_unlock(); - - exit: - return err; -} diff --git a/vnet/src/vnet-module/vnet_dev.h b/vnet/src/vnet-module/vnet_dev.h deleted file mode 100644 index 438c1f023c4..00000000000 --- a/vnet/src/vnet-module/vnet_dev.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_VNET_DEV_H_ -#define _VNET_VNET_DEV_H_ - -struct Vnet; - -extern int vnet_dev_add(struct Vnet *vnet); -extern void vnet_dev_remove(struct Vnet *vnet); - -#endif diff --git a/vnet/src/vnet-module/vnet_eval.c b/vnet/src/vnet-module/vnet_eval.c deleted file mode 100644 index d0d8902e5f3..00000000000 --- a/vnet/src/vnet-module/vnet_eval.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include -#include - -#else - -#include "sys_kernel.h" -#include "spinlock.h" - -#include -#include -#include -#include - -#endif - -#include "vnet.h" -#include "varp.h" -#include "vif.h" -#include "vnet_forward.h" -#include "sa.h" - -#include "iostream.h" - -#ifdef __KERNEL__ -#include "kernel_stream.h" -#else -#include "file_stream.h" -#endif - -#include "sxpr_util.h" -#include "vnet_eval.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** Create a vnet. - * It is an error if a vnet with the same id exists. - * - * @param vnet vnet id - * @param device vnet device name - * @param security security level - * @return 0 on success, error code otherwise - */ -static int ctrl_vnet_add(VnetId *vnet, char *device, int security){ - int err = 0; - Vnet *vnetinfo = NULL; - - if(strlen(device) >= IFNAMSIZ){ - err = -EINVAL; - goto exit; - } - if(Vnet_lookup(vnet, NULL) == 0){ - err = -EEXIST; - goto exit; - } - err = Vnet_alloc(&vnetinfo); - if(err) goto exit; - vnetinfo->vnet = *vnet; - vnetinfo->security = security; - strcpy(vnetinfo->device, device); - err = Vnet_create(vnetinfo); - exit: - if(vnetinfo) Vnet_decref(vnetinfo); - return err; -} - -/** Create an entry for a vif with the given vnet and vmac. - * - * @param vnet vnet id - * @param vmac mac address - * @return 0 on success, error code otherwise - */ -static int ctrl_vif_add(VnetId *vnet, Vmac *vmac){ - int err = 0; - Vif *vif = NULL; - - err = Vnet_lookup(vnet, NULL); - if(err) goto exit; - err = vif_create(vnet, vmac, 0, &vif); - exit: - if(vif) vif_decref(vif); - return err; -} - -/** Delete a vif. - * - * @param vnet vnet id - * @param vmac mac address - * @return 0 on success, error code otherwise - */ -static int ctrl_vif_del(VnetId *vnet, Vmac *vmac){ - int err = 0; - Vif *vif = NULL; - - err = Vnet_lookup(vnet, NULL); - if(err) goto exit; - err = vif_lookup(vnet, vmac, &vif); - if(err) goto exit; - vif_remove(vnet, vmac); - exit: - if(vif) vif_decref(vif); - return err; -} - -/** (varp.print) - */ -static int eval_varp_print(Sxpr exp, IOStream *out, void *data){ - int err = 0; - vnet_print(out); - vif_print(out); - varp_print(out); - return err; -} - -static int eval_varp_list(Sxpr exp, IOStream *out, void *data){ - int err = 0; - varp_print(out); - return err; -} - -/** (varp.mcaddr (addr )) - */ -static int eval_varp_mcaddr(Sxpr exp, IOStream *out, void *data){ - int err =0; - Sxpr oaddr = intern("addr"); - uint32_t addr; - - err = child_addr(exp, oaddr, &addr); - if(err < 0) goto exit; - varp_set_mcast_addr(addr); - exit: - return err; -} - -/** (varp.flush) - */ -static int eval_varp_flush(Sxpr exp, IOStream *out, void *data){ - int err = 0; - varp_flush(); - return err; -} - -/** (vnet.add (id ) - * [(vnetif )] - * [(security { none | auth | conf } )] - * ) - */ -int eval_vnet_add(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr oid = intern("id"); - Sxpr osecurity = intern("security"); - Sxpr ovnetif = intern("vnetif"); - Sxpr csecurity; - VnetId vnet = {}; - char *device = NULL; - char dev[IFNAMSIZ] = {}; - char *security = NULL; - int sec; - - err = child_vnet(exp, oid, &vnet); - if(err) goto exit; - child_string(exp, ovnetif, &device); - if(!device){ - snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1])); - device = dev; - } - csecurity = sxpr_child_value(exp, osecurity, intern("none")); - err = stringof(csecurity, &security); - if(err) goto exit; - if(strcmp(security, "none")==0){ - sec = 0; - } else if(strcmp(security, "auth")==0){ - sec = SA_AUTH; - } else if(strcmp(security, "conf")==0){ - sec = SA_CONF; - } else { - err = -EINVAL; - goto exit; - } - err = ctrl_vnet_add(&vnet, device, sec); - exit: - return err; -} - -/** Delete a vnet. - * - * (vnet.del (id )) - * - * @param vnet vnet id - * @return 0 on success, error code otherwise - */ -static int eval_vnet_del(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr oid = intern("id"); - VnetId vnet = {}; - - err = child_vnet(exp, oid, &vnet); - if(err) goto exit; - err = Vnet_del(&vnet); - exit: - return err; -} - -static int eval_vnet_list(Sxpr exp, IOStream *out, void *data){ - int err = 0; - vnet_print(out); - return err; -} - -/** (vif.add (vnet ) (vmac )) - */ -static int eval_vif_add(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr ovnet = intern("vnet"); - Sxpr ovmac = intern("vmac"); - VnetId vnet = {}; - Vmac vmac = {}; - - err = child_vnet(exp, ovnet, &vnet); - if(err) goto exit; - err = child_mac(exp, ovmac, vmac.mac); - if(err) goto exit; - err = ctrl_vif_add(&vnet, &vmac); - exit: - return err; -} - -/** (vif.del (vnet ) (vmac )) - */ -static int eval_vif_del(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr ovnet = intern("vnet"); - Sxpr ovmac = intern("vmac"); - VnetId vnet = {}; - Vmac vmac = {}; - - err = child_vnet(exp, ovnet, &vnet); - if(err) goto exit; - err = child_mac(exp, ovmac, vmac.mac); - if(err) goto exit; - err = ctrl_vif_del(&vnet, &vmac); - exit: - return err; -} - -static int eval_vif_list(Sxpr exp, IOStream *out, void *data){ - int err = 0; - vif_print(out); - return err; -} - -/** Eval a vnet add request. - * - * (peer.add (addr ) [(port )]) - * - * @param exp request - * @param out output stream - * @param data data - * @return 0 on success, error code otherwise - */ -int eval_peer_add(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr oaddr = intern("addr"); - Sxpr oport = intern("port"); - VarpAddr addr = { .family = AF_INET }; - int port; - - err = child_addr(exp, oaddr, &addr.u.ip4.s_addr); - if(err < 0) goto exit; - err = child_int(exp, oport, &port); - if(err < 0){ - err = 0; - port = varp_port; - } - if(err) goto exit; - err = vnet_peer_add(&addr, port); - exit: - return err; -} - -/** Eval a peer delete request. - * - * (peer.del (addr )) - * - * @param vnetd vnetd - * @param exp request - * @param out output stream - * @param data data - * @return 0 on success, error code otherwise - */ -static int eval_peer_del(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Sxpr oaddr = intern("addr"); - VarpAddr addr = { .family = AF_INET }; - - err = child_addr(exp, oaddr, &addr.u.ip4.s_addr); - if(err < 0) goto exit; - err = vnet_peer_del(&addr); - exit: - return err; -} - -/** Eval a peer list request. - * - * (peer.list) - * - * @param exp request - * @param out output stream - * @param data data - * @return 0 on success, error code otherwise - */ -static int eval_peer_list(Sxpr exp, IOStream *out, void *data){ - int err = 0; - vnet_peer_print(out); - return err; -} - -int vnet_eval_defs(SxprEval *defs, Sxpr exp, IOStream *io, void *data){ - int err = 0; - SxprEval *def; - - iprintf("> "); objprint(iostdout, exp, 0); IOStream_print(iostdout, "\n"); - err = -ENOSYS; - for(def = defs; !NONEP(def->name); def++){ - if(sxpr_elementp(exp, def->name)){ - err = def->fn(exp, io, data); - break; - } - } - iprintf("< err=%d\n", err); - return err; -} - -int vnet_eval(Sxpr exp, IOStream *io, void *data){ - SxprEval defs[] = { - { .name = intern("peer.add"), .fn = eval_peer_add }, - { .name = intern("peer.del"), .fn = eval_peer_del }, - { .name = intern("peer.list"), .fn = eval_peer_list }, - { .name = intern("varp.flush"), .fn = eval_varp_flush }, - { .name = intern("varp.list"), .fn = eval_varp_list }, - { .name = intern("varp.mcaddr"), .fn = eval_varp_mcaddr }, - { .name = intern("varp.print"), .fn = eval_varp_print }, - { .name = intern("vif.add"), .fn = eval_vif_add }, - { .name = intern("vif.del"), .fn = eval_vif_del }, - { .name = intern("vif.list"), .fn = eval_vif_list }, - { .name = intern("vnet.add"), .fn = eval_vnet_add }, - { .name = intern("vnet.del"), .fn = eval_vnet_del }, - { .name = intern("vnet.list"), .fn = eval_vnet_list }, - { .name = ONONE, .fn = NULL } }; - return vnet_eval_defs(defs, exp, io, data); -} diff --git a/vnet/src/vnet-module/vnet_eval.h b/vnet/src/vnet-module/vnet_eval.h deleted file mode 100644 index a3dddedcec9..00000000000 --- a/vnet/src/vnet-module/vnet_eval.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_EVAL_H_ -#define _VNET_EVAL_H_ - -#include "sxpr.h" -struct IOStream; - -typedef struct SxprEval { - Sxpr name; - int (*fn)(Sxpr, struct IOStream *, void *data); -} SxprEval; - -extern int eval_peer_add(Sxpr exp, struct IOStream *out, void *data); -extern int eval_vnet_add(Sxpr exp, struct IOStream *out, void *data); -extern int vnet_eval_defs(SxprEval *defs, Sxpr exp, struct IOStream *out, void *data); -extern int vnet_eval(Sxpr exp, struct IOStream *out, void *data); - -#endif /* ! _VNET_EVAL_H_ */ diff --git a/vnet/src/vnet-module/vnet_forward.c b/vnet/src/vnet-module/vnet_forward.c deleted file mode 100644 index 74a55c45820..00000000000 --- a/vnet/src/vnet-module/vnet_forward.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2005, 2006 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#else - -#include -#include - -#include "sys_kernel.h" -#include "spinlock.h" -#include "skbuff.h" -#include -#include - -#endif - -#include -#include -#include -#include -#include - -#include "allocate.h" -#include "iostream.h" -#include "hash_table.h" -#include "vnet_forward.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -extern int _skb_xmit(struct sk_buff *skb, uint32_t saddr); - -typedef struct VnetPeer { - struct VarpAddr addr; - uint16_t port; - atomic_t refcount; - int tx_packets; - int rx_packets; -} VnetPeer; - -static HashTable *vnet_peer_table = NULL; -static rwlock_t vnet_peer_table_lock = RW_LOCK_UNLOCKED; - -#define vnet_peer_read_lock(flags) read_lock_irqsave(&vnet_peer_table_lock, (flags)) -#define vnet_peer_read_unlock(flags) read_unlock_irqrestore(&vnet_peer_table_lock, (flags)) -#define vnet_peer_write_lock(flags) write_lock_irqsave(&vnet_peer_table_lock, (flags)) -#define vnet_peer_write_unlock(flags) write_unlock_irqrestore(&vnet_peer_table_lock, (flags)) - -static void VnetPeer_decref(VnetPeer *peer){ - if(!peer) return; - if(atomic_dec_and_test(&peer->refcount)){ - kfree(peer); - } -} - -static void VnetPeer_incref(VnetPeer *peer){ - if(!peer) return; - atomic_inc(&peer->refcount); -} - -static void VnetPeer_print(VnetPeer *peer, IOStream *io){ - char addrbuf[VARP_ADDR_BUF]; - - IOStream_print(io, "(vnet_peer\n"); - IOStream_print(io, " (addr %s)\n", VarpAddr_ntoa(&peer->addr, addrbuf)); - IOStream_print(io, " (port %d)\n", htons(peer->port)); - IOStream_print(io, " (tx_packets %d)\n", peer->tx_packets); - IOStream_print(io, " (rx_packets %d)\n", peer->tx_packets); - IOStream_print(io, ")\n"); -} - -static int VnetPeer_forward(VnetPeer *peer, struct sk_buff *fwdskb){ - int err = 0; - const int ip_n = sizeof(struct iphdr); - const int udp_n = sizeof(struct udphdr); - const int vnet_n = sizeof(struct VnetMsgHdr); - int head_n = 16 + ip_n + udp_n + vnet_n; - int push_n = 0; - struct sk_buff *skb = NULL; - struct VnetMsgHdr *vhdr; - uint32_t saddr = 0; - uint16_t sport = varp_port; - uint32_t daddr = peer->addr.u.ip4.s_addr; - uint16_t dport = varp_port; - - if(!fwdskb) goto exit; - if(daddr == fwdskb->nh.iph->saddr){ - // Don't forward if the skb src addr is the peer addr. - dprintf("> Forward loop on " IPFMT "\n", NIPQUAD(daddr)); - goto exit; - } - // On entry fwdskb->data should be at fwdskb->nh.raw (adjust if not). - // Also fwdskb->h.raw and fwdskb->nh.raw are set. - if(fwdskb->data > fwdskb->nh.raw){ - push_n = fwdskb->data - fwdskb->nh.raw; - head_n += push_n; - } - // If has headroom, copies header (which incs ref on dst), - // otherwise only clones header, which does not inc ref on dst. - skb = skb_realloc_headroom(fwdskb, head_n); - //skb = skb_copy_expand(fwdskb, head_n, 0, GFP_ATOMIC); - if(!skb){ - err = -ENOMEM; - goto exit; - } - - if(push_n){ - skb_push(skb, push_n); - } - -#ifdef DEBUG - printk("\nOriginal packet:\n"); - print_iphdr(__FUNCTION__, skb); - skb_print_bits(__FUNCTION__, skb, 0, skb->len); -#endif - - skb->mac.raw = NULL; - vhdr = (void*)skb_push(skb, vnet_n); - vhdr->id = htons(VFWD_ID); - vhdr->opcode = 0; - - // Setup the UDP header. - skb->h.raw = skb_push(skb, udp_n); - skb->h.uh->source = sport; // Source port. - skb->h.uh->dest = dport; // Destination port. - skb->h.uh->len = htons(skb->len); // Total packet length (bytes). - skb->h.uh->check = 0; - - // Setup the IP header. - skb->nh.raw = skb_push(skb, ip_n); - skb->nh.iph->version = 4; // Standard version. - skb->nh.iph->ihl = ip_n / 4; // IP header length (32-bit words). - skb->nh.iph->tos = 0; // No special type-of-service. - skb->nh.iph->tot_len = htons(skb->len); // Total packet length (bytes). - skb->nh.iph->id = 0; // No flow id. - skb->nh.iph->protocol = IPPROTO_UDP; // IP protocol number. - skb->nh.iph->frag_off = 0; - skb->nh.iph->ttl = 64; // Linux default time-to-live. - skb->nh.iph->saddr = saddr; // Source address. - skb->nh.iph->daddr = daddr; // Destination address. - skb->nh.iph->check = 0; - -#ifdef DEBUG - printk("\nWrapped packet:\n"); - print_iphdr(__FUNCTION__, skb); - print_udphdr(__FUNCTION__, skb); - skb_print_bits(__FUNCTION__, skb, 0, skb->len); -#endif - - err = _skb_xmit(skb, saddr); - peer->tx_packets++; - - exit: - if(err < 0) kfree_skb(skb); - return err; -} - -int vnet_peer_get(VarpAddr *addr, VnetPeer **peer){ - unsigned long flags; - - vnet_peer_read_lock(flags); - *peer = HashTable_get(vnet_peer_table, addr); - VnetPeer_incref(*peer); - vnet_peer_read_unlock(flags); - return (*peer ? 0 : -ENOENT); -} - -int vnet_peer_add(VarpAddr *addr, uint16_t port){ - int err = 0; - unsigned long flags; - VnetPeer *peer; - - vnet_peer_write_lock(flags); - peer = HashTable_get(vnet_peer_table, addr); - if(peer){ - VnetPeer_incref(peer); - goto exit; - } - peer = ALLOCATE(VnetPeer); - if(!peer){ - err = -ENOMEM; - goto exit; - } - peer->addr = *addr; - peer->port = port; - VnetPeer_incref(peer); - if(!HashTable_add(vnet_peer_table, &peer->addr, peer)){ - VnetPeer_decref(peer); - err = -ENOMEM; - } - exit: - vnet_peer_write_unlock(flags); - return err; -} - -int vnet_peer_del(VarpAddr *addr){ - int ret = 0; - unsigned long flags; - - vnet_peer_write_lock(flags); - ret = HashTable_remove(vnet_peer_table, addr); - vnet_peer_write_unlock(flags); - return ret; -} - -void vnet_peer_print(IOStream *io){ - HashTable_for_decl(entry); - unsigned long flags; - - if(!vnet_peer_table) return; - vnet_peer_read_lock(flags); - HashTable_for_each(entry, vnet_peer_table){ - VnetPeer *peer = entry->value; - VnetPeer_print(peer, io); - } - vnet_peer_read_unlock(flags); -} - -int vnet_forward_send(struct sk_buff *skb){ - int err = 0; - unsigned long flags; - HashTable_for_decl(entry); - int count = 0; - - if(!vnet_peer_table){ - goto exit; - } - vnet_peer_read_lock(flags); - HashTable_for_each(entry, vnet_peer_table){ - VnetPeer *peer = entry->value; - VnetPeer_forward(peer, skb); - count++; - } - vnet_peer_read_unlock(flags); - exit: - return err; -} - -int vnet_forward_recv(struct sk_buff *skb){ - int err = 0; - VarpAddr addr = { .family = AF_INET }; - VnetPeer *peer = NULL; - unsigned char eth[ETH_HLEN] = {}; - struct sk_buff *recvskb; - - if(!vnet_peer_table){ - dprintf("> no table\n"); - return -ENOSYS; - } - // On entry mac.raw, h.raw, nh.raw are set. - // skb->data points after the fwd vnet header, at the complete - // forwarded packet (which has IP hdr, no eth hdr). - - // Save the eth hdr and source addr (peer). - memcpy(eth, skb->mac.raw, ETH_HLEN); - addr.u.ip4.s_addr = skb->nh.iph->saddr; - err = vnet_peer_get(&addr, &peer); - if(err){ - wprintf("> no peer for " IPFMT "\n", NIPQUAD(skb->nh.iph->saddr)); - goto exit; - } - peer->rx_packets++; - skb->mac.raw = NULL; - skb->nh.raw = skb->data; - skb->h.raw = skb->data + sizeof(struct iphdr); - if(!skb->nh.iph->saddr){ - skb->nh.iph->saddr = addr.u.ip4.s_addr; - } -#ifdef __KERNEL__ - // Fix IP options, checksum, skb dst, netfilter state. - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); - skb->dev = NULL; - dst_release(skb->dst); - skb->dst = NULL; - nf_reset(skb); -#endif // __KERNEL__ - - skb->mac.raw = skb->nh.raw - ETH_HLEN; - memcpy(skb->mac.raw, eth, ETH_HLEN); - - // Map destination mcast addresses to our mcast address. - if(MULTICAST(skb->nh.iph->daddr)){ - skb->nh.iph->daddr = varp_mcast_addr; - //xmit does this: ip_eth_mc_map(varp_mcast_addr, eth_hdr(skb)->h_dest); - } - - // Handle (a copy of) it ourselves, because - // if it is looped-back by xmit it will be ignored. - recvskb = alloc_skb(skb->len, GFP_ATOMIC); - if(recvskb){ - recvskb->protocol = htons(ETH_P_IP); - - recvskb->nh.raw = skb_put(recvskb, skb->len); - recvskb->h.raw = recvskb->data + sizeof(struct iphdr); - skb_copy_bits(skb, 0, recvskb->data, skb->len); - - // Data points at the unwrapped iphdr, but varp_handle_message() - // expects it to point at the udphdr, so pull. - skb_pull_vn(recvskb, sizeof(struct iphdr)); - if(varp_handle_message(recvskb) <= 0){ - kfree_skb(recvskb); - } - } - err = _skb_xmit(skb, skb->nh.iph->saddr); - if(err >= 0) err = 1; - exit: - return err; -} - -/** Hash function for keys in the peer table. - */ -static Hashcode peer_key_hash_fn(void *k){ - return hash_hvoid(0, k, sizeof(struct VarpAddr)); -} - -/** Equality function for keys in the peer table. - */ -static int peer_key_equal_fn(void *k1, void *k2){ - return memcmp(k1, k2, sizeof(struct VarpAddr)) == 0; -} - -static void peer_entry_free_fn(HashTable *table, HTEntry *entry){ - if(!entry) return; - VnetPeer_decref((VnetPeer*)entry->value); - HTEntry_free(entry); -} - -int vnet_forward_init(void){ - int err = 0; - if(vnet_peer_table) goto exit; - vnet_peer_table = HashTable_new(0); - if(!vnet_peer_table){ - err = -ENOMEM; - goto exit; - } - vnet_peer_table->key_size = sizeof(struct VarpAddr); - vnet_peer_table->key_equal_fn = peer_key_equal_fn; - vnet_peer_table->key_hash_fn = peer_key_hash_fn; - vnet_peer_table->entry_free_fn = peer_entry_free_fn; - exit: - return err; -} - -void vnet_forward_exit(void){ - HashTable_free(vnet_peer_table); - vnet_peer_table = NULL; -} diff --git a/vnet/src/vnet-module/vnet_forward.h b/vnet/src/vnet-module/vnet_forward.h deleted file mode 100644 index c84f495c717..00000000000 --- a/vnet/src/vnet-module/vnet_forward.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2005, 2006 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_FORWARD_H_ -#define _VNET_FORWARD_H_ - -#include - -struct sk_buff; -struct IOStream; - -extern int vnet_peer_add(struct VarpAddr *addr, uint16_t port); -extern int vnet_peer_del(struct VarpAddr *addr); -extern void vnet_peer_print(struct IOStream *io); - -extern int vnet_forward_send(struct sk_buff *skb); -extern int vnet_forward_recv(struct sk_buff *skb); -extern int vnet_forward_init(void); -extern void vnet_forward_exit(void); - -#endif /* _VNET_FORWARD_H_ */ diff --git a/vnet/src/vnet-module/vnet_ioctl.c b/vnet/src/vnet-module/vnet_ioctl.c deleted file mode 100644 index 6629c2e942d..00000000000 --- a/vnet/src/vnet-module/vnet_ioctl.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#include -#include - -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include "vif.h" -#include "vnet.h" -#include "varp.h" -#include "vnet_dev.h" -#include "vnet_eval.h" -#include "vnet_forward.h" - -#include "iostream.h" -#include "kernel_stream.h" -#include "mem_stream.h" -#include "sys_string.h" -#include "sys_net.h" -#include "sxpr_parser.h" - -#define MODULE_NAME "VNET" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** @file - * - * Kernel interface to files in /proc. - * todo: Add a sysfs interface using kobject. - */ - -#define PROC_ROOT "/proc/" -#define PROC_ROOT_LEN 6 -#define MODULE_ROOT PROC_ROOT "vnet" - -enum { - VNET_POLICY = 1, - VNET_VNETS, - VNET_VIFS, - VNET_VARP, - VNET_PEERS, -}; - -typedef struct proc_dir_entry ProcEntry; -typedef struct inode Inode; -typedef struct file File; - -static int proc_open_fn(struct inode *inode, File *file); -//static ssize_t proc_read_fn(File *file, char *buffer, size_t count, loff_t *offset); -//static ssize_t proc_write_fn(File *file, const char *buffer, size_t count, loff_t *offset) ; -//static int proc_flush_fn(File *file); -static loff_t proc_lseek_fn(File * file, loff_t offset, int orig); -static int proc_ioctl_fn(struct inode *inode, File *file, unsigned opcode, unsigned long arg); -//static int proc_release_fn(struct inode *inode, File *file); - -static int ProcEntry_has_name(ProcEntry *entry, const char *name, int namelen){ - dprintf("> name=%.*s entry=%.*s\n", namelen, name, entry->namelen, entry->name); - if(!entry || !entry->low_ino) return FALSE; - if(entry->namelen != namelen) return FALSE; - return memcmp(name, entry->name, namelen) == 0; -} - -// Set f->f_error on error? -// Does interface stop r/w on first error? -// Is release called after an error? -// - -static int proc_get_parser(File *file, Parser **val){ - int err = 0; - Parser *parser = NULL; - parser = file->private_data; - if(!parser){ - parser = Parser_new(); - if(!parser){ - err = -ENOMEM; - goto exit; - } - file->private_data = parser; - } - exit: - *val = parser; - return err; -} - -static int proc_open_fn(Inode *inode, File *file){ - // User open. - // Return errcode or 0 on success. - // Can stuff data in file->private_data (void*). - // Get entry from - //ProcEntry *entry = (ProcEntry *)inode->u.generic_ip; - //file->private_data = NULL; - //file->f_dentry->d_ino is inode. - // Check for user privilege - deny otherwise. - // -EACCESS - int err = 0; - dprintf(">\n"); - file->private_data = NULL; - return err; -} - -static ssize_t proc_read_fn(File *file, char *buffer, - size_t count, loff_t *offset){ - // User read. - // Copy data to user buffer, increment offset by count, return count. - dprintf(">\n"); - count = 0; - //if(copy_to_user(buffer, data, count)){ - // return -EFAULT; - //} - //*offset += count; - return count; -} - -#if 0 -static ssize_t proc_write_fn(File *file, const char *buffer, - size_t count, loff_t *offset) { - return -EINVAL; -} -#endif - - -#if 0 -static int proc_flush_fn(File *file){ - // User flush. - int writing = (file->f_flags & O_ACCMODE) == O_WRONLY; - int f_count = atomic_read(&file->f_count); - if (writing && f_count == 1) { - ProcEntry *pentry = (ProcEntry *)file->f_dentry->d_inode->u.generic_ip; - // ... - } - return retval; -} -#endif - -#ifndef SEEK_SET -enum { - /** Offset from start. */ - SEEK_SET = 0, - /** Offset from current position. */ - SEEK_CUR = 1, - /** Offset from size of file. */ - SEEK_END = 2 -}; -#endif /* !SEEK_SET */ - -static loff_t proc_lseek_fn(File * file, loff_t offset, int from){ - // User lseek. - dprintf(">\n"); - switch(from){ - case SEEK_SET: - break; - case SEEK_CUR: - offset += file->f_pos; - break; - case SEEK_END: - return -EINVAL; - default: - return -EINVAL; - } - if(offset < 0) return -EINVAL; - file->f_pos = offset; - return offset; -} - -static int proc_ioctl_fn(Inode *inode, File *file, - unsigned opcode, unsigned long arg){ - // User ioctl. - dprintf(">\n"); - return 0; -} - -static ssize_t proc_policy_write_fn(File *file, const char *buffer, - size_t count, loff_t *offset) { - // User write. - // Copy data into kernel space from buffer. - // Increment offset by count, return count (or code). - int err = 0; - char *data = NULL; - Parser *parser = NULL; - - err = proc_get_parser(file, &parser); - if(err) goto exit; - data = allocate(count); - if(!data){ - err = -ENOMEM; - goto exit; - } - err = copy_from_user(data, buffer, count); - if(err) goto exit; - *offset += count; - err = Parser_input(parser, data, count); - exit: - deallocate(data); - err = (err < 0 ? err : count); - return err; -} - -static int proc_policy_release_fn(Inode *inode, File *file){ - // User close. - // Cleanup file->private_data, return errcode. - int err = 0; - Parser *parser = NULL; - Sxpr obj, l; - - dprintf(">\n"); - err = proc_get_parser(file, &parser); - if(err) goto exit; - err = Parser_input(parser, NULL, 0); - if(err) goto exit; - obj = parser->val; - for(l = obj; CONSP(l); l = CDR(l)){ - err = vnet_eval(CAR(l), iostdout, NULL); - if(err) break; - } - exit: - Parser_free(parser); - file->private_data = NULL; - dprintf("< err=%d\n", err); - return err; -} - -static int proc_io_open(Inode *inode, File *file, IOStream **val){ - int err = 0; - IOStream *io = mem_stream_new(); - if(!io){ - err = -ENOMEM; - goto exit; - } - file->private_data = io; - exit: - *val = (err ? NULL: io); - return err; -} - -static ssize_t proc_io_read_fn(File *file, char *buffer, - size_t count, loff_t *offset){ - // User read. - // Copy data to user buffer, increment offset by count, return count. - int err = 0; - char kbuf[1024] = {}; - int kbuf_n = sizeof(kbuf); - int k, n = 0; - char *ubuf = buffer; - IOStream *io = file->private_data; - - dprintf(">\n"); - if(!io) goto exit; - while(n < count){ - k = count - n; - if(k > kbuf_n){ - k = kbuf_n; - } - k = IOStream_read(io, kbuf, k); - if(k <= 0) break; - if(copy_to_user(ubuf, kbuf, k)){ - err = -EFAULT; - goto exit; - } - n += k; - ubuf += k; - } - *offset += n; - exit: - return (err ? err : n); -} - -static int proc_io_release_fn(Inode *inode, File *file){ - // User close. - int err = 0; - IOStream *io = file->private_data; - if(io) IOStream_close(io); - dprintf("< err=%d\n", err); - return err; -} - -static int proc_vnets_open_fn(Inode *inode, File *file){ - int err = 0; - IOStream *io; - if(proc_io_open(inode, file, &io)) goto exit; - vnet_print(io); - exit: - return err; -} - -static int proc_vifs_open_fn(Inode *inode, File *file){ - int err = 0; - IOStream *io; - if(proc_io_open(inode, file, &io)) goto exit; - vif_print(io); - exit: - return err; -} - -static int proc_peers_open_fn(Inode *inode, File *file){ - int err = 0; - IOStream *io; - if(proc_io_open(inode, file, &io)) goto exit; - vnet_peer_print(io); - exit: - return err; -} - -static int proc_varp_open_fn(Inode *inode, File *file){ - int err = 0; - IOStream *io; - if(proc_io_open(inode, file, &io)) goto exit; - varp_print(io); - exit: - return err; -} - -static struct file_operations proc_policy_ops = { - open: proc_open_fn, - read: proc_read_fn, - write: proc_policy_write_fn, - //flush: proc_flush_fn, - llseek: proc_lseek_fn, - ioctl: proc_ioctl_fn, - release: proc_policy_release_fn, -}; - -static struct file_operations proc_vnets_ops = { - open: proc_vnets_open_fn, - read: proc_io_read_fn, - release: proc_io_release_fn, -}; - -static struct file_operations proc_vifs_ops = { - open: proc_vifs_open_fn, - read: proc_io_read_fn, - release: proc_io_release_fn, -}; - -static struct file_operations proc_peers_ops = { - open: proc_peers_open_fn, - read: proc_io_read_fn, - release: proc_io_release_fn, -}; - -static struct file_operations proc_varp_ops = { - open: proc_varp_open_fn, - read: proc_io_read_fn, - release: proc_io_release_fn, -}; - -static ProcEntry *proc_fs_root = &proc_root; - -static int proc_path_init(const char *path, const char **rest){ - int err = 0; - - if(!path){ - err = -EINVAL; - goto exit; - } - if(*path == '/'){ - if(strncmp(PROC_ROOT, path, PROC_ROOT_LEN)){ - err = -EINVAL; - } else { - path += PROC_ROOT_LEN; - } - } - exit: - *rest = path; - return err; -} - -/** Parse a path relative to `dir'. If dir is null or the proc root - * the path is relative to "/proc/", and the leading "/proc/" may be - * supplied. - * - */ -static ProcEntry * ProcFS_lookup(const char *path, ProcEntry *dir){ - const char *pathptr = path, *next = NULL; - ProcEntry *entry, *result = NULL; - int pathlen; - - if(dir && (dir != proc_fs_root)){ - entry = dir; - } else { - if(proc_path_init(path, &pathptr)) goto exit; - entry = proc_fs_root; - } - if(!pathptr || !*pathptr) goto exit; - while(1){ - next = strchr(pathptr, '/'); - pathlen = (next ? next - pathptr : strlen(pathptr)); - for(entry = entry->subdir; entry ; entry = entry->next) { - if(ProcEntry_has_name(entry, pathptr, pathlen)) break; - } - if (!entry) break; - if(!next){ - result = entry; - break; - } - pathptr = next + 1; - } - exit: - return result; -} - -static ProcEntry *ProcFS_register(const char *name, ProcEntry *dir, - int val, struct file_operations *ops){ - mode_t mode = 0; - ProcEntry *entry; - - entry = create_proc_entry(name, mode, dir); - if(entry){ - entry->proc_fops = ops; - entry->data = (void*)val; // Whatever data we need. - } - return entry; -} - -static ProcEntry *ProcFS_mkdir(const char *name, ProcEntry *parent){ - ProcEntry *entry = NULL; - entry = ProcFS_lookup(name, parent); - if(!entry){ - const char *path; - if(proc_path_init(name, &path)) goto exit; - entry = proc_mkdir(path, parent); - } - exit: - return entry; -} - -static void ProcFS_remove(const char *name, ProcEntry *parent){ - remove_proc_entry(name, parent); -} - -static void ProcFS_rmrec_entry(ProcEntry *entry){ - if(entry){ - // Don't want to remove /proc itself! - if(entry->parent == entry) return; - while(entry->subdir){ - ProcFS_rmrec_entry(entry->subdir); - } - dprintf("> remove %s\n", entry->name); - ProcFS_remove(entry->name, entry->parent); - } -} - -static void ProcFS_rmrec(const char *name, ProcEntry *parent){ - ProcEntry *entry; - - dprintf("> name=%s\n", name); - entry = ProcFS_lookup(name, parent); - if(entry){ - ProcFS_rmrec_entry(entry); - } - dprintf("<\n"); -} - -void __init ProcFS_init(void){ - ProcEntry *root_entry; - ProcEntry *policy_entry; - ProcEntry *vnets_entry; - ProcEntry *vifs_entry; - ProcEntry *peers_entry; - ProcEntry *varp_entry; - - dprintf(">\n"); - root_entry = ProcFS_mkdir(MODULE_ROOT, NULL); - if(!root_entry) goto exit; - policy_entry = ProcFS_register("policy", root_entry, VNET_POLICY, &proc_policy_ops); - vnets_entry = ProcFS_register("vnets", root_entry, VNET_VNETS, &proc_vnets_ops); - vifs_entry = ProcFS_register("vifs", root_entry, VNET_VIFS, &proc_vifs_ops); - peers_entry = ProcFS_register("peers", root_entry, VNET_PEERS, &proc_peers_ops); - varp_entry = ProcFS_register("varp", root_entry, VNET_VARP, &proc_varp_ops); - exit: - dprintf("<\n"); -} - -void __exit ProcFS_exit(void){ - dprintf(">\n"); - ProcFS_rmrec(MODULE_ROOT, NULL); - dprintf("<\n"); -} diff --git a/vnet/src/vnet-module/vnet_ioctl.h b/vnet/src/vnet-module/vnet_ioctl.h deleted file mode 100644 index e57763284b4..00000000000 --- a/vnet/src/vnet-module/vnet_ioctl.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free software Foundation, Inc., - * 59 Temple Place, suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _VNET_VNET_IOCTL_H_ -#define _VNET_VNET_IOCTL_H_ - -extern void ProcFS_init(void); -extern void ProcFS_exit(void); - -#endif /* ! _VNET_VNET_IOCTL_H_ */ diff --git a/vnet/src/vnetd/Makefile b/vnet/src/vnetd/Makefile deleted file mode 100644 index c4e566f3a24..00000000000 --- a/vnet/src/vnetd/Makefile +++ /dev/null @@ -1,121 +0,0 @@ -# -*- mode: Makefile; -*- -#---------------------------------------------------------------------------- -# Copyright (C) 2004 Mike Wray . -# -# This library is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation; either version 2.1 of the -# License, or (at your option) any later version. This library is -# distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#---------------------------------------------------------------------------- - -VNET_ROOT ?= $(shell cd .. && pwd) -include $(VNET_ROOT)/Make.env - -.PHONY: all -all: vnetd - -#---------------------------------------------------------------------------- - -# Comment out when outside xen. -#include $(XEN_ROOT)/tools/Rules.mk - -INSTALL_PROG ?= $(INSTALL) -m0755 -p - -INCLUDES += -I$(LIBXUTIL_DIR) -INCLUDES += -I$(VNET_MODULE_DIR) -INCLUDES += -I$(shell pwd) - -#---------------------------------------------------------------------------- -# GC. - -INCLUDES += -I$(GC_INCLUDE) -#LIBS += -L$(GC_LIB_DIR) -#CPPFLAGS += -D USE_GC - -# Sometimes linux/atomic.h is not #ifdef __KERNEL__. -CPPFLAGS += -D __ARCH_I386_ATOMIC__ - -#---------------------------------------------------------------------------- -CFLAGS += -O3 -CFLAGS += $(INCLUDES) $(LIBS) - -LDFLAGS += $(LIBS) - -# Dependencies. Gcc generates them for us. -CFLAGS += -Wp,-MD,.$(@F).d -PROG_DEP = .*.d - -vpath %.c $(LIBXUTIL_DIR) -vpath %.c $(VNET_MODULE_DIR) - -IPATHS:=$(INCLUDES:-I=) -vpath %.h $(IPATHS) - -#---------------------------------------------------------------------------- -VNETD_SRC:= -VNETD_SRC+= connection.c -VNETD_SRC+= select.c -VNETD_SRC+= timer.c -VNETD_SRC+= spinlock.c -VNETD_SRC+= skbuff.c -VNETD_SRC+= vnetd.c - -VNETD_SRC+= skb_util.c -VNETD_SRC+= sxpr_util.c -VNETD_SRC+= timer_util.c -VNETD_SRC+= etherip.c -VNETD_SRC+= vnet.c -VNETD_SRC+= vnet_eval.c -VNETD_SRC+= vnet_forward.c -VNETD_SRC+= vif.c -VNETD_SRC+= tunnel.c -VNETD_SRC+= sa.c -VNETD_SRC+= varp.c - -#---------------------------------------------------------------------------- -LIB_SRC:= -LIB_SRC+= allocate.c -LIB_SRC+= enum.c -LIB_SRC+= file_stream.c -LIB_SRC+= hash_table.c -LIB_SRC+= iostream.c -LIB_SRC+= lexis.c -LIB_SRC+= socket_stream.c -LIB_SRC+= string_stream.c -LIB_SRC+= sxpr.c -LIB_SRC+= sxpr_parser.c -LIB_SRC+= sys_net.c -LIB_SRC+= sys_string.c -LIB_SRC+= util.c - -VNETD_SRC+=$(LIB_SRC) - -VNETD_OBJ := $(VNETD_SRC:.c=.o) - -#VNETD_LIBS:= $(GC_LIB_SO) -#VNETD_LIBS:= -lgc -#VNETD_LIBS:= $(GC_LIB_A) - -vnetd: $(VNETD_OBJ) - $(CC) $(CFLAGS) -o $@ $^ $(VNETD_LIBS) -ldl -lpthread - -.PHONY: install -install: vnetd - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) vnetd $(DESTDIR)$(SBINDIR) - -.PHONY: clean -clean: - -@$(RM) *.a *.o *~ - -@$(RM) vnetd - -@$(RM) $(PROG_DEP) - --include $(PROG_DEP) diff --git a/vnet/src/vnetd/connection.c b/vnet/src/vnetd/connection.c deleted file mode 100644 index e457914cffa..00000000000 --- a/vnet/src/vnetd/connection.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2003 - 2004 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include "allocate.h" -#include "connection.h" -#include "file_stream.h" -#include "socket_stream.h" - -#define MODULE_NAME "conn" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -/** Initialize a file stream from a file desciptor. - * - * @param fd file descriptor - * @param mode file mode - * @param buffered make the stream buffered if 1, unbuffered if 0 - * @param io return parameter for the stream - * @return 0 on success, error code otherwise - */ -int stream_init(int fd, const char *mode, int buffered, IOStream **io){ - int err = 0; - *io = file_stream_fdopen(fd, mode); - if(!*io){ - err = -errno; - perror("fdopen"); - goto exit; - } - if(!buffered){ - // Make unbuffered. - err = file_stream_setvbuf(*io, NULL, _IONBF, 0); - if(err){ - err = -errno; - perror("setvbuf"); - goto exit; - } - } - exit: - if(err && *io){ - IOStream_close(*io); - *io = NULL; - } - return err; -} - -ConnList * ConnList_add(ConnList *l, Conn *conn){ - ConnList *v; - v = ALLOCATE(ConnList); - v->conn = conn; - v->next =l; - return v; -} - -ConnList * ConnList_del(ConnList *l, Conn *conn){ - ConnList *prev, *curr, *next; - for(prev = NULL, curr = l; curr; prev = curr, curr = next){ - next = curr->next; - if(curr->conn == conn){ - if(prev){ - prev->next = curr->next; - } else { - l = curr->next; - } - } - } - return l; -} - -void ConnList_close(ConnList *l){ - for( ; l; l = l->next){ - Conn_close(l->conn); - } -} - -void ConnList_select(ConnList *l, SelectSet *set){ - for( ; l; l = l->next){ - Conn_select(l->conn, set); - } -} - -/** Handle connections according to a select set. - * - * @param set indicates ready connections - */ -ConnList * ConnList_handle(ConnList *l, SelectSet *set){ - ConnList *prev, *curr, *next; - Conn *conn; - int err; - - for(prev = NULL, curr = l; curr; prev = curr, curr = next){ - next = curr->next; - conn = curr->conn; - err = Conn_handle(conn, set); - if(err){ - if(prev){ - prev->next = curr->next; - } else { - l = curr->next; - } - } - } - return l; -} - -Conn *Conn_new(int (*fn)(Conn *conn, int mode), void *data){ - Conn *conn; - conn = ALLOCATE(Conn); - conn->fn = fn; - conn->data = data; - return conn; -} - -int Conn_handler(Conn *conn, int mode){ - int err = 0; - dprintf(">\n"); - if(conn->fn){ - err = conn->fn(conn, mode); - } else { - dprintf("> no handler\n"); - err = -ENOSYS; - } - if(err < 0){ - dprintf("> err=%d, closing %d\n", err, conn->sock); - Conn_close(conn); - } - dprintf("< err=%d\n", err); - return err; -} - -int Conn_handle(Conn *conn, SelectSet *set){ - int err = 0; - int mode = SelectSet_in(set, conn->sock); - - dprintf("> sock=%d mode=%d\n", conn->sock, mode); - if(mode){ - err = Conn_handler(conn, mode); - - } - return err; -} - -void Conn_select(Conn *conn, SelectSet *set){ - dprintf("> sock=%d\n", conn->sock); - SelectSet_add(set, conn->sock, conn->mode); -} - -/** Initialize a connection. - * - * @param conn connection - * @param sock socket - * @param ipaddr ip address - * @return 0 on success, error code otherwise - */ -int Conn_init(Conn *conn, int sock, int type, int mode, struct sockaddr_in addr){ - int err = 0; - conn->addr = addr; - conn->type = type; - conn->mode = mode; - conn->sock = sock; - if(type == SOCK_STREAM){ - err = stream_init(sock, "r", 0, &conn->in); - if(err) goto exit; - err = stream_init(sock, "w", 0, &conn->out); - if(err) goto exit; - } else { - conn->in = socket_stream_new(sock); - conn->out = socket_stream_new(sock); - socket_stream_set_addr(conn->out, &addr); - } - exit: - if(err) eprintf("< err=%d\n", err); - return err; -} - -/** Open a connection. - * - * @param conn connection - * @param socktype socket type - * @param ipaddr ip address to connect to - * @param port port - * @return 0 on success, error code otherwise - */ -int Conn_connect(Conn *conn, int socktype, struct in_addr ipaddr, uint16_t port){ - int err = 0; - int sock; - struct sockaddr_in addr_in; - struct sockaddr *addr = (struct sockaddr *)&addr_in; - socklen_t addr_n = sizeof(addr_in); - dprintf("> addr=%s:%d\n", inet_ntoa(ipaddr), ntohs(port)); - sock = socket(AF_INET, socktype, 0); - if(sock < 0){ - err = -errno; - goto exit; - } - addr_in.sin_family = AF_INET; - addr_in.sin_addr = ipaddr; - addr_in.sin_port = port; - err = connect(sock, addr, addr_n); - if(err) goto exit; - err = Conn_init(conn, sock, socktype, 0, addr_in); - exit: - if(err){ - perror("Conn_connect"); - eprintf("< err=%d\n", err); - } - return err; -} - -/** Close a connection. - * - * @param conn connection - */ -void Conn_close(Conn *conn){ - if(!conn) return; - if(conn->in) IOStream_close(conn->in); - if(conn->out) IOStream_close(conn->out); - shutdown(conn->sock, 2); -} - -/** Set socket option to reuse address. - */ -int setsock_reuse(int sock, int val){ - int err = 0; - err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - if(err < 0){ - err = -errno; - perror("setsockopt SO_REUSEADDR"); - } - return err; -} - -/** Set socket broadcast option. - */ -int setsock_broadcast(int sock, int val){ - int err = 0; - err = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)); - if(err < 0){ - err = -errno; - perror("setsockopt SO_BROADCAST"); - } - return err; -} - -/** Join a socket to a multicast group. - */ -int setsock_multicast(int sock, uint32_t iaddr, uint32_t maddr){ - int err = 0; - struct ip_mreqn mreq = {}; - int mloop = 0; - // See 'man 7 ip' for these options. - mreq.imr_multiaddr.s_addr = maddr; // IP multicast address. - mreq.imr_address.s_addr = iaddr; // Interface IP address. - mreq.imr_ifindex = 0; // Interface index (0 means any). - err = setsockopt(sock, SOL_IP, IP_MULTICAST_LOOP, &mloop, sizeof(mloop)); - if(err < 0){ - err = -errno; - perror("setsockopt IP_MULTICAST_LOOP"); - goto exit; - } - err = setsockopt(sock, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); - if(err < 0){ - err = -errno; - perror("setsockopt IP_ADD_MEMBERSHIP"); - goto exit; - } - exit: - return err; -} - -/** Set a socket's multicast ttl (default is 1). - */ -int setsock_multicast_ttl(int sock, uint8_t ttl){ - int err = 0; - err = setsockopt(sock, SOL_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); - if(err < 0){ - err = -errno; - perror("setsockopt IP_MULTICAST_TTL"); - } - return err; -} - -int setsock_pktinfo(int sock, int val){ - int err = 0; - err = setsockopt(sock, SOL_IP, IP_PKTINFO, &val, sizeof(val)); - if(err < 0){ - err = -errno; - perror("setsockopt IP_PKTINFO"); - } - return err; -} - -char * socket_flags(int flags){ - static char s[6]; - int i = 0; - s[i++] = (flags & VSOCK_CONNECT ? 'c' : '-'); - s[i++] = (flags & VSOCK_BIND ? 'b' : '-'); - s[i++] = (flags & VSOCK_REUSE ? 'r' : '-'); - s[i++] = (flags & VSOCK_BROADCAST ? 'B' : '-'); - s[i++] = (flags & VSOCK_MULTICAST ? 'M' : '-'); - s[i++] = '\0'; - return s; -} - -/** Create a socket. - * The flags can include VSOCK_REUSE, VSOCK_BROADCAST, VSOCK_CONNECT. - * - * @param socktype socket type - * @param saddr address - * @param port port - * @param flags flags - * @param val return value for the socket connection - * @return 0 on success, error code otherwise - */ -int create_socket(int socktype, uint32_t saddr, uint32_t port, int flags, int *val){ - int err = 0; - int sock = 0; - struct sockaddr_in addr_in; - struct sockaddr *addr = (struct sockaddr *)&addr_in; - socklen_t addr_n = sizeof(addr_in); - int reuse, bcast; - - //dprintf(">\n"); - reuse = (flags & VSOCK_REUSE); - bcast = (flags & VSOCK_BROADCAST); - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = saddr; - addr_in.sin_port = port; - dprintf("> flags=%s addr=%s port=%d\n", socket_flags(flags), - inet_ntoa(addr_in.sin_addr), ntohs(addr_in.sin_port)); - - sock = socket(AF_INET, socktype, 0); - if(sock < 0){ - err = -errno; - goto exit; - } - if(reuse){ - err = setsock_reuse(sock, reuse); - if(err < 0) goto exit; - } - if(bcast){ - err = setsock_broadcast(sock, bcast); - if(err < 0) goto exit; - } - if(flags & VSOCK_CONNECT){ - err = connect(sock, addr, addr_n); - if(err < 0){ - err = -errno; - perror("connect"); - goto exit; - } - } - if(flags & VSOCK_BIND){ - err = bind(sock, addr, addr_n); - if(err < 0){ - err = -errno; - perror("bind"); - goto exit; - } - } - { - struct sockaddr_in self = {}; - socklen_t self_n = sizeof(self); - getsockname(sock, (struct sockaddr *)&self, &self_n); - dprintf("> sockname sock=%d addr=%s port=%d reuse=%d bcast=%d\n", - sock, inet_ntoa(self.sin_addr), ntohs(self.sin_port), - reuse, bcast); - } - exit: - *val = (err ? -1 : sock); - //dprintf("< err=%d\n", err); - return err; -} - -int Conn_socket(int socktype, uint32_t saddr, uint32_t port, int flags, Conn **val){ - int err; - int sock; - struct sockaddr_in addr_in; - Conn *conn; - - err = create_socket(socktype, saddr, port, flags, &sock); - if(err) goto exit; - conn = Conn_new(NULL, NULL); - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = saddr; - addr_in.sin_port = port; - Conn_init(conn, sock, socktype, 0, addr_in); - exit: - *val = (err ? NULL : conn); - return err; -} diff --git a/vnet/src/vnetd/connection.h b/vnet/src/vnetd/connection.h deleted file mode 100644 index ea65ad952f7..00000000000 --- a/vnet/src/vnetd/connection.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2003 - 2004 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _VNET_CONNECTION_H_ -#define _VNET_CONNECTION_H_ - -#include - -#include "iostream.h" -#include "select.h" - -/** A connection. - * The underlying transport is a socket. - * Contains in and out streams using the socket. - */ -typedef struct Conn { - struct sockaddr_in addr; - int sock; - int type; - int mode; // select mode - IOStream *in; - IOStream *out; - int (*fn)(struct Conn *conn, int mode); - void *data; -} Conn; - -typedef struct ConnList { - Conn *conn; - struct ConnList *next; -} ConnList; - -extern ConnList * ConnList_add(ConnList *l, Conn *conn); -extern ConnList * ConnList_del(ConnList *l, Conn *conn); -extern void ConnList_close(ConnList *l); -extern void ConnList_select(ConnList *l, SelectSet *set); -extern ConnList * ConnList_handle(ConnList *l, SelectSet *set); - -extern Conn * Conn_new(int (*fn)(struct Conn *conn, int mode), void *data); -extern int Conn_init(Conn *conn, int sock, int type, int mode, struct sockaddr_in addr); -extern int Conn_connect(Conn *conn, int type, struct in_addr ipaddr, uint16_t port); -extern void Conn_select(Conn *conn, SelectSet *set); -extern int Conn_handle(Conn *conn, SelectSet *set); -extern void Conn_close(Conn *conn); -extern int Conn_socket(int socktype, uint32_t saddr, uint32_t port, int flags, Conn **val); - -/** Socket flags. */ -enum { - VSOCK_REUSE = 1, - VSOCK_BIND = 2, - VSOCK_CONNECT = 4, - VSOCK_BROADCAST = 8, - VSOCK_MULTICAST = 16, - }; - -extern int create_socket(int socktype, uint32_t saddr, uint32_t port, int flags, int *sock); -extern int setsock_reuse(int sock, int val); -extern int setsock_broadcast(int sock, int val); -extern int setsock_multicast(int sock, uint32_t iaddr, uint32_t maddr); -extern int setsock_multicast_ttl(int sock, uint8_t ttl); -extern int setsock_pktinfo(int sock, int val); -extern char * socket_flags(int flags); - -#endif /* ! _VNET_CONNECTION_H_ */ diff --git a/vnet/src/vnetd/list.h b/vnet/src/vnetd/list.h deleted file mode 100644 index 7727177bda3..00000000000 --- a/vnet/src/vnetd/list.h +++ /dev/null @@ -1,284 +0,0 @@ -#ifndef _VNETD_LIST_H_ -#define _VNETD_LIST_H_ - -/* Taken from Linux kernel code, but de-kernelized for userspace. */ -#include - -/* - * These are non-NULL pointers that will result in page faults - * under normal circumstances, used to verify that nobody uses - * non-initialized list entries. - */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) - -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = LIST_POISON1; - entry->prev = LIST_POISON2; -} - -/** - * list_del_rcu - deletes entry from list without re-initialization - * @entry: the element to delete from the list. - * - * Note: list_empty on entry does not return true after this, - * the entry is in an undefined state. It is useful for RCU based - * lockfree traversal. - * - * In particular, it means that we can not poison the forward - * pointers that may still be used for walking the list. - */ -static inline void list_del_rcu(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->prev = LIST_POISON2; -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(struct list_head *head) -{ - return head->next == head; -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - - -/** - * list_for_each_entry_safe - iterate over list of given type safe against - * removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - - - -#endif /* _VNETD_LIST_H_ */ diff --git a/vnet/src/vnetd/select.c b/vnet/src/vnetd/select.c deleted file mode 100644 index 06fdcc9c2d0..00000000000 --- a/vnet/src/vnetd/select.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2003 - 2004 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include "select.h" - -#define MODULE_NAME "select" -#define DEBUG -#undef DEBUG -#include "debug.h" - -/** Zero all the file descriptor sets. - * - * @param set select set - * @param fd file descriptor - * @return 0 on success, -1 otherwise - */ -void SelectSet_zero(SelectSet *set){ - set->n = 0; - FD_ZERO(&set->rd); - FD_ZERO(&set->wr); - FD_ZERO(&set->er); -} - -/** Add a file descriptor to the set. - * - * @param set select set - * @param fd file descriptor - * @param mode mask of sets to add to - * @return 0 on success, -1 otherwise - */ -void SelectSet_add(SelectSet *set, int fd, int mode){ - if(fd < 0) return; - if(mode & SELECT_READ){ - SelectSet_add_read(set, fd); - } - if(mode & SELECT_WRITE){ - SelectSet_add_write(set, fd); - } - if(mode & SELECT_ERROR){ - SelectSet_add_error(set, fd); - } -} - -/** Add a file descriptor to the write set. - * - * @param set select set - * @param fd file descriptor - * @return 0 on success, -1 otherwise - */ -void SelectSet_add_read(SelectSet *set, int fd){ - dprintf("> fd=%d\n", fd); - if(fd < 0) return; - FD_SET(fd, &set->rd); - if(fd > set->n) set->n = fd; -} - -/** Add a file descriptor to the write set. - * - * @param set select set - * @param fd file descriptor - * @return 0 on success, -1 otherwise - */ -void SelectSet_add_write(SelectSet *set, int fd){ - dprintf("> fd=%d\n", fd); - if(fd < 0) return; - FD_SET(fd, &set->wr); - if(fd > set->n) set->n = fd; -} - -/** Add a file descriptor to the error set. - * - * @param set select set - * @param fd file descriptor - * @return 0 on success, -1 otherwise - */ -void SelectSet_add_error(SelectSet *set, int fd){ - dprintf("> fd=%d\n", fd); - if(fd < 0) return; - FD_SET(fd, &set->er); - if(fd > set->n) set->n = fd; -} - -/** Select on file descriptors. - * - * @param set select set - * @param timeout timeout (may be NULL for no timeout) - * @return 0 on success, -1 otherwise - */ -int SelectSet_select(SelectSet *set, struct timeval *timeout){ - return select(set->n+1, &set->rd, &set->wr, &set->er, timeout); -} diff --git a/vnet/src/vnetd/select.h b/vnet/src/vnetd/select.h deleted file mode 100644 index 4fedd3e9e5f..00000000000 --- a/vnet/src/vnetd/select.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2003 - 2004 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _VFC_SELECT_H_ -#define _VFC_SELECT_H_ - -/** Set of file descriptors for select. - */ -typedef struct SelectSet { - int n; - fd_set rd, wr, er; -} SelectSet; - -enum { - SELECT_READ = 1, - SELECT_WRITE = 2, - SELECT_ERROR = 4, -}; - -extern void SelectSet_zero(SelectSet *set); -extern void SelectSet_add(SelectSet *set, int fd, int mode); -extern void SelectSet_add_read(SelectSet *set, int fd); -extern void SelectSet_add_write(SelectSet *set, int fd); -extern void SelectSet_add_error(SelectSet *set, int fd); -extern int SelectSet_select(SelectSet *set, struct timeval *timeout); - -static inline int SelectSet_in(SelectSet *set, int fd){ - return ((fd >= 0) - ? ((FD_ISSET(fd, &set->rd) ? SELECT_READ : 0) | - (FD_ISSET(fd, &set->wr) ? SELECT_WRITE : 0) | - (FD_ISSET(fd, &set->er) ? SELECT_ERROR : 0)) - : 0); -} - -static inline int SelectSet_in_read(SelectSet *set, int fd){ - return (fd >= 0) && FD_ISSET(fd, &set->rd); -} - -static inline int SelectSet_in_write(SelectSet *set, int fd){ - return (fd >= 0) && FD_ISSET(fd, &set->wr); -} - -static inline int SelectSet_in_err(SelectSet *set, int fd){ - return (fd >= 0) && FD_ISSET(fd, &set->er); -} - -#endif /* ! _VFC_SELECT_H_ */ diff --git a/vnet/src/vnetd/selector.c b/vnet/src/vnetd/selector.c deleted file mode 100644 index 25fffcf8777..00000000000 --- a/vnet/src/vnetd/selector.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include - -#include "connection.h" -#include "selector.h" - -#define MODULE_NAME "select" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -void Selector_init(Selector *sel){ - INIT_LIST_HEAD(&sel->list); -} - -/** Close a selector and remove it from its list. - * - * @param sel selector (may be null) - */ -void Selector_close(Selector *sel){ - if(!sel) return; - dprintf(">\n"); - if(sel->close){ - sel->close(sel); - } - if(sel->list.next - && sel->list.next != LIST_POISON1 - && !list_empty(&sel->list)){ - list_del_init(&sel->list); - } -} - -/** Add a selector to a select set. - * The selector is closed if it has no 'select' function, - * or it has one and it returns an error. - * - * @param sel selector - * @param set select set - */ -int Selector_select(Selector *sel, SelectSet *set){ - int err = -EINVAL; - dprintf(">\n"); - if(sel->select){ - err = sel->select(sel, set); - } - if(err){ - Selector_close(sel); - } - return err; -} - -/** Call a selector with a select set. - * The selector is closed if it has no 'selected' function, - * or it has one and it returns an error. - * - * @param sel selector - * @param set select set - */ -int Selector_selected(Selector *sel, SelectSet *set){ - int err = -EINVAL; - dprintf(">\n"); - if(sel->selected){ - err = sel->selected(sel, set); - } - if(err){ - Selector_close(sel); - } - return err; -} - -int conn_select_fn(Selector *sel, SelectSet *set){ - int err = -EINVAL; - Conn *conn = sel->data; - - dprintf(">\n"); - if(conn){ - err = 0; - SelectSet_add(set, conn->sock, conn->mode); - } - return err; -} - -int conn_selected_fn(Selector *sel, SelectSet *set){ - int err = -EINVAL; - Conn *conn = sel->data; - - dprintf(">\n"); - if(conn){ - err = Conn_handle(conn, set); - } - return err; -} - -void conn_close_fn(Selector *sel){ - Conn *conn = sel->data; - - wprintf("> sel=%p\n", sel); - if(conn){ - Conn_close(conn); - } -} - -void Selector_conn_init(Selector *sel, Conn *conn, - int mode, void *data, - int (*fn)(struct Conn *conn, int mode)){ - conn->mode = SELECT_READ; - conn->data = data; - conn->fn = fn; - sel->data = conn; - sel->select = conn_select_fn; - sel->close = conn_close_fn; - sel->selected = conn_selected_fn; -} - diff --git a/vnet/src/vnetd/selector.h b/vnet/src/vnetd/selector.h deleted file mode 100644 index 24bd76454b9..00000000000 --- a/vnet/src/vnetd/selector.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _VNETD_SELECTOR_H_ -#define _VNETD_SELECTOR_H_ - -#include "list.h" -#include "select.h" - -struct Conn; - -typedef struct Selector { - - /** List the selector is linked into (if any). */ - struct list_head list; - - /** Function called by Selector_select() to add a selector to a select set. - * The selector is closed if this returns an error (non-zero). - */ - int (*select)(struct Selector *sel, struct SelectSet *set); - - /** Function called by Selector_selected() to notify a selector of select set. - * The selector is closed if this returns an error (non-zero). - */ - int (*selected)(struct Selector *sel, struct SelectSet *set); - - /** Function called by Selector_close() to close a selector. - */ - void (*close)(struct Selector *sel); - - /** User data. */ - void *data; - -} Selector; - -void Selector_init(struct Selector *sel); -void Selector_close(struct Selector *sel); -int Selector_select(struct Selector *sel, struct SelectSet *set); -int Selector_selected(struct Selector *sel, struct SelectSet *set); - -int conn_select_fn(struct Selector *sel, struct SelectSet *set); -int conn_selected_fn(struct Selector *sel, struct SelectSet *set); -void conn_close_fn(struct Selector *sel); -void Selector_conn_init(struct Selector *sel, struct Conn *conn, - int mode, void *data, - int (*fn)(struct Conn *conn, int mode)); - -#endif /* _VNETD_SELECTOR_H_ */ diff --git a/vnet/src/vnetd/skbuff.c b/vnet/src/vnetd/skbuff.c deleted file mode 100644 index 968b1943d61..00000000000 --- a/vnet/src/vnetd/skbuff.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Routines having to do with the 'struct sk_buff' memory handlers. - * - * Authors: Alan Cox - * Florian La Roche - * - * Fixes: - * Alan Cox : Fixed the worst of the load - * balancer bugs. - * Dave Platt : Interrupt stacking fix. - * Richard Kooijman : Timestamp fixes. - * Alan Cox : Changed buffer format. - * Alan Cox : destructor hook for AF_UNIX etc. - * Linus Torvalds : Better skb_clone. - * Alan Cox : Added skb_copy. - * Alan Cox : Added all the changed routines Linus - * only put in the headers - * Ray VanTassle : Fixed --skb->lock in free - * Alan Cox : skb_copy copy arp field - * Andi Kleen : slabified it. - * Robert Olsson : Removed skb_head_pool - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -#include "allocate.h" -#include "debug.h" -#include "skbuff.h" - -#define SKB_DATA_ALIGN(size) ((((size) + 7) >> 3) << 3) - -/** - * skb_over_panic - private function - * @skb: buffer - * @sz: size - * @here: address - * - * Out of line support code for skb_put(). Not user callable. - */ -void skb_over_panic(struct sk_buff *skb, int sz, void *here) -{ - eprintf("skput:over: %p:%d put:%d\n", here, skb->len, sz); - BUG(); -} - -/** - * skb_under_panic - private function - * @skb: buffer - * @sz: size - * @here: address - * - * Out of line support code for skb_push(). Not user callable. - */ - -void skb_under_panic(struct sk_buff *skb, int sz, void *here) -{ - eprintf("skput:under: %p:%d put:%d\n", here, skb->len, sz); - BUG(); -} - -/** - * alloc_skb - allocate a network buffer - * @size: size to allocate - * @gfp_mask: allocation mask - * - * Allocate a new &sk_buff. The returned buffer has no headroom and a - * tail room of size bytes. The object has a reference count of one. - * The return is the buffer. On a failure the return is %NULL. - */ -struct sk_buff *alloc_skb(unsigned int size, int gfp_mask) -{ - struct sk_buff *skb; - u8 *data; - - /* Get the HEAD */ - skb = ALLOCATE(struct sk_buff); - if (!skb) - goto out; - - /* Get the DATA. Size must match skb_add_mtu(). */ - size = SKB_DATA_ALIGN(size); - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (!data) - goto nodata; - - memset(skb, 0, offsetof(struct sk_buff, truesize)); - skb->truesize = size + sizeof(struct sk_buff); - atomic_set(&skb->users, 1); - skb->head = data; - skb->data = data; - skb->tail = data; - skb->end = data + size; - skb->list = NULL; - - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->tso_size = 0; - skb_shinfo(skb)->tso_segs = 0; - skb_shinfo(skb)->frag_list = NULL; -out: - return skb; -nodata: - kfree(skb); - skb = NULL; - goto out; -} - - -void skb_release_data(struct sk_buff *skb) -{ - kfree(skb->head); -} - -/* - * Free an skbuff by memory without cleaning the state. - */ -void kfree_skbmem(struct sk_buff *skb) -{ - skb_release_data(skb); - kfree(skb); -} - -/** - * __kfree_skb - private function - * @skb: buffer - * - * Free an sk_buff. Release anything attached to the buffer. - * Clean the state. This is an internal helper function. Users should - * always call kfree_skb - */ - -void __kfree_skb(struct sk_buff *skb) -{ - if (skb->list) { - wprintf("Warning: kfree_skb passed an skb still " - "on a list.\n"); - //BUG(); - } - - if(skb->destructor) { - skb->destructor(skb); - } - kfree_skbmem(skb); -} - - -/** - * skb_clone - duplicate an sk_buff - * @skb: buffer to clone - * @gfp_mask: allocation priority - * - * Duplicate an &sk_buff. The new one is not owned by a socket. Both - * copies share the same packet data but not structure. The new - * buffer has a reference count of 1. If the allocation fails the - * function returns %NULL otherwise the new buffer is returned. - * - * If this function is called from an interrupt gfp_mask() must be - * %GFP_ATOMIC. - */ - -struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) -{ - return pskb_copy(skb, gfp_mask); -} - -static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -{ - /* - * Shift between the two data areas in bytes - */ - unsigned long offset = new->data - old->data; - - new->list = NULL; - new->protocol = old->protocol; - new->h.raw = old->h.raw + offset; - new->nh.raw = old->nh.raw + offset; - new->mac.raw = old->mac.raw + offset; - new->pkt_type = old->pkt_type; - new->destructor = NULL; - atomic_set(&new->users, 1); -} - - -/** - * pskb_expand_head - reallocate header of &sk_buff - * @skb: buffer to reallocate - * @nhead: room to add at head - * @ntail: room to add at tail - * @gfp_mask: allocation priority - * - * Expands (or creates identical copy, if &nhead and &ntail are zero) - * header of skb. &sk_buff itself is not changed. &sk_buff MUST have - * reference count of 1. Returns zero in the case of success or error, - * if expansion failed. In the last case, &sk_buff is not changed. - * - * All the pointers pointing into skb header may change and must be - * reloaded after call to this function. - */ - -int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask) -{ - u8 *data; - int size = nhead + (skb->end - skb->head) + ntail; - long off; - - if (skb_shared(skb)) - BUG(); - - size = SKB_DATA_ALIGN(size); - - data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); - if (!data) - goto nodata; - - /* Copy only real data... and, alas, header. This should be - * optimized for the cases when header is void. */ - memcpy(data + nhead, skb->head, skb->tail - skb->head); - memcpy(data + size, skb->end, sizeof(struct skb_shared_info)); - - skb_release_data(skb); - - off = (data + nhead) - skb->head; - - skb->head = data; - skb->end = data + size; - skb->data += off; - skb->tail += off; - skb->mac.raw += off; - skb->h.raw += off; - skb->nh.raw += off; - return 0; - -nodata: - return -ENOMEM; -} - -struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask) -{ - /* - * Allocate the copy buffer - */ - struct sk_buff *n = alloc_skb(skb->end - skb->head, gfp_mask); - - if (!n) - goto out; - - /* Set the data pointer */ - skb_reserve(n, skb->data - skb->head); - /* Set the tail pointer and length */ - skb_put(n, skb_headlen(skb)); - /* Copy the bytes */ - memcpy(n->data, skb->data, n->len); - - n->data_len = skb->data_len; - n->len = skb->len; - - copy_skb_header(n, skb); -out: - return n; -} - -/* Make private copy of skb with writable head and some headroom */ - -struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) -{ - struct sk_buff *skb2; - int delta = headroom - skb_headroom(skb); - - if (delta <= 0) - skb2 = pskb_copy(skb, GFP_ATOMIC); - else { - skb2 = skb_copy_expand(skb, headroom, 0, GFP_ATOMIC); - } - return skb2; -} - - -/** - * skb_copy_expand - copy and expand sk_buff - * @skb: buffer to copy - * @newheadroom: new free bytes at head - * @newtailroom: new free bytes at tail - * @gfp_mask: allocation priority - * - * Make a copy of both an &sk_buff and its data and while doing so - * allocate additional space. - * - * This is used when the caller wishes to modify the data and needs a - * private copy of the data to alter as well as more space for new fields. - * Returns %NULL on failure or the pointer to the buffer - * on success. The returned buffer has a reference count of 1. - * - * You must pass %GFP_ATOMIC as the allocation priority if this function - * is called from an interrupt. - * - * BUG ALERT: ip_summed is not copied. Why does this work? Is it used - * only by netfilter in the cases when checksum is recalculated? --ANK - */ -struct sk_buff *skb_copy_expand(const struct sk_buff *skb, - int newheadroom, int newtailroom, int gfp_mask) -{ - /* - * Allocate the copy buffer - */ - struct sk_buff *n = alloc_skb(newheadroom + skb->len + newtailroom, - gfp_mask); - int head_copy_len, head_copy_off; - - if (!n) - return NULL; - - skb_reserve(n, newheadroom); - - /* Set the tail pointer and length */ - skb_put(n, skb->len); - - head_copy_len = skb_headroom(skb); - head_copy_off = 0; - if (newheadroom <= head_copy_len) - head_copy_len = newheadroom; - else - head_copy_off = newheadroom - head_copy_len; - - /* Copy the linear header and data. */ - if (skb_copy_bits(skb, -head_copy_len, n->head + head_copy_off, - skb->len + head_copy_len)) - BUG(); - - copy_skb_header(n, skb); - - return n; -} - - -/* Copy some data bits from skb to kernel buffer. */ - -int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) -{ - int copy; - int start = skb_headlen(skb); - - if (offset > (int)skb->len - len) - goto fault; - - /* Copy header. */ - if ((copy = start - offset) > 0) { - if (copy > len) - copy = len; - memcpy(to, skb->data + offset, copy); - if ((len -= copy) == 0) - return 0; - offset += copy; - to += copy; - } - - if (!len) - return 0; - -fault: - return -EFAULT; -} - - -/** - * skb_dequeue - remove from the head of the queue - * @list: list to dequeue from - * - * Remove the head of the list. The list lock is taken so the function - * may be used safely with other locking list functions. The head item is - * returned or %NULL if the list is empty. - */ - -struct sk_buff *skb_dequeue(struct sk_buff_head *list) -{ - unsigned long flags; - struct sk_buff *result; - - spin_lock_irqsave(&list->lock, flags); - result = __skb_dequeue(list); - spin_unlock_irqrestore(&list->lock, flags); - return result; -} - -/** - * skb_dequeue_tail - remove from the tail of the queue - * @list: list to dequeue from - * - * Remove the tail of the list. The list lock is taken so the function - * may be used safely with other locking list functions. The tail item is - * returned or %NULL if the list is empty. - */ -struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list) -{ - unsigned long flags; - struct sk_buff *result; - - spin_lock_irqsave(&list->lock, flags); - result = __skb_dequeue_tail(list); - spin_unlock_irqrestore(&list->lock, flags); - return result; -} - -/** - * skb_queue_purge - empty a list - * @list: list to empty - * - * Delete all buffers on an &sk_buff list. Each buffer is removed from - * the list and one reference dropped. This function takes the list - * lock and is atomic with respect to other list locking functions. - */ -void skb_queue_purge(struct sk_buff_head *list) -{ - struct sk_buff *skb; - while ((skb = skb_dequeue(list)) != NULL) - kfree_skb(skb); -} - -/** - * skb_queue_head - queue a buffer at the list head - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the start of the list. This function takes the - * list lock and can be used safely with other locking &sk_buff functions - * safely. - * - * A buffer cannot be placed on two lists at the same time. - */ -void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - __skb_queue_head(list, newsk); - spin_unlock_irqrestore(&list->lock, flags); -} - -/** - * skb_queue_tail - queue a buffer at the list tail - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the tail of the list. This function takes the - * list lock and can be used safely with other locking &sk_buff functions - * safely. - * - * A buffer cannot be placed on two lists at the same time. - */ -void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - __skb_queue_tail(list, newsk); - spin_unlock_irqrestore(&list->lock, flags); -} -/** - * skb_unlink - remove a buffer from a list - * @skb: buffer to remove - * - * Place a packet after a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls - * - * Works even without knowing the list it is sitting on, which can be - * handy at times. It also means that THE LIST MUST EXIST when you - * unlink. Thus a list must have its contents unlinked before it is - * destroyed. - */ -void skb_unlink(struct sk_buff *skb) -{ - struct sk_buff_head *list = skb->list; - - if (list) { - unsigned long flags; - - spin_lock_irqsave(&list->lock, flags); - if (skb->list == list) - __skb_unlink(skb, skb->list); - spin_unlock_irqrestore(&list->lock, flags); - } -} - - -/** - * skb_append - append a buffer - * @old: buffer to insert after - * @newsk: buffer to insert - * - * Place a packet after a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls. - * A buffer cannot be placed on two lists at the same time. - */ - -void skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&old->list->lock, flags); - __skb_append(old, newsk); - spin_unlock_irqrestore(&old->list->lock, flags); -} - - -/** - * skb_insert - insert a buffer - * @old: buffer to insert before - * @newsk: buffer to insert - * - * Place a packet before a given packet in a list. The list locks are taken - * and this function is atomic with respect to other list locked calls - * A buffer cannot be placed on two lists at the same time. - */ - -void skb_insert(struct sk_buff *old, struct sk_buff *newsk) -{ - unsigned long flags; - - spin_lock_irqsave(&old->list->lock, flags); - __skb_insert(newsk, old->prev, old, old->list); - spin_unlock_irqrestore(&old->list->lock, flags); -} - diff --git a/vnet/src/vnetd/skbuff.h b/vnet/src/vnetd/skbuff.h deleted file mode 100644 index 69568c324e4..00000000000 --- a/vnet/src/vnetd/skbuff.h +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Definitions for the 'struct sk_buff' memory handlers. - * - * Authors: - * Alan Cox, - * Florian La Roche, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _VNET_SKBUFF_H -#define _VNET_SKBUFF_H - -#include "sys_kernel.h" -#include "spinlock.h" - -struct sk_buff; - -struct sk_buff_head { - /* These two members must be first. */ - struct sk_buff *next; - struct sk_buff *prev; - - __u32 qlen; - spinlock_t lock; -}; - - - -#define MAX_SKB_FRAGS 8 // (65536/PAGE_SIZE + 2) - -typedef struct skb_frag_struct skb_frag_t; - -struct skb_frag_struct { - //struct page *page; - void *page; - __u16 page_offset; - __u16 size; -}; - -/* This data is invariant across clones and lives at - * the end of the header data, ie. at skb->end. - */ -struct skb_shared_info { - atomic_t dataref; - unsigned int nr_frags; - unsigned short tso_size; - unsigned short tso_segs; - struct sk_buff *frag_list; - skb_frag_t frags[MAX_SKB_FRAGS]; -}; - -struct sk_buff { - /* These two members must be first. */ - struct sk_buff *next; - struct sk_buff *prev; - - struct sk_buff_head *list; - struct net_device *dev; - - union { - struct tcphdr *th; - struct udphdr *uh; - struct icmphdr *icmph; - struct igmphdr *igmph; - struct iphdr *ipiph; - struct ipv6hdr *ipv6h; - unsigned char *raw; - } h; - - union { - struct iphdr *iph; - struct ipv6hdr *ipv6h; - struct arphdr *arph; - unsigned char *raw; - } nh; - - union { - unsigned char *raw; - } mac; - - unsigned int len, - data_len; - unsigned char pkt_type; - unsigned short protocol; - - void (*destructor)(struct sk_buff *skb); - - /* These elements must be at the end, see alloc_skb() for details. */ - unsigned int truesize; - atomic_t users; - unsigned char *head, - *data, - *tail, - *end; -}; - -extern void skb_over_panic(struct sk_buff *skb, int len, - void *here); -extern void skb_under_panic(struct sk_buff *skb, int len, - void *here); - -#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end)) - -extern void __kfree_skb(struct sk_buff *skb); -extern struct sk_buff *alloc_skb(unsigned int size, int priority); -extern struct sk_buff *skb_clone(struct sk_buff *skb, int priority); -extern struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask); -extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, - unsigned int headroom); -extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, - int newheadroom, int newtailroom, - int priority); - -extern int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); - -static inline void kfree_skb(struct sk_buff *skb) -{ - if (atomic_dec_and_test(&skb->users) || atomic_read(&skb->users) == 1 ) - __kfree_skb(skb); -} - -static inline void dev_kfree_skb(struct sk_buff *skb) -{ - kfree_skb(skb); -} - -static inline int skb_cloned(const struct sk_buff *skb) -{ - return 0; -} - -/** - * skb_shared - is the buffer shared - * @skb: buffer to check - * - * Returns true if more than one person has a reference to this - * buffer. - */ -static inline int skb_shared(const struct sk_buff *skb) -{ - return atomic_read(&skb->users) != 1; -} - -/** - * skb_peek - * @list_: list to peek at - * - * Peek an &sk_buff. Unlike most other operations you _MUST_ - * be careful with this one. A peek leaves the buffer on the - * list and someone else may run off with it. You must hold - * the appropriate locks or have a private queue to do this. - * - * Returns %NULL for an empty list or a pointer to the head element. - * The reference count is not incremented and the reference is therefore - * volatile. Use with caution. - */ -static inline struct sk_buff *skb_peek(struct sk_buff_head *list_) -{ - struct sk_buff *list = ((struct sk_buff *)list_)->next; - if (list == (struct sk_buff *)list_) - list = NULL; - return list; -} - -/** - * skb_peek_tail - * @list_: list to peek at - * - * Peek an &sk_buff. Unlike most other operations you _MUST_ - * be careful with this one. A peek leaves the buffer on the - * list and someone else may run off with it. You must hold - * the appropriate locks or have a private queue to do this. - * - * Returns %NULL for an empty list or a pointer to the tail element. - * The reference count is not incremented and the reference is therefore - * volatile. Use with caution. - */ -static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_) -{ - struct sk_buff *list = ((struct sk_buff *)list_)->prev; - if (list == (struct sk_buff *)list_) - list = NULL; - return list; -} - -/** - * skb_queue_len - get queue length - * @list_: list to measure - * - * Return the length of an &sk_buff queue. - */ -static inline __u32 skb_queue_len(const struct sk_buff_head *list_) -{ - return list_->qlen; -} - -static inline void skb_queue_head_init(struct sk_buff_head *list) -{ - spin_lock_init(&list->lock); - list->prev = list->next = (struct sk_buff *)list; - list->qlen = 0; -} - -/* - * Insert an sk_buff at the start of a list. - * - * The "__skb_xxxx()" functions are the non-atomic ones that - * can only be called with interrupts disabled. - */ - -/** - * __skb_queue_head - queue a buffer at the list head - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the start of a list. This function takes no locks - * and you must therefore hold required locks before calling it. - * - * A buffer cannot be placed on two lists at the same time. - */ -extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk); -static inline void __skb_queue_head(struct sk_buff_head *list, - struct sk_buff *newsk) -{ - struct sk_buff *prev, *next; - - newsk->list = list; - list->qlen++; - prev = (struct sk_buff *)list; - next = prev->next; - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; -} - -/** - * __skb_queue_tail - queue a buffer at the list tail - * @list: list to use - * @newsk: buffer to queue - * - * Queue a buffer at the end of a list. This function takes no locks - * and you must therefore hold required locks before calling it. - * - * A buffer cannot be placed on two lists at the same time. - */ -extern void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk); -static inline void __skb_queue_tail(struct sk_buff_head *list, - struct sk_buff *newsk) -{ - struct sk_buff *prev, *next; - - newsk->list = list; - list->qlen++; - next = (struct sk_buff *)list; - prev = next->prev; - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; -} - - -/** - * __skb_dequeue - remove from the head of the queue - * @list: list to dequeue from - * - * Remove the head of the list. This function does not take any locks - * so must be used with appropriate locks held only. The head item is - * returned or %NULL if the list is empty. - */ -extern struct sk_buff *skb_dequeue(struct sk_buff_head *list); -static inline struct sk_buff *__skb_dequeue(struct sk_buff_head *list) -{ - struct sk_buff *next, *prev, *result; - - prev = (struct sk_buff *) list; - next = prev->next; - result = NULL; - if (next != prev) { - result = next; - next = next->next; - list->qlen--; - next->prev = prev; - prev->next = next; - result->next = result->prev = NULL; - result->list = NULL; - } - return result; -} - - -/* - * Insert a packet on a list. - */ -extern void skb_insert(struct sk_buff *old, struct sk_buff *newsk); -static inline void __skb_insert(struct sk_buff *newsk, - struct sk_buff *prev, struct sk_buff *next, - struct sk_buff_head *list) -{ - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; - newsk->list = list; - list->qlen++; -} - -/* - * Place a packet after a given packet in a list. - */ -extern void skb_append(struct sk_buff *old, struct sk_buff *newsk); -static inline void __skb_append(struct sk_buff *old, struct sk_buff *newsk) -{ - __skb_insert(newsk, old, old->next, old->list); -} - -/* - * remove sk_buff from list. _Must_ be called atomically, and with - * the list known.. - */ -extern void skb_unlink(struct sk_buff *skb); -static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) -{ - struct sk_buff *next, *prev; - - list->qlen--; - next = skb->next; - prev = skb->prev; - skb->next = skb->prev = NULL; - skb->list = NULL; - next->prev = prev; - prev->next = next; -} - - -/* XXX: more streamlined implementation */ - -/** - * __skb_dequeue_tail - remove from the tail of the queue - * @list: list to dequeue from - * - * Remove the tail of the list. This function does not take any locks - * so must be used with appropriate locks held only. The tail item is - * returned or %NULL if the list is empty. - */ -extern struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list); -static inline struct sk_buff *__skb_dequeue_tail(struct sk_buff_head *list) -{ - struct sk_buff *skb = skb_peek_tail(list); - if (skb) - __skb_unlink(skb, list); - return skb; -} - - -/* - * Add data to an sk_buff - */ -static inline unsigned char *__skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp = skb->tail; - skb->tail += len; - skb->len += len; - return tmp; -} - -/** - * skb_put - add data to a buffer - * @skb: buffer to use - * @len: amount of data to add - * - * This function extends the used data area of the buffer. If this would - * exceed the total buffer size the kernel will panic. A pointer to the - * first byte of the extra data is returned. - */ -static inline unsigned char *skb_put(struct sk_buff *skb, unsigned int len) -{ - unsigned char *tmp = skb->tail; - skb->tail += len; - skb->len += len; - if (unlikely(skb->tail>skb->end)) - skb_over_panic(skb, len, current_text_addr()); - return tmp; -} - -static inline unsigned char *__skb_push(struct sk_buff *skb, unsigned int len) -{ - skb->data -= len; - skb->len += len; - return skb->data; -} - -/** - * skb_push - add data to the start of a buffer - * @skb: buffer to use - * @len: amount of data to add - * - * This function extends the used data area of the buffer at the buffer - * start. If this would exceed the total buffer headroom the kernel will - * panic. A pointer to the first byte of the extra data is returned. - */ -static inline unsigned char *skb_push(struct sk_buff *skb, unsigned int len) -{ - skb->data -= len; - skb->len += len; - if (unlikely(skb->datahead)){ - skb_under_panic(skb, len, current_text_addr()); - } - return skb->data; -} - -static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) -{ - skb->len -= len; - //BUG_ON(skb->len < skb->data_len); - return skb->data += len; -} - -/** - * skb_pull - remove data from the start of a buffer - * @skb: buffer to use - * @len: amount of data to remove - * - * This function removes data from the start of a buffer, returning - * the memory to the headroom. A pointer to the next data in the buffer - * is returned. Once the data has been pulled future pushes will overwrite - * the old data. - */ -static inline unsigned char *skb_pull(struct sk_buff *skb, unsigned int len) -{ - return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len); -} - -static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len) -{ - return (len <= skb->len); -} - -static inline unsigned int skb_headlen(const struct sk_buff *skb) -{ - return skb->len - skb->data_len; -} - -/** - * skb_headroom - bytes at buffer head - * @skb: buffer to check - * - * Return the number of bytes of free space at the head of an &sk_buff. - */ -static inline int skb_headroom(const struct sk_buff *skb) -{ - return skb->data - skb->head; -} - -/** - * skb_tailroom - bytes at buffer end - * @skb: buffer to check - * - * Return the number of bytes of free space at the tail of an sk_buff - */ -static inline int skb_tailroom(const struct sk_buff *skb) -{ - return skb->end - skb->tail; -} - -/** - * skb_reserve - adjust headroom - * @skb: buffer to alter - * @len: bytes to move - * - * Increase the headroom of an empty &sk_buff by reducing the tail - * room. This is only allowed for an empty buffer. - */ -static inline void skb_reserve(struct sk_buff *skb, unsigned int len) -{ - skb->data += len; - skb->tail += len; -} - -/** - * __skb_queue_purge - empty a list - * @list: list to empty - * - * Delete all buffers on an &sk_buff list. Each buffer is removed from - * the list and one reference dropped. This function does not take the - * list lock and the caller must hold the relevant locks to use it. - */ -extern void skb_queue_purge(struct sk_buff_head *list); -static inline void __skb_queue_purge(struct sk_buff_head *list) -{ - struct sk_buff *skb; - while ((skb = __skb_dequeue(list)) != NULL) - kfree_skb(skb); -} - -/** - * __dev_alloc_skb - allocate an skbuff for sending - * @length: length to allocate - * @gfp_mask: get_free_pages mask, passed to alloc_skb - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned in there is no free memory. - */ -static inline struct sk_buff *__dev_alloc_skb(unsigned int length, - int gfp_mask) -{ - struct sk_buff *skb = alloc_skb(length + 16, gfp_mask); - if (likely(skb)) - skb_reserve(skb, 16); - return skb; -} - -/** - * dev_alloc_skb - allocate an skbuff for sending - * @length: length to allocate - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned in there is no free memory. Although this function - * allocates memory it can be called from an interrupt. - */ -static inline struct sk_buff *dev_alloc_skb(unsigned int length) -{ - return __dev_alloc_skb(length, GFP_ATOMIC); -} - -#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000)) - -#endif /* _VNET_SKBUFF_H */ diff --git a/vnet/src/vnetd/spinlock.c b/vnet/src/vnetd/spinlock.c deleted file mode 100644 index d99f46820dd..00000000000 --- a/vnet/src/vnetd/spinlock.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "spinlock.h" - -int atomic_read(const atomic_t *v){ - return v->val; -} - -int atomic_dec_and_test(atomic_t *v){ - if(v->val > 0){ - v->val--; - return v->val == 0; - } - return 0; -} - -void atomic_inc(atomic_t *v){ - v->val++; -} - -void atomic_set(atomic_t *v, int x){ - v->val = x; -} - -void spin_lock_init(spinlock_t *lock){ - *lock = (spinlock_t){}; -} - -unsigned long _spin_lock_irqsave(spinlock_t *lock){ - lock->val++; - return 0; -} - -void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags){ - lock->val--; -} - -unsigned long _read_lock_irqsave(rwlock_t *lock){ - lock->val++; - return 0; -} - -void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags){ - lock->val--; -} - -unsigned long _write_lock_irqsave(rwlock_t *lock){ - lock->val++; - return 0; -} - -void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags){ - lock->val--; -} - -void init_MUTEX(struct semaphore *sem){ - *sem = (struct semaphore){ .count = 1 }; -} - -void down(struct semaphore *sem){ - sem->count--; -} - -void up(struct semaphore *sem){ - sem->count++; -} - diff --git a/vnet/src/vnetd/spinlock.h b/vnet/src/vnetd/spinlock.h deleted file mode 100644 index 5480ad22ca9..00000000000 --- a/vnet/src/vnetd/spinlock.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _VNET_SPINLOCK_H_ -#define _VNET_SPINLOCK_H_ - -typedef struct atomic_t { - unsigned val; -} atomic_t; - -int atomic_read(const atomic_t *v); -int atomic_dec_and_test(atomic_t *v); -void atomic_inc(atomic_t *v); -void atomic_set(atomic_t *v, int x); - -typedef struct spinlock_t { - unsigned val; -} spinlock_t; - -#define SPIN_LOCK_UNLOCKED ((struct spinlock_t){}) - -void spin_lock_init(spinlock_t *lock); - -unsigned long _spin_lock_irqsave(spinlock_t *lock); -#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock) -void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags); - -typedef struct rwlock_t{ - unsigned val; -} rwlock_t; - -#define RW_LOCK_UNLOCKED ((struct rwlock_t){}) - -unsigned long _read_lock_irqsave(rwlock_t *lock); -#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock) -void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags); - -unsigned long _write_lock_irqsave(rwlock_t *lock); -#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock) -void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags); - -struct semaphore { - int count; -}; - -void init_MUTEX(struct semaphore *sem); -void down(struct semaphore *sem); -void up(struct semaphore *sem); - -#endif /* ! _VNET_SPINLOCK_H_ */ diff --git a/vnet/src/vnetd/sys_kernel.h b/vnet/src/vnetd/sys_kernel.h deleted file mode 100644 index 7b358e92e24..00000000000 --- a/vnet/src/vnetd/sys_kernel.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2005 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef _VNET_SYS_KERNEL_H_ -#define _VNET_SYS_KERNEL_H_ - -/** @file Compatibility replacements for some kernel defs. - */ - -#include -#include -//#include -#include - -#define printk printf - -#define likely(x) x -#define unlikely(x) x -#define current_text_addr() NULL - -#define BUG_ON(x) assert(x) -#define BUG() BUG_ON(1) -#define kmalloc(n, m) allocate_type(n, m) -#define kfree(p) deallocate(p) -#define in_atomic() 0 - -#define __init -#define __exit - -#define module_init(x) -#define module_exit(x) -#define MODULE_LICENSE(x) -#define MODULE_PARM(v, t) -#define module_param(v, t, s) -#define MODULE_PARM_DESC(v, s) - -enum { - GFP_USER, - GFP_ATOMIC, - GFP_KERNEL, -}; - -typedef signed char s8; -typedef unsigned char u8; - -typedef signed short s16; -typedef unsigned short u16; - -typedef signed int s32; -typedef unsigned int u32; - -typedef signed long long s64; -typedef unsigned long long u64; - -#include "allocate.h" - -#endif /* ! _VNET_SYS_KERNEL_H_ */ diff --git a/vnet/src/vnetd/timer.c b/vnet/src/vnetd/timer.c deleted file mode 100644 index f9cc6ead06f..00000000000 --- a/vnet/src/vnetd/timer.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include - -#include "allocate.h" -#include "timer.h" - -#define MODULE_NAME "TIMER" -#undef DEBUG -#define DEBUG 1 -#include "debug.h" - -static Timer *timers = NULL; - -/** Get the time now as a double (in seconds). - * Returns zero if could not get the time. - * - * @return time now - */ -double time_now(void){ - struct timeval time; - if(gettimeofday(&time, NULL)) return 0.0; - return (double)time.tv_sec + (1.0e-6 * (double)time.tv_usec); -} - -/** Set the process real-time timer to go off at a given expiry time. - * The timer will not be set to go off in less than 10 ms - * (even if the expiry time is sooner, or in the past). - * - * @param expiry time (in seconds) - * @return 0 on success, error code otherwise - */ -static int itimer_set(double expiry){ - struct itimerval val = {}; - struct itimerval old = {}; - double now, delay; - int err = 0; - - if(expiry == 0.0){ - val.it_value.tv_sec = 0; - val.it_value.tv_usec = 0; - } else { - now = time_now(); - delay = expiry - now; - if(delay < 0.01) delay = 0.01; - val.it_value.tv_sec = (long)delay; - val.it_value.tv_usec = (long)((delay - (double)(long)delay) * 1.0e6); - } - err = setitimer(ITIMER_REAL, &val, &old); - return err; -} - -void Timer_free(Timer *z){ -#ifndef USE_GC - if(!z) return; - deallocate(z); -#endif -} - -/** Process any expired timers. - * Calls the functions of expired timers and removes them - * from the timer list. - * Reschedules the interval timer for the earliest expiring timer - * (if any). - * - * Should not be called from within the SIGALRM handler - set - * a flag there and call it later. - * - * @return 0 on success, error code otherwise. - */ -int process_timers(void){ - double now = time_now(); - Timer *curr, *next; - for(curr = timers; curr; curr = next){ - next = curr->next; - if(curr->expiry > now) break; - if(curr->fn) curr->fn(curr->data); - } - timers = curr; - itimer_set((curr ? curr->expiry : 0)); - return 0; -} - -void Timer_add(Timer *timer){ - // Insert timer in list ordered by (increasing) expiry time. - Timer *prev, *curr, *next; - prev = NULL; - for(curr = timers; curr; prev = curr, curr = next){ - next = curr->next; - if(timer->expiry < curr->expiry) break; - } - if(prev){ - prev->next = timer; - } else { - timers = timer; - } - timer->next = curr; - - // Set interval timer to go off for earliest expiry time. - itimer_set(timer->expiry); -} - -Timer * Timer_set(double delay, TimerFn *fn, unsigned long data){ - // Get 'now'. - double now = time_now(); - Timer *timer = NULL; - timer = ALLOCATE(Timer); - if(!timer) goto exit; - // Add delay to now to get expiry time. - timer->expiry = now + delay; - timer->fn = fn; - timer->data = data; - - Timer_add(timer); - exit: - return timer; -} - -int Timer_cancel(Timer *timer){ - // Remove timer from list. - int err = -ENOENT; - Timer *prev, *curr, *next; - for(prev = NULL, curr = timers; curr; prev = curr, curr = next){ - next = curr->next; - if(curr == timer){ - err = 0; - if(prev){ - prev->next = curr->next; - } else { - timers = curr->next; - } - curr->next = NULL; - break; - } - } - return err; -} - diff --git a/vnet/src/vnetd/timer.h b/vnet/src/vnetd/timer.h deleted file mode 100644 index 2316c8be227..00000000000 --- a/vnet/src/vnetd/timer.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2004 Mike Wray - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _VNET_TIMER_H_ -#define _VNET_TIMER_H_ - -struct Timer; - -typedef void TimerFn(unsigned long); - -typedef struct Timer { - struct Timer *next; - TimerFn *fn; - unsigned long data; - double expiry; -} Timer; - -extern void timer_alarm(void); -extern double time_now(void); -extern int process_timers(void); -extern Timer * Timer_set(double delay, TimerFn *fn, unsigned long data); -extern void Timer_add(Timer *timer); -extern int Timer_cancel(Timer *timer); - -#endif /* ! _VNET_TIMER_H_ */ diff --git a/vnet/src/vnetd/vnetd.c b/vnet/src/vnetd/vnetd.c deleted file mode 100644 index 27040838b14..00000000000 --- a/vnet/src/vnetd/vnetd.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* - * Copyright (C) 2005, 2006 Mike Wray . - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. This library is - * distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include // For __u32 etc. - -#include // For struct iphdr. -#include // For struct udphdr. - -#include -#include -#include - -#include "sys_kernel.h" -#include "skbuff.h" -#include "spinlock.h" - -#include "allocate.h" - -#include "file_stream.h" -#include "string_stream.h" -#include "socket_stream.h" -#include "sys_net.h" - -#include "enum.h" -#include "sxpr.h" -#include "sxpr_parser.h" - -#include "connection.h" -#include "select.h" -#include "timer.h" - -#include "if_etherip.h" -#include "if_varp.h" -#include "varp.h" -#include "vnet.h" -#include "vnet_dev.h" -#include "vnet_eval.h" -#include "vnet_forward.h" -#include "tunnel.h" -#include "etherip.h" -#include "sxpr_util.h" - -#define MODULE_NAME "VNETD" -#define DEBUG 1 -#undef DEBUG -#include "debug.h" - -#define PROGRAM "vnetd" -#define VERSION "1.0" - -typedef struct Vnetd { - unsigned long port; - int ttl; - int verbose; - int etherip; - - int udp_sock; - struct sockaddr_in udp_sock_addr; - int mcast_sock; - struct sockaddr_in mcast_sock_addr; - int etherip_sock; - struct sockaddr_in etherip_sock_addr; - int unix_sock; - char *unix_path; - - int raw_sock; - - struct sockaddr_in ucast_addr; - struct sockaddr_in mcast_addr; - - HashTable *vnet_table; - - ConnList *conns; - -} Vnetd; - -Vnetd _vnetd = {}, *vnetd = &_vnetd; - -uint32_t vnetd_intf_addr(Vnetd *vnetd){ - return vnetd->ucast_addr.sin_addr.s_addr; -} - -uint32_t vnetd_mcast_addr(Vnetd *vnetd){ - return vnetd->mcast_addr.sin_addr.s_addr; -} - -void vnetd_set_mcast_addr(Vnetd *vnetd, uint32_t addr){ - varp_mcast_addr = addr; - vnetd->mcast_addr.sin_addr.s_addr = addr; -} - -uint16_t vnetd_mcast_port(Vnetd *vnetd){ - return vnetd->mcast_addr.sin_port; -} - -uint32_t vnetd_addr(void){ - return vnetd_intf_addr(vnetd); -} - -/** Open tap device. - */ -int tap_open(struct net_device *dev){ - int err; - /* IFF_TAP : Ethernet tap device. - * IFF_NO_PI : Don't add packet info struct when reading. - * IFF_ONE_QUEUE: Drop packets when the dev queue is full. The driver uses - * the queue size from the device, which defaults to 1000 for etherdev. - * If not set the driver stops the device queue when it goes over - * TUN_READQ_SIZE, which is 10. Broken - makes the device stall - * under load. - */ - struct ifreq ifr = { }; - ifr.ifr_flags = (IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE); - - dprintf(">\n"); - dev->tapfd = open("/dev/net/tun", O_RDWR); - if(dev->tapfd < 0){ - err = -errno; - perror("open"); - goto exit; - } - strcpy(ifr.ifr_name, dev->name); - err = ioctl(dev->tapfd, TUNSETIFF, (void *)&ifr); - if(err < 0){ - err = -errno; - perror("ioctl"); - goto exit; - } - strcpy(dev->name, ifr.ifr_name); - dprintf("> dev=%s\n", dev->name); - // Make it non-blocking. - fcntl(dev->tapfd, F_SETFL, O_NONBLOCK); - - exit: - if(err && (dev->tapfd >= 0)){ - close(dev->tapfd); - dev->tapfd = -1; - } - dprintf("< err=%d\n", err); - return err; -} - -/** Close tap device. - */ -int tap_close(struct net_device *dev){ - int err = 0; - - if(dev->tapfd >= 0){ - err = close(dev->tapfd); - dev->tapfd = -1; - } - return err; -} - -/** Open vnif tap device for a vnet. - */ -int vnet_dev_add(struct Vnet *vnet){ - int err = 0; - struct net_device *dev = ALLOCATE(struct net_device); - strcpy(dev->name, vnet->device); - err = tap_open(dev); - if(err){ - wprintf("> Unable to open tap device.\n" - "The tun module must be loaded and\n" - "the vnet kernel module must not be loaded.\n"); - deallocate(dev); - goto exit; - } - vnet->dev = dev; - exit: - return err; -} - -/** Close vnif tap device for a vnet. - */ -void vnet_dev_remove(struct Vnet *vnet){ - if(vnet->dev){ - tap_close(vnet->dev); - deallocate(vnet->dev); - vnet->dev = NULL; - } -} - -/** Receive decapsulated ethernet packet on skb->dev. - * Always succeeds. The skb must not be referred to after - * this is called. - */ -int netif_rx(struct sk_buff *skb){ - int err = 0, n, k; - struct net_device *dev = skb->dev; - if(!dev){ - err = -ENODEV; - goto exit; - } - n = skb->tail - skb->mac.raw; - k = write(dev->tapfd, skb->mac.raw, n); - if(k < 0){ - err = -errno; - perror("write"); - } else if(k < n){ - //todo: What? - } - exit: - kfree_skb(skb); - return err; -} - -static const int SKB_SIZE = 1700; - -struct sk_buff *skb_new(void){ - return alloc_skb(SKB_SIZE, GFP_ATOMIC); -} - -/** Receive a packet and fill-in source and destination addresses. - * Just like recvfrom() but adds the destination address. - * The socket must have the IP_PKTINFO option set so that the - * destination address information is available. - * - * @param sock socket - * @param buf receive buffer - * @param len size of buffer - * @param flags receive flags - * @param from source address - * @param fromlen size of source address - * @param dest destination address - * @param destlen size of destination address - * @return number of bytes read on success, negative otherwise - */ -int recvfromdest(int sock, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen, - struct sockaddr *dest, socklen_t *destlen){ - int ret = 0; - struct iovec iov; - struct msghdr msg; - struct cmsghdr *cmsg; - char cbuf[1024]; - struct in_pktinfo *info; - struct sockaddr_in *dest_in = (struct sockaddr_in *)dest; - - //dest_in->sin_family = AF_INET; - //dest_in->sin_port = 0; - getsockname(sock, dest, destlen); - - iov.iov_base = buf; - iov.iov_len = len; - msg.msg_name = from; - msg.msg_namelen = *fromlen; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = cbuf; - msg.msg_controllen = sizeof(cbuf); - - ret = recvmsg(sock, &msg, flags); - if(ret < 0) goto exit; - *fromlen = msg.msg_namelen; - - for(cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)){ - if((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)){ - info = (void*)CMSG_DATA(cmsg); - dest_in->sin_addr = info->ipi_addr; - break; - } - } - - exit: - return ret; -} - -/** Read an skb from a udp socket and fill in its headers. - */ -int skb_recv_udp(int sock, int flags, - struct sockaddr_in *peer, socklen_t *peer_n, - struct sockaddr_in *dest, socklen_t *dest_n, - struct sk_buff **pskb){ - int err = 0, n; - struct sk_buff *skb = skb_new(); - - skb->mac.raw = skb->data; - skb_reserve(skb, ETH_HLEN); - skb->nh.raw = skb->data; - skb_reserve(skb, sizeof(struct iphdr)); - // Rcvr wants skb->data pointing at the udphdr. - skb->h.raw = skb_put(skb, sizeof(struct udphdr)); - n = recvfromdest(sock, skb->tail, skb_tailroom(skb), flags, - (struct sockaddr *)peer, peer_n, - (struct sockaddr *)dest, dest_n); - if(n < 0){ - err = -errno; - //perror("recvfrom"); - goto exit; - } - dprintf("> peer=%s:%d\n", inet_ntoa(peer->sin_addr), ntohs(peer->sin_port)); - dprintf("> dest=%s:%d\n", inet_ntoa(dest->sin_addr), ntohs(dest->sin_port)); - skb_put(skb, n); - skb->protocol = skb->nh.iph->protocol = IPPROTO_UDP; - skb->nh.iph->saddr = peer->sin_addr.s_addr; - skb->h.uh->source = peer->sin_port; - skb->nh.iph->daddr = dest->sin_addr.s_addr; - skb->h.uh->dest = dest->sin_port; - exit: - if(err < 0){ - kfree_skb(skb); - *pskb = NULL; - } else { - *pskb = skb; - } - return (err < 0 ? err : n); -} - -/** Read an skb fom a raw socket and fill in its headers. - */ -int skb_recv_raw(int sock, int flags, - struct sockaddr_in *peer, socklen_t *peer_n, - struct sockaddr_in *dest, socklen_t *dest_n, - struct sk_buff **pskb){ - int err = 0, n; - struct sk_buff *skb = skb_new(); - - skb->mac.raw = skb->data; - skb_reserve(skb, ETH_HLEN); - skb->nh.raw = skb->data; - skb_reserve(skb, sizeof(struct iphdr)); - // Rcvr wants skb->data pointing after ip hdr, at raw protocol hdr. - n = recvfromdest(sock, skb->tail, skb_tailroom(skb), flags, - (struct sockaddr *)peer, peer_n, - (struct sockaddr *)dest, dest_n); - if(n < 0){ - err = -errno; - //perror("recvfrom"); - goto exit; - } - skb_put(skb, n); - // On a raw socket the port in the address is the protocol. - skb->protocol = skb->nh.iph->protocol = peer->sin_port; - skb->nh.iph->saddr = peer->sin_addr.s_addr; - skb->nh.iph->daddr = dest->sin_addr.s_addr; - exit: - if(err < 0){ - kfree_skb(skb); - *pskb = NULL; - } else { - *pskb = skb; - } - return (err < 0 ? err : n); -} - -/** Read an skb from a file descriptor. - * Used for skbs coming to us from the tap device. - * The skb content is an ethernet frame. - */ -int skb_read(int fd, struct sk_buff **pskb){ - int err = 0, n; - struct sk_buff *skb = skb_new(); - - // Reserve space for the headers we will add. - skb_reserve(skb, 100); - // Rcvr will want ethhdr on the skb. - skb->mac.raw = skb->tail; - n = read(fd, skb->tail, skb_tailroom(skb)); - if(n < 0){ - err = -errno; - //perror("read"); - goto exit; - } - skb_put(skb, n); - exit: - if(err < 0){ - kfree_skb(skb); - *pskb = NULL; - } else { - *pskb = skb; - } - return (err < 0 ? err : n); -} - -/** Read an skb from the tap device for a vnet and send it. - */ -int vnet_read(Vnet *vnet){ - int err; - struct sk_buff *skb = NULL; - - err = skb_read(vnet->dev->tapfd, &skb); - if(err < 0) goto exit; - err = vnet_skb_send(skb, &vnet->vnet); - exit: - if(skb) kfree_skb(skb); - return (err < 0 ? err : 0); -} - -/** Transmit an skb to the network. - */ -int _skb_xmit(struct sk_buff *skb, uint32_t saddr){ - int err = 0; - int sock; - unsigned char *data; - struct sockaddr_in addr = { .sin_family = AF_INET }; - int flags = 0; - - if(saddr){ - dprintf("> Raw IP send\n"); - sock = vnetd->raw_sock; - skb->nh.iph->saddr = saddr; - addr.sin_addr.s_addr = skb->nh.iph->daddr; - // Should be the protocol, but is ignored. See raw(7) man page. - addr.sin_port = 0; - // Data includes the ip header. - data = (void*)(skb->nh.iph); - } else { - switch(skb->nh.iph->protocol){ - case IPPROTO_UDP: - dprintf("> protocol=UDP\n"); - sock = vnetd->udp_sock; - // Data comes after the udp header. - data = (void*)(skb->h.uh + 1); - addr.sin_addr.s_addr = skb->nh.iph->daddr; - addr.sin_port = skb->h.uh->dest; - break; - case IPPROTO_ETHERIP: - dprintf("> protocol=ETHERIP\n"); - if(vnetd->etherip_sock < 0){ - err = -ENOSYS; - goto exit; - } - sock = vnetd->etherip_sock; - // Data comes after the ip header. - data = (void*)(skb->nh.iph + 1); - addr.sin_addr.s_addr = skb->nh.iph->daddr; - // Should be the protocol, but is ignored. See raw(7) man page. - addr.sin_port = 0; - break; - default: - err = -ENOSYS; - wprintf("> protocol=%d, %d\n", skb->nh.iph->protocol, skb->protocol); - goto exit; - } - } - - dprintf("> sending %d bytes to %s:%d protocol=%d\n", - skb->tail - data, - inet_ntoa(addr.sin_addr), - ntohs(addr.sin_port), - skb->nh.iph->protocol); - - err = sendto(sock, data, skb->tail - data, flags, - (struct sockaddr *)&addr, sizeof(addr)); - if(err < 0){ - err = -errno; - perror("sendto"); - } - exit: - if(err >= 0){ - // Caller will assume skb freed if no error. - kfree_skb(skb); - err = 0; - } - dprintf("< err=%d\n", err); - return err; -} - -int varp_open(uint32_t mcaddr, uint16_t port){ - return 0; -} - -void varp_close(void){ -} - -/** Create a raw socket. - * - * @param protocol protocol - * @param flags flags (VSOCK_*) - * @param mcaddr multicast addr used with flag VSOCK_MULTICAST - * @param sock return value for the socket - */ -int vnetd_raw_socket(Vnetd *vnetd, int protocol, int flags, - uint32_t mcaddr, int *sock){ - int err; - int bcast = (flags & VSOCK_BROADCAST); - - err = *sock = socket(AF_INET, SOCK_RAW, protocol); - if(err < 0){ - err = -errno; - perror("socket"); - goto exit; - } - if(bcast){ - err = setsock_broadcast(*sock, bcast); - if(err < 0) goto exit; - } - if(flags & VSOCK_MULTICAST){ - err = setsock_multicast(*sock, INADDR_ANY, mcaddr); - if(err < 0) goto exit; - } - //todo ?? fcntl(*sock, F_SETFL, O_NONBLOCK); - exit: - return err; -} - -int get_dev_address(char *dev, unsigned long *addr){ - int err = 0; - int sock = -1; - struct ifreq ifreq = {}; - struct sockaddr_in *in_addr; - - sock = socket(AF_INET, SOCK_DGRAM, 0); - if(sock < 0){ - err = -errno; - goto exit; - } - strncpy(ifreq.ifr_name, dev, IFNAMSIZ); - err = ioctl(sock, SIOCGIFADDR, &ifreq); - if(err){ - err = -errno; - goto exit; - } - in_addr = (struct sockaddr_in *) &ifreq.ifr_addr; - *addr = in_addr->sin_addr.s_addr; - //iprintf("> dev=%s addr=%s\n", dev, inet_ntoa(in_addr->sin_addr)); - exit: - if(sock >= 0) close(sock); - return err; -} - -int get_intf_address(unsigned long *addr){ - int err = 0; - char *devs[] = {"cloudbr0", "eth0", "eth1", "eth2", "wlan0", "wlan1", NULL}; - char **dev; - - for(dev = devs; *dev; dev++){ - err = get_dev_address(*dev, addr); - if(err == 0) goto exit; - } - err = -ENOSYS; - exit: - return err; -} - -/** Get our own address. So we can ignore broadcast traffic - * we sent ourselves. - * - * @param addr - * @return 0 on success, error code otherwise - */ -int get_self_addr(struct sockaddr_in *addr){ - int err = 0; - unsigned long saddr; - - err = get_intf_address(&saddr); - if(err) goto exit; - addr->sin_addr.s_addr = saddr; - err = 0; - exit: - return err; -} - -static int eval_vnetd_mcaddr(Sxpr exp, IOStream *out, void *data){ - int err = 0; - Vnetd *vnetd = data; - Sxpr oaddr = intern("addr"); - Sxpr ottl = intern("ttl"); - uint32_t addr; - int ttl; - - err = child_addr(exp, oaddr, &addr); - if(err < 0) goto exit; - vnetd_set_mcast_addr(vnetd, addr); - if(child_int(exp, ottl, &ttl) == 0){ - vnetd->ttl = ttl; - } - exit: - return err; -} - -static int vnetd_eval_io(Vnetd *vnetd, Parser *parser, SxprEval *defs, - IOStream *in, IOStream *out){ - int err = 0; - char buf[1024]; - int k, n = sizeof(buf) - 1; - - for( ; ; ){ - k = IOStream_read(in, buf, n); - if(k < 0){ - err = k; - goto exit; - } - err = Parser_input(parser, buf, k); - if(err < 0) goto exit; - while(Parser_ready(parser)){ - Sxpr exp = Parser_get_val(parser); - if(NONEP(exp)) break; - err = vnet_eval_defs(defs, exp, out, vnetd); - if(err) goto exit; - } - if(Parser_at_eof(parser)) break; - } - exit: - return err; -} - -static int vnetd_configure(Vnetd *vnetd, char *file){ - int err = 0; - Parser *parser = NULL; - IOStream *io = NULL; - SxprEval defs[] = { - { .name = intern("peer.add"), .fn = eval_peer_add }, - { .name = intern("varp.mcaddr"), .fn = eval_vnetd_mcaddr }, - { .name = intern("vnet.add"), .fn = eval_vnet_add }, - { .name = ONONE, .fn = NULL } }; - - parser = Parser_new(); - io = file_stream_fopen(file, "rb"); - if(!io){ - err = -errno; - goto exit; - } - vnetd_eval_io(vnetd, parser, defs, io, iostdout); - exit: - if(io) IOStream_close(io); - Parser_free(parser); - return err; -} - -#define OPT_MCADDR 'a' -#define KEY_MCADDR "varp_mcaddr" -#define DOC_MCADDR "\n\t VARP multicast address" - -#define OPT_FILE 'f' -#define KEY_FILE "file" -#define DOC_FILE "\n\t Configuration file to load" - -#define OPT_HELP 'h' -#define KEY_HELP "help" -#define DOC_HELP "\n\tprint help" - -#define OPT_VERSION 'v' -#define KEY_VERSION "version" -#define DOC_VERSION "\n\tprint version" - -#define OPT_VERBOSE 'V' -#define KEY_VERBOSE "verbose" -#define DOC_VERBOSE "\n\tverbose flag" - -/** Print a usage message. - * Prints to stdout if err is zero, and exits with 0. - * Prints to stderr if err is non-zero, and exits with 1. - * - * @param err error code - */ -static void usage(int err){ - FILE *out = (err ? stderr : stdout); - - fprintf(out, "Usage: %s [options]\n", PROGRAM); - fprintf(out, "-%c, --%s %s\n", OPT_MCADDR, KEY_MCADDR, DOC_MCADDR); - fprintf(out, "-%c, --%s %s\n", OPT_FILE, KEY_FILE, DOC_FILE); - fprintf(out, "-%c, --%s %s\n", OPT_VERBOSE, KEY_VERBOSE, DOC_VERBOSE); - fprintf(out, "-%c, --%s %s\n", OPT_VERSION, KEY_VERSION, DOC_VERSION); - fprintf(out, "-%c, --%s %s\n", OPT_HELP, KEY_HELP, DOC_HELP); - exit(err ? 1 : 0); -} - -/** Short options. Options followed by ':' take an argument. */ -static char *short_opts = (char[]){ - OPT_MCADDR, ':', - OPT_FILE, ':', - OPT_HELP, - OPT_VERSION, - OPT_VERBOSE, - 0 }; - -/** Long options. */ -static struct option const long_opts[] = { - { KEY_MCADDR, required_argument, NULL, OPT_MCADDR }, - { KEY_FILE, required_argument, NULL, OPT_FILE }, - { KEY_HELP, no_argument, NULL, OPT_HELP }, - { KEY_VERSION, no_argument, NULL, OPT_VERSION }, - { KEY_VERBOSE, no_argument, NULL, OPT_VERBOSE }, - { NULL, 0, NULL, 0 } -}; - -static int vnetd_getopts(Vnetd *vnetd, int argc, char *argv[]){ - int err = 0; - int key = 0; - int long_index = 0; - - while(1){ - key = getopt_long(argc, argv, short_opts, long_opts, &long_index); - if(key == -1) break; - switch(key){ - case OPT_MCADDR: { - unsigned long addr; - err = get_inet_addr(optarg, &addr); - if(err) goto exit; - vnetd_set_mcast_addr(vnetd, addr); - break; } - case OPT_FILE: - err = vnetd_configure(vnetd, optarg); - if(err) goto exit; - break; - case OPT_HELP: - usage(0); - break; - case OPT_VERBOSE: - vnetd->verbose = true; - break; - case OPT_VERSION: - iprintf("> %s %s\n", PROGRAM, VERSION); - exit(0); - break; - default: - usage(EINVAL); - break; - } - } - exit: - return err; -} - -/** Initialise vnetd params. - * - * @param vnetd vnetd - */ -static int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){ - int err = 0; - - // Use etherip-in-udp encapsulation. - etherip_in_udp = true; - - *vnetd = (Vnetd){}; - vnetd->port = htons(VARP_PORT); - vnetd->verbose = false; - vnetd->ttl = 1; // Default multicast ttl. - vnetd->etherip = true; - vnetd->udp_sock = -1; - vnetd->mcast_sock = -1; - vnetd->etherip_sock = -1; - vnetd_set_mcast_addr(vnetd, htonl(VARP_MCAST_ADDR)); - vnetd->mcast_addr.sin_port = vnetd->port; - vnetd->unix_path = "/tmp/vnetd"; - - vnetd_getopts(vnetd, argc, argv); - - err = get_self_addr(&vnetd->ucast_addr); - vnetd->ucast_addr.sin_port = vnetd->port; - dprintf("> mcaddr=%s\n", inet_ntoa(vnetd->mcast_addr.sin_addr)); - dprintf("> addr =%s\n", inet_ntoa(vnetd->ucast_addr.sin_addr)); - return err; -} - -static void vnet_select(Vnetd *vnetd, SelectSet *set){ - HashTable_for_decl(entry); - - HashTable_for_each(entry, vnetd->vnet_table){ - Vnet *vnet = entry->value; - struct net_device *dev = vnet->dev; - if(!dev) continue; - if(dev->tapfd < 0) continue; - SelectSet_add(set, dev->tapfd, SELECT_READ); - } -} - -static void vnet_handle(Vnetd *vnetd, SelectSet *set){ - HashTable_for_decl(entry); - - HashTable_for_each(entry, vnetd->vnet_table){ - Vnet *vnet = entry->value; - struct net_device *dev = vnet->dev; - if(!dev) continue; - if(dev->tapfd < 0) continue; - if(SelectSet_in_read(set, dev->tapfd)){ - int n; - for(n = 64; n > 0; --n){ - if(vnet_read(vnet) < 0) break; - } - } - } -} - -static int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ - int err = 0, n = 0; - struct sockaddr_in peer, dest; - socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest); - int flags = MSG_DONTWAIT; - struct sk_buff *skb = NULL; - - dest = *addr; - n = skb_recv_udp(sock, flags, &peer, &peer_n, &dest, &dest_n, &skb); - if(n < 0){ - err = n; - goto exit; - } - dprintf("> Received %d bytes from=%s:%d dest=%s:%d\n", - n, - inet_ntoa(peer.sin_addr), htons(peer.sin_port), - inet_ntoa(dest.sin_addr), htons(dest.sin_port)); - if(peer.sin_addr.s_addr == vnetd_intf_addr(vnetd)){ - dprintf("> Ignoring message from self.\n"); - goto exit; - } - if(dest.sin_addr.s_addr == vnetd_mcast_addr(vnetd)){ - vnet_forward_send(skb); - } - err = varp_handle_message(skb); - - exit: - if(skb) kfree_skb(skb); - return err; -} - -static int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){ - int err = 0, n = 0; - struct sockaddr_in peer, dest; - socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest); - int flags = 0; - struct sk_buff *skb = NULL; - - dest = *addr; - n = skb_recv_raw(sock, flags, &peer, &peer_n, &dest, &dest_n, &skb); - if(n < 0){ - err = n; - goto exit; - } - dprintf("> Received %d bytes from=%s:%d dest=%s:%d\n", - n, - inet_ntoa(peer.sin_addr), htons(peer.sin_port), - inet_ntoa(dest.sin_addr), htons(dest.sin_port)); - if(peer.sin_addr.s_addr == vnetd_intf_addr(vnetd)){ - dprintf("> Ignoring message from self.\n"); - goto exit; - } - err = etherip_protocol_recv(skb); - exit: - if(skb) kfree_skb(skb); - return err; -} - -typedef struct ConnClient { - Vnetd *vnetd; - Parser *parser; -} ConnClient; - -static int conn_handle_fn(Conn *conn, int mode){ - int err; - ConnClient *client = conn->data; - char data[1024] = {}; - int k; - int done = false; - - k = IOStream_read(conn->in, data, sizeof(data)); - if(k < 0){ - err = k; - goto exit; - } - if(!client->parser){ - err = -ENOSYS; - goto exit; - } - if((k == 0) && Parser_at_eof(client->parser)){ - err = -EINVAL; - goto exit; - } - err = Parser_input(client->parser, data, k); - if(err < 0) goto exit; - while(Parser_ready(client->parser)){ - Sxpr sxpr = Parser_get_val(client->parser); - err = vnet_eval(sxpr, conn->out, NULL); - if(err) goto exit; - done = true; - } - if(done || Parser_at_eof(client->parser)){ - // Close at EOF. - err = -EIO; - } - exit: - if(err < 0){ - Parser_free(client->parser); - client->parser = NULL; - } - return (err < 0 ? err : 0); -} - -static int vnetd_handle_unix(Vnetd *vnetd, int sock){ - int err; - ConnClient *client = NULL; - Conn *conn = NULL; - struct sockaddr_un peer = {}; - socklen_t peer_n = sizeof(peer); - int peersock; - - peersock = accept(sock, (struct sockaddr *)&peer, &peer_n); - if(peersock < 0){ - perror("accept"); - err = -errno; - goto exit; - } - // We want non-blocking i/o. - fcntl(peersock, F_SETFL, O_NONBLOCK); - client = ALLOCATE(ConnClient); - client->vnetd = vnetd; - client->parser = Parser_new(); - conn = Conn_new(conn_handle_fn, client); - err = Conn_init(conn, peersock, SOCK_STREAM, SELECT_READ, - (struct sockaddr_in){}); - if(err) goto exit; - vnetd->conns = ConnList_add(vnetd->conns, conn); - exit: - if(err){ - Conn_close(conn); - close(peersock); - } - if(err < 0) wprintf("< err=%d\n", err); - return err; -} - -static void vnetd_select(Vnetd *vnetd, SelectSet *set){ - SelectSet_add(set, vnetd->unix_sock, SELECT_READ); - SelectSet_add(set, vnetd->udp_sock, SELECT_READ); - SelectSet_add(set, vnetd->mcast_sock, SELECT_READ); - if(vnetd->etherip_sock >= 0){ - SelectSet_add(set, vnetd->etherip_sock, SELECT_READ); - } - vnet_select(vnetd, set); - ConnList_select(vnetd->conns, set); -} - -static void vnetd_handle(Vnetd *vnetd, SelectSet *set){ - if(SelectSet_in_read(set, vnetd->unix_sock)){ - vnetd_handle_unix(vnetd, vnetd->unix_sock); - } - if(SelectSet_in_read(set, vnetd->udp_sock)){ - int n; - - for(n = 256; n > 0; --n){ - if(vnetd_handle_udp(vnetd, &vnetd->udp_sock_addr, vnetd->udp_sock) < 0){ - break; - } - } - } - if(SelectSet_in_read(set, vnetd->mcast_sock)){ - vnetd_handle_udp(vnetd, &vnetd->mcast_sock_addr, vnetd->mcast_sock); - } - if((vnetd->etherip_sock >= 0) && - SelectSet_in_read(set, vnetd->etherip_sock)){ - vnetd_handle_etherip(vnetd, &vnetd->etherip_sock_addr, vnetd->etherip_sock); - } - vnet_handle(vnetd, set); - vnetd->conns = ConnList_handle(vnetd->conns, set); -} - -/** Counter for timer alarms. - */ -static unsigned timer_alarms = 0; - -static int vnetd_main(Vnetd *vnetd){ - int err = 0; - SelectSet _set = {}, *set = &_set; - struct timeval _timeout = {}, *timeout = &_timeout; - - vnetd->vnet_table = vnet_table; - - for( ; ; ){ - timeout->tv_sec = 0; - timeout->tv_usec = 500000; - SelectSet_zero(set); - vnetd_select(vnetd, set); - err = SelectSet_select(set, timeout); - if(err == 0) continue; - if(err < 0){ - switch(errno){ - case EINTR: - if(timer_alarms){ - timer_alarms = 0; - process_timers(); - } - continue; - case EBADF: - continue; - default: - perror("select"); - goto exit; - } - } - vnetd_handle(vnetd, set); - } - exit: - return err; -} - -static int getsockaddr(int sock, struct sockaddr_in *addr){ - socklen_t addr_n = sizeof(struct sockaddr_in); - return getsockname(sock, (struct sockaddr*)addr, &addr_n); -} - -static int vnetd_etherip_sock(Vnetd *vnetd){ - int err = 0; - - if(!vnetd->etherip) goto exit; - err = vnetd_raw_socket(vnetd, IPPROTO_ETHERIP, - (VSOCK_BROADCAST | VSOCK_MULTICAST), - vnetd_mcast_addr(vnetd), - &vnetd->etherip_sock); - if(err < 0) goto exit; - err = setsock_pktinfo(vnetd->etherip_sock, true); - if(err < 0) goto exit; - getsockaddr(vnetd->etherip_sock, &vnetd->etherip_sock_addr); - exit: - return err; -} - -static int vnetd_udp_sock(Vnetd *vnetd){ - int err; - uint32_t mcaddr = vnetd_mcast_addr(vnetd); - - err = create_socket(SOCK_DGRAM, INADDR_ANY, vnetd->port, - (VSOCK_BIND | VSOCK_REUSE), - &vnetd->udp_sock); - if(err < 0) goto exit; - err = setsock_pktinfo(vnetd->udp_sock, true); - if(err < 0) goto exit; - getsockaddr(vnetd->udp_sock, &vnetd->udp_sock_addr); - vnetd->mcast_sock_addr.sin_addr.s_addr = vnetd_intf_addr(vnetd); - - err = create_socket(SOCK_DGRAM, mcaddr, vnetd_mcast_port(vnetd), - (VSOCK_REUSE | VSOCK_BROADCAST | VSOCK_MULTICAST), - &vnetd->mcast_sock); - if(err < 0) goto exit; - err = setsock_pktinfo(vnetd->udp_sock, true); - if(err < 0) goto exit; - err = setsock_multicast(vnetd->mcast_sock, INADDR_ANY, mcaddr); - if(err < 0) goto exit; - err = setsock_multicast_ttl(vnetd->mcast_sock, vnetd->ttl); - if(err < 0) goto exit; - getsockaddr(vnetd->mcast_sock, &vnetd->mcast_sock_addr); - vnetd->mcast_sock_addr.sin_addr.s_addr = mcaddr; - - exit: - if(err < 0){ - close(vnetd->udp_sock); - close(vnetd->mcast_sock); - vnetd->udp_sock = -1; - vnetd->mcast_sock = -1; - } - return err; -} - -static int vnetd_raw_sock(Vnetd *vnetd){ - int err; - - err = vnetd_raw_socket(vnetd, IPPROTO_RAW, - (VSOCK_BROADCAST), - vnetd_mcast_addr(vnetd), - &vnetd->raw_sock); - if(err){ - close(vnetd->raw_sock); - vnetd->raw_sock = -1; - } - return err; -} - -static int vnetd_unix_sock(Vnetd *vnetd){ - int err = 0; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - socklen_t addr_n; - - vnetd->unix_sock = socket(addr.sun_family, SOCK_STREAM, 0); - if(vnetd->unix_sock < 0){ - err = -errno; - perror("unix socket"); - goto exit; - } - unlink(vnetd->unix_path); - strcpy(addr.sun_path, vnetd->unix_path); - addr_n = sizeof(addr) - sizeof(addr.sun_path) + strlen(vnetd->unix_path) + 1; - err = bind(vnetd->unix_sock, (struct sockaddr *)&addr, addr_n); - if(err < 0){ - err = -errno; - perror("unix bind"); - goto exit; - } - err = listen(vnetd->unix_sock, 5); - if(err < 0){ - err = -errno; - perror("unix listen"); - } - exit: - return err; -} - -/** Handle SIGPIPE. - * - * @param code signal code - * @param info signal info - * @param data - */ -static void sigaction_SIGPIPE(int code, siginfo_t *info, void *data){ - dprintf("> SIGPIPE\n"); -} - -/** Handle SIGALRM. - * - * @param code signal code - * @param info signal info - * @param data - */ -static void sigaction_SIGALRM(int code, siginfo_t *info, void *data){ - timer_alarms++; -} - -/** Type for signal handling functions. */ -typedef void SignalAction(int code, siginfo_t *info, void *data); - -/** Install a handler for a signal. - * - * @param signum signal - * @param action handler - * @return 0 on success, error code otherwise - */ -static int catch_signal(int signum, SignalAction *action){ - int err = 0; - struct sigaction sig = {}; - dprintf(">\n"); - sig.sa_sigaction = action; - sig.sa_flags = SA_SIGINFO; - err = sigaction(signum, &sig, NULL); - if(err){ - err = -errno; - perror("sigaction"); - } - return err; -} - -int main(int argc, char *argv[]){ - int err = 0; - - err = tunnel_module_init(); - if(err < 0) goto exit; - err = vnet_init(); - if(err < 0) goto exit; - err = vnetd_init(vnetd, argc, argv); - if(err < 0) goto exit; - err = catch_signal(SIGPIPE, sigaction_SIGPIPE); - if(err < 0) goto exit; - err = catch_signal(SIGALRM, sigaction_SIGALRM); - if(err < 0) goto exit; - err = vnetd_etherip_sock(vnetd); - if(err < 0) goto exit; - err = vnetd_udp_sock(vnetd); - if(err < 0) goto exit; - err = vnetd_raw_sock(vnetd); - if(err < 0) goto exit; - err = vnetd_unix_sock(vnetd); - if(err < 0) goto exit; - err = vnetd_main(vnetd); -exit: - return (err ? 1 : 0); -} diff --git a/vnet/wscript_build b/vnet/wscript_build deleted file mode 100644 index 270368b32c3..00000000000 --- a/vnet/wscript_build +++ /dev/null @@ -1,21 +0,0 @@ -import Utils - -if bld.env.DISTRO not in ['Windows','Mac']: - # build / install declarations of vnet - files = """vnetd/connection.c vnetd/select.c vnetd/timer.c vnetd/spinlock.c vnetd/skbuff.c - vnetd/vnetd.c vnet-module/skb_util.c vnet-module/sxpr_util.c vnet-module/timer_util.c - vnet-module/etherip.c vnet-module/vnet.c vnet-module/vnet_eval.c vnet-module/vnet_forward.c - vnet-module/vif.c vnet-module/tunnel.c vnet-module/sa.c vnet-module/varp.c - libxutil/allocate.c libxutil/enum.c libxutil/file_stream.c libxutil/hash_table.c - libxutil/iostream.c libxutil/lexis.c libxutil/socket_stream.c libxutil/string_stream.c - libxutil/sxpr.c libxutil/sxpr_parser.c libxutil/sys_net.c libxutil/sys_string.c libxutil/util.c""" - files = [ "src/%s"%s for s in Utils.to_list(files) ] - bld( - name='vnetd', - features='cc cprogram', - source= files, - includes="src/libxutil src/vnet-module src/vnetd", - lib='dl pthread'.split(), - target='%s-vnetd'%bld.env.PACKAGE, - install_path="${SBINDIR}" - ) diff --git a/wscript_build b/wscript_build index 0401cd4b8dc..2f89a744160 100644 --- a/wscript_build +++ b/wscript_build @@ -87,7 +87,7 @@ tgen = bld(rule=Utils.runant, name='runant', source=ant_sources, target=ant_jars # =================== C / Python compilation ========================= -bld.recurse(["vnet","daemonize","python"],'build') +bld.recurse(["daemonize","python"],'build') # ===================== End C / Python compilation ==========================