Exemplo n.º 1
0
    def vdp_vlan_change_internal(self, vsw_cb_data, vdp_vlan, fail_reason):
        """Callback Function from VDP when provider VLAN changes.

        This will be called only during error cases when switch
        reloads or when compute reloads.
        """
        LOG.debug("In VDP VLAN change VLAN %s", vdp_vlan)
        if not vsw_cb_data:
            LOG.error("NULL vsw_cb_data Info received")
            return
        net_uuid = vsw_cb_data.get('net_uuid')
        port_uuid = vsw_cb_data.get('port_uuid')
        lvm = self.local_vlan_map.get(net_uuid)
        if not lvm:
            LOG.error("Network %s is not in the local vlan map", net_uuid)
            return
        lldpad_port = self.lldpad_info
        if not lldpad_port:
            LOG.error("There is no LLDPad port available.")
            return
        exist_vdp_vlan = lvm.late_binding_vlan
        lvid = lvm.vlan
        LOG.debug("lvid %(lvid)s exist %(vlan)s",
                  {'lvid': lvid, 'vlan': exist_vdp_vlan})
        lvm.decr_reset_vlan(port_uuid, vdp_vlan)
        lvm.set_fail_reason(port_uuid, fail_reason)
        self.vdp_vlan_cb(port_uuid, lvid, vdp_vlan, fail_reason)
        if vdp_vlan == exist_vdp_vlan:
            LOG.debug("No change in provider VLAN %s", vdp_vlan)
            return
        # Logic is if the VLAN changed to 0, clear the flows only if none of
        # the VM's in the network has a valid VLAN.
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            if ovs_lib.is_valid_vlan_tag(exist_vdp_vlan) and not (
               lvm.any_valid_vlan()):
                # Clear the old flows
                LOG.debug("Clearing flows, no valid vlans")
                self.program_vm_ovs_flows(lvid, exist_vdp_vlan, 0)
                lvm.late_binding_vlan = 0
            lvm.vdp_nego_req = False
        else:
            # If any VM gets a VLAN change, we immediately modify the flow.
            # This is done to not wait for all VM's VLAN getting updated from
            # switch. Logic is if any VM gts a new VLAN, the other VM's of the
            # same network will be updated eventually.
            if vdp_vlan != exist_vdp_vlan and (
               ovs_lib.is_valid_vlan_tag(vdp_vlan)):
                # Add the new flows and remove the old flows
                LOG.warning("Non Zero VDP Vlan change %s %s" %
                            (vdp_vlan, exist_vdp_vlan))
                self.program_vm_ovs_flows(lvid, exist_vdp_vlan, vdp_vlan)
                lvm.late_binding_vlan = vdp_vlan
                lvm.vdp_nego_req = False
            else:
                LOG.error("Invalid or same VLAN Exist %(exist)s "
                          "New %(new)s VLANs",
                          {'exist': exist_vdp_vlan, 'new': vdp_vlan})
