Beispiel #1
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index, visited):
        assert (isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]
                # takes care of loops in parser (e.g. for TLV parsing)
                elif parse_state in visited:
                    return

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state:
                continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy(),
                     visited | {parse_state})

    start_state = hlir.p4_parse_states["start"]
    for pragma in start_state._pragmas:
        try:
            words = pragma.split()
            if words[0] != "header_ordering":
                continue
        except:  # pragma: no cover
            continue
        sorting = process_forced_header_ordering(hlir, words[1:])
        if sorting is None:  # pragma: no cover
            LOG_CRITICAL("invalid 'header_ordering' pragma")
        return sorting

    walk_rec(hlir, start_state, None, defaultdict(int), set())

    header_topo_sorting = header_graph.produce_topo_sorting()
    if header_topo_sorting is None:  # pragma: no cover
        LOG_CRITICAL("could not produce topo sorting because of cycles")

    return header_topo_sorting
Beispiel #2
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index, visited):
        assert(isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]
                # takes care of loops in parser (e.g. for TLV parsing)
                elif parse_state in visited:
                    return

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state:
                continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node,
                     tag_stacks_index.copy(), visited | {parse_state})

    start_state = hlir.p4_parse_states["start"]
    for pragma in start_state._pragmas:
        try:
            words = pragma.split()
            if words[0] != "header_ordering":
                continue
        except:  # pragma: no cover
            continue
        sorting = process_forced_header_ordering(hlir, words[1:])
        if sorting is None:  # pragma: no cover
            LOG_CRITICAL("invalid 'header_ordering' pragma")
        return sorting

    walk_rec(hlir, start_state, None, defaultdict(int), set())

    header_topo_sorting = header_graph.produce_topo_sorting()
    if header_topo_sorting is None:  # pragma: no cover
        LOG_CRITICAL("could not produce topo sorting because of cycles")

    return header_topo_sorting
Beispiel #3
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index):
        assert(isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr;
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state: continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy())


    start_state = hlir.p4_parse_states["start"]
    walk_rec(hlir, start_state, None, defaultdict(int))

    header_topo_sorting = header_graph.produce_topo_sorting()

    # topo_sorting = []
    # for hdr in header_topo_sorting:
    #     topo_sorting.append(get_header_instance_name(hdr))

    # dirty fix, to ensure that all tags in a stag are contiguous
    # this makes the (questionable) assumption that all those tags are
    # contiguous in the deparsed packet
    buckets = defaultdict(list)
    for header_instance in header_topo_sorting:
        base_name = header_instance.base_name
        buckets[base_name].append(header_instance)
    collapsed = []
    for header_instance in header_topo_sorting:
        base_name = header_instance.base_name
        collapsed += buckets[base_name]
        buckets[base_name] = []

    return collapsed
Beispiel #4
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index):
        assert(isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr;
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state: continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy())


    start_state = hlir.p4_parse_states["start"]
    walk_rec(hlir, start_state, None, defaultdict(int))

    header_topo_sorting = header_graph.produce_topo_sorting()

    # topo_sorting = []
    # for hdr in header_topo_sorting:
    #     topo_sorting.append(get_header_instance_name(hdr))

    # dirty fix, to ensure that all tags in a stag are contiguous
    # this makes the (questionable) assumption that all those tags are
    # contiguous in the deparsed packet
    buckets = defaultdict(list)
    for header_instance in header_topo_sorting:
        base_name = header_instance.base_name
        buckets[base_name].append(header_instance)
    collapsed = []
    for header_instance in header_topo_sorting:
        base_name = header_instance.base_name
        collapsed += buckets[base_name]
        buckets[base_name] = []

    return collapsed
Beispiel #5
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index):
        assert (isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state:
                continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy())

    start_state = hlir.p4_parse_states["start"]
    walk_rec(hlir, start_state, None, defaultdict(int))

    header_topo_sorting = header_graph.produce_topo_sorting()

    return header_topo_sorting
Beispiel #6
0
def produce_parser_topo_sorting(hlir):
    header_graph = Graph()

    def walk_rec(hlir, parse_state, prev_hdr_node, tag_stacks_index):
        assert(isinstance(parse_state, p4.p4_parse_state))
        for call in parse_state.call_sequence:
            call_type = call[0]
            if call_type == p4.parse_call.extract:
                hdr = call[1]

                if hdr.virtual:
                    base_name = hdr.base_name
                    current_index = tag_stacks_index[base_name]
                    if current_index > hdr.max_index:
                        return
                    tag_stacks_index[base_name] += 1
                    name = base_name + "[%d]" % current_index
                    hdr = hlir.p4_header_instances[name]

                if hdr not in header_graph:
                    header_graph.add_node(hdr)
                hdr_node = header_graph.get_node(hdr)

                if prev_hdr_node:
                    prev_hdr_node.add_edge_to(hdr_node)
                else:
                    header_graph.root = hdr
                prev_hdr_node = hdr_node

        for branch_case, next_state in parse_state.branch_to.items():
            if not next_state:
                continue
            if not isinstance(next_state, p4.p4_parse_state):
                continue
            walk_rec(hlir, next_state, prev_hdr_node, tag_stacks_index.copy())

    start_state = hlir.p4_parse_states["start"]
    walk_rec(hlir, start_state, None, defaultdict(int))

    header_topo_sorting = header_graph.produce_topo_sorting()

    return header_topo_sorting