# Path: networking_sfc/services/sfc/agent/extensions/sfc.py
# LOG = logging.getLogger(__name__)
# class SfcPluginApi():
# class SfcAgentDriver(metaclass=abc.ABCMeta):
# class SfcAgentExtension(l2_extension.L2AgentExtension):
#     def __init__(self, topic, host):
#     def update_flowrules_status(self, context, flowrules_status):
#     def get_flowrules_by_host_portid(self, context, port_id):
#     def initialize(self):
#     def consume_api(self, agent_api):
#     def update_flow_rules(self, flowrule, flowrule_status):
#     def delete_flow_rule(self, flowrule, flowrule_status):
#     def initialize(self, connection, driver_type):
#     def consume_api(self, agent_api):
#     def handle_port(self, context, port):
#     def delete_port(self, context, port):
#     def update_flow_rules(self, context, **kwargs):
#     def delete_flow_rules(self, context, **kwargs):
#     def _sfc_setup_rpc(self):
#     def _delete_ports_flowrules_by_id(self, context, ports_id):
# 
# Path: networking_sfc/services/sfc/common/ovs_ext_lib.py
# LOG = logging.getLogger(__name__)
# def get_port_mask(min_port, max_port):
#     def __init__(self, ovs_bridge):
#     def __getattr__(self, name):
#     def do_action_groups(self, action, kwargs_list):
#     def add_group(self, **kwargs):
#     def mod_group(self, **kwargs):
#     def delete_group(self, **kwargs):
#     def dump_group_for_id(self, group_id):
#     def get_bridge_ports(self):
# def _build_group_expr_str(group_dict, cmd):
# class SfcOVSBridgeExt():
# 
# Path: networking_sfc/services/sfc/drivers/ovs/constants.py
# STATUS_BUILDING = 'building'
# STATUS_ACTIVE = 'active'
# STATUS_ERROR = 'error'
# SRC_NODE = 'src_node'
# DST_NODE = 'dst_node'
# SF_NODE = 'sf_node'
# INSERTION_TYPE_L2 = 'l2'
# INSERTION_TYPE_L3 = 'l3'
# INSERTION_TYPE_BITW = 'bitw'
# INSERTION_TYPE_TAP = 'tap'
# MAX_HASH = 16
# INSERTION_TYPE_DICT = {
#     n_const.DEVICE_OWNER_ROUTER_HA_INTF: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_INTF: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_GW: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_FLOATINGIP: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_DHCP: INSERTION_TYPE_TAP,
#     n_const.DEVICE_OWNER_DVR_INTERFACE: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_AGENT_GW: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_SNAT: INSERTION_TYPE_TAP,
#     n_const.DEVICE_OWNER_LOADBALANCER: INSERTION_TYPE_TAP,
#     'compute': INSERTION_TYPE_L2
# }
# ETH_TYPE_IP = 0x0800
# ETH_TYPE_MPLS = 0x8847
# ETH_TYPE_NSH = 0x894f


from neutron.plugins.ml2.drivers.openvswitch.agent import vlanmanager
from neutron_lib import constants as n_consts
from neutron_lib.plugins.ml2 import ovs_constants as ovs_consts
from oslo_config import cfg
from oslo_log import log as logging
from networking_sfc.services.sfc.agent.extensions import sfc
from networking_sfc.services.sfc.common import ovs_ext_lib
from networking_sfc.services.sfc.drivers.ovs import constants

# actions
RESUBMIT_TAP_TABLE = ',resubmit(,%s)' % TAP_CLASSIFIER_TABLE
NORMAL_ACTION = ",NORMAL"


class SfcOVSAgentDriver(sfc.SfcAgentDriver):
    """This class will support MPLS frame

    Ethernet + MPLS
    IPv4 Packet:
    +-------------------------------+---------------+--------------------+
    |Outer Ethernet, ET=0x8847      | MPLS head,    | original IP Packet |
    +-------------------------------+---------------+--------------------+
    """

    def __init__(self):
        super(SfcOVSAgentDriver, self).__init__()
        self.agent_api = None
        self.br_int = None
        self.br_tun = None

        self.local_ip = None
        self.patch_tun_ofport = None
        self.vlan_manager = None

    def consume_api(self, agent_api):
        self.agent_api = agent_api

    def initialize(self):