Exemplo n.º 2
0
    def vdp_vlan_change(self, vsw_cb_data, vdp_vlan):
        '''Callback Function from VDP when provider VLAN changes

        This will be called only during error cases when switch
        reloads or when compute reloads
        '''
        LOG.debug("In VDP VLAN change VLAN %s", vdp_vlan)
        if not vsw_cb_data:
            LOG.error(_LE("NULL vsw_cb_data Info received"))
            return
        net_uuid = vsw_cb_data.get('net_uuid')
        lvm = self.local_vlan_map.get(net_uuid)
        if not lvm:
            LOG.error(_LE("Network %s is not in the local vlan map"), net_uuid)
            return
        lldpad_port = self.lldpad_info
        if not lldpad_port:
            LOG.error(_LE("There is no LLDPad port available."))
            return
        exist_vdp_vlan = lvm.late_binding_vlan
        lvid = lvm.vlan
        br = self.ext_br_obj
        LOG.debug("lvid %(lvid)s exist %(vlan)s", {
            'lvid': lvid,
            'vlan': exist_vdp_vlan
        })
        if vdp_vlan == exist_vdp_vlan:
            LOG.debug("No change in provider VLAN %s", vdp_vlan)
            return
        if ovs_lib.is_valid_vlan_tag(exist_vdp_vlan):
            # Clear the old flows
            # outbound
            br.delete_flows(in_port=self.phy_peer_port_num, dl_vlan=lvid)
            # inbound
            self.integ_br_obj.delete_flows(in_port=self.int_peer_port_num,
                                           dl_vlan=exist_vdp_vlan)
        if ovs_lib.is_valid_vlan_tag(vdp_vlan):
            # Add the new flows
            # outbound
            br.add_flow(priority=4,
                        in_port=self.phy_peer_port_num,
                        dl_vlan=lvid,
                        actions="mod_vlan_vid:%s,normal" % vdp_vlan)
            # inbound
            self.integ_br_obj.add_flow(priority=3,
                                       in_port=self.int_peer_port_num,
                                       dl_vlan=vdp_vlan,
                                       actions="mod_vlan_vid:%s,normal" % lvid)
        else:
            LOG.error(_LE("Returned vlan %s is invalid"), vdp_vlan)

        # Even if it's 0, it's still stored to reflect provider
        # hasn't allocated a VLAN from VDP, happens during error case.
        lvm.late_binding_vlan = vdp_vlan
Exemplo n.º 3
0
    def vdp_vlan_change(self, vsw_cb_data, vdp_vlan):
        '''Callback Function from VDP when provider VLAN changes

        This will be called only during error cases when switch
        reloads or when compute reloads
        '''
        LOG.debug("In VDP VLAN change VLAN %s", vdp_vlan)
        if not vsw_cb_data:
            LOG.error(_LE("NULL vsw_cb_data Info received"))
            return
        net_uuid = vsw_cb_data.get('net_uuid')
        lvm = self.local_vlan_map.get(net_uuid)
        if not lvm:
            LOG.error(_LE("Network %s is not in the local vlan map"), net_uuid)
            return
        lldpad_port = self.lldpad_info
        if not lldpad_port:
            LOG.error(_LE("There is no LLDPad port available."))
            return
        exist_vdp_vlan = lvm.late_binding_vlan
        lvid = lvm.vlan
        br = self.ext_br_obj
        LOG.debug("lvid %(lvid)s exist %(vlan)s",
                  {'lvid': lvid, 'vlan': exist_vdp_vlan})
        if vdp_vlan == exist_vdp_vlan:
            LOG.debug("No change in provider VLAN %s", vdp_vlan)
            return
        if ovs_lib.is_valid_vlan_tag(exist_vdp_vlan):
            # Clear the old flows
            # outbound
            br.delete_flows(in_port=self.phy_peer_port_num,
                            dl_vlan=lvid)
            # inbound
            self.integ_br_obj.delete_flows(in_port=self.int_peer_port_num,
                                           dl_vlan=exist_vdp_vlan)
        if ovs_lib.is_valid_vlan_tag(vdp_vlan):
            # Add the new flows
            # outbound
            br.add_flow(priority=4,
                        in_port=self.phy_peer_port_num, dl_vlan=lvid,
                        actions="mod_vlan_vid:%s,normal" % vdp_vlan)
            # inbound
            self.integ_br_obj.add_flow(priority=3,
                                       in_port=self.int_peer_port_num,
                                       dl_vlan=vdp_vlan,
                                       actions="mod_vlan_vid:%s,normal" % lvid)
        else:
            LOG.error(_LE("Returned vlan %s is invalid"), vdp_vlan)

        # Even if it's 0, it's still stored to reflect provider
        # hasn't allocated a VLAN from VDP, happens during error case.
        lvm.late_binding_vlan = vdp_vlan
Exemplo n.º 4
0
    def _flow_check_handler_internal(self):
        """Periodic handler to check if installed flows are present.

        This handler runs periodically to check if installed flows are present.
        This function cannot detect and delete the stale flows, if present.
        It requires more complexity to delete stale flows. Generally, stale
        flows are not present. So, that logic is not put here.
        """
        integ_flow = self.integ_br_obj.dump_flows_for(
            in_port=self.int_peer_port_num)
        ext_flow = self.ext_br_obj.dump_flows_for(
            in_port=self.phy_peer_port_num)
        for net_uuid, lvm in six.iteritems(self.local_vlan_map):
            vdp_vlan = lvm.any_consistent_vlan()
            flow_required = False
            if not (vdp_vlan and ovs_lib.is_valid_vlan_tag(vdp_vlan)):
                return
            if not self._check_bridge_flow(integ_flow, vdp_vlan, lvm.lvid):
                LOG.error("Flow for VDP Vlan %(vdp_vlan)s, Local vlan "
                          "%(lvid)s not present on Integ bridge",
                          {'vdp_vlan': vdp_vlan, 'lvid': lvm.lvid})
                flow_required = True
            if not self._check_bridge_flow(ext_flow, lvm.lvid, vdp_vlan):
                LOG.error("Flow for VDP Vlan %(vdp_vlan)s, Local vlan "
                          "%(lvid)s not present on External bridge",
                          {'vdp_vlan': vdp_vlan, 'lvid': lvm.lvid})
                flow_required = True
            if flow_required:
                LOG.info("Programming flows for lvid %(lvid)s vdp vlan"
                         " %(vdp)s",
                         {'lvid': lvm.lvid, 'vdp': vdp_vlan})
                self.program_vm_ovs_flows(lvm.lvid, 0, vdp_vlan)
Exemplo n.º 5
0
 def set_port_vlan(self, vdp_vlan):
     if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
         LOG.info("Passed Invalid vlan in set_port_vlan")
         return
     if vdp_vlan not in self.port_vdp_vlan_dict:
         self.port_vdp_vlan_dict[vdp_vlan] = 0
     self.port_vdp_vlan_dict[vdp_vlan] += 1
Exemplo n.º 6
0
    def unprovision_vdp_overlay_networks(self, net_uuid, lvid, vdp_vlan, oui):
        '''Provisions a overlay type network configured using VDP.

        :param net_uuid: the uuid of the network associated with this vlan.
        :lvid: Local VLAN ID
        :vdp_vlan: VDP VLAN ID
        :oui: OUI Parameters
        '''
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error(
                _LE("Cannot unprovision VDP Overlay network for"
                    " net-id=%(net_uuid)s - Invalid "), {'net_uuid': net_uuid})
            return

        LOG.info(
            _LI('unprovision_vdp_overlay_networks: add_flow for '
                'Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s'), {
                    'local_vlan': lvid,
                    'vdp_vlan': vdp_vlan
                })
        # outbound
        self.ext_br_obj.delete_flows(in_port=self.phy_peer_port_num,
                                     dl_vlan=lvid)
        # inbound
        self.integ_br_obj.delete_flows(in_port=self.int_peer_port_num,
                                       dl_vlan=vdp_vlan)
