コード例 #1
0
ファイル: p4_parser.py プロジェクト: hanw/p4-hlir
    def build(self, hlir):
        for idx, set_statement in enumerate(self.set_statements):
            metadata_field_ref = set_statement[1]
            metadata_value = set_statement[2]
                
            metadata_field_ref = p4_field_reference(hlir, metadata_field_ref)
                
            # metadata_value can either be latest.*, or *.* or int or
            # (*, *) (for current)
            if type(metadata_value) is int:
                metadata_value = metadata_value
            elif type(metadata_value) is tuple:
                metadata_value = (metadata_value[1], metadata_value[2])
            elif type(metadata_value) is str:
                hdr, field = metadata_value.split(".")
                if hdr == "latest":
                    metadata_value = p4_field_reference(
                        hlir, 
                        self.latest_extraction.name + "." + field
                    )
                else:
                    metadata_value = p4_field_reference(hlir, metadata_value)
            else:
                assert(False)

            self.set_statements[idx] = (parse_call.set, metadata_field_ref, metadata_value)
            
        if self.return_or_drop != P4_PARSER_DROP:
            self.return_or_drop = hlir.p4_control_flows[self.return_or_drop]
コード例 #2
0
ファイル: p4_parser.py プロジェクト: orNvidia/p4-hlir
    def build(self, hlir):
        for idx, set_statement in enumerate(self.set_statements):
            metadata_field_ref = set_statement[1]
            metadata_value = set_statement[2]
                
            metadata_field_ref = p4_field_reference(hlir, metadata_field_ref)
                
            # metadata_value can either be latest.*, or *.* or int or
            # (*, *) (for current)
            if type(metadata_value) is int:
                metadata_value = metadata_value
            elif type(metadata_value) is tuple:
                metadata_value = (metadata_value[1], metadata_value[2])
            elif type(metadata_value) is str:
                hdr, field = metadata_value.split(".")
                if hdr == "latest":
                    metadata_value = p4_field_reference(
                        hlir, 
                        self.latest_extraction.name + "." + field
                    )
                else:
                    metadata_value = p4_field_reference(hlir, metadata_value)
            else:
                assert(False)

            self.set_statements[idx] = (parse_call.set, metadata_field_ref, metadata_value)
            
        if self.return_or_drop != P4_PARSER_DROP:
            self.return_or_drop = hlir.p4_control_flows[self.return_or_drop]
コード例 #3
0
    def build_return(self, hlir):
        return_type = self.return_statement[0]
        if return_type == "immediate":
            next_state = self.resolve_parse_target(hlir,
                                                   self.return_statement[1])

            self.branch_on = []
            self.branch_to = OrderedDict({P4_DEFAULT: next_state})
        elif return_type == "select":
            select_exp = self.return_statement[1]
            select_cases = self.return_statement[2]

            # select_exp is a list of field_references
            self.branch_on = []
            for field_ref in select_exp:
                if type(field_ref) is tuple:  # current
                    field_ref = (field_ref[0], field_ref[1])
                elif field_ref[:6] == "latest":
                    field_ref = p4_field_reference(
                        hlir,
                        self.latest_extraction.name + "." + field_ref[7:])
                elif "." in field_ref:
                    field_ref = p4_field_reference(hlir, field_ref)

                self.branch_on.append(field_ref)

            self.branch_to = OrderedDict()
            for case in select_cases:
                value_list = case[0]
                next_state = self.resolve_parse_target(hlir, case[1])

                for value_or_masked in value_list:
                    value_type = value_or_masked[0]
                    if value_type == "value_set":
                        # still need to check that this is a valid reference
                        value_set_name = value_or_masked[1]
                        branch_case = hlir.p4_parse_value_sets[value_set_name]
                    elif value_type == "default":
                        branch_case = P4_DEFAULT
                    elif value_type == "value":
                        branch_case = value_or_masked[1]
                    elif value_type == "masked_value":
                        branch_case = (value_or_masked[1], value_or_masked[2])

                    self.branch_to[branch_case] = next_state

        else:
            assert (False)
