def create(flow_entry): from evc_map import EVCMap device_id = flow_entry.device_id if device_id not in _mcast_evcs: _mcast_evcs[device_id] = {} evc_table = _mcast_evcs[device_id] try: evc = evc_table.get(flow_entry.vlan_id) if evc is None: # Create EVC and initial EVC Map evc = MCastEVC(flow_entry) evc_table[flow_entry.vlan_id] = evc else: if flow_entry.flow_id in evc.downstream_flows: # TODO: Debug only to see if flow_ids are unique pass else: evc.add_downstream_flows(flow_entry.flow_id) fake_flow = FakeUpstreamFlow(flow_entry.flow, flow_entry.handler) evc_map_name = EVCMap.create_evc_map_name(fake_flow) if evc_map_name not in evc.evc_map_names: EVCMap.create_ingress_map(fake_flow, evc) return evc except Exception as e: log.exception('mcast-create', e=e) return None
def _create_evc_and_maps(downstream_flow, upstream_flows): """ Give a set of flows, find (or create) the EVC and any needed EVC-MAPs :param downstream_flow: NNI -> UNI flow (provides much of the EVC values) :param upstream_flows: UNI -> NNI flows (provides much of the EVC-MAP values) :return: EVC object """ # Get any existing EVC if a flow is already created if downstream_flow.evc is None: downstream_flow.evc = EVC(downstream_flow) evc = downstream_flow.evc if not evc.valid: return None # Create EVC-MAPs for flow in upstream_flows: if flow.evc_map is None: flow.evc_map = EVCMap.create_ingress_map(flow, evc) all_valid = all(flow.evc_map.valid for flow in upstream_flows) return evc if all_valid else None
def _create_evc_and_maps(evc, downstream_flow, upstream_flows): """ Give a set of flows, find (or create) the EVC and any needed EVC-MAPs :param evc: (EVC) Existing EVC for downstream flow. May be null if not created :param downstream_flow: (FlowEntry) NNI -> UNI flow (provides much of the EVC values) :param upstream_flows: (list of FlowEntry) UNI -> NNI flows (provides much of the EVC-MAP values) :return: EVC object """ if (evc is None and downstream_flow is None) or upstream_flows is None: return None # Get any existing EVC if a flow is already created if downstream_flow.evc is None: if evc is not None: downstream_flow.evc = evc elif downstream_flow.is_multicast_flow: from mcast import MCastEVC downstream_flow.evc = MCastEVC.create(downstream_flow) else: downstream_flow.evc = EVC(downstream_flow) if not downstream_flow.evc.valid: return None # Create EVC-MAPs. Note upstream_flows is empty list for multicast for flow in upstream_flows: if flow.evc_map is None: flow.evc_map = EVCMap.create_ingress_map( flow, downstream_flow.evc) all_maps_valid = all(flow.evc_map.valid for flow in upstream_flows) \ or downstream_flow.is_multicast_flow return downstream_flow.evc if all_maps_valid else None
def _create_evc_and_maps(evc, downstream_flow, upstream_flows): """ Give a set of flows, find (or create) the EVC and any needed EVC-MAPs :param evc: (EVC) Existing EVC for downstream flow. May be null if not created :param downstream_flow: (FlowEntry) NNI -> UNI flow (provides much of the EVC values) :param upstream_flows: (list of FlowEntry) UNI -> NNI flows (provides much of the EVC-MAP values) :return: EVC object """ if (evc is None and downstream_flow is None) or upstream_flows is None: return None # Get any existing EVC if a flow is already created if downstream_flow.evc is None: if evc is not None: downstream_flow.evc = evc elif downstream_flow.is_multicast_flow: from mcast import MCastEVC downstream_flow.evc = MCastEVC.create(downstream_flow) elif downstream_flow.is_acl_flow: downstream_flow.evc = downstream_flow.get_utility_evc(upstream_flows) else: downstream_flow.evc = EVC(downstream_flow) if not downstream_flow.evc.valid: return None # Create EVC-MAPs. Note upstream_flows is empty list for multicast # For Packet In/Out support. The upstream flows for will have matching # signatures. So the first one to get created should create the EVC and # if it needs and ACL, do so then. The second one should just reference # the first map. # # If the second has and ACL, then it should add it to the map. # TODO: What to do if the second (or third, ...) is the data one. # What should it do then? sig_map_map = {f.signature: f.evc_map for f in upstream_flows if f.evc_map is not None} for flow in upstream_flows: if flow.evc_map is None: if flow.signature in sig_map_map: # Found an explicity matching existing EVC-MAP. Add flow to this EVC-MAP flow.evc_map = sig_map_map[flow.signature].add_flow(flow, downstream_flow.evc) else: # May need to create a MAP or search for an existing ACL/user EVC-Map upstream_flow_table = _existing_upstream_flow_entries[flow.device_id] existing_flow = EVCMap.find_matching_ingress_flow(flow, upstream_flow_table) if existing_flow is None: flow.evc_map = EVCMap.create_ingress_map(flow, downstream_flow.evc) else: flow.evc_map = existing_flow.add_flow(flow, downstream_flow.evc) all_maps_valid = all(flow.evc_map.valid for flow in upstream_flows) \ or downstream_flow.is_multicast_flow return downstream_flow.evc if all_maps_valid else None
def _create_evc_map(self, flow_entry): from evc_map import EVCMap flow = FakeUpstreamFlow(flow_entry.flow, flow_entry.handler) return EVCMap.create_ingress_map(flow, self)