diff --git a/install.sh b/install.sh index 6c9907c2fd..0f9a450e15 100755 --- a/install.sh +++ b/install.sh @@ -262,6 +262,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vmm/az \ $VAR_LOCATION/remotes/vnm \ $VAR_LOCATION/remotes/vnm/802.1Q \ + $VAR_LOCATION/remotes/vnm/vxlan \ $VAR_LOCATION/remotes/vnm/dummy \ $VAR_LOCATION/remotes/vnm/ebtables \ $VAR_LOCATION/remotes/vnm/fw \ @@ -449,6 +450,7 @@ INSTALL_FILES=( DATASTORE_DRIVER_DEV_SCRIPTS:$VAR_LOCATION/remotes/datastore/dev NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q + NETWORK_VXLAN_FILES:$VAR_LOCATION/remotes/vnm/vxlan NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy NETWORK_EBTABLES_FILES:$VAR_LOCATION/remotes/vnm/ebtables NETWORK_FW_FILES:$VAR_LOCATION/remotes/vnm/fw @@ -940,6 +942,7 @@ NETWORK_FILES="src/vnm_mad/remotes/lib/vnm_driver.rb \ src/vnm_mad/remotes/lib/address.rb \ src/vnm_mad/remotes/lib/command.rb \ src/vnm_mad/remotes/lib/vm.rb \ + src/vnm_mad/remotes/lib/vlan.rb \ src/vnm_mad/remotes/lib/security_groups.rb \ src/vnm_mad/remotes/lib/security_groups_iptables.rb \ src/vnm_mad/remotes/lib/nic.rb" @@ -947,7 +950,13 @@ NETWORK_FILES="src/vnm_mad/remotes/lib/vnm_driver.rb \ NETWORK_8021Q_FILES="src/vnm_mad/remotes/802.1Q/clean \ src/vnm_mad/remotes/802.1Q/post \ src/vnm_mad/remotes/802.1Q/pre \ - src/vnm_mad/remotes/802.1Q/vlan_driver.rb" + src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb" + +NETWORK_VXLAN_FILES="src/vnm_mad/remotes/vxlan/clean \ + src/vnm_mad/remotes/vxlan/post \ + src/vnm_mad/remotes/vxlan/pre \ + src/vnm_mad/remotes/vxlan/vxlan_driver.rb" + NETWORK_DUMMY_FILES="src/vnm_mad/remotes/dummy/clean \ src/vnm_mad/remotes/dummy/post \ diff --git a/src/vnm_mad/remotes/802.1Q/pre b/src/vnm_mad/remotes/802.1Q/pre index 656fca6415..1dd5d1d12d 100755 --- a/src/vnm_mad/remotes/802.1Q/pre +++ b/src/vnm_mad/remotes/802.1Q/pre @@ -19,7 +19,7 @@ $: << File.dirname(__FILE__) $: << File.join(File.dirname(__FILE__), "..") -require 'vlan_driver' +require 'vlan_tag_driver' -hm = VLANDriver.from_base64(ARGV[0]) +hm = VLANTagDriver.from_base64(ARGV[0]) exit hm.activate diff --git a/src/vnm_mad/remotes/802.1Q/vlan_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_driver.rb deleted file mode 100644 index f3dcf5dabc..0000000000 --- a/src/vnm_mad/remotes/802.1Q/vlan_driver.rb +++ /dev/null @@ -1,130 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -require 'vnmmad' - -################################################################################ -# This driver tag VM traffic with a VLAN_ID using 802.1Q protocol. Features: -# - Creates a bridge and bind phisycal device if not present -# - Creates a tagged interface for the VM dev.vlan_id -# -# Once activated the VM will be attached to this bridge -################################################################################ -class VLANDriver < VNMMAD::VNMDriver - - # DRIVER name and XPATH for relevant NICs - DRIVER = "802.1Q" - XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" - - ############################################################################ - # Creatges the driver device operations are not locked - ############################################################################ - def initialize(vm, deploy_id = nil, hypervisor = nil) - super(vm, XPATH_FILTER, deploy_id, hypervisor) - @locking = false - - lock - @bridges = get_interfaces - unlock - end - - ############################################################################ - # Activate the driver and creates bridges and tags devices as needed. - ############################################################################ - def activate - lock - - vm_id = @vm['ID'] - - process do |nic| - bridge = nic[:bridge] - dev = nic[:phydev] - - if dev - if nic[:vlan_id] - vlan = nic[:vlan_id] - else - vlan = CONF[:start_vlan] + nic[:network_id].to_i - end - - if !bridge_exists? bridge - create_bridge bridge - ifup bridge - end - - if !device_exists?(dev, vlan) - create_dev_vlan(dev, vlan) - ifup(dev, vlan) - end - - if !attached_bridge_dev?(bridge, dev, vlan) - attach_brigde_dev(bridge, dev, vlan) - end - end - end - - unlock - - return 0 - end - - ############################################################################ - # Private interface, methods to manage bridges and VLAN tags through the - # brctl and ip commands - ############################################################################ - private - - def bridge_exists?(bridge) - @bridges.keys.include? bridge - end - - def create_bridge(bridge) - OpenNebula.exec_and_log("#{command(:brctl)} addbr #{bridge}") - @bridges[bridge] = Array.new - end - - def device_exists?(dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - `#{command(:ip)} link show #{dev}` - $?.exitstatus == 0 - end - - def create_dev_vlan(dev, vlan) - cmd = "#{command(:ip)} link add link #{dev}" - cmd << " name #{dev}.#{vlan} type vlan id #{vlan}" - - OpenNebula.exec_and_log(cmd) - end - - def attached_bridge_dev?(bridge, dev, vlan=nil) - return false if !bridge_exists? bridge - - dev = "#{dev}.#{vlan}" if vlan - @bridges[bridge].include? dev - end - - def attach_brigde_dev(bridge, dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - - OpenNebula.exec_and_log("#{command(:brctl)} addif #{bridge} #{dev}") - @bridges[bridge] << dev - end - - def ifup(dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - OpenNebula.exec_and_log("#{command(:ip)} link set #{dev} up") - end -end diff --git a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb new file mode 100644 index 0000000000..bc2f6c0ce1 --- /dev/null +++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb @@ -0,0 +1,51 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'vnmmad' + +################################################################################ +# This driver tag VM traffic with a VLAN_ID using 802.1Q protocol. Features: +# - Creates a bridge and bind phisycal device if not present +# - Creates a tagged interface for the VM dev.vlan_id +# +# Once activated the VM will be attached to this bridge +################################################################################ +class VLANTagDriver < VNMMAD::VLANDriver + + # DRIVER name and XPATH for relevant NICs + DRIVER = "802.1Q" + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + ############################################################################ + # Creatges the driver device operations are not locked + ############################################################################ + def initialize(vm, deploy_id = nil, hypervisor = nil) + @locking = false + + super(vm, XPATH_FILTER, deploy_id, hypervisor) + end + + ############################################################################ + # This function creates and activate a VLAN device + ############################################################################ + def create_vlan_dev(options) + OpenNebula.exec_and_log("#{command(:ip)} link add link"\ + " #{options[:phydev]} name #{options[:vlan_dev]} type vlan id"\ + " #{options[:vlan_id]}") + + OpenNebula.exec_and_log("#{command(:ip)} link set #{options[:vlan_dev]} up") + end +end diff --git a/src/vnm_mad/remotes/OpenNebulaNetwork.conf b/src/vnm_mad/remotes/OpenNebulaNetwork.conf index 8ab0d99ad4..f622b63d87 100644 --- a/src/vnm_mad/remotes/OpenNebulaNetwork.conf +++ b/src/vnm_mad/remotes/OpenNebulaNetwork.conf @@ -27,3 +27,10 @@ # Enable ARP Cache Poisoning Prevention Rules :arp_cache_poisoning: true + +################################################################################ +# VXLAN Options +################################################################################ + +# Base multicast address for each VLAN. The mc address is :vxlan_mc + :vlan_id +:vxlan_mc: 239.0.0.0 diff --git a/src/vnm_mad/remotes/lib/vlan.rb b/src/vnm_mad/remotes/lib/vlan.rb new file mode 100644 index 0000000000..0a2f20e951 --- /dev/null +++ b/src/vnm_mad/remotes/lib/vlan.rb @@ -0,0 +1,135 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +module VNMMAD + + ############################################################################ + # Module to use as mixin for implementing VLAN drivers based on special + # link devices though the Linux kernel features and bridges. It provides + # common functionality to handle bridges + ############################################################################ + class VLANDriver < VNMMAD::VNMDriver + + def initialize(vm_tpl, xpath_filter, deploy_id = nil, hypervisor = nil) + super(vm_tpl, xpath_filter, deploy_id, hypervisor) + + lock + @bridges = get_bridges + unlock + end + + # Activate the driver and creates bridges and tags devices as needed. + def activate + lock + + options = Hash.new + + process do |nic| + + options.clear + + options[:bridge] = nic[:bridge] + options[:phydev] = nic[:phydev] + options[:vlan_id] = nic[:vlan_id] + options[:network_id] = nic[:network_id] + + return if options[:phydev].nil? + + set_up_vlan(options) + end + + unlock + + return 0 + end + + # Set ups the VLAN for the VMs. + # @param options [Hash] including + # - :phydev Physical Device to bind the VLAN traffic to + # - :bridge Name of the bridge to attach the VMs and VLAN dev to + # - :network_id + def set_up_vlan(options) + + if options[:vlan_id].nil? + options[:vlan_id] = CONF[:start_vlan] + options[:network_id].to_i + end + + options[:vlan_dev] = "#{options[:phydev]}.#{options[:vlan_id]}" + + create_bridge(options[:bridge]) + + return if @bridges[options[:bridge]].include? options[:vlan_dev] + + create_vlan_dev(options) + + OpenNebula.exec_and_log("#{command(:brctl)} addif"\ + " #{options[:bridge]} #{options[:vlan_dev]}") + + @bridges[options[:bridge]] << options[:vlan_dev] + end + + # This function needs to be implemented by any VLAN driver to + # create the VLAN device. The device MUST be set up by this function + # Options is a driver specific hash. It includes + # :vlan_dev the name for the VLAN device + # :phydev Physical Device to bind the VLAN traffic to + # :vlan_id the VLAN ID + # : additional driver specific parameters + def create_vlan_dev(options) + OpenNebula.log_error("create_vlan_dev function not implemented.") + + exit -1 + end + + private + # Creates a bridge if it does not exists, and brings it up. + # This function IS FINAL, exits if action cannot be completed + # @param bridge [String] the bridge name + def create_bridge(bridge) + return if @bridges.keys.include? bridge + + OpenNebula.exec_and_log("#{command(:brctl)} addbr #{bridge}") + + @bridges[bridge] = Array.new + + OpenNebula.exec_and_log("#{command(:ip)} link set #{bridge} up") + end + + # Get hypervisor bridges + # @return [Hash] with the bridge names + def get_bridges + bridges = Hash.new + brctl_exit =`#{VNMNetwork::COMMANDS[:brctl]} show` + + cur_bridge = "" + + brctl_exit.split("\n")[1..-1].each do |l| + l = l.split + + if l.length > 1 + cur_bridge = l[0] + + bridges[cur_bridge] = Array.new + bridges[cur_bridge] << l[3] if l[3] + else + bridges[cur_bridge] << l[0] + end + end + + bridges + end + end +end diff --git a/src/vnm_mad/remotes/lib/vnm_driver.rb b/src/vnm_mad/remotes/lib/vnm_driver.rb index f62df56e06..8ee3ba71c9 100644 --- a/src/vnm_mad/remotes/lib/vnm_driver.rb +++ b/src/vnm_mad/remotes/lib/vnm_driver.rb @@ -35,7 +35,7 @@ module VNMMAD # @param deploy_id [String] # @param hypervisor [String] def initialize(vm_tpl, xpath_filter, deploy_id = nil, hypervisor = nil) - @locking = false + @locking ||= false if !hypervisor @hypervisor = detect_hypervisor @@ -92,30 +92,6 @@ module VNMMAD nil end end - - # Get hypervisor bridges - # @return [Hash] with the bridge names - def get_interfaces - bridges = Hash.new - brctl_exit =`#{VNMNetwork::COMMANDS[:brctl]} show` - - cur_bridge = "" - - brctl_exit.split("\n")[1..-1].each do |l| - l = l.split - - if l.length > 1 - cur_bridge = l[0] - - bridges[cur_bridge] = Array.new - bridges[cur_bridge] << l[3] if l[3] - else - bridges[cur_bridge] << l[0] - end - end - - bridges - end # Returns true if the template contains the deprecated firewall attributes: # - ICMP diff --git a/src/vnm_mad/remotes/lib/vnmmad.rb b/src/vnm_mad/remotes/lib/vnmmad.rb index dad4386931..08c816acdf 100644 --- a/src/vnm_mad/remotes/lib/vnmmad.rb +++ b/src/vnm_mad/remotes/lib/vnmmad.rb @@ -30,7 +30,7 @@ require 'security_groups_iptables' require 'vnm_driver' require 'fw_driver' require 'sg_driver' - +require 'vlan' require 'scripts_common' include OpenNebula diff --git a/src/vnm_mad/remotes/vxlan/clean b/src/vnm_mad/remotes/vxlan/clean new file mode 120000 index 0000000000..940540d063 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/clean @@ -0,0 +1 @@ +../fw/clean \ No newline at end of file diff --git a/src/vnm_mad/remotes/vxlan/post b/src/vnm_mad/remotes/vxlan/post new file mode 120000 index 0000000000..e0046b5997 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/post @@ -0,0 +1 @@ +../fw/post \ No newline at end of file diff --git a/src/vnm_mad/remotes/vxlan/pre b/src/vnm_mad/remotes/vxlan/pre new file mode 100755 index 0000000000..a44a58d8a8 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/pre @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +$: << File.dirname(__FILE__) +$: << File.join(File.dirname(__FILE__), "..") + +require 'vxlan_driver' + +hm = VXLANDriver.from_base64(ARGV[0]) +exit hm.activate diff --git a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb new file mode 100644 index 0000000000..c145db4726 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb @@ -0,0 +1,54 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'vnmmad' + +################################################################################ +# This driver tag VM traffic with a VLAN_ID using VXLAN protocol. Features: +# - Creates a bridge and bind phisycal device if not present +# - Creates a tagged interface for the VM dev.vlan_id +# +# Once activated the VM will be attached to this bridge +################################################################################ +class VXLANDriver < VNMMAD::VLANDriver + + # DRIVER name and XPATH for relevant NICs + DRIVER = "vxlan" + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + ############################################################################ + # Creatges the driver device operations are not locked + ############################################################################ + def initialize(vm, deploy_id = nil, hypervisor = nil) + @locking = false + + super(vm, XPATH_FILTER, deploy_id, hypervisor) + end + + ############################################################################ + # This function creates and activate a VLAN device + ############################################################################ + def create_vlan_dev(options) + mc = VNMMAD::VNMNetwork::IPv4.to_i(CONF[:vxlan_mc]) + options[:vlan_id].to_i + mcs = VNMMAD::VNMNetwork::IPv4.to_s(mc) + + OpenNebula.exec_and_log("#{command(:ip)} link add #{options[:vlan_dev]}"\ + " type vxlan id #{options[:vlan_id]} group #{mcs}"\ + " dev #{options[:phydev]}") + + OpenNebula.exec_and_log("#{command(:ip)} link set #{options[:vlan_dev]} up") + end +end