Problems encountered in program compilation

I encountered this error when compiling the program

“[–Werror=invalid] error: MyIngress.packet_route: Invalid Program can not be implemented on this taret since it contains a path from table MyIngress.packet_route back to itself
table packet_route{
^^^^^^^^^^^^
Compilation Error”

and My code is as follows:

    action forward(macAddr_t dstAddr, egressSpec_t port){
        hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
        hdr.ethernet.dstAddr = dstAddr;
        standard_metadata.egress_spec = port;
        hdr.id.ttl = hdr.id.ttl - 1;
    }
    table packet_route{
        key = {
            hdr.id.routeAddr: exact;
        }
        actions = {
            forward;
            drop;
        }
        size = 1024;
        default_action = drop();
    }

    apply{
        if (hdr.ethernet.etherType == TYPE_IPV4){
            ipv4_storage();
            select_outpoint.apply();
            packet_route.apply();
            hdr.ipv4.setInvalid();
        }

        if(hdr.ethernet.etherType == TYPE_ID){
            route_finish_judge.apply();
            if (hdr.id.routeAddr == hdr.id.dstAddr){
                ipv4_lpm.apply();
                hdr.id.setInvalid();

            }
            else{
                packet_route.apply();
            }
        }
    }

Is it because the same table is called twice?

Hi :slight_smile:

From this thread: error: Program is not supported by this target, because table .iFwdBrgMacKeyTbl has multiple successors · Issue #1394 · p4lang/p4c · GitHub and quoting “ChrisDodd”: “P4 is deliberately designed with no loops, to model a “once through” pipeline for packets – each table sees each packet, doing a single lookup, and then goes on to the next packet. So if you want two lookups, you’ll need to either use two tables, or arrange to process the entire packet twice (with resubmit or recirculate)”.

To be fair, this seems to be more of an issue related to a target limitation than a P4 issue itself. As mentioned in the thread, some targets might allow multiple reads indeed and some others will not.

You will have to design your code so it executed one or the other.

    action forward(macAddr_t dstAddr, egressSpec_t port){
        hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
        hdr.ethernet.dstAddr = dstAddr;
        standard_metadata.egress_spec = port;
        hdr.id.ttl = hdr.id.ttl - 1;
    }
    table packet_route{
        key = {
            hdr.id.routeAddr: exact;
        }
        actions = {
            forward;
            drop;
        }
        size = 1024;
        default_action = drop();
    }

    apply{

        if(hdr.ethernet.etherType == TYPE_ID){
            route_finish_judge.apply();
            if (hdr.id.routeAddr == hdr.id.dstAddr){
                ipv4_lpm.apply(); 
                hdr.id.setInvalid();

            } else {

                if (hdr.ethernet.etherType == TYPE_IPV4){
                    ipv4_storage();
                    select_outpoint.apply();
                    hdr.ipv4.setInvalid();
                }
                packet_route.apply();
            }
        }
    }

I think this code might work.

Cheers,

Yes, there is nothing about the P4 language itself that prevents apply’ing a table more than once per target, but many target devices impose a restriction like this, including the behavioral-model target with the v1model architecture.

Thanks for your help, I will redesign the table.

Thanks for your help