Exemplo n.º 7
0
    def _vdp_refrsh_hndlr(self):
        '''Periodic refresh of vNIC events to VDP

        VDP daemon itself has keepalives. This is needed on top of it
        to keep Orchestrator like OpenStack, VDP daemon and the physical
        switch in sync.
        '''
        LOG.debug("Refresh handler")
        try:
            if not self.vdp_vif_map:
                LOG.debug("vdp_vif_map not created, returning")
                return
            vdp_vif_map = dict.copy(self.vdp_vif_map)
            oui_vif_map = dict.copy(self.oui_vif_map)
            for key in vdp_vif_map.viewkeys():
                lvdp_dict = vdp_vif_map.get(key)
                loui_dict = oui_vif_map.get(key)
                if not lvdp_dict:
                    return
                if not loui_dict:
                    oui_id = ""
                    oui_data = ""
                else:
                    oui_id = loui_dict.get('oui_id')
                    oui_data = loui_dict.get('oui_data')
                with self.mutex_lock:
                    if key in self.vdp_vif_map:
                        LOG.debug("Sending Refresh for VSI %s", lvdp_dict)
                        vdp_vlan = self.send_vdp_assoc(
                            vsiid=lvdp_dict.get('vsiid'),
                            mgrid=lvdp_dict.get('mgrid'),
                            typeid=lvdp_dict.get('typeid'),
                            typeid_ver=lvdp_dict.get('typeid_ver'),
                            vsiid_frmt=lvdp_dict.get('vsiid_frmt'),
                            filter_frmt=lvdp_dict.get('filter_frmt'),
                            gid=lvdp_dict.get('gid'),
                            mac=lvdp_dict.get('mac'),
                            vlan=lvdp_dict.get('vdp_vlan'),
                            oui_id=oui_id,
                            oui_data=oui_data,
                            sw_resp=True)
                # check validity.
                if not utils.is_valid_vlan_tag(vdp_vlan):
                    LOG.error(_LE("Returned vlan %(vlan)s is invalid."),
                              {'vlan': vdp_vlan})
                    # Need to invoke CB. So no return here.
                    vdp_vlan = 0
                exist_vdp_vlan = lvdp_dict.get('vdp_vlan')
                # Condition will be hit only during error cases when switch
                # reloads or when compute reloads
                if vdp_vlan != exist_vdp_vlan:
                    # Invoke the CB Function
                    cb_fn = lvdp_dict.get('vsw_cb_fn')
                    cb_data = lvdp_dict.get('vsw_cb_data')
                    if cb_fn:
                        cb_fn(cb_data, vdp_vlan)
                    lvdp_dict['vdp_vlan'] = vdp_vlan
        except Exception as e:
            LOG.error(_LE("Exception in Refrsh %s"), str(e))
Exemplo n.º 8
0
    def _vdp_refrsh_hndlr(self):
        '''Periodic refresh of vNIC events to VDP

        VDP daemon itself has keepalives. This is needed on top of it
        to keep Orchestrator like OpenStack, VDP daemon and the physical
        switch in sync.
        '''
        LOG.debug("Refresh handler")
        try:
            if not self.vdp_vif_map:
                LOG.debug("vdp_vif_map not created, returning")
                return
            vdp_vif_map = dict.copy(self.vdp_vif_map)
            oui_vif_map = dict.copy(self.oui_vif_map)
            for key in vdp_vif_map.viewkeys():
                lvdp_dict = vdp_vif_map.get(key)
                loui_dict = oui_vif_map.get(key)
                if not lvdp_dict:
                    return
                if not loui_dict:
                    oui_id = ""
                    oui_data = ""
                else:
                    oui_id = loui_dict.get('oui_id')
                    oui_data = loui_dict.get('oui_data')
                with self.mutex_lock:
                    if key in self.vdp_vif_map:
                        LOG.debug("Sending Refresh for VSI %s", lvdp_dict)
                        vdp_vlan = self.send_vdp_assoc(
                            vsiid=lvdp_dict.get('vsiid'),
                            mgrid=lvdp_dict.get('mgrid'),
                            typeid=lvdp_dict.get('typeid'),
                            typeid_ver=lvdp_dict.get('typeid_ver'),
                            vsiid_frmt=lvdp_dict.get('vsiid_frmt'),
                            filter_frmt=lvdp_dict.get('filter_frmt'),
                            gid=lvdp_dict.get('gid'),
                            mac=lvdp_dict.get('mac'),
                            vlan=0, oui_id=oui_id, oui_data=oui_data,
                            sw_resp=True)
                # check validity.
                if not utils.is_valid_vlan_tag(vdp_vlan):
                    LOG.error(_LE("Returned vlan %(vlan)s is invalid."),
                              {'vlan': vdp_vlan})
                    # Need to invoke CB. So no return here.
                    vdp_vlan = 0
                exist_vdp_vlan = lvdp_dict.get('vdp_vlan')
                # Condition will be hit only during error cases when switch
                # reloads or when compute reloads
                if vdp_vlan != exist_vdp_vlan:
                    # Invoke the CB Function
                    cb_fn = lvdp_dict.get('vsw_cb_fn')
                    cb_data = lvdp_dict.get('vsw_cb_data')
                    if cb_fn:
                        cb_fn(cb_data, vdp_vlan)
                    lvdp_dict['vdp_vlan'] = vdp_vlan
        except Exception as e:
            LOG.error(_LE("Exception in Refrsh %s"), str(e))
