mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-24 02:03:52 +03:00
feature #3208: Implement VXLAN support. Moved common bridge functions from 802.1Q to VLANDriver class. Rename vlan_driver to vlan_tag_driver for 802.1Q.
This commit is contained in:
parent
e061f11f69
commit
5d44f6e758
11
install.sh
11
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 \
|
||||
|
@ -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
|
||||
|
@ -23,7 +23,7 @@ require 'vnmmad'
|
||||
#
|
||||
# Once activated the VM will be attached to this bridge
|
||||
################################################################################
|
||||
class VLANDriver < VNMMAD::VNMDriver
|
||||
class VLANTagDriver < VNMMAD::VLANDriver
|
||||
|
||||
# DRIVER name and XPATH for relevant NICs
|
||||
DRIVER = "802.1Q"
|
||||
@ -33,12 +33,9 @@ class VLANDriver < VNMMAD::VNMDriver
|
||||
# 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
|
||||
super(vm, XPATH_FILTER, deploy_id, hypervisor)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -47,33 +44,21 @@ class VLANDriver < VNMMAD::VNMDriver
|
||||
def activate
|
||||
lock
|
||||
|
||||
vm_id = @vm['ID']
|
||||
vm_id = @vm['ID']
|
||||
options = Hash.new
|
||||
|
||||
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
|
||||
options.clear
|
||||
|
||||
if !bridge_exists? bridge
|
||||
create_bridge bridge
|
||||
ifup bridge
|
||||
end
|
||||
options[:bridge] = nic[:bridge]
|
||||
options[:phydev] = nic[:phydev]
|
||||
options[:vlan_id] = nic[:vlan_id]
|
||||
options[:network_id] = nic[:network_id]
|
||||
|
||||
if !device_exists?(dev, vlan)
|
||||
create_dev_vlan(dev, vlan)
|
||||
ifup(dev, vlan)
|
||||
end
|
||||
return if options[:phydev].nil?
|
||||
|
||||
if !attached_bridge_dev?(bridge, dev, vlan)
|
||||
attach_brigde_dev(bridge, dev, vlan)
|
||||
end
|
||||
end
|
||||
set_up_vlan(options)
|
||||
end
|
||||
|
||||
unlock
|
||||
@ -82,49 +67,13 @@ class VLANDriver < VNMMAD::VNMDriver
|
||||
end
|
||||
|
||||
############################################################################
|
||||
# Private interface, methods to manage bridges and VLAN tags through the
|
||||
# brctl and ip commands
|
||||
# This function creates and activate a VLAN device
|
||||
############################################################################
|
||||
private
|
||||
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]}")
|
||||
|
||||
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")
|
||||
OpenNebula.exec_and_log("#{command(:ip)} link set #{options[:vlan_dev]} up")
|
||||
end
|
||||
end
|
@ -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
|
||||
|
110
src/vnm_mad/remotes/lib/vlan.rb
Normal file
110
src/vnm_mad/remotes/lib/vlan.rb
Normal file
@ -0,0 +1,110 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
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<String>] 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
|
@ -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<String>] 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
|
||||
|
@ -30,7 +30,7 @@ require 'security_groups_iptables'
|
||||
require 'vnm_driver'
|
||||
require 'fw_driver'
|
||||
require 'sg_driver'
|
||||
|
||||
require 'vlan'
|
||||
require 'scripts_common'
|
||||
|
||||
include OpenNebula
|
||||
|
1
src/vnm_mad/remotes/vxlan/clean
Symbolic link
1
src/vnm_mad/remotes/vxlan/clean
Symbolic link
@ -0,0 +1 @@
|
||||
../fw/clean
|
1
src/vnm_mad/remotes/vxlan/post
Symbolic link
1
src/vnm_mad/remotes/vxlan/post
Symbolic link
@ -0,0 +1 @@
|
||||
../fw/post
|
25
src/vnm_mad/remotes/vxlan/pre
Executable file
25
src/vnm_mad/remotes/vxlan/pre
Executable file
@ -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
|
81
src/vnm_mad/remotes/vxlan/vxlan_driver.rb
Normal file
81
src/vnm_mad/remotes/vxlan/vxlan_driver.rb
Normal file
@ -0,0 +1,81 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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
|
||||
|
||||
############################################################################
|
||||
# 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
|
||||
|
||||
############################################################################
|
||||
# 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
|
Loading…
x
Reference in New Issue
Block a user