コード例 #4
0
ファイル: p4_parser.py プロジェクト: hanw/p4-hlir
    def build_return (self, hlir):
        return_type = self.return_statement[0]
        if return_type == "immediate":
            next_state = self.resolve_parse_target(hlir, self.return_statement[1])

            self.branch_on = []
            self.branch_to = OrderedDict({P4_DEFAULT:next_state})
        elif return_type == "select":
            select_exp = self.return_statement[1]
            select_cases = self.return_statement[2]
            
            # select_exp is a list of field_references
            self.branch_on = []
            for field_ref in select_exp:
                if type(field_ref) is tuple: # current
                    field_ref = (field_ref[0], field_ref[1])
                elif field_ref[:6] == "latest":
                    field_ref = p4_field_reference(
                        hlir,
                        self.latest_extraction.name + "." + field_ref[7:]
                    )
                elif "." in field_ref:
                    field_ref = p4_field_reference(hlir, field_ref)

                self.branch_on.append(field_ref)
            
            self.branch_to = OrderedDict()
            for case in select_cases:
                value_list = case[0]
                next_state = self.resolve_parse_target(hlir, case[1])

                for value_or_masked in value_list:
                    value_type = value_or_masked[0]
                    if value_type == "value_set":
                        # still need to check that this is a valid reference
                        value_set_name = value_or_masked[1]
                        branch_case = hlir.p4_parse_value_sets[value_set_name]
                    elif value_type == "default":
                        branch_case = P4_DEFAULT
                    elif value_type == "value":
                        branch_case = value_or_masked[1]
                    elif value_type == "masked_value":
                        branch_case = (value_or_masked[1], value_or_masked[2])

                    self.branch_to[branch_case] = next_state

        else:
            assert(False)
コード例 #5
0
 def build(self, hlir):
     self.register = p4_stateful.p4_register.get_from_hlir(
         hlir, self.register_name)
     # I thought this was done earlier but it appears that string idices are
     # never resolved before this point
     if type(self.idx) is str:
         self.idx = p4_headers.p4_field_reference(hlir, self.idx)
コード例 #6
0
    def build_body(self, hlir):
        for idx, call in enumerate(self.call_sequence):
            call_type = call[0]
            if call_type == "extract":
                extract_ref = call[1]

                extract_ref = hlir.p4_header_instances[extract_ref]

                self.latest_extraction = extract_ref
                self.call_sequence[idx] = (parse_call.extract, extract_ref)

            elif call_type == "set_metadata":
                metadata_field_ref = call[1]
                metadata_value = call[2]

                metadata_field_ref = p4_field_reference(
                    hlir, metadata_field_ref)

                # metadata_value can either be latest.*, or *.* or int or
                # (*, *) (for current)
                if type(metadata_value) is int:
                    metadata_value = metadata_value
                elif type(metadata_value) is tuple:
                    metadata_value = (metadata_value[1], metadata_value[2])
                elif type(metadata_value) is str:
                    hdr, field = metadata_value.split(".")
                    if hdr == "latest":
                        metadata_value = p4_field_reference(
                            hlir, self.latest_extraction.name + "." + field)
                    else:
                        metadata_value = p4_field_reference(
                            hlir, metadata_value)
                elif type(metadata_value) is p4_expression:
                    metadata_value = metadata_value
                    metadata_value.resolve_names(hlir)
                else:
                    print type(metadata_value)
                    assert (False)

                self.call_sequence[idx] = (parse_call.set, metadata_field_ref,
                                           metadata_value)