# Path: networking_sfc/services/sfc/agent/extensions/sfc.py
# LOG = logging.getLogger(__name__)
# class SfcPluginApi():
# class SfcAgentDriver(metaclass=abc.ABCMeta):
# class SfcAgentExtension(l2_extension.L2AgentExtension):
#     def __init__(self, topic, host):
#     def update_flowrules_status(self, context, flowrules_status):
#     def get_flowrules_by_host_portid(self, context, port_id):
#     def initialize(self):
#     def consume_api(self, agent_api):
#     def update_flow_rules(self, flowrule, flowrule_status):
#     def delete_flow_rule(self, flowrule, flowrule_status):
#     def initialize(self, connection, driver_type):
#     def consume_api(self, agent_api):
#     def handle_port(self, context, port):
#     def delete_port(self, context, port):
#     def update_flow_rules(self, context, **kwargs):
#     def delete_flow_rules(self, context, **kwargs):
#     def _sfc_setup_rpc(self):
#     def _delete_ports_flowrules_by_id(self, context, ports_id):
# 
# Path: networking_sfc/services/sfc/common/ovs_ext_lib.py
# LOG = logging.getLogger(__name__)
# def get_port_mask(min_port, max_port):
#     def __init__(self, ovs_bridge):
#     def __getattr__(self, name):
#     def do_action_groups(self, action, kwargs_list):
#     def add_group(self, **kwargs):
#     def mod_group(self, **kwargs):
#     def delete_group(self, **kwargs):
#     def dump_group_for_id(self, group_id):
#     def get_bridge_ports(self):
# def _build_group_expr_str(group_dict, cmd):
# class SfcOVSBridgeExt():
# 
# Path: networking_sfc/services/sfc/drivers/ovs/constants.py
# STATUS_BUILDING = 'building'
# STATUS_ACTIVE = 'active'
# STATUS_ERROR = 'error'
# SRC_NODE = 'src_node'
# DST_NODE = 'dst_node'
# SF_NODE = 'sf_node'
# INSERTION_TYPE_L2 = 'l2'
# INSERTION_TYPE_L3 = 'l3'
# INSERTION_TYPE_BITW = 'bitw'
# INSERTION_TYPE_TAP = 'tap'
# MAX_HASH = 16
# INSERTION_TYPE_DICT = {
#     n_const.DEVICE_OWNER_ROUTER_HA_INTF: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_INTF: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_GW: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_FLOATINGIP: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_DHCP: INSERTION_TYPE_TAP,
#     n_const.DEVICE_OWNER_DVR_INTERFACE: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_AGENT_GW: INSERTION_TYPE_L3,
#     n_const.DEVICE_OWNER_ROUTER_SNAT: INSERTION_TYPE_TAP,
#     n_const.DEVICE_OWNER_LOADBALANCER: INSERTION_TYPE_TAP,
#     'compute': INSERTION_TYPE_L2
# }
# ETH_TYPE_IP = 0x0800
# ETH_TYPE_MPLS = 0x8847
# ETH_TYPE_NSH = 0x894f


# Path: networking_sfc/services/sfc/agent/extensions/openvswitch/sfc_driver.py
from neutron.plugins.ml2.drivers.openvswitch.agent import vlanmanager
from neutron_lib import constants as n_consts
from neutron_lib.plugins.ml2 import ovs_constants as ovs_consts
from oslo_config import cfg
from oslo_log import log as logging
from networking_sfc.services.sfc.agent.extensions import sfc
from networking_sfc.services.sfc.common import ovs_ext_lib
from networking_sfc.services.sfc.drivers.ovs import constants


# actions
RESUBMIT_TAP_TABLE = ',resubmit(,%s)' % TAP_CLASSIFIER_TABLE
NORMAL_ACTION = ",NORMAL"


class SfcOVSAgentDriver(sfc.SfcAgentDriver):
    """This class will support MPLS frame

    Ethernet + MPLS
    IPv4 Packet:
    +-------------------------------+---------------+--------------------+
    |Outer Ethernet, ET=0x8847      | MPLS head,    | original IP Packet |
    +-------------------------------+---------------+--------------------+
    """

    def __init__(self):
        super(SfcOVSAgentDriver, self).__init__()
        self.agent_api = None
        self.br_int = None
        self.br_tun = None

        self.local_ip = None
        self.patch_tun_ofport = None
        self.vlan_manager = None

    def consume_api(self, agent_api):
        self.agent_api = agent_api

    def initialize(self):

        self.br_int = ovs_ext_lib.SfcOVSBridgeExt(