Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set the idle_timeout? #630

Closed
dairui777 opened this issue Aug 22, 2024 · 6 comments
Closed

How to set the idle_timeout? #630

dairui777 opened this issue Aug 22, 2024 · 6 comments

Comments

@dairui777
Copy link

I want to write a P4 program to set the idle_timeout for a table entry (e.g. 10 seconds).

The BMv2 v1model implementation supports the table property support_timeout. How to set a specific idle_timeout (e.g. 10 seconds) after assigning this table property to true when defining a table?

Can I specify an idle_timeout when installing a table entry? But buildTableEntry in helper.py doesn't seem to provide such a feature.

Thanks a lot!

@dairui777
Copy link
Author

I modified basic to try to set idle_timeout. Specifically, I modified insertTableEntryin simple_controller.py.

def insertTableEntry(sw, flow, p4info_helper):
    table_name = flow['table']
    match_fields = flow.get('match') # None if not found
    action_name = flow['action_name']
    default_action = flow.get('default_action') # None if not found
    action_params = flow['action_params']
    priority = flow.get('priority')  # None if not found
    options = flow.get('options')

    table_entry = p4info_helper.buildTableEntry(
        table_name=table_name,
        match_fields=match_fields,
        default_action=default_action,
        action_name=action_name,
        action_params=action_params,
        priority=priority,
        options=options)

    sw.WriteTableEntry(table_entry)

I also modified buildTableEntryin helper.py.

def buildTableEntry(self,
                        table_name,
                        match_fields=None,
                        default_action=False,
                        action_name=None,
                        action_params=None,
                        priority=None,
                        options=None):
        table_entry = p4runtime_pb2.TableEntry()
        table_entry.table_id = self.get_tables_id(table_name)

        if priority is not None:
            table_entry.priority = priority

        if match_fields:
            table_entry.match.extend([
                self.get_match_field_pb(table_name, match_field_name, value)
                for match_field_name, value in match_fields.items()
            ])

        if default_action:
            table_entry.is_default_action = True

        if action_name:
            action = table_entry.action.action
            action.action_id = self.get_actions_id(action_name)
            if action_params:
                action.params.extend([
                    self.get_action_param_pb(action_name, field_name, value)
                    for field_name, value in action_params.items()
                ])

        if options is not None:
            if "idle_timeout_ns" in options:
                table_entry.idle_timeout_ns = options["idle_timeout_ns"]
                print("===dr debug=== options")
                print(options["idle_timeout_ns"])
                print("===dr debug=== options")
            if "elapsed_ns" in options:
                table_entry.time_since_last_hit.elapsed_ns = options["elapsed_ns"]

        return table_entry

I also modified table_entries in s1-runtime.json. The "idle_timeout_ns": 10000000000 means that I want to set idle_timeout as 10 seconds.

"table_entries": [
    {
      "table": "MyIngress.ipv4_lpm",
      "default_action": true,
      "action_name": "MyIngress.drop",
      "action_params": { }
    },
    {
      "table": "MyIngress.ipv4_lpm",
      "match": {
        "hdr.ipv4.dstAddr": ["10.0.1.1", 32]
      },
      "action_name": "MyIngress.ipv4_forward",
      "action_params": {
        "dstAddr": "08:00:00:00:01:11",
        "port": 1
      },
      "options": {
        "idle_timeout_ns": 10000000000
      }
    }
]

I then ran basic and used simple_switch_CLI to look at the table entries and found that the table entries were not deleted due to a timeout. But idle_timeout seems to be in effect. Is the operation of deleting a timeout table entry something that needs to be implemented separately?
image

Thanks a lot!

@jafingerhut
Copy link
Collaborator

There is an example P4 program using the v1model architecture and the idle_timeout feature, and a Python program that does automated testing of it, that you can find here: https://github.com/jafingerhut/p4-guide/tree/master/ptf-tests/idletimeout

I have not read your last comment and understood it in detail, but I would guess you have already figured out a significant fraction of what you were hoping to find out, already, but maybe take a look at my test program above and see if it answers any more of your questions.

@jafingerhut
Copy link
Collaborator

Oh, and idle_timeout only NOTIFIES the control plane when table entries have not been matched for a long time. It does not automatically delete them. It is up to the control plane software to do that, if it wishes to.

The PNA architecture defines a way to have a table that behaves this way, but also defines a way to define a table where the data plane automatically deletes the entries that are not matched for this timeout duration. I am not aware of any open source implementation in a software switch of this behavior, but there are commercially sold programmable NICs that do implement this.

@dairui777
Copy link
Author

dairui777 commented Aug 26, 2024

Thanks for your help!

I want to implement the deletion of idle timeout table entries in the P4 tutorial project. In the P4 tutorial, how does the controller receive idle timeout notification messages generated by the switch? Thank you.

@jafingerhut
Copy link
Collaborator

All P4Runtime API clients receive idle timeout notifications from the switch via specific kinds of gRPC messages, over the same TCP connection that the controller uses to send table insert, modification, and delete operations.

I am not certain, but I believe there might not currently be any exercises that demonstrate this.

Because these idle timeout notifications are unsolicited messages from the switch, where by "unsolicited" I simply mean the switch can generate them at any time, without the controller having first made a request, it requires some extra code in the controller to check for these unsolicited messages.

If such code has been developed in Python in the tutorials repository, I am unaware of it. If you are interested in looking for such Python code in the tutoraisl repository and taking advantage of it to create a new exercise that demonstrates this feature, and/or developing new Python code in the tutorials repo to demonstrate this feature, please consider doing so.

@jafingerhut
Copy link
Collaborator

Closing this issue, since the original submitter seems to have had their questions answered, but linking to this issue from a new one requesting that someone create a new exercise that demonstrates these features: #656

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants