def _message_exchange(self, device): # register for receiving async messages self.adapter_agent.register_for_proxied_messages(device.proxy_address) # reset incoming message queue while self.incoming_messages.pending: _ = yield self.incoming_messages.get() # construct message msg = EOAMPayload(body=CablelabsOUI() / DPoEOpcode_GetRequest() / DeviceId()) # send message log.info('ONU-send-proxied-message') self.adapter_agent.send_proxied_message(device.proxy_address, msg) # wait till we detect incoming message yield self.incoming_messages.get() # construct install of igmp query address msg = EOAMPayload(body=CablelabsOUI() / DPoEOpcode_SetRequest() / AddStaticMacAddress(mac='01:00:5e:00:00:01')) # send message log.info('ONU-send-proxied-message') self.adapter_agent.send_proxied_message(device.proxy_address, msg) # wait till we detect incoming message yield self.incoming_messages.get()
def _message_exchange(self, device): # register for receiving async messages self.adapter_agent.register_for_proxied_messages(device.proxy_address) # reset incoming message queue while self.incoming_messages.pending: _ = yield self.incoming_messages.get() # send out ping frame to ONU device get device information ping_frame = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Get Request"], body=VendorName() / OnuMode() / HardwareVersion() / ManufacturerInfo() ) / EndOfPDU() ) log.info('ONU-send-proxied-message to Get Version Info for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, ping_frame) # Loop until we have a Get Response ack = False while not ack: frame = yield self.incoming_messages.get() respType = get_oam_msg_type(log, frame) if (respType == RxedOamMsgTypeEnum["DPoE Get Response"]): ack = True else: # Handle unexpected events/OMCI messages check_resp(log, frame) if ack: log.info('ONU-response received for Get Version Info for ONU: {}'.format(device.mac_address)) self._process_ping_frame_response(device, frame) if self.mode.upper()[0] == "G": # GPON # construct multicast LLID set msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Multicast Register"],body=MulticastRegisterSet(MulticastLink=0x10bc, UnicastLink=0) )) # send message log.info('ONU-send-proxied-message to Multicast Register Set for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg)
def reboot_device(self, device): log.info('Rebooting ONU: {}'.format(device.mac_address)) # Update the operational status to ACTIVATING and connect status to # UNREACHABLE previous_oper_status = device.oper_status previous_conn_status = device.connect_status device.oper_status = OperStatus.ACTIVATING device.connect_status = ConnectStatus.UNREACHABLE self.adapter_agent.update_device(device) msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"], body=DeviceReset())/ EndOfPDU() ) action = "Device Reset" # send message log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) rc = [] yield self._handle_set_resp(device, action, rc) # Change the operational status back to its previous state. device.oper_status = previous_oper_status device.connect_status = previous_conn_status self.adapter_agent.update_device(device) log.info('ONU Rebooted: {}'.format(device.mac_address))
def _send_clear_static_mac_table(self, device): # construct install of igmp query address msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Set Request"],body=ClearStaticMacTable() )) action = "Clear Static MAC Table" # send message log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) rc = [] yield self._handle_set_resp(device, action, rc)
def _send_igmp_mcast_addr(self, device): # construct install of igmp query address msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=Dpoe_Opcodes["Set Request"],body=AddStaticMacAddress(mac='01:00:5e:00:00:01') )) action = "Set Static IGMP MAC address" # send message log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) rc = [] yield self._handle_set_resp(device, action, rc)
def update_flows_bulk(self, device, flows, groups): log.info('########################################') log.info('bulk-flow-update', device_id=device.id, flows=flows, groups=groups) assert len(groups.items) == 0, "Cannot yet deal with groups" Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()} Operator = {v: k for k, v in RuleOperatorEnum.iteritems()} for flow in flows.items: in_port = get_in_port(flow) assert in_port is not None precedence = 255 - min(flow.priority / 256, 255) if in_port == 2: log.info('#### Upstream Rule ####') dn_req = EOAMPayload(body=CablelabsOUI() / DPoEOpcode_SetRequest()) for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####', field_type=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####') elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####', port=_port) elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid) elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp) elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') else: log.info('#### field.type == NOT IMPLEMENTED!! ####') raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-tpid', ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: pass else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) elif in_port == 1: log.info('#### Downstream Rule ####') #### Loop through fields again... for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####', in_port=in_port, match=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####', in_port=in_port, ip_proto=ip_proto) elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####') elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####') elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####') elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') a = int(hex(_ipv4_dst)[2:4], 16) b = int(hex(_ipv4_dst)[4:6], 16) c = int(hex(_ipv4_dst)[6:8], 16) d = int(hex(_ipv4_dst)[8:], 16) dn_req = EOAMPayload( body=CablelabsOUI() / DPoEOpcode_SetRequest() / AddStaticMacAddress( mac=mcastIp2McastMac('%d.%d.%d.%d' % (a, b, c, d)))) # send message log.info('ONU-send-proxied-message') self.adapter_agent.send_proxied_message( device.proxy_address, dn_req) else: raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-ether-type', ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: pass else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) else: raise Exception('Port should be 1 or 2 by our convention')
def update_flows_bulk(self, device, flows, groups): log.info('########################################') log.info('bulk-flow-update', device_id=device.id, flows=flows, groups=groups) assert len(groups.items) == 0, "Cannot yet deal with groups" # Only do something if there are flows to program if (len(flows.items) > 0): # Clear the existing entries in the Static MAC Address Table yield self._send_clear_static_mac_table(device) # Re-add the IGMP Multicast Address yield self._send_igmp_mcast_addr(device) Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()} Operator = {v: k for k, v in RuleOperatorEnum.iteritems()} for flow in flows.items: in_port = get_in_port(flow) assert in_port is not None precedence = 255 - min(flow.priority / 256, 255) if in_port == 2: log.info('#### Upstream Rule ####') up_req = UserPortObject() up_req /= PortIngressRuleHeader(precedence=precedence) for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####',field_type=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####') elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####', port=_port) elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid) up_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp) elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####', udp_dst=_udp_dst) elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####', ipv4_dst=_ipv4_dst) elif field.type == METADATA: _metadata = field.table_metadata log.info('#### field.type == METADATA ####', metadata=_metadata) else: log.info('#### field.type == NOT IMPLEMENTED!! ####') raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') up_req /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag']) elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') up_req /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag']) # if action.push.ethertype != 0x8100: # log.error('unhandled-tpid', # ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: log.info("#### action.field.vlan {} ####".format(field.vlan_vid & 0xfff)) up_req /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) up_req /= PortIngressRuleTerminator() up_req /= AddPortIngressRule() msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"], body=up_req)/ EndOfPDU() ) # send message action = "Set ONU US Rule" log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) # Get and process the Set Response rc = [] yield self._handle_set_resp(device, action, rc) elif in_port == 1: log.info('#### Downstream Rule ####') Is_MCast = False dn_req = PonPortObject() dn_req /= PortIngressRuleHeader(precedence=precedence) #### Loop through fields again... for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####', in_port=in_port, match=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####', in_port=in_port, ip_proto=_proto) elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####') elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####') elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####') elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') a = int(hex(_ipv4_dst)[2:4], 16) b = int(hex(_ipv4_dst)[4:6], 16) c = int(hex(_ipv4_dst)[6:8], 16) d = int(hex(_ipv4_dst)[8:], 16) dn_req = AddStaticMacAddress(mac=mcastIp2McastMac('%d.%d.%d.%d' % (a,b,c,d))) Is_MCast = True else: raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) dn_req /= PortIngressRuleResultReplace(fieldcode=Clause['C-VLAN Tag']) dn_req /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-ether-type', ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) dn_req /= PortIngressRuleResultReplace(fieldcode=Clause['C-VLAN Tag']) dn_req /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) if Is_MCast is True: action = "Set Static IP MCAST address" else: dn_req /= PortIngressRuleTerminator() dn_req /= AddPortIngressRule() action = "Set ONU DS Rule" msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode = Dpoe_Opcodes["Set Request"], body=dn_req)/ EndOfPDU() ) # send message log.info('ONU-send-proxied-message to {} for ONU: {}'.format(action, device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) # Get and process the Set Response rc = [] yield self._handle_set_resp(device, action, rc) else: raise Exception('Port should be 1 or 2 by our convention') log.info('bulk-flow-update finished', device_id=device.id, flows=flows, groups=groups) log.info('########################################')
def update_flows_bulk(self, device, flows, groups): log.info('########################################') log.info('bulk-flow-update', device_id=device.id, flows=flows, groups=groups) assert len(groups.items) == 0, "Cannot yet deal with groups" # extract ONU VID vid_from_device_id = {v[0]: k for k,v in self.vlan_to_device_ids.iteritems()} ONU_VID = vid_from_device_id[device.id] Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()} Operator = {v: k for k, v in RuleOperatorEnum.iteritems()} for flow in flows.items: try: in_port = get_in_port(flow) assert in_port is not None precedence = 255 - min(flow.priority / 256, 255) if in_port == 2: log.info('#### Downstream Rule ####') dn_req = NetworkToNetworkPortObject() dn_req /= PortIngressRuleHeader(precedence=precedence) for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####') dn_req /= PortIngressRuleClauseMatchLength02( fieldcode=Clause['L2 Type/Len'], operator=Operator['=='], match=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####') elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####', port=_port) elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid) dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) if (_vlan_vid != 140): dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=Clause['C-VLAN Tag'], fieldinstance=1, operator=Operator['=='], match=ONU_VID) elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp) elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == UDP_SRC: _udp_src = field.udp_src log.info('#### field.type == UDP_SRC ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') elif field.type == METADATA: log.info('#### field.type == METADATA ####') pass else: raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') dn_req /= PortIngressRuleResultForward() serial = ONU_VID - 200 link = (0xe222 << 16) | (serial << 8) dn_req /= PortIngressRuleResultOLTQueue(unicastvssn="TBIT", unicastlink=link) elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') dn_req /= PortIngressRuleResultDelete(fieldcode=Clause['S-VLAN Tag']) elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-tpid', ethertype=action.push.ethertype) dn_req /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag']) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: dn_req /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) dn_req /= PortIngressRuleTerminator() dn_req /= AddPortIngressRule() msg = ( Ether(dst=device.mac_address) / Dot1Q(vlan=TIBIT_MGMT_VLAN, prio=TIBIT_MGMT_PRIORITY) / EOAMPayload( body=CablelabsOUI() / DPoEOpcode_SetRequest() / dn_req) ) self.io_port.send(str(msg)) elif in_port == 1: # Upstream rule log.info('#### Upstream Rule ####') field_match_vlan_upstream_with_link = False up_req_link = PortIngressRuleHeader(precedence=precedence) up_req_pon = PonPortObject() up_req_pon /= PortIngressRuleHeader(precedence=precedence) for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####', in_port=in_port, match=_type) up_req_pon /= PortIngressRuleClauseMatchLength02( fieldcode=Clause['L2 Type/Len'], operator=Operator['=='], match=_type) up_req_link /= PortIngressRuleClauseMatchLength02( fieldcode=Clause['L2 Type/Len'], operator=Operator['=='], match=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####', in_port=in_port, ip_proto=_proto) up_req_pon /= PortIngressRuleClauseMatchLength01( fieldcode=Clause['IPv4/IPv6 Protocol Type'], operator=Operator['=='], match=_proto) up_req_link /= PortIngressRuleClauseMatchLength01( fieldcode=Clause['IPv4/IPv6 Protocol Type'], operator=Operator['=='], match=_proto) elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####') elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####') up_req_pon /= PortIngressRuleClauseMatchLength02( fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) serial = _vlan_vid - 200 link = (0xe222 << 16) | (serial << 8) up_req_link /= OLTUnicastLogicalLink(unicastvssn='TBIT', unicastlink=link) up_req_link /= PortIngressRuleClauseMatchLength02( fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=_vlan_vid) field_match_vlan_upstream_with_link = True elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####') elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') up_req_pon /= (PortIngressRuleClauseMatchLength02(fieldcode=Clause['TCP/UDP source port'], operator=Operator['=='], match=0x0044)/ PortIngressRuleClauseMatchLength02(fieldcode=Clause['TCP/UDP destination port'], operator=Operator['=='], match=0x0043)) elif field.type == UDP_SRC: _udp_src = field.udp_src log.info('#### field.type == UDP_SRC ####') else: raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') up_req_pon /= PortIngressRuleResultForward() up_req_link /= PortIngressRuleResultForward() elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-ether-type', ethertype=action.push.ethertype) if field_match_vlan_upstream_with_link == True: up_req_link /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag'], fieldinstance=1) else: up_req_pon /= PortIngressRuleResultInsert(fieldcode=Clause['C-VLAN Tag'], fieldinstance=0) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: if field_match_vlan_upstream_with_link == True: up_req_link /=(PortIngressRuleResultCopy(fieldcode=Clause['C-VLAN Tag'])/ PortIngressRuleResultReplace(fieldcode=Clause['C-VLAN Tag'])) up_req_pon /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) up_req_link /= PortIngressRuleResultSet( fieldcode=Clause['C-VLAN Tag'], value=field.vlan_vid & 0xfff) else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) if (field_match_vlan_upstream_with_link == True): up_req = up_req_link else: up_req = up_req_pon up_req /= PortIngressRuleTerminator() up_req /= AddPortIngressRule() msg = ( Ether(dst=device.mac_address) / Dot1Q(vlan=TIBIT_MGMT_VLAN, prio=TIBIT_MGMT_PRIORITY) / EOAMPayload( body=CablelabsOUI() / DPoEOpcode_SetRequest() / up_req) ) self.io_port.send(str(msg)) else: raise Exception('Port should be 1 or 2 by our convention') except Exception, e: log.exception('failed-to-install-flow', e=e, flow=flow)
def _detect_onus(self, device): # send out get 'links' to the OLT device olt_mac = device.mac_address links_frame = self._make_links_frame(mac_address=olt_mac) self.io_port.send(links_frame) while True: response = yield self.incoming_queues[olt_mac].get() # verify response and if not the expected response if 1: # TODO check if it is really what we expect, and wait if not break jdev = json.loads(response.payload.payload.body.load) onu_mac = '' for macid in jdev['results']: if macid['macid'] is None: log.info('MAC ID is NONE %s' % str(macid['macid'])) elif macid['macid'][:6].upper( ) == SUMITOMO_ELECTRIC_INDUSTRIES_OUI: onu_mac = macid['macid'] log.info('SUMITOMO mac address %s' % str(macid['macid'])) log.info('activate-olt-for-onu-%s' % onu_mac) # Convert from string to colon separated form onu_mac = ':'.join( s.encode('hex') for s in onu_mac.decode('hex')) vlan_id = self._olt_side_onu_activation( int(macid['macid'][-4:-2], 16)) self.adapter_agent.child_device_detected( parent_device_id=device.id, parent_port_no=1, child_device_type='dpoe_onu', mac_address=onu_mac, proxy_address=Device.ProxyAddress(device_id=device.id, channel_id=vlan_id), vlan=vlan_id) else: onu_mac_string = '000c' + macid.get('macid', 'e2000000')[4:] log.info('activate-olt-for-onu-%s' % onu_mac) # Convert from string to colon separated form onu_mac = ':'.join( s.encode('hex') for s in onu_mac_string.decode('hex')) serial_num = int(macid['macid'][-4:-2], 16) vlan_id = self._olt_side_onu_activation(serial_num) self.adapter_agent.child_device_detected( parent_device_id=device.id, parent_port_no=1, child_device_type='tibit_onu', mac_address=onu_mac, proxy_address=Device.ProxyAddress(device_id=device.id, channel_id=vlan_id), vlan=vlan_id) ## Automatically setup default downstream control frames flow (in this case VLAN 4000) Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()} Operator = {v: k for k, v in RuleOperatorEnum.iteritems()} packet_out_rule = ( Ether(dst=device.mac_address) / Dot1Q(vlan=TIBIT_MGMT_VLAN, prio=TIBIT_MGMT_PRIORITY) / EOAMPayload( body=CablelabsOUI() / DPoEOpcode_SetRequest() / NetworkToNetworkPortObject() / PortIngressRuleHeader(precedence=13) / PortIngressRuleClauseMatchLength02( fieldcode=Clause['C-VLAN Tag'], fieldinstance=0, operator=Operator['=='], match=TIBIT_PACKET_OUT_VLAN) / PortIngressRuleClauseMatchLength02( fieldcode=Clause['C-VLAN Tag'], fieldinstance=1, operator=Operator['=='], match=vlan_id) / PortIngressRuleResultOLTQueue( unicastvssn="TBIT", unicastlink=int(onu_mac_string[4:], 16)) / PortIngressRuleResultForward() / PortIngressRuleResultDelete( fieldcode=Clause['C-VLAN Tag']) / PortIngressRuleTerminator() / AddPortIngressRule())) self.io_port.send(str(packet_out_rule)) while True: response = yield self.incoming_queues[olt_mac].get() # verify response and if not the expected response if 1: # TODO check if it is really what we expect, and wait if not break # also record the vlan_id -> (device_id, logical_device_id, linkid) for # later use. The linkid is the macid returned. self.vlan_to_device_ids[vlan_id] = (device.id, device.parent_id, macid.get('macid', 0))
def _message_exchange(self, device): # register for receiving async messages self.adapter_agent.register_for_proxied_messages(device.proxy_address) # reset incoming message queue while self.incoming_messages.pending: _ = yield self.incoming_messages.get() # construct message msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=0x01,body=DeviceId()) ) # send message log.info('ONU-send-proxied-message to Get Device Id for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) # wait till we detect incoming message yield self.incoming_messages.get() log.info('ONU-response received for Get Device Id for ONU: {}'.format(device.mac_address)) #TODO Add a timeout to the above, if we do not recieve a message #The above get request/ get response is done to verify the message exchange is #functioning correctly, there is nothing to store from the response # construct install of igmp query address msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=0x03,body=AddStaticMacAddress(mac='01:00:5e:00:00:01') )) # send message log.info('ONU-send-proxied-message to Set Static IGMP MAC address for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg) # Get and process the Set Response ack = False start_time = time.time() # Loop until we have a set response or timeout while not ack: frame = yield self.incoming_messages.get() #TODO - Need to add propoer timeout functionality #if (time.time() - start_time) > TIBIT_MSG_WAIT_TIME or (frame is None): # break # don't wait forever respType = self._get_oam_msg_type(frame) log.info('Received OAM Message 0x %s' % str(respType)) #Check that the message received is a Set Response if (respType == RxedOamMsgTypeEnum["DPoE Set Response"]): ack = True else: # Handle unexpected events/OMCI messages self._check_resp(frame) # Verify Set Response if ack: log.info('ONU-response received for Set Static IGMP MAC address for ONU: {}'.format(device.mac_address)) (rc,branch,leaf,status) = self._check_set_resp(frame) if (rc == True): log.info('Set Response had no errors') else: log.info('Set Response had errors - Branch 0x{:X} Leaf 0x{:0>4X} {}'.format(branch, leaf, DPoEVariableResponseCodes[status])) # construct multicast LLID set # TODO - This is needed to support multicast traffic for GPON. This should only be done for a # a GPON ONU and the UnicastLink value needs to come from the OLT. This will work only for # a single GPON ONU. msg = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=0x06,body=MulticastRegisterSet(MulticastLink=0x10bc, UnicastLink=0x1008) )) # send message log.info('ONU-send-proxied-message to Set Static IGMP MAC address for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, msg)
def update_flows_bulk(self, device, flows, groups): log.info('########################################') log.info('bulk-flow-update', device_id=device.id, flows=flows, groups=groups) assert len(groups.items) == 0, "Cannot yet deal with groups" Clause = {v: k for k, v in ClauseSubtypeEnum.iteritems()} Operator = {v: k for k, v in RuleOperatorEnum.iteritems()} for flow in flows.items: in_port = get_in_port(flow) assert in_port is not None precedence = 255 - min(flow.priority / 256, 255) if in_port == 2: log.info('#### Upstream Rule ####') up_req = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=0x03) ) #TODO - There is no body to the message above, is there ever an Upstream Rule for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####',field_type=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####') elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####', port=_port) elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####', vlan=_vlan_vid) elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####', pcp=_vlan_pcp) elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') else: log.info('#### field.type == NOT IMPLEMENTED!! ####') raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-tpid', ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: pass else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) elif in_port == 1: log.info('#### Downstream Rule ####') #### Loop through fields again... for field in get_ofb_fields(flow): if field.type == ETH_TYPE: _type = field.eth_type log.info('#### field.type == ETH_TYPE ####', in_port=in_port, match=_type) elif field.type == IP_PROTO: _proto = field.ip_proto log.info('#### field.type == IP_PROTO ####', in_port=in_port, ip_proto=ip_proto) elif field.type == IN_PORT: _port = field.port log.info('#### field.type == IN_PORT ####') elif field.type == VLAN_VID: _vlan_vid = field.vlan_vid & 0xfff log.info('#### field.type == VLAN_VID ####') elif field.type == VLAN_PCP: _vlan_pcp = field.vlan_pcp log.info('#### field.type == VLAN_PCP ####') elif field.type == UDP_DST: _udp_dst = field.udp_dst log.info('#### field.type == UDP_DST ####') elif field.type == IPV4_DST: _ipv4_dst = field.ipv4_dst log.info('#### field.type == IPV4_DST ####') a = int(hex(_ipv4_dst)[2:4], 16) b = int(hex(_ipv4_dst)[4:6], 16) c = int(hex(_ipv4_dst)[6:8], 16) d = int(hex(_ipv4_dst)[8:], 16) dn_req = ( EOAMPayload() / EOAM_VendSpecificMsg(oui=CableLabs_OUI) / EOAM_DpoeMsg(dpoe_opcode=0x03, body=AddStaticMacAddress(mac=mcastIp2McastMac('%d.%d.%d.%d' % (a,b,c,d))) )) # send message log.info('ONU-send-proxied-message to Set Static IP MCAST address for ONU: {}'.format(device.mac_address)) self.adapter_agent.send_proxied_message(device.proxy_address, dn_req) # Get and process the Set Response ack = False start_time = time.time() # Loop until we have a set response or timeout while not ack: frame = yield self.incoming_messages.get() #TODO - Need to add propoer timeout functionality #if (time.time() - start_time) > TIBIT_MSG_WAIT_TIME or (frame is None): # break # don't wait forever respType = self._get_oam_msg_type(frame) log.info('Received OAM Message 0x %s' % str(respType)) #Check that the message received is a Set Response if (respType == RxedOamMsgTypeEnum["DPoE Set Response"]): ack = True else: # Handle unexpected events/OMCI messages self._check_resp(frame) # Verify Set Response if ack: log.info('ONU-response received for Set Static IP MCAST address for ONU: {}'.format(device.mac_address)) (rc,branch,leaf,status) = self._check_set_resp(frame) if (rc == True): log.info('Set Response had no errors') else: log.info('Set Response had errors - Branch 0x{:X} Leaf 0x{:0>4X} {}'.format(branch, leaf, DPoEVariableResponseCodes[status])) else: raise NotImplementedError('field.type={}'.format( field.type)) for action in get_actions(flow): if action.type == OUTPUT: log.info('#### action.type == OUTPUT ####') elif action.type == POP_VLAN: log.info('#### action.type == POP_VLAN ####') elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: log.error('unhandled-ether-type', ethertype=action.push.ethertype) elif action.type == SET_FIELD: log.info('#### action.type == SET_FIELD ####') assert (action.set_field.field.oxm_class == ofp.OFPXMC_OPENFLOW_BASIC) field = action.set_field.field.ofb_field if field.type == VLAN_VID: pass else: log.error('unsupported-action-set-field-type', field_type=field.type) else: log.error('UNSUPPORTED-ACTION-TYPE', action_type=action.type) else: raise Exception('Port should be 1 or 2 by our convention')
def _message_exchange(self, device): # register for receiving async messages self.adapter_agent.register_for_proxied_messages(device.proxy_address) # reset incoming message queue while self.incoming_messages.pending: _ = yield self.incoming_messages.get() # construct message msg = EOAMPayload(body=TibitOUI() / DPoEOpcode_GetRequest() / DeviceId()) # send message log.info('ONU-send-proxied-message') self.adapter_agent.send_proxied_message(device.proxy_address, msg) # wait till we detect incoming message yield self.incoming_messages.get() # construct install of igmp query address msg = EOAMPayload(body=TibitOUI() / DPoEOpcode_SetRequest() / AddStaticMacAddress(mac='01:00:5e:00:00:01')) # send message log.info('ONU-send-proxied-message') self.adapter_agent.send_proxied_message(device.proxy_address, msg) # wait till we detect incoming message #frame = yield self.incoming_messages.get() # Get and process the Set Response ack = False start_time = time.time() # Loop until we have a set response or timeout while not ack: frame = yield self.incoming_messages.get() #TODO - Need to add propoer timeout functionality #if (time.time() - start_time) > TIBIT_MSG_WAIT_TIME or (frame is None): # break # don't wait forever respType = self._voltha_get_oam_msg_type(frame) log.info('Received OAM Message 0x %s' % str(respType)) #Check that the message received is a Set Response if (respType == RxedOamMsgTypeEnum["DPoE Set Response"]): ack = True else: # Handle unexpected events/OMCI messages self._voltha_check_resp(frame) # Verify Set Response if ack: (rc, branch, leaf, status) = self._voltha_check_set_resp(frame) log.info('REturn from Set resp') if (rc == True): log.info('Set Response had no errors') else: log.info('Set Respose had errors') log.info('Branch 0x{:X} Leaf 0x{:0>4X} {}'.format( branch, leaf, DPoEVariableResponseCodes[status]))