p4lang / tutorials

P4 language tutorials
Apache License 2.0
1.36k stars 887 forks source link

Topology.json and MAC Addr of next port #495

Closed whyLongWay closed 1 year ago

whyLongWay commented 1 year ago

In topology.json, we can see "hosts" "switches" "links", and we set MAC for hosts. But in common sx-runtime.txt, p4 codes in tutorials use table ipv4_lpm to get next hop, set next port (the next hop may be a switch in pod-topo) and according MAC for a packet. We only write hosts' MAC in topology.json, but in sx-runtime.json, we also have switch's MAC, How to set switch's MAC explicitly in topology.json? Thank you.

whyLongWay commented 1 year ago

The topo is in this file https://github.com/p4lang/tutorials/tree/master/exercises/basic/pod-topo

jafingerhut commented 1 year ago

The contents of the sx-runtime.json files are read by a Python program, and used to add table entries to the P4 programs running on the switches. Those tables have MAC addresses in them, so if the sx-runtime.json files did not contain those MAC addresses, the software running in the tutorials would not be able to add them to the appropriate P4 tables, i.e. that software has NOT been written to determine the host MAC addresses from the contents of the toplogy.json file, but only from the contents of the sx-runtime.json file.

I believe the MAC addresses in the topology.json file might be used by Mininet to configure those MAC addresses in the simulated hosts of the Mininet network. I'm not sure about that, but it would make sense.

Is there redundant representation of addresses here? Definitely.

Could that redundancy be removed? Perhaps, if you wrote different Python programs to read them and use their contents, different than the Python programs provided with the exercises.

The included Python programs are written to be relatively simple and straightforward, though, getting the information to add to the P4 tables from one file only, not from sources spread over multiple files.

whyLongWay commented 1 year ago

Thanks @jafingerhut

So, write MAC address ( that I want ) for next hop switch ONLY in sx-runtime.json is OK?

But, in host command from topology.json "h4": {"ip": "10.0.4.4/24", "mac": "08:00:00:00:04:44", "commands":["route add default gw 10.0.4.40 dev eth0", "arp -i eth0 -s 10.0.4.40 08:00:00:00:04:00"]

And in s3-runtime.json: { "table": "MyIngress.ipv4_lpm", "match": { "hdr.ipv4.dstAddr": ["10.0.2.2", 32] }, "action_name": "MyIngress.ipv4_forward", "action_params": { "dstAddr": "08:00:00:00:04:00", "port": 3 } },

From pod-topo.png( https://github.com/p4lang/tutorials/blob/master/exercises/basic/pod-topo/pod-topo.png) we know Port 3 of switch s2 is connected to switch s4. The h4 use 'arp' command to set arp cache, 08:00:00:00:04:00 is the MAC of s4, "10.0.4.40" is associated with "08:00:00:00:04:00", but h4 is NOT directly connected to s4 (h4 is connected to s2), so why we set default gateway "10.0.4.40 " in h4? This IP addr is not showed in any sx-runtime.json.

jafingerhut commented 1 year ago

I agree there seem to be some inconsistencies there.

And you know what? The demo still is able to ping between the hosts.

Do you know why?

I am pretty sure that the answer is: the P4 code loaded into the switches DOESN'T CARE what the dest MAC addresses are in the Ethernet frames they receive are. They just ignore them. Well, they copy the dest MAC addresses in received frames into the source MAC addresses, yes, but they don't actually check to see that the dest MAC addresses of received frames are equal to a MAC address configured on the switch before deciding that it should forward the packet using L3 routing, which a real L2/L3 switch would do.

Why not? Because basic.p4 isn't trying to implement everything a real L2/L3 switch does. It is doing something much simpler than that.

whyLongWay commented 1 year ago

Got it. Really thank you for your help @jafingerhut So in the "host command" field in topology.json, if I set randomly like below, the P4 example can still work? "host commands": ["route add default gw 44.33.22.11 dev eth0", "arp -i eth0 -s 44.33.22.11 88:77:66:55:44:33"]

Besides, I think I can use a table in P4 code, to query local MAC and then check if local MAC == header.ethernet.dstAddr when receiving a packet. I think it is easy to write in code, but is it as the same as real P4 forwarding process?

jafingerhut commented 1 year ago

"but is it as the same as real P4 forwarding process"

The whole point of P4 is that whatever P4 code you write IS the "real P4 forwarding process". If you want your P4 network device to check that the dest Ethernet MAC address is equal to a configured value before using the IP header for forwarding, you can do that. But you can also write P4 code that has no IPv4 or IPv6 headers at all, and make up on your own exactly what the device should do in every case.

whyLongWay commented 1 year ago

I got it, thanks for your help.