From fd03fafb8f7ddf4da29f8d4ff38cc4ae8819003e Mon Sep 17 00:00:00 2001 From: Daniel Clavijo Coca Date: Mon, 16 Nov 2020 10:37:56 -0600 Subject: [PATCH] B #4903: Fix rogue vlans on vnet pre (#427) Co-authored-by: Daniel Clavijo Coca --- src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb | 30 ++++++++++------ src/vnm_mad/remotes/lib/vnm_driver.rb | 35 ++++++++++++------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb index dede4ae886..99183e23ca 100644 --- a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb +++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb @@ -26,7 +26,7 @@ require 'vnmmad' class VLANTagDriver < VNMMAD::VLANDriver # DRIVER name and XPATH for relevant NICs - DRIVER = "802.1Q" + DRIVER = '802.1Q' XPATH_FILTER = "TEMPLATE/NIC[VN_MAD='802.1Q']" ############################################################################ @@ -43,21 +43,27 @@ class VLANTagDriver < VNMMAD::VLANDriver # This function creates and activate a VLAN device ############################################################################ def create_vlan_dev - mtu = @nic[:mtu] ? "mtu #{@nic[:mtu]}" : "mtu #{CONF[:vlan_mtu]}" + @nic[:mtu] ? mtu = "mtu #{@nic[:mtu]}" : mtu = "mtu #{CONF[:vlan_mtu]}" - ip_link_conf = "" + ip_link_conf = '' @nic[:ip_link_conf].each do |option, value| case value when true - value = "on" + value = 'on' when false - value = "off" + value = 'off' end ip_link_conf << "#{option} #{value} " end + # Delete vlan if it stuck in another bridge. + if nic_exist?(@nic[:vlan_dev])[0] + cmd = "#{command(:ip)} link delete #{@nic[:vlan_dev]}" + OpenNebula.exec_and_log(cmd) + end + OpenNebula.exec_and_log("#{command(:ip)} link add link"\ " #{@nic[:phydev]} name #{@nic[:vlan_dev]} #{mtu} type vlan id"\ " #{@nic[:vlan_id]} #{ip_link_conf}") @@ -66,13 +72,16 @@ class VLANTagDriver < VNMMAD::VLANDriver end def delete_vlan_dev - OpenNebula.exec_and_log("#{command(:ip)} link delete"\ - " #{@nic[:vlan_dev]}") if @nic[:vlan_dev] != @nic[:phydev] - end + return unless @nic[:vlan_dev] != @nic[:phydev] + + OpenNebula.exec_and_log("\ + #{command(:ip)} link delete #{@nic[:vlan_dev]}") + end def list_interface_vlan(name) - text = %x(#{command(:ip_unpriv)} -d link show #{name}) - return nil if $?.exitstatus != 0 + text, status = nic_exist?(name) + + return if status == false text.each_line do |line| m = line.match(/vlan protocol 802.1Q id (\d+)/) @@ -82,4 +91,5 @@ class VLANTagDriver < VNMMAD::VLANDriver nil end + end diff --git a/src/vnm_mad/remotes/lib/vnm_driver.rb b/src/vnm_mad/remotes/lib/vnm_driver.rb index ffbe5bb590..654c59badb 100644 --- a/src/vnm_mad/remotes/lib/vnm_driver.rb +++ b/src/vnm_mad/remotes/lib/vnm_driver.rb @@ -16,6 +16,7 @@ require 'shellwords' require 'open3' +require 'English' ################################################################################ # The VNMMAD module provides the basic abstraction to implement custom @@ -38,7 +39,7 @@ module VNMMAD # @param xpath_filter [String] to get relevant NICs for the driver # @param deploy_id [String] def initialize(vm_tpl, xpath_filter, deploy_id = nil) - @locking ||= false + @locking = false @vm = VNMNetwork::VM.new(REXML::Document.new(vm_tpl).root, xpath_filter, deploy_id) @@ -47,8 +48,8 @@ module VNMMAD # Creates a new VNMDriver using: # @param vm_64 [String] Base64 encoded XML String from oned # @param deploy_id [String] - def self.from_base64(vm_64, xpath_filter = nil, deploy_id = nil) - vm_xml = Base64.decode64(vm_64) + def self.from_base64(vm64, xpath_filter = nil, deploy_id = nil) + vm_xml = Base64.decode64(vm64) new(vm_xml, xpath_filter, deploy_id) end @@ -56,18 +57,16 @@ module VNMMAD # Locking function to serialized driver operations if needed. Similar # to flock. File is created as /tmp/onevnm--lock def lock - if @locking - driver_name = self.class.name.downcase - @locking_file = File.open("/tmp/onevnm-#{driver_name}-lock", 'w') - @locking_file.flock(File::LOCK_EX) - end + return unless @locking + + driver_name = self.class.name.downcase + @locking_file = File.open("/tmp/onevnm-#{driver_name}-lock", 'w') + @locking_file.flock(File::LOCK_EX) end # Unlock driver execution mutex def unlock - if @locking - @locking_file.close - end + @locking_file.close if @locking end # Executes the given block on each NIC @@ -158,8 +157,8 @@ module VNMMAD # Returns a filter object based on the contents of the template # # @return SGDriver object - def self.filter_driver(vm_64, xpath_filter, deploy_id) - SGDriver.new(vm_64, xpath_filter, deploy_id) + def self.filter_driver(vm64, xpath_filter, deploy_id) + SGDriver.new(vm64, xpath_filter, deploy_id) end # Returns the associated command including sudo and other configuration @@ -216,6 +215,16 @@ module VNMMAD 0 end + # Checks wether a NIC exist or not. Returns true/false and the NIC info + def nic_exist?(name) + text = `#{command(:ip)} link show #{name}` + status = $CHILD_STATUS.exitstatus + + return true, text if status == 0 + + [false, text] + end + private # returns files sorted alphabetically