Пример #1
0
 def run_lldptool(self, args):
     '''Function for invoking the lldptool utility'''
     full_args = ['lldptool'] + args
     try:
         utils.execute(full_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error(_LE("Unable to execute %(cmd)s. "
                   "Exception: %(exception)s"),
                   {'cmd': full_args, 'exception': e})
Пример #2
0
 def run_lldptool(self, args):
     '''Function for invoking the lldptool utility'''
     full_args = ['lldptool'] + args
     try:
         utils.execute(full_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error(_LE("Unable to execute %(cmd)s. "
                   "Exception: %(exception)s"),
                   {'cmd': full_args, 'exception': e})
Пример #3
0
    def update_ip_rule(self, ip, mac):
        """Update a rule associated with given ip and mac."""

        rule_no = self._find_rule_no(mac)
        chain = self._find_chain_name(mac)
        if not rule_no or not chain:
            LOG.error(_LE('Failed to update ip rule for %(ip)s %(mac)s'),
                      {'ip': ip, 'mac': mac})
            return

        update_cmd = ['iptables', '-R', '%s' % chain, '%s' % rule_no,
                      '-s', '%s/32' % ip, '-m', 'mac', '--mac-source',
                      '%s' % mac, '-j', 'RETURN']
        LOG.debug('Execute command: %s', update_cmd)
        dsl.execute(update_cmd, self._root_helper, log_output=False)
 def program_rtr(self, args, rout_id, namespace=None):
     """Execute the command against the namespace. """
     if namespace is None:
         namespace = self.find_rtr_namespace(rout_id)
     if namespace is None:
         LOG.error("Unable to find namespace for router %s", rout_id)
         return False
     final_args = ['ip', 'netns', 'exec', namespace] + args
     try:
         utils.execute(final_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error("Unable to execute %(cmd)s. "
                   "Exception: %(exception)s",
                   {'cmd': final_args, 'exception': e})
         return False
     return True
 def program_rtr(self, args, rout_id, namespace=None):
     """Execute the command against the namespace. """
     if namespace is None:
         namespace = self.find_rtr_namespace(rout_id)
     if namespace is None:
         LOG.error(_LE("Unable to find namespace for router %s"), rout_id)
         return False
     final_args = ['ip', 'netns', 'exec', namespace] + args
     try:
         utils.execute(final_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error(_LE("Unable to execute %(cmd)s. "
                   "Exception: %(exception)s"),
                   {'cmd': final_args, 'exception': e})
         return False
     return True
Пример #6
0
    def update_iptables(self):
        """Update iptables based on information in the rule_info."""

        # Read the iptables
        iptables_cmds = ['iptables-save', '-c']
        all_rules = dsl.execute(iptables_cmds,
                                root_helper=self._root_helper,
                                log_output=False)

        # For each rule in rule_info update the rule if necessary.
        new_rules = []
        is_modified = False
        for line in all_rules.split('\n'):
            new_line = line
            line_content = line.split()
            # The spoofing rule which includes mac and ip should have
            # -s cidr/32  option for ip address. Otherwise no rule
            # will be modified.
            if '-s' in line_content:
                tmp_rule_info = list(self.rule_info)
                for rule in tmp_rule_info:
                    if (rule.mac in line.lower()
                            and rule.chain.lower() in line.lower() and
                            not self._is_ip_in_rule(rule.ip, line_content)):
                        ip_loc = line_content.index('-s') + 1
                        line_content[ip_loc] = rule.ip + '/32'
                        new_line = ' '.join(line_content)
                        LOG.debug('Modified %(old_rule)s. '
                                  'New rule is %(new_rule)s.' %
                                  ({
                                      'old_rule': line,
                                      'new_rule': new_line
                                  }))
                        is_modified = True
            new_rules.append(new_line)

        if is_modified and new_rules:
            # Updated all the rules. Now commit the new rules.
            iptables_cmds = ['iptables-restore', '-c']
            dsl.execute(iptables_cmds,
                        process_input='\n'.join(new_rules),
                        root_helper=self._root_helper,
                        log_output=False)
Пример #7
0
 def run_vdptool(self, args, oui_args=None):
     '''Function that runs the vdptool utility'''
     if oui_args is None:
         oui_args = []
     full_args = ['vdptool'] + args + oui_args
     try:
         return utils.execute(full_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error(_LE("Unable to execute %(cmd)s. "
                       "Exception: %(exception)s"),
                   {'cmd': full_args, 'exception': e})
Пример #8
0
 def run_vdptool(self, args, oui_args=None):
     '''Function that runs the vdptool utility'''
     if oui_args is None:
         oui_args = []
     full_args = ['vdptool'] + args + oui_args
     try:
         return utils.execute(full_args, root_helper=self.root_helper)
     except Exception as e:
         LOG.error(_LE("Unable to execute %(cmd)s. "
                       "Exception: %(exception)s"),
                   {'cmd': full_args, 'exception': e})
Пример #9
0
 def run_lldptool(self, args):
     """Function for invoking the lldptool utility. """
     full_args = ['lldptool'] + args
     try:
         return utils.execute(full_args, root_helper=self.root_helper)
     except Exception as exc:
         LOG.error("Unable to execute %(cmd)s. "
                   "Exception: %(exception)s", {
                       'cmd': full_args,
                       'exception': str(exc)
                   })
Пример #10
0
    def _find_rule_no(self, mac):
        """Find rule number associated with a given mac."""

        ipt_cmd = ['iptables', '-L', '--line-numbers']
        cmdo = dsl.execute(ipt_cmd, self._root_helper, log_output=False)
        for o in cmdo.split('\n'):
            if mac in o.lower():
                rule_no = o.split()[0]
                LOG.info(_LI('Found rule %(rule)s for %(mac)s.'),
                         {'rule': rule_no, 'mac': mac})
                return rule_no
Пример #11
0
    def _find_chain_name(self, mac):
        """Find a rule associated with a given mac."""

        ipt_cmd = ['iptables', '-t', 'filter', '-S']
        cmdo = dsl.execute(ipt_cmd, root_helper=self._root_helper,
                           log_output=False)
        for o in cmdo.split('\n'):
            if mac in o.lower():
                chain = o.split()[1]
                LOG.info(_LI('Find %(chain)s for %(mac)s.'),
                         {'chain': chain, 'mac': mac})
                return chain
Пример #12
0
    def update_ip_rule(self, ip, mac):
        """Update a rule associated with given ip and mac."""

        rule_no = self._find_rule_no(mac)
        chain = self._find_chain_name(mac)
        if not rule_no or not chain:
            LOG.error(_LE('Failed to update ip rule for %(ip)s %(mac)s'), {
                'ip': ip,
                'mac': mac
            })
            return

        update_cmd = [
            'iptables', '-R',
            '%s' % chain,
            '%s' % rule_no, '-s',
            '%s/32' % ip, '-m', 'mac', '--mac-source',
            '%s' % mac, '-j', 'RETURN'
        ]
        LOG.debug('Execute command: %s', update_cmd)
        dsl.execute(update_cmd, self._root_helper, log_output=False)
Пример #13
0
    def _find_rule_no(self, mac):
        """Find rule number associated with a given mac."""

        ipt_cmd = ['iptables', '-L', '--line-numbers']
        cmdo = dsl.execute(ipt_cmd, self._root_helper, log_output=False)
        for o in cmdo.split('\n'):
            if mac in o.lower():
                rule_no = o.split()[0]
                LOG.info(_LI('Found rule %(rule)s for %(mac)s.'), {
                    'rule': rule_no,
                    'mac': mac
                })
                return rule_no
Пример #14
0
    def update_iptables(self):
        """Update iptables based on information in the rule_info."""

        # Read the iptables
        iptables_cmds = ['iptables-save', '-c']
        all_rules = dsl.execute(iptables_cmds, root_helper=self._root_helper,
                                log_output=False)

        # For each rule in rule_info update the rule if necessary.
        new_rules = []
        is_modified = False
        for line in all_rules.split('\n'):
            new_line = line
            line_content = line.split()
            # The spoofing rule which includes mac and ip should have
            # -s cidr/32  option for ip address. Otherwise no rule
            # will be modified.
            if '-s' in line_content:
                tmp_rule_info = list(self.rule_info)
                for rule in tmp_rule_info:
                    if (rule.mac in line.lower() and
                        rule.chain.lower() in line.lower() and
                            not self._is_ip_in_rule(rule.ip, line_content)):
                        ip_loc = line_content.index('-s') + 1
                        line_content[ip_loc] = rule.ip + '/32'
                        new_line = ' '.join(line_content)
                        LOG.debug('Modified %(old_rule)s. '
                                  'New rule is %(new_rule)s.' % (
                                      {'old_rule': line,
                                       'new_rule': new_line}))
                        is_modified = True
            new_rules.append(new_line)

        if is_modified and new_rules:
            # Updated all the rules. Now commit the new rules.
            iptables_cmds = ['iptables-restore', '-c']
            dsl.execute(iptables_cmds, process_input='\n'.join(new_rules),
                        root_helper=self._root_helper, log_output=False)
 def find_rtr_namespace(self, rout_id):
     """Find the namespace associated with the router. """
     if rout_id is None:
         return None
     args = ['ip', 'netns', 'list']
     try:
         ns_list = utils.execute(args, root_helper=self.root_helper)
     except Exception as exc:
         LOG.error(_LE("Unable to find the namespace list Exception %s"),
                   exc)
         return None
     for ns in ns_list.split():
         if 'router' in ns and rout_id in ns:
             return ns
 def find_rtr_namespace(self, rout_id):
     """Find the namespace associated with the router. """
     if rout_id is None:
         return None
     args = ['ip', 'netns', 'list']
     try:
         ns_list = utils.execute(args, root_helper=self.root_helper)
     except Exception as exc:
         LOG.error("Unable to find the namespace list Exception %s",
                   exc)
         return None
     for ns in ns_list.split():
         if 'router' in ns and rout_id in ns:
             return ns
Пример #17
0
    def _find_chain_name(self, mac):
        """Find a rule associated with a given mac."""

        ipt_cmd = ['iptables', '-t', 'filter', '-S']
        cmdo = dsl.execute(ipt_cmd,
                           root_helper=self._root_helper,
                           log_output=False)
        for o in cmdo.split('\n'):
            if mac in o.lower():
                chain = o.split()[1]
                LOG.info(_LI('Find %(chain)s for %(mac)s.'), {
                    'chain': chain,
                    'mac': mac
                })
                return chain
Пример #18
0
    def setup_lldpad_ports(self):
        """Setup the flows for passing LLDP/VDP frames in OVS."""
        # Creating the physical bridge and setting up patch ports is done by
        # Openstack
        ovs_bridges = ovs_lib.get_bridges(self.root_helper)
        if self.ext_br not in ovs_bridges or self.integ_br not in ovs_bridges:
            LOG.error(_LE("Integ or Physical Bridge not configured by" "Openstack"))
            raise dfae.DfaAgentFailed(reason="Bridge Unavailable")
        br = ovs_lib.OVSBridge(self.ext_br, root_helper=self.root_helper)
        self.ext_br_obj = br
        int_br = ovs_lib.OVSBridge(self.integ_br, root_helper=self.root_helper)
        self.integ_br_obj = int_br

        self.phy_peer_port, self.int_peer_port = self.find_interconnect_ports()
        if self.phy_peer_port is None or self.int_peer_port is None:
            LOG.error(_LE("Integ or Physical Patch/Veth Ports not " "configured by Openstack"))
            raise dfae.DfaAgentFailed(reason="Ports Unconfigured")

        lldp_ovs_veth_str = constants.LLDPAD_OVS_VETH_PORT + self.uplink
        if len(lldp_ovs_veth_str) > constants.MAX_VETH_NAME:
            lldp_ovs_veth_str = self.gen_veth_str(constants.LLDPAD_OVS_VETH_PORT, self.uplink)
        lldp_loc_veth_str = constants.LLDPAD_LOC_VETH_PORT + self.uplink
        if len(lldp_loc_veth_str) > constants.MAX_VETH_NAME:
            lldp_loc_veth_str = self.gen_veth_str(constants.LLDPAD_LOC_VETH_PORT, self.uplink)
        ip_wrapper = ip_lib.IPWrapper()
        self.delete_vdp_flows()
        br.delete_port(lldp_ovs_veth_str)
        if ip_lib.device_exists(lldp_ovs_veth_str):
            # What about OVS restart cases fixme(padkrish)

            # IMPORTANT.. The link delete should be done only for non-restart
            # cases. Otherwise, The MAC address of the veth interface changes
            # for every delete/create. So, if lldpad has the association sent
            # already, retriggering it will make the ASSOC appear as coming
            # from another station and more than one VSI instance will appear
            # at the Leaf. Deleting the assoc and creating the assoc for new
            # veth is not optimal. fixme(padkrish)
            # ip_lib.IPDevice(lldp_ovs_veth_str,self.root_helper).link.delete()
            ovs_lib.execute(["/sbin/udevadm", "settle", "--timeout=10"])
            lldp_loc_veth = ip_wrapper.device(lldp_loc_veth_str)
            lldp_ovs_veth = ip_wrapper.device(lldp_ovs_veth_str)
        else:
            # fixme(padkrish) Due to above reason, do the vethcreate below only
            # if it doesn't exist and not deleted.
            lldp_loc_veth, lldp_ovs_veth = ip_wrapper.add_veth(lldp_loc_veth_str, lldp_ovs_veth_str)
        if not br.port_exists(self.uplink):
            phy_port_num = br.add_port(self.uplink)
        else:
            phy_port_num = br.get_port_ofport(self.uplink)
        if phy_port_num == cconstants.INVALID_OFPORT:
            LOG.error(_LE("Uplink port not detected on external bridge"))
            return False
        if not br.port_exists(lldp_ovs_veth_str):
            lldp_ovs_portnum = br.add_port(lldp_ovs_veth)
        else:
            lldp_ovs_portnum = br.get_port_ofport(lldp_ovs_veth)
        if lldp_ovs_portnum == cconstants.INVALID_OFPORT:
            LOG.error(_LE("lldp veth port not detected on external bridge"))
            return False
        lldp_loc_veth.link.set_up()
        lldp_ovs_veth.link.set_up()
        # What about OVS restart cases fixme(padkrish)
        self.program_vdp_flows(lldp_ovs_portnum, phy_port_num)

        self.phy_peer_port_num = br.get_port_ofport(self.phy_peer_port)
        self.int_peer_port_num = int_br.get_port_ofport(self.int_peer_port)
        if self.phy_peer_port_num == cconstants.INVALID_OFPORT or self.int_peer_port_num == cconstants.INVALID_OFPORT:
            LOG.error(
                _LE("int or phy peer OF Port not detected on Int or" "Phy Bridge %(phy)s %(int)s"),
                {"phy": self.phy_peer_port_num, "int": self.int_peer_port_num},
            )
            return False
        self.lldpad_info = lldpad.LldpadDriver(lldp_loc_veth_str, self.uplink, self.root_helper)
        ret = self.lldpad_info.enable_evb()
        if not ret:
            LOG.error(_LE("Unable to cfg EVB"))
            return False
        self.lldp_veth_port = lldp_loc_veth_str
        LOG.info(_LI("Setting up lldpad ports complete"))
        return True
Пример #19
0
    def setup_lldpad_ports(self):
        '''Setup the flows for passing LLDP/VDP frames in OVS.'''
        # Creating the physical bridge and setting up patch ports is done by
        # Openstack
        ovs_bridges = ovs_lib.get_bridges(self.root_helper)
        if self.ext_br not in ovs_bridges or self.integ_br not in ovs_bridges:
            LOG.error(
                _LE("Integ or Physical Bridge not configured by"
                    "Openstack"))
            raise dfae.DfaAgentFailed(reason="Bridge Unavailable")
        br = ovs_lib.OVSBridge(self.ext_br, root_helper=self.root_helper)
        self.ext_br_obj = br
        int_br = ovs_lib.OVSBridge(self.integ_br, root_helper=self.root_helper)
        self.integ_br_obj = int_br

        self.phy_peer_port, self.int_peer_port = self.find_interconnect_ports()
        if self.phy_peer_port is None or self.int_peer_port is None:
            LOG.error(
                _LE("Integ or Physical Patch/Veth Ports not "
                    "configured by Openstack"))
            raise dfae.DfaAgentFailed(reason="Ports Unconfigured")

        lldp_ovs_veth_str = constants.LLDPAD_OVS_VETH_PORT + self.uplink
        if len(lldp_ovs_veth_str) > constants.MAX_VETH_NAME:
            lldp_ovs_veth_str = self.gen_veth_str(
                constants.LLDPAD_OVS_VETH_PORT, self.uplink)
        lldp_loc_veth_str = constants.LLDPAD_LOC_VETH_PORT + self.uplink
        if len(lldp_loc_veth_str) > constants.MAX_VETH_NAME:
            lldp_loc_veth_str = self.gen_veth_str(
                constants.LLDPAD_LOC_VETH_PORT, self.uplink)
        ip_wrapper = ip_lib.IPWrapper()
        self.delete_vdp_flows()
        br.delete_port(lldp_ovs_veth_str)
        if ip_lib.device_exists(lldp_ovs_veth_str):
            # What about OVS restart cases fixme(padkrish)

            # IMPORTANT.. The link delete should be done only for non-restart
            # cases. Otherwise, The MAC address of the veth interface changes
            # for every delete/create. So, if lldpad has the association sent
            # already, retriggering it will make the ASSOC appear as coming
            # from another station and more than one VSI instance will appear
            # at the Leaf. Deleting the assoc and creating the assoc for new
            # veth is not optimal. fixme(padkrish)
            # ip_lib.IPDevice(lldp_ovs_veth_str,self.root_helper).link.delete()
            ovs_lib.execute(['/sbin/udevadm', 'settle', '--timeout=10'])
            lldp_loc_veth = ip_wrapper.device(lldp_loc_veth_str)
            lldp_ovs_veth = ip_wrapper.device(lldp_ovs_veth_str)
        else:
            # fixme(padkrish) Due to above reason, do the vethcreate below only
            # if it doesn't exist and not deleted.
            lldp_loc_veth, lldp_ovs_veth = (ip_wrapper.add_veth(
                lldp_loc_veth_str, lldp_ovs_veth_str))
        if not br.port_exists(self.uplink):
            phy_port_num = br.add_port(self.uplink)
        else:
            phy_port_num = br.get_port_ofport(self.uplink)
        if phy_port_num == cconstants.INVALID_OFPORT:
            LOG.error(_LE("Uplink port not detected on external bridge"))
            return False
        if not br.port_exists(lldp_ovs_veth_str):
            lldp_ovs_portnum = br.add_port(lldp_ovs_veth)
        else:
            lldp_ovs_portnum = br.get_port_ofport(lldp_ovs_veth)
        if lldp_ovs_portnum == cconstants.INVALID_OFPORT:
            LOG.error(_LE("lldp veth port not detected on external bridge"))
            return False
        lldp_loc_veth.link.set_up()
        lldp_ovs_veth.link.set_up()
        # What about OVS restart cases fixme(padkrish)
        self.program_vdp_flows(lldp_ovs_portnum, phy_port_num)

        self.phy_peer_port_num = br.get_port_ofport(self.phy_peer_port)
        self.int_peer_port_num = int_br.get_port_ofport(self.int_peer_port)
        if (self.phy_peer_port_num == cconstants.INVALID_OFPORT
                or self.int_peer_port_num == cconstants.INVALID_OFPORT):
            LOG.error(
                _LE("int or phy peer OF Port not detected on Int or"
                    "Phy Bridge %(phy)s %(int)s"), {
                        'phy': self.phy_peer_port_num,
                        'int': self.int_peer_port_num
                    })
            return False
        self.lldpad_info = (lldpad.LldpadDriver(lldp_loc_veth_str, self.uplink,
                                                self.root_helper))
        ret = self.lldpad_info.enable_evb()
        if not ret:
            LOG.error(_LE("Unable to cfg EVB"))
            return False
        self.lldp_veth_port = lldp_loc_veth_str
        LOG.info(_LI("Setting up lldpad ports complete"))
        return True