コード例 #7
0
ファイル: p4_parser.py プロジェクト: hanw/p4-hlir
    def build_body (self, hlir):
        for idx, call in enumerate(self.call_sequence):
            call_type = call[0]
            if call_type == "extract":
                extract_ref = call[1]
                
                extract_ref = hlir.p4_header_instances[extract_ref]
                
                self.latest_extraction = extract_ref
                self.call_sequence[idx] = (parse_call.extract, extract_ref)

            elif call_type == "set_metadata":
                metadata_field_ref = call[1]
                metadata_value = call[2]
                
                metadata_field_ref = p4_field_reference(hlir, metadata_field_ref)
                
                # metadata_value can either be latest.*, or *.* or int or
                # (*, *) (for current)
                if type(metadata_value) is int:
                    metadata_value = metadata_value
                elif type(metadata_value) is tuple:
                    metadata_value = (metadata_value[0], metadata_value[1])
                elif type(metadata_value) is str:
                    hdr, field = metadata_value.split(".")
                    if hdr == "latest":
                        metadata_value = p4_field_reference(
                            hlir, 
                            self.latest_extraction.name + "." + field
                        )
                    else:
                        metadata_value = p4_field_reference(hlir, metadata_value)
                elif type(metadata_value) is p4_expression:
                    metadata_value = metadata_value
                    metadata_value.resolve_names(hlir)
                else:
                    print type(metadata_value)
                    assert(False)

                self.call_sequence[idx] = (parse_call.set, metadata_field_ref, metadata_value)
コード例 #8
0
ファイル: p4_parser.py プロジェクト: orNvidia/p4-hlir
    def build_return (self, hlir):
        return_type = self.return_statement[0]
        if return_type == "immediate":
            next_state = self.resolve_parse_target(hlir, self.return_statement[1])

            self.branch_on = []
            self.branch_to = OrderedDict({P4_DEFAULT:next_state})
        elif return_type == "select":
            select_exp = self.return_statement[1]
            select_cases = self.return_statement[2]
            
            # select_exp is a list of field_references
            self.branch_on = []
            self.bitwidths = []
            for field_ref in select_exp:
                if type(field_ref) is tuple: # current
                    field_ref = (field_ref[0], field_ref[1])
                    self.bitwidths.append(field_ref[1])
                elif field_ref[:6] == "latest":
                    field_ref = p4_field_reference(
                        hlir,
                        self.latest_extraction.name + "." + field_ref[7:]
                    )
                    self.bitwidths.append(field_ref.width)
                elif "." in field_ref:
                    field_ref = p4_field_reference(hlir, field_ref)
                    self.bitwidths.append(field_ref.width)

                self.branch_on.append(field_ref)

            self.branch_to = OrderedDict()
            normalized_values = []
            def mask():
                width = sum(self.bitwidths)
                return (1 << width) - 1
            def normalize(value):
                return value & mask()

            def validate_normalized(normalized, original):
                if P4_DEFAULT in normalized_values:
                    p4_compiler_msg(
                        "Select case '{}' in state '{}' appears after 'default' case and will be ignored".format(original, self.name),
                        self.filename, self.lineno, logging.WARN)
                    return False
                if normalized == P4_DEFAULT:
                    return True
                if isinstance(normalized, p4_parse_value_set):
                    if normalized in normalized_values:
                        p4_compiler_msg(
                            "Select case '{}' in state '{}' is a duplicate and will be ignored".format(original, self.name),
                            self.filename, self.lineno, logging.WARN)
                        return False
                    return True
                for existing in normalized_values:
                    if isinstance(existing, p4_parse_value_set):
                        continue

                    v1, m1 = existing
                    v2, m2 = normalized
                    # This is not complete; detecting that "v2 mask m2" is
                    # included in "v1 mask m1" is non-trivial so we only check
                    # for the most basic case
                    if ((v2 & m1) == (v1 & m1)) and m2 == mask():
                        p4_compiler_msg(
                            "Select case '{}' in state '{}' is redundant with a previous one and will be ignored".format(original, self.name),
                            self.filename, self.lineno, logging.WARN)
                        return False
                return True

            for case in select_cases:
                value_list = case[0]
                next_state = self.resolve_parse_target(hlir, case[1])

                for value_or_masked in value_list:
                    value_type = value_or_masked[0]
                    if value_type == "value_set":
                        # still need to check that this is a valid reference
                        value_set_name = value_or_masked[1]
                        branch_case = hlir.p4_parse_value_sets[value_set_name]
                        normalized = branch_case
                        original = value_set_name
                    elif value_type == "default":
                        branch_case = P4_DEFAULT
                        normalized = branch_case
                        original = "default"
                    elif value_type == "value":
                        branch_case = value_or_masked[1]
                        normalized = (normalize(value_or_masked[1]), mask())
                        original = "{}".format(value_or_masked[1])
                    elif value_type == "masked_value":
                        branch_case = (value_or_masked[1], value_or_masked[2])
                        normalized = (normalize(value_or_masked[1]),
                                      normalize(value_or_masked[2]))
                        original = "{} mask {}".format(
                            value_or_masked[1], value_or_masked[2])

                    if validate_normalized(normalized, original):
                        normalized_values.append(normalized)
                    # We should really not be adding this case to the branch_to
                    # dictionary if validate_normalized returned False. However,
                    # a lot of existing P4 code relies on so-called "dummy
                    # transitions" in parser states which happen after the
                    # DEFAULT transition. These dummy transitions are used to
                    # increase the number of edges in the parse graph and
                    # therefore constrain the topological sorting of headers
                    # which determines the deparser flow.
                    if branch_case not in self.branch_to:
                        self.branch_to[branch_case] = next_state

        else:
            assert(False)
