def packet_out(self, egress_port, msg): pkt = Ether(msg) self.log.info('packet out', egress_port=egress_port, packet=str(pkt).encode("HEX")) # Find port type egress_port_type = self.port_type(egress_port) if egress_port_type == Port.ETHERNET_UNI: if pkt.haslayer(Dot1Q): outer_shim = pkt.getlayer(Dot1Q) if isinstance(outer_shim.payload, Dot1Q): # If double tag, remove the outer tag payload = ( Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) / outer_shim.payload) else: payload = pkt else: payload = pkt send_pkt = binascii.unhexlify(str(payload).encode("HEX")) self.log.info( 'sending-packet-to-ONU', egress_port=egress_port, intf_id=platform.intf_id_from_uni_port_num(egress_port), onu_id=platform.onu_id_from_port_num(egress_port), packet=str(payload).encode("HEX")) onu_pkt = openolt_pb2.OnuPacket( intf_id=platform.intf_id_from_uni_port_num(egress_port), onu_id=platform.onu_id_from_port_num(egress_port), pkt=send_pkt) self.stub.OnuPacketOut(onu_pkt) elif egress_port_type == Port.ETHERNET_NNI: self.log.info('sending-packet-to-uplink', egress_port=egress_port, packet=str(pkt).encode("HEX")) send_pkt = binascii.unhexlify(str(pkt).encode("HEX")) uplink_pkt = openolt_pb2.UplinkPacket( intf_id=platform.intf_id_from_nni_port_num(egress_port), pkt=send_pkt) self.stub.UplinkPacketOut(uplink_pkt) else: self.log.warn('Packet-out-to-this-interface-type-not-implemented', egress_port=egress_port, port_type=egress_port_type)
def is_eap_enabled(self, intf_id, onu_id): flows = self.logical_flows_proxy.get('/').items for flow in flows: eap_flow = False eap_intf_id = None eap_onu_id = None for field in fd.get_ofb_fields(flow): if field.type == fd.ETH_TYPE: if field.eth_type == EAP_ETH_TYPE: eap_flow = True if field.type == fd.IN_PORT: eap_intf_id = platform.intf_id_from_uni_port_num( field.port) eap_onu_id = platform.onu_id_from_port_num(field.port) if eap_flow: self.log.debug('eap flow detected', onu_id=onu_id, intf_id=intf_id, eap_intf_id=eap_intf_id, eap_onu_id=eap_onu_id) if eap_flow and intf_id == eap_intf_id and onu_id == eap_onu_id: return (True, flow) return (False, None)
def add_flow(self, flow, is_down_stream): self.log.debug('add flow', flow=flow, is_down_stream=is_down_stream) classifier_info = dict() action_info = dict() in_port = fd.get_in_port(flow) assert in_port is not None for field in fd.get_ofb_fields(flow): if field.type == fd.ETH_TYPE: classifier_info['eth_type'] = field.eth_type self.log.debug('field-type-eth-type', eth_type=classifier_info['eth_type']) elif field.type == fd.IP_PROTO: classifier_info['ip_proto'] = field.ip_proto self.log.debug('field-type-ip-proto', ip_proto=classifier_info['ip_proto']) elif field.type == fd.IN_PORT: classifier_info['in_port'] = field.port self.log.debug('field-type-in-port', in_port=classifier_info['in_port']) elif field.type == fd.VLAN_VID: classifier_info['vlan_vid'] = field.vlan_vid & 0xfff self.log.debug('field-type-vlan-vid', vlan=classifier_info['vlan_vid']) elif field.type == fd.VLAN_PCP: classifier_info['vlan_pcp'] = field.vlan_pcp self.log.debug('field-type-vlan-pcp', pcp=classifier_info['vlan_pcp']) elif field.type == fd.UDP_DST: classifier_info['udp_dst'] = field.udp_dst self.log.debug('field-type-udp-dst', udp_dst=classifier_info['udp_dst']) elif field.type == fd.UDP_SRC: classifier_info['udp_src'] = field.udp_src self.log.debug('field-type-udp-src', udp_src=classifier_info['udp_src']) elif field.type == fd.IPV4_DST: classifier_info['ipv4_dst'] = field.ipv4_dst self.log.debug('field-type-ipv4-dst', ipv4_dst=classifier_info['ipv4_dst']) elif field.type == fd.IPV4_SRC: classifier_info['ipv4_src'] = field.ipv4_src self.log.debug('field-type-ipv4-src', ipv4_dst=classifier_info['ipv4_src']) elif field.type == fd.METADATA: classifier_info['metadata'] = field.table_metadata self.log.debug('field-type-metadata', metadata=classifier_info['metadata']) else: raise NotImplementedError('field.type={}'.format(field.type)) for action in fd.get_actions(flow): if action.type == fd.OUTPUT: action_info['output'] = action.output.port self.log.debug('action-type-output', output=action_info['output'], in_port=classifier_info['in_port']) elif action.type == fd.POP_VLAN: action_info['pop_vlan'] = True self.log.debug('action-type-pop-vlan', in_port=in_port) elif action.type == fd.PUSH_VLAN: action_info['push_vlan'] = True action_info['tpid'] = action.push.ethertype self.log.debug('action-type-push-vlan', push_tpid=action_info['tpid'], in_port=in_port) if action.push.ethertype != 0x8100: self.log.error('unhandled-tpid', ethertype=action.push.ethertype) elif action.type == fd.SET_FIELD: # action_info['action_type'] = 'set_field' _field = action.set_field.field.ofb_field assert ( action.set_field.field.oxm_class == OFPXMC_OPENFLOW_BASIC) self.log.debug('action-type-set-field', field=_field, in_port=in_port) if _field.type == fd.VLAN_VID: self.log.debug('set-field-type-vlan-vid', vlan_vid=_field.vlan_vid & 0xfff) action_info['vlan_vid'] = (_field.vlan_vid & 0xfff) else: self.log.error('unsupported-action-set-field-type', field_type=_field.type) else: self.log.error('unsupported-action-type', action_type=action.type, in_port=in_port) # FIXME - Why ignore downstream flows? if is_down_stream is False: intf_id = platform.intf_id_from_uni_port_num( classifier_info['in_port']) onu_id = platform.onu_id_from_port_num(classifier_info['in_port']) self.divide_and_add_flow(intf_id, onu_id, classifier_info, action_info)