Exemplo n.º 9
0
    def provision_vdp_overlay_networks(self, port_uuid, mac, net_uuid,
                                       segmentation_id, lvid, oui):
        '''Provisions a overlay type network configured using VDP.

        :param port_uuid: the uuid of the VM port.
        :param mac: the MAC address of the VM.
        :param net_uuid: the uuid of the network associated with this vlan.
        :param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
        :lvid: Local VLAN ID
        :oui: OUI Parameters
        '''
        lldpad_port = self.lldpad_info
        if lldpad_port:
            ovs_cb_data = {
                'obj': self,
                'port_uuid': port_uuid,
                'mac': mac,
                'net_uuid': net_uuid
            }
            vdp_vlan = lldpad_port.send_vdp_vnic_up(
                port_uuid=port_uuid,
                vsiid=port_uuid,
                gid=segmentation_id,
                mac=mac,
                new_network=True,
                oui=oui,
                vsw_cb_fn=self.vdp_vlan_change,
                vsw_cb_data=ovs_cb_data)
        else:
            LOG.error(_LE("There is no LLDPad port available."))
            return False, cconstants.INVALID_VLAN
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error(
                _LE("Cannot provision VDP Overlay network for"
                    " net-id=%(net_uuid)s - Invalid "), {'net_uuid': net_uuid})
            return True, cconstants.INVALID_VLAN

        LOG.info(
            _LI('provision_vdp_overlay_networks: add_flow for '
                'Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s'), {
                    'local_vlan': lvid,
                    'vdp_vlan': vdp_vlan
                })
        # outbound
        self.ext_br_obj.add_flow(priority=4,
                                 in_port=self.phy_peer_port_num,
                                 dl_vlan=lvid,
                                 actions="mod_vlan_vid:%s,normal" % vdp_vlan)
        # inbound
        self.integ_br_obj.add_flow(priority=3,
                                   in_port=self.int_peer_port_num,
                                   dl_vlan=vdp_vlan,
                                   actions="mod_vlan_vid:%s,normal" % lvid)
        return True, vdp_vlan
Exemplo n.º 10
0
    def provision_vdp_overlay_networks(self, port_uuid, mac, net_uuid,
                                       segmentation_id, lvid, oui):
        """Provisions a overlay type network configured using VDP.

        :param port_uuid: the uuid of the VM port.
        :param mac: the MAC address of the VM.
        :param net_uuid: the uuid of the network associated with this vlan.
        :param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
        :lvid: Local VLAN ID
        :oui: OUI Parameters
        """
        lldpad_port = self.lldpad_info
        if lldpad_port:
            ovs_cb_data = {
                'obj': self,
                'port_uuid': port_uuid,
                'mac': mac,
                'net_uuid': net_uuid
            }
            vdp_vlan, fail_reason = lldpad_port.send_vdp_vnic_up(
                port_uuid=port_uuid,
                vsiid=port_uuid,
                gid=segmentation_id,
                mac=mac,
                new_network=True,
                oui=oui,
                vsw_cb_fn=self.vdp_vlan_change,
                vsw_cb_data=ovs_cb_data)
        else:
            fail_reason = "There is no LLDPad port available."
            LOG.error(_LE("%s"), fail_reason)
            return {
                'result': False,
                'vdp_vlan': cconstants.INVALID_VLAN,
                'fail_reason': fail_reason
            }
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error(
                _LE("Cannot provision VDP Overlay network for"
                    " net-id=%(net_uuid)s - Invalid "), {'net_uuid': net_uuid})
            return {
                'result': True,
                'vdp_vlan': cconstants.INVALID_VLAN,
                'fail_reason': fail_reason
            }

        LOG.info(
            _LI('provision_vdp_overlay_networks: add_flow for '
                'Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s'), {
                    'local_vlan': lvid,
                    'vdp_vlan': vdp_vlan
                })
        self.program_vm_ovs_flows(lvid, 0, vdp_vlan)
        return {'result': True, 'vdp_vlan': vdp_vlan, 'fail_reason': None}
