def ReceiveICRQ(self, pkt): """Receive a ICRQ from remote, if it is a good ICRQ, will send a ICRP. :param pkt: The ICRQ control packet, has been decoded. :return: ICRP packet or None """ if L2tpv3GlobalSettings.L2tpv3GlobalSettings.MustAvpsCheck is True: ret = self.connection.checkMustAvps( L2tpv3ControlPacket.L2tpv3ControlPacket.ICRQMandatoryAVPs, pkt.avps) if ret is not True: self.fsm.recvBadICRQ() return L2tpv3ControlPacket.L2tpv3CDN( self, 2, 4, "Avp cannot be handled correctly") self.logger.debug("L2tp session[%d, %d] receives a ICRQ message.", self.localSessionId, self.remoteSessionId) avps = list() avps.append( L2tpv3RFC3931AVPs.ControlMessageAVP( L2tpv3RFC3931AVPs.ControlMessageAVP.ICRP)) avps.append( L2tpv3RFC3931AVPs.DataSequencing( L2tpv3RFC3931AVPs.DataSequencing.AllSeq)) # TODO add sbfd support for ipv6 if Convert.is_valid_ipv4_address(self.connection.localAddr): avps.append( L2tpv3RFC3931AVPs.SbfdDiscriminator( int( socket.inet_aton( self.connection.localAddr).encode('hex'), 16))) avps.append( L2tpv3RFC3931AVPs.SbfdVccv( L2tpv3RFC3931AVPs.SbfdVccv.VccvValue)) # Need add some Cable labs avp self.logger.debug( "Session [%d, %d]sends a ICRP packet to remote, connection:%d", self.localSessionId, self.remoteSessionId, pkt.Connection.remoteConnID) icrp = L2tpv3ControlPacket.L2tpv3ControlPacket( pkt.Connection.remoteConnID, 0, 0, avps) del self.avps_icrq[:] del self.mcast[:] if len(pkt.avps) > 1: for i in xrange(1, len(pkt.avps)): avp = pkt.avps[i] if isinstance( avp, L2tpv3CableLabsAvps.DepiL2SpecificSublayerSubtype): self.session_l2Sublayer = avp.pw_type self.avps_icrq.append(avp) # We got a bad ICRQ, we should send a CDN if not avp.handleAvp(pkt, icrp): self.fsm.recvBadICRQ() return L2tpv3ControlPacket.L2tpv3CDN( self, 2, 4, "Avp cannot be handled correctly") self.logger.debug("We got a good ICRQ, send to fsm") self.fsm.recvGoodICRQ() return icrp
int(ip_bytes[3]) > 0 and int(ip_bytes[3]) != 255: return True return False if __name__ == "__main__": if len(sys.argv) <= 1: print "Please specify ipv4 or ipv6\n" print "EXAMPLE:\n" print "python L2tpv3MasterSim.py ipv4 <remote IP> <local IP>\n" sys.exit(False) if sys.argv[1] != 'ipv4' and sys.argv[1] != 'ipv6': print "Please specify ipv4 or ipv6" sys.exit(False) if sys.argv[1] == 'ipv4': if len(sys.argv) > 2 and Convert.is_valid_ipv4_address(sys.argv[2]): RemoteIPAddress = sys.argv[2] else: RemoteIPAddress = "127.0.0.1" if len(sys.argv) > 3 and Convert.is_valid_ipv4_address(sys.argv[3]): LocalIPAddress = sys.argv[3] else: LocalIPAddress = "127.0.0.1" for intf in net_if_addrs().values(): (family, addr, mask) = (intf[0][0], intf[0][1], intf[0][2]) if family == 2: addr_b = addr.split(".") mask_b = mask.split(".") raddr_b = RemoteIPAddress.split(".") if int(addr_b[0]) & int(mask_b[0]) == int(raddr_b[0]) & int(mask_b[0]) and \
def _get_intf_ip_address(): output = check_output(['uci', 'show', 'network.lan.ipaddr']) ip_addr = output.strip().split('=')[1].split('\'')[1] return ip_addr if Convert.is_valid_ipv4_address(ip_addr) else None
def handle_msg_eds_req(self, msg, slave, pkt): """Handles GCP EDS REQ message. :param msg: The GCP EDS REQ message :type msg: Message :param slave: The RCP slave sessions on which the message has been received. :type slave: RCPSlaveSession :param pkt: The RCP packet where the message was encapsulated :type pkt: RCPPacket :return: """ seq_list = [] for rcp_msg in msg.tlv_data.rcp_msgs: for seq in rcp_msg.sequences: # Handle special messages including redirect # and CCAP Capabilities and ssd if rcp_msg.rcp_message_id == rcp_tlv_def.RCP_MSG_TYPE_IRA: if slave.is_ira_recv == False: slave.is_ira_recv = True self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), msg_type=t_RcpMessage.IRA_RECEIVED) if rcp_msg.rcp_message_id == rcp_tlv_def.RCP_MSG_TYPE_REX: if slave.is_rex_recv == False: slave.is_rex_recv = True self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), msg_type=t_RcpMessage.REX_RECEIVED) if seq.parent_gpb.HasField("Ssd"): self.logger.info("Handling Ssd received at %s" % slave.get_descriptor()) if (not slave.ccap_identification.is_active) \ or (not slave.ccap_identification.is_principal): self.logger.debug( "Ssd received from non active %d or non principal %d ", slave.ccap_identification.is_active, slave.ccap_identification.is_principal) try: resp = self.pkt_director.get_positive_rsp_packets( slave, pkt) except Exception as ex: self.logger.warning( "Got exception when constructing ssd rsp packet: %s", str(ex)) raise if 1 != len(resp): raise RCPMSGHandlingError( "Invalid packet response returned by director") resp = resp[0] try: slave.io_ctx.add_tx_packet(resp) self.logger.debug("send ssd response") except GCPSessionFull: self.logger.error( "GCP session tx full, failed to send SSD response msg" ) raise continue if len(seq.parent_gpb.RpdRedirect) > 0: self.logger.info("Handling redirect received at %s" % slave.get_descriptor()) # handle redirect and drop all next data addr_list = [] for redir_item in seq.parent_gpb.RpdRedirect: ip_addr = redir_item.RedirectIpAddress addr_family = (socket.AF_INET if Convert.is_valid_ipv4_address(ip_addr) else socket.AF_INET6) addr_list.append((ip_addr, addr_family)) # send redirect response try: resp = self.pkt_director.get_positive_rsp_packets( slave, pkt) except Exception as ex: self.logger.warning( "Got exception when constructing redirect rsp packet: %s", str(ex)) raise if 1 != len(resp): raise RCPMSGHandlingError( "Invalid packet response returned by director") resp = resp[0] try: slave.io_ctx.add_tx_packet(resp) except GCPSessionFull: self.logger.error( "GCP session tx full, failed to send redirect response msg" ) raise slave.dispatcher.fd_modify(slave.get_socket_fd(), slave.dispatcher.MASK_WR_ERR) self.logger.debug("Response to redirect added to TX queue") try: self.callback_set.redirect_received(slave, addr_list) except Exception as ex: self.logger.warning( "Got exception when handling redirect msg: %s", str(ex)) raise continue if len(seq.parent_gpb.CcapCoreIdentification) > 0: index = -1 identRecord = CcapCoreIdentification() self.logger.info("Handling CcapCoreIdentification update") ccap_caps = seq.parent_gpb.CcapCoreIdentification[0] self.logger.debug("msg is: %s", ccap_caps) op = seq.operation if len(seq.parent_gpb.CcapCoreIdentification) > 1: self.logger.warning( "Only one instance of CCAP caps is expected, but received: %u", len(seq.parent_gpb.CcapCoreIdentification)) core_ip = slave.get_descriptor().addr_remote if ccap_caps.HasField("CoreIpAddress"): core_ip = Convert.format_ip(ccap_caps.CoreIpAddress) ip = Convert.format_ip(ccap_caps.CoreIpAddress) if op == rcp_tlv_def.RCP_OPERATION_TYPE_WRITE: if ccap_caps.HasField("Index"): index = ccap_caps.Index identRecord.index = index identRecord.read() else: self.logger.warning( "RCP write type %d should include index", op) self.pkt_director.send_eds_response_directly( slave, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), seq, False) continue elif op == rcp_tlv_def.RCP_OPERATION_TYPE_ALLOCATE_WRITE: identRecord.allocateIndex(core_ip) ccap_caps.Index = identRecord.index elif op == rcp_tlv_def.RCP_OPERATION_TYPE_READ: seq_list.append(seq) continue identRecord.core_ip_addr = core_ip if ccap_caps.HasField("IsPrincipal"): self.logger.info( "Received NotifyRSP from CCAP core is_principal[%s]", ccap_caps.IsPrincipal) identRecord.is_principal = True if ccap_caps.IsPrincipal else False self.logger.debug( "CcapCoreIdentification operation=%d index=%d", op, ccap_caps.Index) if ccap_caps.HasField("CoreId"): identRecord.core_id = ccap_caps.CoreId if ccap_caps.HasField("CoreName"): identRecord.core_name = ccap_caps.CoreName if ccap_caps.HasField("VendorId"): identRecord.vendor_id = ccap_caps.VendorId if ccap_caps.HasField("CoreMode"): identRecord.core_mode = ccap_caps.CoreMode identRecord.is_active = ccap_caps.CoreMode is t_CcapCoreIdentification.COREMODEACTIVE if ccap_caps.HasField("InitialConfigurationComplete"): identRecord.initial_configuration_complete = ccap_caps.InitialConfigurationComplete if ccap_caps.HasField("MoveToOperational"): identRecord.move_to_operational = ccap_caps.MoveToOperational if ccap_caps.HasField("CoreFunction"): identRecord.core_function = ccap_caps.CoreFunction if ccap_caps.HasField("ResourceSetIndex"): identRecord.resource_set_index = ccap_caps.ResourceSetIndex if op in [ rcp_tlv_def.RCP_OPERATION_TYPE_WRITE, rcp_tlv_def.RCP_OPERATION_TYPE_ALLOCATE_WRITE ]: identRecord.write() self.logger.debug( "Core ident DB save index =%d core_ip_addr=%s op=%d", identRecord.index, identRecord.core_ip_addr, op) # Set the ccap core Identification into the slave session slave.ccap_identification = identRecord # call CCAP caps update callback self.callback_set.ccap_identification_update(slave) try: self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val()) except Exception as ex: self.logger.warning( "Got exception when handling core identification msg: %s", str(ex)) raise if seq.parent_gpb.HasField('RpdConfigurationDone'): self.logger.info( "Handling configuration done message to MGR") self.pkt_director.send_eds_response_directly( slave, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), seq) try: self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), msg_type=t_RcpMessage.RPD_CONFIGURATION_DONE) except Exception as ex: self.logger.warning( "Got exception when handling cfg_done msg: %s", str(ex)) raise continue if seq.parent_gpb.HasField('RpdGlobal'): if slave.ccap_identification.is_principal and slave.ccap_identification.is_active: self.logger.info( "Receive RpdGlobal message from active principal core via session %s", slave.get_descriptor()) else: self.logger.info( "Receive RpdGlobal message from non active principal core via session %s", slave.get_descriptor()) self.pkt_director.send_eds_response_directly( slave, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), seq) continue if len(seq.parent_gpb.ConfiguredCoreTable) > 0: self.logger.info( "Handling configuration core table message to MGR") self.pkt_director.send_eds_response_directly( slave, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), seq) try: self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val()) except Exception as ex: self.logger.warning( "Got exception when handling core_table msg: %s", str(ex)) raise continue if seq.parent_gpb.HasField('MultiCore'): self.logger.info( "Handling MultiCore configuration msg is_principal=%d is_active=%d", slave.ccap_identification.is_principal, slave.ccap_identification.is_active) # ****** temporary 4 line hack follows to work around # ****** the issue described in C3RPHY-122 resource_set_index = 0 for resource_set in seq.parent_gpb.MulitCore.ResourceSet: resource_set.ResourceSetIndex = resource_set_index resource_set_index = resource_set_index + 1 # ****** end of 4 line hack to get around C3RPHY-122 self.pkt_director.send_eds_response_directly( slave, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val(), seq) try: self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val()) except Exception as ex: self.logger.warning( "Got exception when handling MultiCore msg: %s", str(ex)) raise continue if seq.parent_gpb.HasField('ActivePrincipalCore'): self.logger.info( "Handling get active principal request on session %s", slave.get_descriptor()) try: self.callback_set.configuration_to_rcp_wrapper( slave, seq, pkt.transaction_identifier, msg.msg_fields.TransactionID.get_val()) except Exception as ex: self.logger.warning( "Got exception when handling Active Principal core msg: %s", str(ex)) raise continue seq_list.append(seq) if not seq_list: self.logger.info("EDS message without any RCPSequence received") return try: self.callback_set.configuration_operation( session=slave, rcp_sequence_list=seq_list, pkt_req=pkt, gcp_msg=msg) except Exception as ex: # TODO we need to handle failures with a granularity self.logger.error("Failed to process configuration: %s", ex) import traceback self.logger.error(traceback.format_stack()) raise RCPMSGHandlingError()