在nat的时候,会根据5元组查找出对应的connection,然后进行ip和port的替换,那么问题来了,对于一个很大的UDP包,会进行分片,后续分片的ip包是没有udp头的,也就是没有端口,那么这个包是没有5元组的,也就得不到这个包所属的连接,那怎么办呢?
原来内核是会对UDP进行合并的。
net/ipv4/netfilter/nf_defrag_ipv4.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | int nf_defrag_ipv4_enable( struct net *net) { int err = 0; mutex_lock(&defrag4_mutex); if (net->nf.defrag_ipv4_users == UINT_MAX) { err = -EOVERFLOW; goto out_unlock; } if (net->nf.defrag_ipv4_users) { net->nf.defrag_ipv4_users++; goto out_unlock; } err = nf_register_net_hooks(net, ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops)); if (err == 0) net->nf.defrag_ipv4_users = 1; out_unlock: mutex_unlock(&defrag4_mutex); return err; } EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); |
当内核需要重组分片的时候,就调用nf_defrag_ipv4_enable(),比如开启连接追踪的时候,nf_defrag_ipv4_enable()会注册一个钩子,来实现分片重组,这个钩子运行在连接追踪之前。
参考