Exemplo n.º 11
0
 def reset_port_vlan(self, vdp_vlan):
     if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
         LOG.info("Passed Invalid vlan in reset_port_vlan")
         return
     if vdp_vlan not in self.port_vdp_vlan_dict:
         LOG.error("wrongly called, no VLAN's present")
         self.port_vdp_vlan_dict[vdp_vlan] = 0
     else:
         self.port_vdp_vlan_dict[vdp_vlan] -= 1
         if not self.port_vdp_vlan_dict[vdp_vlan]:
             del self.port_vdp_vlan_dict[vdp_vlan]
Exemplo n.º 12
0
    def provision_vdp_overlay_networks(self, port_uuid, mac, net_uuid, segmentation_id, lvid, oui):
        """Provisions a overlay type network configured using VDP.

        :param port_uuid: the uuid of the VM port.
        :param mac: the MAC address of the VM.
        :param net_uuid: the uuid of the network associated with this vlan.
        :param segmentation_id: the VID for 'vlan' or tunnel ID for 'tunnel'
        :lvid: Local VLAN ID
        :oui: OUI Parameters
        """
        lldpad_port = self.lldpad_info
        if lldpad_port:
            ovs_cb_data = {"obj": self, "port_uuid": port_uuid, "mac": mac, "net_uuid": net_uuid}
            vdp_vlan = lldpad_port.send_vdp_vnic_up(
                port_uuid=port_uuid,
                vsiid=port_uuid,
                gid=segmentation_id,
                mac=mac,
                new_network=True,
                oui=oui,
                vsw_cb_fn=self.vdp_vlan_change,
                vsw_cb_data=ovs_cb_data,
            )
        else:
            LOG.error(_LE("There is no LLDPad port available."))
            return False, cconstants.INVALID_VLAN
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error(
                _LE("Cannot provision VDP Overlay network for" " net-id=%(net_uuid)s - Invalid "),
                {"net_uuid": net_uuid},
            )
            return True, cconstants.INVALID_VLAN

        LOG.info(
            _LI("provision_vdp_overlay_networks: add_flow for " "Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s"),
            {"local_vlan": lvid, "vdp_vlan": vdp_vlan},
        )
        # outbound
        self.ext_br_obj.add_flow(
            priority=4, in_port=self.phy_peer_port_num, dl_vlan=lvid, actions="mod_vlan_vid:%s,normal" % vdp_vlan
        )
        # inbound
        self.integ_br_obj.add_flow(
            priority=3, in_port=self.int_peer_port_num, dl_vlan=vdp_vlan, actions="mod_vlan_vid:%s,normal" % lvid
        )
        return True, vdp_vlan
Exemplo n.º 13
0
    def unprovision_vdp_overlay_networks(self, net_uuid, lvid, vdp_vlan, oui):
        """Unprovisions a overlay type network configured using VDP.

        :param net_uuid: the uuid of the network associated with this vlan.
        :lvid: Local VLAN ID
        :vdp_vlan: VDP VLAN ID
        :oui: OUI Parameters
        """
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error("Cannot unprovision VDP Overlay network for"
                      " net-id=%(net_uuid)s - Invalid ",
                      {'net_uuid': net_uuid})
            return

        LOG.info('unprovision_vdp_overlay_networks: add_flow for '
                 'Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s',
                 {'local_vlan': lvid, 'vdp_vlan': vdp_vlan})
        self.program_vm_ovs_flows(lvid, vdp_vlan, 0)
Exemplo n.º 14
0
    def unprovision_vdp_overlay_networks(self, net_uuid, lvid, vdp_vlan, oui):
        """Provisions a overlay type network configured using VDP.

        :param net_uuid: the uuid of the network associated with this vlan.
        :lvid: Local VLAN ID
        :vdp_vlan: VDP VLAN ID
        :oui: OUI Parameters
        """
        # check validity
        if not ovs_lib.is_valid_vlan_tag(vdp_vlan):
            LOG.error(
                _LE("Cannot unprovision VDP Overlay network for" " net-id=%(net_uuid)s - Invalid "),
                {"net_uuid": net_uuid},
            )
            return

        LOG.info(
            _LI("unprovision_vdp_overlay_networks: add_flow for " "Local Vlan %(local_vlan)s VDP VLAN %(vdp_vlan)s"),
            {"local_vlan": lvid, "vdp_vlan": vdp_vlan},
        )
        # outbound
        self.ext_br_obj.delete_flows(in_port=self.phy_peer_port_num, dl_vlan=lvid)
        # inbound
        self.integ_br_obj.delete_flows(in_port=self.int_peer_port_num, dl_vlan=vdp_vlan)