コード例 #9
0
ファイル: p4_parser.py プロジェクト: oprsystem/P4_ROHC
    def build_body(self, hlir):
        for idx, call in enumerate(self.call_sequence):
            call_type = call[0]
            if call_type == "extract":
                extract_ref = call[1]

                extract_ref = hlir.p4_header_instances[extract_ref]

                self.latest_extraction = extract_ref
                self.call_sequence[idx] = (parse_call.extract, extract_ref)

            elif call_type == "set_metadata":
                metadata_field_ref = call[1]
                metadata_value = call[2]

                metadata_field_ref = p4_field_reference(
                    hlir, metadata_field_ref)

                # metadata_value can either be latest.*, or *.* or int or
                # (*, *) (for current)
                if type(metadata_value) is int:
                    metadata_value = metadata_value
                elif type(metadata_value) is tuple:
                    metadata_value = (metadata_value[0], metadata_value[1])
                elif type(metadata_value) is str:
                    hdr, field = metadata_value.split(".")
                    if hdr == "latest":
                        metadata_value = p4_field_reference(
                            hlir, self.latest_extraction.name + "." + field)
                    else:
                        metadata_value = p4_field_reference(
                            hlir, metadata_value)
                elif type(metadata_value) is p4_expression:
                    metadata_value = metadata_value
                    metadata_value.resolve_names(hlir)
                else:
                    print type(metadata_value)
                    assert (False)

                self.call_sequence[idx] = (parse_call.set, metadata_field_ref,
                                           metadata_value)
            elif call_type == "method":
                bbox = hlir.p4_extern_instances.get(call[1], None)
                if bbox:
                    method_obj = bbox.methods.get(call[2], None)
                    if method_obj:
                        call_args = call[3]
                        try:
                            method_obj.validate_arguments(hlir, call_args)
                        except p4_compiler_msg as p:
                            p.filename = self.filename
                            p.lineno = self.lineno
                            raise
                        self.call_sequence[idx] = (parse_call.method,
                                                   method_obj, call_args)
                    else:
                        raise p4_compiler_msg(
                            "Reference to undefined method '%s.%s'" %
                            (bbox.name, call[2]), self.filename, self.lineno)
                else:
                    raise p4_compiler_msg(
                        "Reference to undefined extern '%s'" % call[1],
                        self.filename, self.lineno)