Drop one packet from stream

1

I'm searching for a way to drop one packet of (UDP) multicast stream.

Is this possible by userspace utilities or the only way would be injecting some code to kernel IP stack?

I expect it should throw away packet that is passing through two bridged interfaces (thus entering by one eth and leaving by some other). It should ideally drop the first packet, that will meet some requirements (in form of BPF filter or just combination of DST|SRC IP|PORT) but dropping just the first packet on interface would be enough.

Mike S.

Posted 2018-12-18T13:59:42.507

Reputation: 106

1Why? Which packet? What software? It's easy enough to call recvfrom() and then throw away the result... – Attie – 2018-12-18T14:04:31.490

I have made few edits to my question. It's not definitely XY problem, as I really need to drop one packet (I'm developing something that could be called "testing environment" and testing "what happens when a packet is dropped" is one of testing scenarios. The source and destination devices of stream can be considered as blackbox, the only device, where I can do that is the device with a bridge). – Mike S. – 2018-12-18T14:16:10.387

So basically you need a rule that sets some state when fired, so it won't fire afterwards. Looking through man iptables-extensions, there seem to be quite a few approaches, e.g. quota, or connbytes (0 for first packet), or ipset (add src or dest IP after first packet). If you could somehow identify the packet you want to drop by content, that would be even simpler. – dirkt – 2018-12-19T07:00:41.210

Finally, I was able to find statistics module of iptables that can be (with simple hack) used exactly for my purpose (it will probably have some race condions on overloaded system but usually it will work good) – Mike S. – 2018-12-19T14:12:39.580

Answers

1

Okay! As @dirkt said in his comment, there is possibility to use some iptables extension. One pretty good for this purpose could be statistic --mode nth. It can be used easily on the bridge (the net.bridge.bridge-nf-call-iptables must be, for bridging, turned on!)

So, if someone would like to block first packet entering bridge0 from ethA , the command would look like:

iptables -N log-and-drop        # create new chain
iptables -A log-and-drop -j LOG --log-level 6 --log-prefix SOMEREALLYUNIQUESTRING     # log received packet into syslog with some string unique enough
iptables -A log-and-drop -j DROP # drop the packet

# rules for every single interface in the bridge
iptables -A FORWARD  -m physdev --physdev-in ethA -m statistic --mode nth --every 1000000 --packet 0 -j log-and-drop

This will create a chain log-and-drop which will be used for logging and dropping received packet. Then, it will take first packet passing by (and then every million-th packet) and drop it.

The last thing we need to do is to create "watch script", that will wait for appearing of that unique string in log and than deletes all iptables rules.

if tail /var/log/messages  | grep -m 1 SOMEREALLYUNIQUESTRING ; then
    iptables -D FORWARD  -m physdev --physdev-in ethA -m statistic --mode nth --every 1000000 --packet 0 -j log-and-drop
    iptables -F log-and-drop
    iptables -X log-and-drop
fi

This is not really beautiful solution but it is the only i was able to figure out. If someone can make a better solution, I'm looking forward to see it :)

Mike S.

Posted 2018-12-18T13:59:42.507

Reputation: 106