Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #6
0
    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
Beispiel #7
0
    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)
Beispiel #8
0
    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 = []
Beispiel #9
0
 def PhdrProfileNumSet(self, p):
     ncc_assert(self.phdr_profile == -1)
     ncc_assert(p != -1)
     self.phdr_profile = p
Beispiel #10
0
    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)
Beispiel #11
0
    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')))
Beispiel #12
0
def log2(x):
    ncc_assert((x != 0))
    log = log2size(x)
    ncc_assert(x == 1 << log, 'Only log of powers of 2 allowed')
    return log