233 lines
6.5 KiB
Python
233 lines
6.5 KiB
Python
"""
|
|
Clients for dealing with bridge/interface commands.
|
|
"""
|
|
|
|
import abc
|
|
import os
|
|
|
|
from future.utils import with_metaclass
|
|
|
|
from core.constants import BRCTL_BIN, IP_BIN, OVS_BIN
|
|
from core.utils import check_cmd
|
|
|
|
|
|
class NetClientBase(with_metaclass(abc.ABCMeta)):
|
|
"""
|
|
Base client for running command line bridge/interface commands.
|
|
"""
|
|
|
|
@abc.abstractmethod
|
|
def create_bridge(self, name):
|
|
"""
|
|
Create a network bridge to connect interfaces to.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_bridge(self, name):
|
|
"""
|
|
Delete a network bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Create an interface associated with a network bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Delete an interface associated with a network bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def existing_bridges(self, _id):
|
|
"""
|
|
Checks if there are any existing bridges for a node.
|
|
|
|
:param _id: node id to check bridges for
|
|
"""
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def disable_mac_learning(self, name):
|
|
"""
|
|
Disable mac learning for a bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
pass
|
|
|
|
|
|
class LinuxNetClient(NetClientBase):
|
|
"""
|
|
Client for creating Linux bridges and ip interfaces for nodes.
|
|
"""
|
|
|
|
def create_bridge(self, name):
|
|
"""
|
|
Create a Linux bridge and bring it up.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([BRCTL_BIN, "addbr", name])
|
|
check_cmd([BRCTL_BIN, "stp", name, "off"])
|
|
check_cmd([BRCTL_BIN, "setfd", name, "0"])
|
|
check_cmd([IP_BIN, "link", "set", name, "up"])
|
|
|
|
# turn off multicast snooping so forwarding occurs w/o IGMP joins
|
|
snoop = "/sys/devices/virtual/net/%s/bridge/multicast_snooping" % name
|
|
if os.path.exists(snoop):
|
|
with open(snoop, "w") as f:
|
|
f.write("0")
|
|
|
|
def delete_bridge(self, name):
|
|
"""
|
|
Bring down and delete a Linux bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([IP_BIN, "link", "set", name, "down"])
|
|
check_cmd([BRCTL_BIN, "delbr", name])
|
|
|
|
def create_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Create an interface associated with a Linux bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([BRCTL_BIN, "addif", bridge_name, interface_name])
|
|
check_cmd([IP_BIN, "link", "set", interface_name, "up"])
|
|
|
|
def delete_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Delete an interface associated with a Linux bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([BRCTL_BIN, "delif", bridge_name, interface_name])
|
|
|
|
def existing_bridges(self, _id):
|
|
"""
|
|
Checks if there are any existing Linux bridges for a node.
|
|
|
|
:param _id: node id to check bridges for
|
|
"""
|
|
output = check_cmd([BRCTL_BIN, "show"])
|
|
lines = output.split("\n")
|
|
for line in lines[1:]:
|
|
columns = line.split()
|
|
name = columns[0]
|
|
fields = name.split(".")
|
|
if len(fields) != 3:
|
|
continue
|
|
if fields[0] == "b" and fields[1] == _id:
|
|
return True
|
|
return False
|
|
|
|
def disable_mac_learning(self, name):
|
|
"""
|
|
Disable mac learning for a Linux bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([BRCTL_BIN, "setageing", name, "0"])
|
|
|
|
|
|
class OvsNetClient(NetClientBase):
|
|
"""
|
|
Client for creating OVS bridges and ip interfaces for nodes.
|
|
"""
|
|
|
|
def create_bridge(self, name):
|
|
"""
|
|
Create a OVS bridge and bring it up.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([OVS_BIN, "add-br", name])
|
|
check_cmd([OVS_BIN, "set", "bridge", name, "stp_enable=false"])
|
|
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:stp-max-age=6"])
|
|
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:stp-forward-delay=4"])
|
|
check_cmd([IP_BIN, "link", "set", name, "up"])
|
|
|
|
def delete_bridge(self, name):
|
|
"""
|
|
Bring down and delete a OVS bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([IP_BIN, "link", "set", name, "down"])
|
|
check_cmd([OVS_BIN, "del-br", name])
|
|
|
|
def create_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Create an interface associated with a network bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([OVS_BIN, "add-port", bridge_name, interface_name])
|
|
check_cmd([IP_BIN, "link", "set", interface_name, "up"])
|
|
|
|
def delete_interface(self, bridge_name, interface_name):
|
|
"""
|
|
Delete an interface associated with a OVS bridge.
|
|
|
|
:param str bridge_name: bridge name
|
|
:param str interface_name: interface name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([OVS_BIN, "del-port", bridge_name, interface_name])
|
|
|
|
def existing_bridges(self, _id):
|
|
"""
|
|
Checks if there are any existing OVS bridges for a node.
|
|
|
|
:param _id: node id to check bridges for
|
|
"""
|
|
output = check_cmd([OVS_BIN, "list-br"])
|
|
if output:
|
|
for line in output.split("\n"):
|
|
fields = line.split(".")
|
|
if fields[0] == "b" and fields[1] == _id:
|
|
return True
|
|
return False
|
|
|
|
def disable_mac_learning(self, name):
|
|
"""
|
|
Disable mac learning for a OVS bridge.
|
|
|
|
:param str name: bridge name
|
|
:return: nothing
|
|
"""
|
|
check_cmd([OVS_BIN, "set", "bridge", name, "other_config:mac-aging-time=0"])
|