def PhdrUnitSet(self, csum_unit): ''' Csum Engine Unit which uses this pseudo hdr ''' ncc_assert(self.phdr_unit == -1 or \ self.phdr_unit == csum_unit) self.phdr_unit = csum_unit
def PhdrValidSet(self, v): #Before setting obj as phdr valid, make sure its invalid with ncc_assert(check.) ncc_assert(self.phdr_vld == 0) self.phdr_vld = v if self.phdr_vld: self.phdr_only = True else: self.phdr_only = False
def PhdrProfileBuild(self, parse_state, phdr_profile_obj, add_len): ''' Pseudo header of type based config for pulling phdr fields ''' log_str = '' log_str += 'Pseudo Header Profile Values\n' ncc_assert(len(self.phdr_fields) >= 3) if not isinstance(self.phdr_fields[0], int): phdr_field = self.phdr_fields[0] phdr_profile_obj.fld0_en = 1 phdr_profile_obj.fld0_start = (phdr_field.offset + 7) / 8 phdr_profile_obj.fld0_end = ( (phdr_field.offset + phdr_field.width + 7) / 8) - 1 phdr_profile_obj.fld0_add_len = add_len # Adds 16b len field # to phdr only in case of TCP # (TCP hdr no payload len field) phdr_profile_obj.fld0_align = 0 if (phdr_field.offset % 16 == 0 and \ (phdr_field.offset + phdr_field.width) % 16 == 0) else 1 if not isinstance(self.phdr_fields[1], int): phdr_field = self.phdr_fields[1] phdr_profile_obj.fld1_en = 1 phdr_profile_obj.fld1_start = (phdr_field.offset + 7) / 8 phdr_profile_obj.fld1_end = ( (phdr_field.offset + phdr_field.width + 7) / 8) - 1 phdr_profile_obj.fld1_add_len = 0 phdr_profile_obj.fld1_align = 0 if (phdr_field.offset % 16 == 0 and \ (phdr_field.offset + phdr_field.width) % 16 == 0) else 1 if not isinstance(self.phdr_fields[2], int): phdr_field = self.phdr_fields[2] phdr_profile_obj.fld2_en = 1 phdr_profile_obj.fld2_start = (phdr_field.offset + 7) / 8 phdr_profile_obj.fld2_end = ( (phdr_field.offset + phdr_field.width + 7) / 8) - 1 phdr_profile_obj.fld2_add_len = 0 phdr_profile_obj.fld2_align = 0 if (phdr_field.offset % 16 == 0 and \ (phdr_field.offset + phdr_field.width) % 16 == 0) else 1 log_str += ' Profile# %d\n' % phdr_profile_obj.phdr_profile log_str += ' fld0_en = %d\n' % phdr_profile_obj.fld0_en log_str += ' fld0_start = %d\n' % phdr_profile_obj.fld0_start log_str += ' fld0_end = %d\n' % phdr_profile_obj.fld0_end log_str += ' fld0_add_en= %d\n' % phdr_profile_obj.fld0_add_len log_str += ' fld0_align = %d\n' % phdr_profile_obj.fld0_align log_str += ' fld1_en = %d\n' % phdr_profile_obj.fld1_en log_str += ' fld1_start = %d\n' % phdr_profile_obj.fld1_start log_str += ' fld1_end = %d\n' % phdr_profile_obj.fld1_end log_str += ' fld1_add_en= %d\n' % phdr_profile_obj.fld1_add_len log_str += ' fld1_align = %d\n' % phdr_profile_obj.fld1_align log_str += ' fld2_en = %d\n' % phdr_profile_obj.fld2_en log_str += ' fld2_start = %d\n' % phdr_profile_obj.fld2_start log_str += ' fld2_end = %d\n' % phdr_profile_obj.fld2_end log_str += ' fld2_add_en= %d\n' % phdr_profile_obj.fld2_add_len log_str += ' fld2_align = %d\n' % phdr_profile_obj.fld2_align log_str += '\n' return log_str
def PayloadCsumProfileBuild(self, parse_state, csum_profile_obj, L4HdrType): log_str = '' log_str += 'Csum Profile Values\n' shift_left = 0 shift_val = 0 addsub_start = 0 start_adj = 0 addsub_phdr = 0 phdr_adj = 0 addsub_end = 0 end_adj = 0 if parse_state and parse_state.phdr_type == 'v4': log_str += ' PseudoHdr Type V4\n' addsub_end = 1 csum_profile_obj.CsumProfileShiftLeftSet(shift_left, shift_val) csum_profile_obj.CsumProfileStartAdjSet(addsub_start, start_adj) csum_profile_obj.CsumProfileEndAdjSet(addsub_end, end_adj) # Phdr start offset is same as IP hdr start offset csum_profile_obj.CsumProfilePhdrSet(addsub_phdr, phdr_adj) elif parse_state and parse_state.phdr_type == 'v6': log_str += ' PseudoHdr Type V6\n' addsub_end = 0 csum_profile_obj.CsumProfileShiftLeftSet(shift_left, shift_val) csum_profile_obj.CsumProfileStartAdjSet(addsub_start, start_adj) csum_profile_obj.CsumProfileEndAdjSet(addsub_end, end_adj) # Phdr start offset is same as IP hdr start offset csum_profile_obj.CsumProfilePhdrSet(addsub_phdr, phdr_adj) elif parse_state: ncc_assert(0) #One of the phdr fields (ipv4.protocol / ipv6.nextHdr) are programmed as constants. #The reason being when ipv6 options are present, protocol value ipv6.nextHdr is #in the last option's header. Since such phdr field is at variable length from #the start of IP header, this field is added as constant value depending on #L4 header is UDP/TCP. csum_profile_obj.CsumProfileConstantSet(L4HdrType) log_str += ' Shift Left = %d\n' % shift_left log_str += ' Shift Val = %d\n' % shift_val log_str += ' AddSubStart= %d\n' % addsub_start log_str += ' StartAdj = %d\n' % start_adj log_str += ' AddSubEnd = %d\n' % addsub_end log_str += ' EndAdj = %d\n' % end_adj log_str += ' AddSubPhdr = %d\n' % addsub_phdr log_str += ' PhdrAdj = %d\n' % phdr_adj log_str += ' Addvalue = 0x%x\n' % csum_profile_obj.CsumProfileConstantGet( ) log_str += '\n' return log_str
def setup_num_phv_flits(capri_model, num_flits): ncc_assert((num_flits % 2) == 0, "Only even number of phv flits is allowed") max_hw_flits = capri_model['phv']['max_hw_flits'] assert num_flits <= max_hw_flits, "Value must be less than %d" % max_hw_flits capri_model['phv']['num_flits'] = num_flits max_phv_bits = num_flits * 512 capri_model['phv']['max_size'] = max_phv_bits max_phv_bytes = max_phv_bits / 8 capri_model['phv']['containers'] = { 8: max_phv_bytes } # {size:num} all 8 bit containers capri_model['parser'][ 'parser_num_flits'] = capri_model['phv']['num_flits'] / 2
def build_field_dictionary(self): headers = self.be.parsers[self.d].headers for hdr in headers: current_field_type = self.field_type_none dp_hdr_fields = [ ] # (phv_chunk|ohi, type=field_type_phv|field_type_ohi, cf) cfields = [] ohi_fields = [] if hdr in self.be.parsers[self.d].ohi: ohi_list = list(self.be.parsers[self.d].ohi[hdr]) else: ohi_list = [] hdr_flds = self.be.pa.get_header_all_cfields(hdr, self.d) phv_chunks = self.be.pa.get_hdr_phv_chunks(hdr_flds, self.d, check_ohi=True) #check for byte alignment for pc in phv_chunks: if pc[0] % 8: ncc_assert(0) if (pc[1] % 8): ncc_assert(0) cur_offset = 0 for f in hdr.fields: cf = self.be.pa.gress_pa[self.d].get_field(get_hfname(f)) ncc_assert(cf, "unknown field %s" % (hdr.name + f.name)) field_byte_offset = cf.get_field_offset() / 8 if field_byte_offset < cur_offset: continue if cf.is_ohi: ohi = ohi_list.pop(0) ncc_assert(field_byte_offset == ohi.start) dp_hdr_fields.append((ohi, self.field_type_ohi, cf)) if (isinstance(ohi.length, int)): cur_offset += ohi.length else: pc = phv_chunks.pop(0) ncc_assert(pc[0] == cf.phv_bit) dp_hdr_fields.append((pc, self.field_type_phv, cf)) cur_offset += pc[1] / 8 self.topo_ordered_phv_ohi_chunks[hdr] = dp_hdr_fields # Some metadata like capri_i2e_metadata may or may not be present. Check for presence if self.be.pa.gress_pa[self.d].i2e_hdr: phv_chunks = self.be.pa.get_hdr_phv_chunks( self.be.pa.gress_pa[self.d].i2e_fields, self.d, check_ohi=False) #check for byte alignment for pc in phv_chunks: if pc[0] % 8: ncc_assert(0) if (pc[1] % 8): ncc_assert(0) phvchunklist = [] for chunks in phv_chunks: phvchunklist.append((chunks, self.field_type_phv, None)) self.topo_ordered_phv_ohi_chunks[self.be.pa.gress_pa[ self.d].i2e_hdr] = phvchunklist
def __init__(self, capri_be, dstField, UpdateFunc): self.be = capri_be self.logstr_tbl = [] self.dstField = dstField self.hdr_valid = -1 self.hdrfld_slot = -1 self.csum_hfield_name = '' # p4 Csum header.field name. self.csum_field_ohi_slot = -1 # Csum field location inside packet. self.gso_csum_result_fld_name = '' # Csum result variable name located in PHV self.gso_csum_result_phv = -1 # phv_bit# of parser computed csum result self.field_size = 2 # two bytes to replace (csum width) self.P4FieldListCalculation= self.be.h.\ p4_field_list_calculations\ [UpdateFunc] #P4 code should have atleast one input field list. ncc_assert(self.P4FieldListCalculation.input[0].fields[0] != None) #Check last input field and last field within the last input field #to determine 'payload' keyword is part of field list. self.payload_checksum = True\ if isinstance(\ self.P4FieldListCalculation.\ input[-1].fields[-1],\ p4.p4_header_keywords)\ else\ False if self.payload_checksum and 'checksum' in \ self.P4FieldListCalculation._parsed_pragmas.keys(): if 'update_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.gso_csum_result_fld_name = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['update_len'].keys()[0] else: ncc_assert(0) if 'gso_checksum_offset' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.csum_hfield_name = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['gso_checksum_offset'].keys()[0] ncc_assert(self.P4FieldListCalculation != None) ncc_assert(self.P4FieldListCalculation.algorithm == 'gso') ncc_assert(self.P4FieldListCalculation.output_width == 16) ncc_assert(self.csum_hfield_name != '') ncc_assert(self.payload_checksum)
def __init__(self, capri_be, dstField, VerifyOrUpdateFunc): self.be = capri_be self.logstr_tbl = [] self.dstField = dstField self.share_csum_engine_with = [] # list of other checksums with which # this csum object shares csum engine. self.csum_hdr_obj = None # Csum hdr obj which will # update cal fld self.csum_profile_obj = None # Csum profile obj that # csum unit will use self.phdr_profile_obj = None # In case of payload csum, # obj to build Phdr profile. self.phdr_csum_hdr_obj = None # Reference to phdr csum hdr obj # in case of payload checksum self.P4FieldListCalculation= self.be.h.\ p4_field_list_calculations\ [VerifyOrUpdateFunc] #P4 code should have atleast one input field list. ncc_assert(self.P4FieldListCalculation.input[0].fields[0] != None) #Check last input field and last field within the last input field #to determine 'payload' keyword is part of field list. self.payload_checksum = True\ if isinstance(\ self.P4FieldListCalculation.\ input[-1].fields[-1],\ p4.p4_header_keywords)\ else\ False self.no_phdr_in_checksum = True\ if isinstance(self.P4FieldListCalculation.\ input[0].fields[0], \ p4.p4_header_keywords)\ else\ False self.payload_checksum = False if self.no_phdr_in_checksum else self.payload_checksum #Find pseudo header associated with payload checksum if self.payload_checksum and 'checksum' in \ self.P4FieldListCalculation._parsed_pragmas.keys(): if 'update_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.payload_update_len_field = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['update_len'].keys()[0] self.phdr_name, self.phdr_type, self.payload_hdr_type, self.phdr_fields = \ self.be.checksum.ProcessCalFields(\ self.P4FieldListCalculation,\ self.dstField) if self.P4FieldListCalculation.algorithm == 'l2_complete_csum': #This is not regular payload checksum. Hence clear payload checksum self.payload_checksum = False else: self.phdr_name = '' self.phdr_type = '' self.payload_hdr_type = '' self.phdr_fields = None self.payload_update_len_field = '' if 'checksum' in \ self.P4FieldListCalculation._parsed_pragmas.keys(): if 'update_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.payload_update_len_field = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['update_len'].keys()[0] if 'checksum' in self.P4FieldListCalculation._parsed_pragmas.keys() and \ 'udp_option' in self.P4FieldListCalculation._parsed_pragmas['checksum']: self.payload_checksum = False self.option_checksum = True else: self.option_checksum = False ncc_assert(self.P4FieldListCalculation != None) ncc_assert(self.P4FieldListCalculation.algorithm == 'csum16' or \ self.P4FieldListCalculation.algorithm == 'csum8' or \ self.P4FieldListCalculation.algorithm == 'l2_complete_csum') if 'checksum' in self.P4FieldListCalculation._parsed_pragmas.keys() and \ 'update_share' in self.P4FieldListCalculation._parsed_pragmas['checksum']: self.share_csum_engine_with = get_pragma_param_list(self.P4FieldListCalculation.\ _parsed_pragmas['checksum']['update_share']) else: self.share_csum_engine_with = []
def PhdrProfileNumSet(self, p): ncc_assert(self.phdr_profile == -1) ncc_assert(p != -1) self.phdr_profile = p
def __init__(self, capri_be, dstField, UpdateFunc): self.be = capri_be self.logstr_tbl = [] self.dstField = dstField self.parser_csum_obj = None # GSO Csum unit obj which will # verify cal fld self.parser_csum_profile_obj = None # GSO Csum profile obj that # csum unit will use self.gso_parse_states = None # Reference to List of Parser # states gso_header is extracted self.P4FieldListCalculation = self.be.h.\ p4_field_list_calculations\ [UpdateFunc] #P4 code should have atleast one input field list. ncc_assert(self.P4FieldListCalculation.input[0].fields[0] != None) self.gso_start_field = self.P4FieldListCalculation.input[0].fields[ 0].name #Check last input field and last field within the last input field #to determine 'payload' keyword is part of field list. self.payload_checksum = True\ if isinstance(\ self.P4FieldListCalculation.\ input[-1].fields[-1],\ p4.p4_header_keywords)\ else\ False if self.payload_checksum and 'checksum' in \ self.P4FieldListCalculation._parsed_pragmas.keys(): if 'update_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.gso_csum_result_fld_name = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['update_len'].keys()[0] else: ncc_assert(0) if 'gso_checksum_offset' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.csum_hfield_name = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['gso_checksum_offset'].keys()[0] ncc_assert(self.P4FieldListCalculation != None) ncc_assert(self.P4FieldListCalculation.algorithm == 'gso') ncc_assert(self.P4FieldListCalculation.output_width == 16) ncc_assert(self.csum_hfield_name != '') ncc_assert(self.payload_checksum)
def __init__(self, capri_be, dstField, VerifyOrUpdateFunc): self.be = capri_be self.logstr_tbl = [] self.dstField = dstField self.parser_csum_obj = None # Csum unit obj which will # verify cal fld self.parser_csum_profile_obj = None # Csum profile obj that # csum unit will use self.parser_phdr_profile_obj = None # In case of payload csum, # obj to build Phdr self.phdr_ohi_sel = -1 # This value will be set to valid # value only in the case where # payload checksum is computed but # not IP hdr checksum. self.phdr_parse_states = None # Reference to List of Parser # states where phdr fields # are extracted/built. self.phdr_name = '' self.phdr_type = '' self.payload_hdr_type = '' self.l4_verify_len_field = '' self.hdrlen_verify_field = '' self.P4FieldListCalculation = self.be.h.\ p4_field_list_calculations\ [VerifyOrUpdateFunc] #P4 code should have atleast one input field list. ncc_assert(self.P4FieldListCalculation.input[0].fields[0] != None) #Check last input field and last field within the last input field #to determine 'payload' keyword is part of field list. self.payload_checksum = True\ if isinstance(\ self.P4FieldListCalculation.\ input[-1].fields[-1],\ p4.p4_header_keywords)\ else\ False if 'checksum' in self.P4FieldListCalculation._parsed_pragmas.keys() and \ 'udp_option' in self.P4FieldListCalculation._parsed_pragmas['checksum']: self.payload_checksum = False self.option_checksum = True else: self.option_checksum = False #Find pseudo header associated with payload checksum if self.payload_checksum and 'checksum' in \ self.P4FieldListCalculation._parsed_pragmas.keys(): if 'verify_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.l4_verify_len_field = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['verify_len'].keys()[0] self.phdr_name, self.phdr_type, self.payload_hdr_type, self.phdr_fields = \ self.be.checksum.ProcessCalFields(\ self.P4FieldListCalculation,\ self.dstField) ncc_assert(self.l4_verify_len_field != '') elif 'checksum' in self.P4FieldListCalculation._parsed_pragmas.keys(): if 'hdr_len_expr' in self.P4FieldListCalculation.\ _parsed_pragmas['checksum'].keys(): self.hdrlen_verify_field = \ self.P4FieldListCalculation.\ _parsed_pragmas['checksum']['hdr_len_expr'].keys()[0] param_list = get_pragma_param_list(self.P4FieldListCalculation.\ _parsed_pragmas['checksum']['hdr_len_expr']) self.end_adj_const = int(param_list[2]) ncc_assert(param_list[1] == '+') if 'verify_len' in \ self.P4FieldListCalculation._parsed_pragmas['checksum']: self.l4_verify_len_field = self.P4FieldListCalculation._parsed_pragmas\ ['checksum']['verify_len'].keys()[0] #ncc_assert(self.hdrlen_verify_field != '') ncc_assert(self.l4_verify_len_field != '') ncc_assert(self.P4FieldListCalculation != None) ncc_assert(((self.P4FieldListCalculation.algorithm == 'csum16') \ or (self.P4FieldListCalculation.algorithm == 'csum8')))
def log2(x): ncc_assert((x != 0)) log = log2size(x) ncc_assert(x == 1 << log, 'Only log of powers of 2 allowed') return log