Exemplo n.º 15
0
 def port_down_segment_mode(self, lldpad_port, port_uuid, mac,
                            net_uuid, segmentation_id, oui):
     lvm = self.local_vlan_map.get(net_uuid)
     if not lvm:
         fail_reason = "Local VLAN Map not available in port_down"
         LOG.error("%s", fail_reason)
         return {'result': False, 'fail_reason': fail_reason}
     if port_uuid not in lvm.port_uuid_list:
         fail_reason = "port_uuid %s not in cache for port_down" % (
             port_uuid)
         LOG.error("%s", fail_reason)
         return {'result': False, 'fail_reason': fail_reason}
     vdp_vlan = lvm.late_binding_vlan
     lldpad_port.send_vdp_vnic_down(port_uuid=port_uuid,
                                    vsiid=port_uuid,
                                    gid=segmentation_id,
                                    mac=mac, vlan=vdp_vlan, oui=oui)
     lvm.port_uuid_list.pop(port_uuid, None)
     lvm.reset_port_vlan(vdp_vlan)
     # Check here that if all the VM's in that network has
     # 0 as VLAN (dis-assoc sent by switch, but flow not removed), then
     # also remove the flow by calling unprovision. Do this after the
     # pop instruction above.
     # Check with the late binding vlan, if that still points to
     # old_vlan, remove the flow and make late_binding_vlan as 0
     # late_binding_vlan should reflect the VLAN that is installed
     # for the flow.
     if not lvm.port_uuid_list:
         self.unprovision_vdp_overlay_networks(net_uuid, lvm.lvid,
                                               vdp_vlan, oui)
         self.local_vlan_map.pop(net_uuid)
         LOG.info("No valid ports, clearing flows")
     else:
         # There are ports present in the network case.
         if not lvm.any_valid_vlan():
             # This condition will be hit when there are still ports
             # remaining in the network, but none of them have a valid
             # VLAN. i.e. Dis-assoc sent by switch for all ports except
             # one, vdp_vlan_change will not remove flows, since there's
             # a valid port left with a VLAN. Now, user removes the VM
             # with valid port. Now flow has to be deleted since
             # there's no valid port with a VLAN.
             self.unprovision_vdp_overlay_networks(net_uuid, lvm.lvid,
                                                   vdp_vlan, oui)
             lvm.late_binding_vlan = 0
             LOG.info("unprovisioned Local %(lvid)s, VDP %(vdp)s VLAN "
                      "since no VM has valid VLAN",
                      {'lvid': lvm.lvid, 'vdp': vdp_vlan})
         else:
             # There are still valid VLAN's present.
             # Say, out of 3 VM's one VM got a VLAN change due to which
             # the new flow will be programmed according to new vlan.
             # The VM with new VLAN gets deleted.
             # Say, for whatever reason, the other VM's in the 'same'
             # network didn't gets changed to new VLAN.
             # VLAN change function won't be called and so it will
             # be stranded with stale flow unless the below
             # functionality of putting back the old VLAN is there.
             vlan_other = lvm.any_consistent_vlan()
             if vlan_other and ovs_lib.is_valid_vlan_tag(vlan_other) and (
                vlan_other != lvm.late_binding_vlan):
                 self.program_vm_ovs_flows(lvm.lvid, vdp_vlan, vlan_other)
                 lvm.late_binding_vlan = vlan_other
                 self.vdp_nego_req = True
                 LOG.info("Reprogrammed old Flows Local %(lvid)s "
                          "VDP %(vdp)s Other %(other)s VLANs",
                          {'lvid': lvm.lvid, 'vdp': vdp_vlan,
                           'other': vlan_other})
     return {'result': True, 'fail_reason': None}