""" 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"])