NetSys / bess

BESS: Berkeley Extensible Software Switch
Other
313 stars 156 forks source link

Support for source port metadata in packets #1019

Open kot-begemot-uk opened 4 years ago

kot-begemot-uk commented 4 years ago

I have ran into this issue on several occasions when trying to implement things using Bess - packets have no source port metadata.

This introduces a whole range of challenges when trying to implement switching, multicast, etc which all have some special treatment for the source port.

I am happy to volunteer to implement it if there is interest as well as the relevant options in replicate, port-out, etc.

Brgds, A.

krsna1729 commented 4 years ago

@kot-begemot-uk Can we use SetMetadata module immediately after PortInc/QueueInc to achieve this?

kot-begemot-uk commented 4 years ago

Not really. Let me give a few examples.

Most trivial case - flooding packets in a switch. If you use set/test metadata you need a replicator per switch port - 32 replicators 32 set-metadata and 32-check-metadata modules with appropriate config for each. You have to update the config on all 32 ports if you add/change port and so on.

If you have port origin recorded and a have a "do not send to self" option in the replicator you can reuse the same replicator for all broadcast in the bridge domain. You just give it the packet and it will skip sending to self.

Ditto for multicast - you need a replicator per port group.

It is also heavily used in learning - invalidating fib entries, etc.

kot-begemot-uk commented 4 years ago

We can reuse metadata structures for this by the way, though IMHO that will incur unnecessary costs. This particular check is very common, so having to match strings every time it is checked to fetch a particular metadata element by name is not a good idea.

krsna1729 commented 4 years ago

Is there a string comparison? I thought the metadata framework converts it to index/offset on init of the metadata. If you can share .bess file highlighting the problem, that would be great.

kot-begemot-uk commented 4 years ago

I was actually thinking of putting it into the metadata - something which is set by Port-Inc and is set by default.

Metadata presently allows int or bytes. Out of the existing properties only name_ looks unique and suitable for comparison and that is a string. That is where the "string comparison" came from.

Probably the best way will be to introduce a port-index similar to ifIndex in SNMP MIBs and add it to the Port properties. Then we can store it as uInt64. The builder will inc() it for every new port which allows not to do any checks for uniqueness until it has rolled over.

This also solves the other problem. In order to make this really useful, one should be able to optionally hand over the port (and other metadata) to external programs along with packets. If we do just the port - that is easy - we can add it to the framing. That is what DSA/Switchdev switching drivers do in the linux kernel - they add port of origin and other metadata to fixed "tag" framing in front of the packet. Alternatively, we can figure out a solution to ship the entire metadata to external programs.