1.首先指出,NF_HOOK系列宏的outdev参数的传递方式(直接传递一个net_device结构体指针)是不正确的 正确的方式要么是不传递,要么是传递指针的地址,即地址的地址。...因为OUTPUT处在路由之后,如果其中的mangle表改变了skb的mark,那么会reroute,不幸的是,reroute并无法改变OUTPUT点上NF_HOOK的outdev参数值!...4.怎么修正 办法很多,依次介绍: a.使用setsockopt打mark而不是iptables打mark,绕开OUTPUT和路由的暧昧关系; b.修改NF_HOOK的dev参数为struct net_device...**类型,然后在reroute中重路由成功后执行*out = (struct dst_entry*)skb_dst(skb)->dev;从而改变NF_HOOK中的outdev的值; c.去掉NF_HOOK
Netfilter挂载点) 在 图1 中,蓝色部分就是 Netfilter 挂载钩子函数的位置,所以 Netfilter 定义了 5 个常量来表示这 5 个位置,如下代码: // 文件:include/linux...要触发调用某个挂载点上(链)的所有钩子函数,需要使用 NF_HOOK 宏来实现,其定义如下: // 文件:include/linux/netfilter.h #define NF_HOOK(pf, hook...既然 Netfilter 是通过调用 NF_HOOK 宏来调用钩子函数链表上的钩子函数,那么内核在什么地方调用这个宏呢?...return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish); } 如上代码所示,在 ip_rcv 函数中调用了 NF_HOOK...六、总结 本文主要介绍了 Netfilter 的实现,因为 Netfilter 是 Linux 网络数据包过滤的框架,而 iptables 就是建立在 Netfilter 之上的。
什么是Netfilter/iptable Netfilter/iptables是Linux内核内置的报文过滤框架,程序可以通过该框架完成报文过滤、地址转换(NAT)以及连接跟踪等功能。...Netfilter Netfilter是嵌入Linux内核协议栈的,设置在报文处理路径上的一系列调用入口。...这个二维数组的每一项代表了一个钩子被调用的点,NF_PROTO代表协议栈,NF_HOOK代表协议栈中某个路径点。...Netfilter在不同协议栈的不同点上放置钩子函数,当数据包经过某个协议栈(NF_PROTO)的某个点(NF_HOOK)时,该协议栈会通过NF_HOOK()函数调用对应钩子链表(nf_hooks[NF_PROTO...][NF_HOOK])中注册的每一个钩子项来处理该数据包。
Linux 内核网络栈是一个纯内核态的东西,和用户层功能是天然隔离。但为了迎合各种各样用户层不同的需求,内核开放了一些口子出来供用户干预。...Linux 在内核网络组件中很多关键位置布置了 netfilter 过滤器。Iptables 就是基于 netfilter 来实现的。...NF_HOOK 这个函数会执行到 iptables 中 pre_routing 里的各种表注册的各种规则。...在 NF_HOOK 执行到这个链的时候,就会把规则按照优先级挨个过一遍。如果有符合条件的规则,则执行规则对应的动作。...NF_HOOK 最终会执行到 nf_nat_rule_find 函数。
Netfilter是Linux 2.4.x引入的一个子系统,它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能...Netfilter使用NF_HOOK(include/linux/netfilter.h)宏在协议栈内部切入到Netfilter框架中。...相比于2.4版本,2.6版内核在该宏的定义上显得更加灵活一些,定义如下: #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \...在include/linux/socket.h中IP协议AF_INET(PF_INET)的序号为2,因此我们就可以得到TCP/IP协议族的钩子函数挂载点为: PRE_ROUTING: nf_hooks...小节:整个Linux内核中Netfilter框架的HOOK机制可以概括如下: 在数据包流经内核协议栈的整个过程中,在一些已预定义的关键点上PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT
Netfilter 的设计与实现 netfilter 的定义是一个工作在 Linux 内核的网络数据包处理框架,为了彻底理解 netfilter 的工作方式,我们首先需要对数据包在 Linux 内核中的处理路径建立基本认识...hook 触发点 对于不同的协议(IPv4、IPv6 或 ARP 等),Linux 内核网络栈会在该协议栈数据包处理路径上的预设位置触发对应的 hook。...所有接收数据包到达的第一个 hook 触发点(实际上新版本 Linux 增加了 INGRESS hook 作为最早触发点),在进行路由判断之前执行。...NF_HOOK 宏和 netfilter 向量 所有的触发点位置统一调用 NF_HOOK 这个宏来触发 hook: static inline int NF_HOOK(uint8_t pf, unsigned...回归到源码,IPv4 内核网络栈会在以下代码模块中调用 NF_HOOK(): NF_HOOK 实际调用方式以 net/ipv4/ip_forward.c[1] 对数据包进行转发的源码为例,在 ip_forward
Netfilter 的设计与实现 netfilter 的定义是一个工作在 Linux 内核的网络数据包处理框架,为了彻底理解 netfilter 的工作方式,我们首先需要对数据包在 Linux 内核中的处理路径建立基本认识...hook 触发点 对于不同的协议(IPv4、IPv6 或 ARP 等),Linux 内核网络栈会在该协议栈数据包处理路径上的预设位置触发对应的 hook。...所有接收数据包到达的第一个 hook 触发点(实际上新版本 Linux 增加了 INGRESS hook 作为最早触发点),在进行路由判断之前执行。...NF_HOOK 宏和 netfilter 向量 所有的触发点位置统一调用 NF_HOOK 这个宏来触发 hook: static inline int NF_HOOK(uint8_t pf, unsigned...回归到源码,IPv4 内核网络栈会在以下代码模块中调用 NF_HOOK(): NF_HOOK 实际调用方式以 `net/ipv4/ip_forward.c`[1] 对数据包进行转发的源码为例,在 ip_forward
一、网络包接收过程 在图解Linux网络包接收过程一文中我们详细介绍了网络包是如何从网卡到达用户进程中的。这个过程我们可以简单用如下这个图来表示。...return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish); } 如果你用 NF_HOOK...在25 张图,一万字,拆解 Linux 网络包发送过程一文中,我们详细描述过网络包的发送过程。发送过程可以汇总成简单的一张图。...return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, dst_output); }...在 Linux 里,支持很多种协议族,在 include/linux/socket.h 中可以找到所有的定义。这里创建的是 packet 类型的 socket。
接下来,IP 协议层将通过调用 nf_hook 进入 netfilter,其返回值将传递回 ip_local_out 。...如果 nf_hook 返回 1,则表示允许数据包通过,并且调用者应该自己发送数据包。...3.1 netfilter and nf_hook nf_hook 只是一个 wrapper,它调用 nf_hook_thresh,首先检查是否有为这个协议族和hook 类型(这里分别为 NFPROTO_IPV4...出于讨论目的,我们假设 nf_hook 返回 1,表示调用者(在这种情况下是 IP 协议层)应该自己发送数据包。 3.2 目的(路由)缓存 dst 代码在 Linux 内核中实现协议无关的目标缓存。...最后调用 dev_queue_xmit 将 skb 传递给 Linux 网络设备子系统。
在 Linux 下这个软件实现交换机的技术就叫做 bridge(再强调下,这是纯软件实现的)。...为了方便大家理解,接下来我们通过动手实践的方式,在一台 Linux 上创建一个小型的虚拟网络出来,并让它们之间互相通信。...forward: NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish);...struct net_bridge_port *to, struct sk_buff *skb) { // 将 skb 中的 dev 改成新的目的 dev skb->dev = to->dev; NF_HOOK...//file: net/bridge/br_forward.c int br_forward_finish(struct sk_buff *skb) { return NF_HOOK(NFPROTO_BRIDGE
linux内核为了高性能,很喜欢用rwlock的改进版rcu,这种思想是值得借鉴的。 ...switch (rx_handler(&skb)) // 交给rx_handler处理,例如ovs, linux bridge等 此类接口处理报文在协议栈之前,因此netfilter对此类接口不起作用,...所以在云环境(openstack)中,需要在虚拟机tap口与虚拟交换机之间增加Linux bridge设备来使报文经过协议栈(netfilter起作用)来实现security group。... } }->deliver_skb{ pt_prev->func // 如ip,则对应的就是ip_rcv ---- 进入第三层 } ip_rcv { return NF_HOOK...ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER)) return 0; } return NF_HOOK
在内核代码中,我们时常可见 NF_HOOK 这样的调用。我的建议是,如果你暂时不考虑 Netfilter,那么就直接跳过, 跟踪 okfn 就行。...static inline int NF_HOOK(uint8_t pf, unsigned int hook, struct net *net, struct sock *sk, struct...struct net_device *out, int (*okfn)(struct net *, struct sock *, struct sk_buff *)) { int ret = nf_hook
准备知识: netfilter:源代码见linux-4.0.4/net/netfilter目录,并需要参考linux-4.0.4/net/ipv4目录。...在ipv4目录下,grep -i nf_hook *.c,可以看到ipv4实现的几个hook点的位置和大致逻辑。其中,这里要使用的就是NF_INET_LOCAL_OUT这个hook点。...代码: 路径:https://github.com/pacepi/port_connection #include linux/netfilter.h> #include linux/init.h...> #include linux/module.h> #include linux/netfilter_ipv4.h> #include linux/ip.h> #include linux/udp.h...> #include linux/inet.h> #include linux/sysctl.h> static unsigned int min_port = 0; static unsigned
在IP层代码中,有一些带有NF_HOOK宏的语句,如IP的转发函数中有: NF_HOOK(PF_INET, NF_IP_FORWARD, skb..., skb->dev, dev2, ip_forward_finish); 其中NF_HOOK宏的定义提炼如下: linux/netfilter.h-> #ifdef CONFIG_NETFILTER...#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) / (list_empty(&nf_hooks[(pf)][(hook)]) / ?...NF_HOOK宏的参数分别为: 1.pf:协议族名,netfilter架构同样可以用于IP层之外,因此这个变量还可以有诸如PF_INET6,PF_DECnet等名字。...linux/skbuff.h> #include linux/netdevice.h> #include linux/config.h> #include linux/ip.h> #include
前言:昨天有个同学碰到发送udp包时收到destination unreachable的icmp包问题,本文简单介绍一下linux5.9中icmp包的处理流程。...dev); skb = ip_rcv_core(skb, net); if (skb == NULL) return NET_RX_DROP; return NF_HOOK...int ip_local_deliver(struct sk_buff *skb){ struct net *net = dev_net(skb->dev); return NF_HOOK
Linux 网络架构 Linux 网络初始化 网络设备子系统初始化 网卡驱动初始化 协议栈初始化 数据包的接收过程 硬中断处理 ksoftirqd 软中断处理 协议栈处理 应用层处理 总结 这里深度理解一下在...Linux 网络架构 在Linux内核实现中,链路层协议靠网卡驱动来实现,内核协议栈来实现网络层和传输层。内核对更上层的应用层提供socket接口来供用户进程访问。...Linux 网络初始化 网络设备子系统初始化 linux内核通过调用subsys_initcall来初始化各个子系统,其中网络子系统的初始化会执行到net_dev_init函数: //net/core/...net = dev_net(dev); skb = ip_rcv_core(skb, net); if (skb == NULL) return NET_RX_DROP; return NF_HOOK...NFPROTO_IPV4, NF_INET_PRE_ROUTING, net, NULL, skb, dev, NULL, ip_rcv_finish); } 这里NF_HOOK
当然,这篇文章并不是介绍 IP协议 的原理,有关 IP协议 的原理可以参考经典的书籍《TCP/IP协议详解》,而这篇文章主要介绍的是 Linux 内核怎么实现 IP协议。...接下来,我们通过源码来分析 Linux 内核是怎么实现 IP协议 的,我们主要分析 IP 数据包的发送与接收过程。...// 目标IP地址 skb->nh.iph = iph; ... // 调用 ip_queue_xmit2() 进行下一步的发送操作 return NF_HOOK...goto inhdr_error; __skb_trim(skb, len); } // 继续调用 ip_rcv_finish() 函数处理数据包 return NF_HOOK...skb) return 0; } // 继续调用 ip_local_deliver_finish() 函数处理数据包 return NF_HOOK(PF_INET
stop monitoring1 drops at skb_queue_purge+18 (0xffffffff92a42868)........案例一iptables 导致丢包,可以通过 是否有 nf_hook
领取专属 10元无门槛券
手把手带您无忧上云