1. first, it is pointed out that the outdev parameter transmission method of the NF_HOOK macro series (directly passing a net_device struct pointer) is incorrect. Either it is not passed, or it is the address of the pointer, that is, the address.
2. Next, I will point out why it is wrong to pass only one address.
Because there may be multiple HOOK functions at this HOOK point, each function may change the route of skb, that is, calling reroute, such as NAT, such as IP Mark, in this way, the subsequent HOOK function will still see the old outdev parameter, instead of the skb_dst (skb)-> dev after reroute.
3. See an actual error example.
Set default route
0.0.0.0/0 via 192.168.1.1 eth0
Iptables-t mangle-a output-d 1.1.1.1-j MARK -- set-mark 100
Prevent mark 100 packets from going out of eth0 (this is actually a redundant rule added to present the problem)
Iptables-a output-d 1.1.1.1-o eth0-j DROP
4. How to fix
There are many methods, which are described in sequence:
A. Use setsockopt to mark rather than iptables to bypass the ambiguous relationship between OUTPUT and route;
The following code is added at the beginning of ipt_do_table, that is, the end of the variable declaration:
Struct xt_target_param tgpar; # if 1 struct dst_entry * dst_e = skb_dst (skb); if (dst_e) {out = dst_e-> dev;} # endif
5. Completely simulate the world
An object can only exist in one location at the same time! Just like a person, When he enters a room, there is no such person outside. Unfortunately, the programming language is not like this.