diff --git a/README.md b/README.md index 0fe208a..c22d125 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Vagrant.configure("2") do |config| The following example shows part of a Vagrantfile that enables the VM to boot from a network interface first and a hard disk second. This could be -used to run VMs that are meant to be a PXE booted machines. Be aware that +used to run VMs that are meant to be a PXE booted machines. Be aware that if `hd` is not specified as a boot option, it will never be tried. ```ruby @@ -218,11 +218,16 @@ Vagrant.configure("2") do |config| Networking features in the form of `config.vm.network` support private networks concept. It supports both the virtual network switch routing types and the point to -point Guest OS to Guest OS setting using TCP tunnel interfaces. +point Guest OS to Guest OS setting using UDP/Mcast/TCP tunnel interfaces. http://wiki.libvirt.org/page/VirtualNetworking + https://libvirt.org/formatdomain.html#elementsNICSTCP +http://libvirt.org/formatdomain.html#elementsNICSMulticast + +http://libvirt.org/formatdomain.html#elementsNICSUDP _(in libvirt v1.2.20 and higher)_ + Public Network interfaces are currently implemented using the macvtap driver. The macvtap driver is only available with the Linux Kernel version >= 2.6.24. See the following libvirt documentation for the details of the macvtap usage. @@ -242,18 +247,18 @@ An examples of network interface definitions: # Guest 1 config.vm.define :test_vm1 do |test_vm1| test_vm1.vm.network :private_network, - :libvirt__tcp_tunnel_type => 'server', + :libvirt__tunnel_type => 'server', # default is 127.0.0.1 if omitted - # :libvirt__tcp_tunnel_ip => '127.0.0.1', - :libvirt__tcp_tunnel_port => '11111' + # :libvirt__tunnel_ip => '127.0.0.1', + :libvirt__tunnel_port => '11111' # Guest 2 config.vm.define :test_vm2 do |test_vm2| test_vm2.vm.network :private_network, - :libvirt__tcp_tunnel_type => 'client', + :libvirt__tunnel_type => 'client', # default is 127.0.0.1 if omitted - # :libvirt__tcp_tunnel_ip => '127.0.0.1', - :libvirt__tcp_tunnel_port => '11111' + # :libvirt__tunnel_ip => '127.0.0.1', + :libvirt__tunnel_port => '11111' # Public Network @@ -317,15 +322,25 @@ starts with 'libvirt__' string. Here is a list of those options: * `:libvirt__forward_device` - Name of interface/device, where network should be forwarded (NATed or routed). Used only when creating new network. By default, all physical interfaces are used. -* `:libvirt_tcp_tunnel_type` - Set it to "server" or "client" to enable TCP - tunnel interface configuration. This configuration type uses TCP tunnels to +* `:libvirt__tunnel_type` - Set to 'udp' if using UDP unicast tunnel mode (libvirt v1.2.20 or higher). + Set this to either "server" or "client" for tcp tunneling. Set this to 'mcast' if using multicast + tunneling. This configuration type uses tunnels to generate point to point connections between Guests. Useful for Switch VMs like - Cumulus Linux. No virtual switch setting like "libvirt__network_name" applies with TCP + Cumulus Linux. No virtual switch setting like "libvirt__network_name" applies with tunnel interfaces and will be ignored if configured. -* `:libvirt_tcp_tunnel_ip` - Sets the source IP of the TCP Tunnel interface. By - default this is `127.0.0.1` -* `:libvirt_tcp_tunnel_port` - Sets the TCP Tunnel interface port that either - the client will connect to, or the server will listen on. +* `:libvirt__tunnel_ip` - Sets the source IP of the libvirt tunnel interface. By + default this is `127.0.0.1` for TCP and UDP tunnels and `239.255.1.1` for Multicast + tunnels. It populates the address field in the `` of the + interface xml configuration. +* `:libvirt__tunnel_port` - Sets the source port the tcp/udp/mcast tunnel + with use. This port information is placed in the `` section of + interface xml configuration. +* `:libvirt__tunnel_local_port` - Sets the local port used by the udp tunnel + interface type. It populates the port field in the `` section of the + interface xml configuration. _(This feature only works in libvirt 1.2.20 and higher)_ +* `:libvirt__tunnel_local_ip` - Sets the local IP used by the udp tunnel + interface type. It populates the ip entry of the `` section of + the interface xml configuration. _(This feature only works in libvirt 1.2.20 and higher)_ * `:mac` - MAC address for the interface. * `:model_type` - parameter specifies the model of the network adapter when you create a domain value by default virtio KVM believe possible values, see the documentation for libvirt @@ -435,7 +450,7 @@ There is support for PXE booting VMs with no disks as well as PXE booting VMs wi * No provisioning scripts are ran * No network configuration is being applied to the VM * No SSH connection can be made -* ```vagrant halt``` will only work cleanly if the VM handles ACPI shutdown signals +* ```vagrant halt``` will only work cleanly if the VM handles ACPI shutdown signals In short, VMs without a box can be created, halted and destroyed but all other functionality cannot be used. diff --git a/lib/vagrant-libvirt/action/create_network_interfaces.rb b/lib/vagrant-libvirt/action/create_network_interfaces.rb index 3324f9e..49e44ee 100644 --- a/lib/vagrant-libvirt/action/create_network_interfaces.rb +++ b/lib/vagrant-libvirt/action/create_network_interfaces.rb @@ -79,15 +79,27 @@ module VagrantPlugins template_name = 'public_interface' @logger.info("Setting up public interface using device #{@device} in mode #{@mode}") @ovs = iface_configuration.fetch(:ovs, false) - # configuration for tcp tunnel interfaces (p2p conn btwn guest OSes) - elsif iface_configuration.fetch(:tcp_tunnel_type, nil) - @tcp_tunnel_port = iface_configuration.fetch(:tcp_tunnel_port, nil) - raise Errors::TcpTunnelPortNotDefined if @tcp_tunnel_port.nil? - @tcp_tunnel_ip = iface_configuration.fetch(:tcp_tunnel_address, '127.0.0.1') - @type = iface_configuration.fetch(:tcp_tunnel_type) + # configuration for udp or tcp tunnel interfaces (p2p conn btwn guest OSes) + elsif iface_configuration.fetch(:tunnel_type, nil) + @type = iface_configuration.fetch(:tunnel_type) + @tunnel_port = iface_configuration.fetch(:tunnel_port, nil) + raise Errors::TunnelPortNotDefined if @tunnel_port.nil? + if @type == 'udp' + # default udp tunnel source to 127.0.0.1 + @udp_tunnel_local_ip = iface_configuration.fetch(:tunnel_local_ip, '127.0.0.1') + @udp_tunnel_local_port = iface_configuration.fetch(:tunnel_local_port) + end + # default mcast tunnel to 239.255.1.1. Web search says this + # 239.255.x.x is a safe range to use for general use mcast + if @type == 'mcast' + default_ip = '239.255.1.1' + else + default_ip = '127.0.0.1' + end + @tunnel_ip = iface_configuration.fetch(:tunnel_address, default_ip) @model_type = iface_configuration.fetch(:model_type, @nic_model_type) - template_name = 'tcp_tunnel_interface' - @logger.info("Setting up #{@type} tunnel interface using #{@tcp_tunnel_ip} port #{@tcp_tunnel_port}") + template_name = 'tunnel_interface' + @logger.info("Setting up #{@type} tunnel interface using #{@tunnel_ip} port #{@tunnel_port}") end @@ -130,7 +142,7 @@ module VagrantPlugins # Configure interfaces that user requested. Machine should be up and # running now. networks_to_configure = [] - + adapters.each_with_index do |options, slot_number| # Skip configuring the management network, which is on the first interface. # It's used for provisioning and it has to be available during provisioning, @@ -138,13 +150,13 @@ module VagrantPlugins next if slot_number == 0 next if options[:auto_config] === false @logger.debug "Configuring interface slot_number #{slot_number} options #{options}" - + network = { :interface => slot_number, :use_dhcp_assigned_default_route => options[:use_dhcp_assigned_default_route], :mac_address => options[:mac], } - + if options[:ip] network = { :type => :static, @@ -154,16 +166,17 @@ module VagrantPlugins else network[:type] = :dhcp end - + # do not run configure_networks for tcp tunnel interfaces - next if options.fetch(:tcp_tunnel_type, nil) - + next if options.fetch(:tunnel_type, nil) + networks_to_configure << network end - + env[:ui].info I18n.t('vagrant.actions.vm.network.configuring') env[:machine].guest.capability( :configure_networks, networks_to_configure) + end end @@ -179,7 +192,7 @@ module VagrantPlugins # Return network name according to interface options. def interface_network(libvirt_client, options) # no need to get interface network for tcp tunnel config - return 'tcp_tunnel' if options.fetch(:tcp_tunnel_type, nil) + return 'tunnel_interface' if options.fetch(:tunnel_type, nil) if options[:network_name] @logger.debug "Found network by name" diff --git a/lib/vagrant-libvirt/action/create_networks.rb b/lib/vagrant-libvirt/action/create_networks.rb index 728ec33..60a1d65 100644 --- a/lib/vagrant-libvirt/action/create_networks.rb +++ b/lib/vagrant-libvirt/action/create_networks.rb @@ -36,7 +36,7 @@ module VagrantPlugins configured_networks(env, @logger).each do |options| # Only need to create private networks next if options[:iface_type] != :private_network or - options.fetch(:tcp_tunnel_type, nil) + options.fetch(:tunnel_type, nil) @logger.debug "Searching for network with options #{options}" # should fix other methods so this doesn't have to be instance var @@ -133,7 +133,7 @@ module VagrantPlugins # Set IP address of network (actually bridge). It will be used as # gateway address for machines connected to this network. net = IPAddr.new(net_address) - + # Default to first address (after network name) @interface_network[:ip_address] = @options[:host_ip].nil? ? \ net.to_range.begin.succ : \ @@ -158,7 +158,7 @@ module VagrantPlugins if @interface_network[:created] verify_dhcp end - + if @options[:network_name] @logger.debug "Checking that network name does not clash with ip" if @interface_network[:created] @@ -177,13 +177,13 @@ module VagrantPlugins ip_address: @options[:ip], network_name: @options[:network_name] end - + # Network with 'name' doesn't exist. Set it as name for new # network. @interface_network[:name] = @options[:network_name] end end - + # Do we need to create new network? if !@interface_network[:created] @@ -235,7 +235,7 @@ module VagrantPlugins @interface_network = network if network # if this interface has a network address, something's wrong. - if @interface_network[:network_address] + if @interface_network[:network_address] raise Errors::NetworkNotAvailableError, network_name: @options[:network_name] end diff --git a/lib/vagrant-libvirt/errors.rb b/lib/vagrant-libvirt/errors.rb index 863a4f0..55bb33e 100644 --- a/lib/vagrant-libvirt/errors.rb +++ b/lib/vagrant-libvirt/errors.rb @@ -106,8 +106,8 @@ module VagrantPlugins error_key(:activate_network_error) end - class TcpTunnelPortNotDefined < VagrantLibvirtError - error_key(:tcp_tunnel_port_not_defined) + class TunnelPortNotDefined < VagrantLibvirtError + error_key(:tunnel_port_not_defined) end # Other exceptions diff --git a/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb b/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb deleted file mode 100644 index 379b740..0000000 --- a/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb +++ /dev/null @@ -1,7 +0,0 @@ - - <% if @mac %> - - <% end %> - - - diff --git a/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb b/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb new file mode 100644 index 0000000..315e1be --- /dev/null +++ b/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb @@ -0,0 +1,11 @@ + + <% if @mac %> + + <% end %> + + <% if @type == 'udp' %> + + <% end %> + + + diff --git a/locales/en.yml b/locales/en.yml index b11d46b..30a853e 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -135,8 +135,8 @@ en: Error while removing network %{network_name}. %{error_message}. delete_snapshot_error: |- Error while deleting snapshot: %{error_message}. - tcp_tunnel_port_not_defined: |- - TCP tunnel port not defined. + tunnel_port_not_defined: |- + tunnel UDP or TCP port not defined. states: paused: |-