mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
* refactor: remove trailing whitespace from Python files * Add the GitHub Super-Linter Add Python flake8 linting for W291 trailing whitespace * Add licenses
146 lines
5.8 KiB
Python
146 lines
5.8 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you 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.
|
|
|
|
# A simple script for enabling and disabling per-vif and tunnel interface rules for explicitly
|
|
# allowing broadcast/multicast traffic from the tunnel ports and on the port where the VIF is attached
|
|
|
|
import copy
|
|
import os
|
|
import sys
|
|
import logging
|
|
|
|
import cloudstack_pluginlib as pluginlib
|
|
|
|
pluginlib.setup_logging("/var/log/cloud/ovstunnel.log")
|
|
|
|
def clear_flows(bridge, this_vif_ofport, vif_ofports):
|
|
action = "".join("output:%s," %ofport
|
|
for ofport in vif_ofports)[:-1]
|
|
# Remove flow entries originating from given ofport
|
|
pluginlib.del_flows(bridge, in_port=this_vif_ofport)
|
|
# The following will remove the port being delete from actions
|
|
pluginlib.add_flow(bridge, priority=1100,
|
|
dl_dst='ff:ff:ff:ff:ff:ff', actions=action)
|
|
pluginlib.add_flow(bridge, priority=1100,
|
|
nw_dst='224.0.0.0/24', actions=action)
|
|
|
|
|
|
def apply_flows(bridge, this_vif_ofport, vif_ofports):
|
|
action = "".join("output:%s," %ofport
|
|
for ofport in vif_ofports)[:-1]
|
|
# Ensure {b|m}casts sent from VIF ports are always allowed
|
|
pluginlib.add_flow(bridge, priority=1200,
|
|
in_port=this_vif_ofport,
|
|
dl_dst='ff:ff:ff:ff:ff:ff',
|
|
actions='NORMAL')
|
|
pluginlib.add_flow(bridge, priority=1200,
|
|
in_port=this_vif_ofport,
|
|
nw_dst='224.0.0.0/24',
|
|
actions='NORMAL')
|
|
# Ensure {b|m}casts are always propagated to VIF ports
|
|
pluginlib.add_flow(bridge, priority=1100,
|
|
dl_dst='ff:ff:ff:ff:ff:ff', actions=action)
|
|
pluginlib.add_flow(bridge, priority=1100,
|
|
nw_dst='224.0.0.0/24', actions=action)
|
|
|
|
def clear_rules(vif):
|
|
try:
|
|
delcmd = "/sbin/ebtables -t nat -L PREROUTING | grep " + vif
|
|
delcmds = pluginlib.do_cmd(['/bin/bash', '-c', delcmd]).split('\n')
|
|
for cmd in delcmds:
|
|
try:
|
|
cmd = '/sbin/ebtables -t nat -D PREROUTING ' + cmd
|
|
pluginlib.do_cmd(['/bin/bash', '-c', cmd])
|
|
except:
|
|
pass
|
|
except:
|
|
pass
|
|
|
|
def main(command, vif_raw):
|
|
if command not in ('online', 'offline'):
|
|
return
|
|
|
|
vif_name, dom_id, vif_index = vif_raw.split('-')
|
|
# validate vif and dom-id
|
|
this_vif = "%s%s.%s" % (vif_name, dom_id, vif_index)
|
|
# Make sure the networking stack is not linux bridge!
|
|
net_stack = pluginlib.do_cmd(['cat', '/etc/xensource/network.conf'])
|
|
if net_stack.lower() == "bridge":
|
|
if command == 'offline':
|
|
clear_rules(this_vif)
|
|
# Nothing to do here!
|
|
return
|
|
|
|
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif])
|
|
|
|
# find xs network for this bridge, verify is used for ovs tunnel network
|
|
xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
|
|
"bridge=%s" % bridge, "--minimal"])
|
|
|
|
ovs_tunnel_network = pluginlib.is_regular_tunnel_network(xs_nw_uuid)
|
|
|
|
# handle case where network is reguar tunnel network
|
|
if ovs_tunnel_network == 'True':
|
|
vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
|
|
if vlan != '0':
|
|
# We need the REAL bridge name
|
|
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
|
|
'br-to-parent', bridge])
|
|
vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
|
|
'list-ports', bridge])
|
|
vifs = vsctl_output.split('\n')
|
|
vif_ofports = []
|
|
vif_other_ofports = []
|
|
for vif in vifs:
|
|
vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
|
|
'Interface', vif, 'ofport'])
|
|
if this_vif == vif:
|
|
this_vif_ofport = vif_ofport
|
|
if vif.startswith('vif'):
|
|
vif_ofports.append(vif_ofport)
|
|
|
|
if command == 'offline':
|
|
vif_other_ofports = copy.copy(vif_ofports)
|
|
vif_other_ofports.remove(this_vif_ofport)
|
|
clear_flows(bridge, this_vif_ofport, vif_other_ofports)
|
|
|
|
if command == 'online':
|
|
apply_flows(bridge, this_vif_ofport, vif_ofports)
|
|
|
|
|
|
# handle case where bridge is setup for VPC which is enabled for distributed routing
|
|
ovs_vpc_distributed_vr_network = pluginlib.is_vpc_network_with_distributed_routing(xs_nw_uuid)
|
|
if ovs_vpc_distributed_vr_network == 'True':
|
|
vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
|
|
if vlan != '0':
|
|
# We need the REAL bridge name
|
|
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
|
|
'br-to-parent', bridge])
|
|
vif_network_id = pluginlib.get_network_id_for_vif(this_vif)
|
|
pluginlib.update_flooding_rules_on_port_plug_unplug(bridge, this_vif, command, vif_network_id)
|
|
|
|
return
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 3:
|
|
print "usage: %s [online|offline] vif-domid-idx" % \
|
|
os.path.basename(sys.argv[0])
|
|
sys.exit(1)
|
|
else:
|
|
command, vif_raw = sys.argv[1:3]
|
|
main(command, vif_raw)
|