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" # 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) 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=RuleClauses['C-VLAN Tag'], fieldinstance=0, operator=RuleOperators['=='], 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=RuleClauses['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=RuleClauses['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)) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) up_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) else: raise NotImplementedError( 'unsupported-action-set-field-type={}'.format( field.type)) else: raise NotImplementedError( 'unsupported-action-type={}'.format(action.type)) up_req /= PortIngressRuleTerminator() up_req /= AddPortIngressRule() # send message action = "Set ONU US Rule" rc = [] yield self._set_req_rsp(device, action, up_req, 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 ####') dn_req /= PortIngressRuleClauseMatchLength02( fieldcode=RuleClauses['C-VLAN Tag'], fieldinstance=0, operator=RuleOperators['=='], match=_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 ####') # TODO - This is not the correct operation for a POP operation. # This should be a Delete result dn_req /= PortIngressRuleResultReplace( fieldcode=RuleClauses['C-VLAN Tag']) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) dn_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: raise NotImplementedError( 'unhandled-ether-type={}'.format( 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)) # TODO - Currently only support setting the VID in the DS to zero (clearing the VID) if ((field.vlan_vid & 0xfff) == 0): dn_req /= PortIngressRuleResultReplace( fieldcode=RuleClauses['C-VLAN Tag']) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) dn_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) else: raise NotImplementedError( 'unsupported-set-vlan-id={}'.format( field.vlan_vid & 0xfff)) else: raise NotImplementedError( 'unsupported-action-set-field-type={}'.format( field.type)) else: raise NotImplementedError( 'unsupported-action-type={}'.format(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" # send message rc = [] yield self._set_req_rsp(device, action, dn_req, 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" 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 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) 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=RuleClauses['C-VLAN Tag'], fieldinstance=0, operator=RuleOperators['=='], 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=RuleClauses['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=RuleClauses['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)) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) up_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) else: raise NotImplementedError('unsupported-action-set-field-type={}'.format(field.type)) else: raise NotImplementedError('unsupported-action-type={}'.format(action.type)) up_req /= PortIngressRuleTerminator() up_req /= AddPortIngressRule() # send message action = "Set ONU US Rule" rc = [] yield self._set_req_rsp(device, action, up_req, 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 ####') dn_req /= PortIngressRuleClauseMatchLength02(fieldcode=RuleClauses['C-VLAN Tag'], fieldinstance=0, operator=RuleOperators['=='], match=_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 ####') # TODO - This is not the correct operation for a POP operation. # This should be a Delete result dn_req /= PortIngressRuleResultReplace(fieldcode=RuleClauses['C-VLAN Tag']) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) dn_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) elif action.type == PUSH_VLAN: log.info('#### action.type == PUSH_VLAN ####') if action.push.ethertype != 0x8100: raise NotImplementedError('unhandled-ether-type={}'.format(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)) # TODO - Currently only support setting the VID in the DS to zero (clearing the VID) if ((field.vlan_vid & 0xfff) == 0): dn_req /= PortIngressRuleResultReplace(fieldcode=RuleClauses['C-VLAN Tag']) # need to convert value in Set to a variable length value ctagStr = struct.pack('>H', (field.vlan_vid & 0xfff)) dn_req /= PortIngressRuleResultSet( fieldcode=RuleClauses['C-VLAN Tag'], value=ctagStr) else: raise NotImplementedError('unsupported-set-vlan-id={}'.format(field.vlan_vid & 0xfff)) else: raise NotImplementedError('unsupported-action-set-field-type={}'.format(field.type)) else: raise NotImplementedError('unsupported-action-type={}'.format(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" # send message rc = [] yield self._set_req_rsp(device, action, dn_req, 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('########################################')