《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

简介: 《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(上)

netfilter框架是Linux操作系统中内置的,通过向内核模块提供对协议栈中的网络数据包进行修改和操作的能力,来实现流量过滤,网络地址转换等高级功能。

 

1) netfilter如何工作

对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照Linux内核定义的网络设备驱动规范,以sk_buff结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元skb。

 

内核通过将网络设备缓冲区环形队列中skb取出,并按照以太网层,网络层,传输层顺序处理后,将报文数据放置到对应Socket缓冲区中,通知用户程序进行读取,从而完成收包

内核为Socket缓冲区待发送数据封装为skb,经过传输层,网络层和以太网层依次填充对应报头后,调用网络设备驱动方法将skb发送到网络上,从而完成发包

 

netfilter工作的核心原理则是在网络层,通过在五个不同的内核处理skb数据包的位置,执行注册到netfilter框架中的回调函数,并根据回调函数的返回来选择下一步的处理,实现复杂的功能。

 

netfilter触发时机

 

netfilter在内核网络数据包的处理流程中,注册了5个可以触发的时机,详情如下:

/* IP Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP_PRE_ROUTING0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING4
#define NF_IP_NUMHOOKS5
#endif /* ! __KERNEL__ */

 

根据源代码中的定义,我们可以参考下图:

 image.png

 从上面的代码定义和示意图中可以知道,在以下几个地方会调用netfilter定义好的方法对数据包进行处理:

 

数据包从网卡进入协议栈后,所有报文都会走到NF_IP_PRE_ROUTING

数据包经过入向路由选择后,确认是由本机传输层进行处理,会进入到NF_IP_LOCAL_IN

数据包经过入向路由选择后,不是由本机处理,需要转发给其他机器,会进入到NF_IP_FORWARD

由本机传输层发出报文,都会经过NF_IP_LOCAL_OUT

经过出向路由选择后报文,会经过NF_IP_POST_ROUTING,包括从本机发出和需要本机转发的。

 

在以上五个时机,当数据包skb到达时,netfilter框架定义的回调方法就会被内核执行。

 

netfilter如何操作网络数据

使用netfilter框架的模块,需要按照netfilter定义的结构体来实现自己的行为,才能正确注册到netfilter框架中,并被内核调用,netfilter约束的注册结构体的定义如下:

struct nf_hook_ops {
    // 这是真正被内核执行的函数,会对skb进行读取和修改
    nf_hookfn*hook;
    struct net_device*dev;
    void*priv;
    u_int8_tpf;
    // hooknum定义了回调函数生效的位置,从上文可知有五个位置可以选择
    unsigned inthooknum;
    // priority定义了回调函数的优先级,通过每个hook时机都会有多个回调函数需要生效
    intpriority;
};

以ipvlan模块为例:

static const struct nf_hook_ops ipvl_nfops[] = {
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV4,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#if IS_ENABLED(CONFIG_IPV6)
  {
    .hook     = ipvlan_nf_input,
    .pf       = NFPROTO_IPV6,
    .hooknum  = NF_INET_LOCAL_IN,
    .priority = INT_MAX,
  },
#endif
};

 

我们可以看到,ipvlan模块根据IP协议的版本定义了两个hook结构体,其中:

hookfn是核心处理逻辑,ipvlan模块注册了ipvlan_nf_input方法

pf是netfilter协议版本,ipvlan模块分别注册了IPv6和IPv4对应方法

hooknum定义了这个hook在netfilter中生效位置,ipvlan模块将自己回调方法注册到了NF_INET_LOCAL_IN,也就是完成路由之后,进入传输层之前

priotity定义了hook优先级

 

那么,hookfn作为真正核心的处理逻辑,他是如何工作的呢?

 

以ipvlan注册在NF_INET_LOCAL_IN上的hook方法ipvlan_nf_input为例:

 

unsigned int ipvlan_nf_input(void *priv, struct sk_buff *skb,
           const struct nf_hook_state *state)
{
    // 参数中可以看到,有前一个生效的hook结构体,当前处理的skb报文本身以及当前netfilter框架的上下文信息
  struct ipvl_addr *addr;
  unsigned int len;
  addr = ipvlan_skb_to_addr(skb, skb->dev);
  if (!addr)
    goto out;
  skb->dev = addr->master->dev;
  len = skb->len + ETH_HLEN;
  ipvlan_count_rx(addr->master, len, true, false);
out:
    // 这里返回了netfilter框架规定的返回码
  return NF_ACCEPT;
}

 从ipvlan_nf_input可以看到,注册到netfilter中的回调函数的核心在于两个约束:

● 回调函数的入参定义,可以接受协议栈中真正的报文结构体skb以及netfilter的上下文状态为参数。

● 回调函数的返回值,需要是netfilter规定好的返回值,他们的定义如下:

/* Responses from hook functions. */
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5/* Deprecated, for userspace nf_queue compatibility. */
#define NF_MAX_VERDICT NF_STOP

从以上的分析不难看出,只要满足netfilter的注册条件,就可以在回调函数中直接对数据报文skb内容进行读取和修改操作,而通过返回值的定义,则可以借助netfilter框架完成对数据包的处理,比如丢弃,接收或者传递到用户态进行处理。

 

netfilter的内核实现

在负责对所有hook方法进行遍历处理的函数中,可以看到,netfilter核心的工作流程就是在相应的触发时机调用这个时机上注册的所有方法,按照优先级进行处理,并根据每一次处理的结果进行操作,包括丢弃,传输给用户态等等:

int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
     const struct nf_hook_entries *e, unsigned int s)
{
  unsigned int verdict;
  int ret;
  for (; s < e->num_hook_entries; s++) {
        // 在这里调用对应的hook时机上的所有注册的hook回调方法,然后根据结果选择是不是继续循环
    verdict = nf_hook_entry_hookfn(&e->hooks[s], skb, state);
    switch (verdict & NF_VERDICT_MASK) {
    case NF_ACCEPT:
      break;
    case NF_DROP:
      kfree_skb(skb);
      ret = NF_DROP_GETERR(verdict);
      if (ret == 0)
        ret = -EPERM;
      return ret;
    case NF_QUEUE:
      ret = nf_queue(skb, state, e, s, verdict);
      if (ret == 1)
        continue;
      return ret;
    default:
      /* Implicit handling for NF_STOLEN, as well as any other
       * non conventional verdicts.
       */
      return 0;
    }
  }
  return 1;

 

更多精彩内容,欢迎观看:

《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——2.netfilter框架(下):https://developer.aliyun.com/article/1221729?spm=a2c6h.13148508.setting.16.15f94f0e18Oqpt

相关文章
|
1月前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
209 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
2月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
172 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
2月前
|
存储 人工智能 调度
容器服务:智算时代云原生操作系统及月之暗面Kimi、深势科技实践分享
容器技术已经发展成为云计算操作系统的关键组成部分,向下高效调度多样化异构算力,向上提供统一编程接口,支持多样化工作负载。阿里云容器服务在2024年巴黎奥运会中提供了稳定高效的云上支持,实现了子弹时间特效等创新应用。此外,容器技术还带来了弹性、普惠的计算能力升级,如每分钟创建1万Pod和秒级CPU资源热变配,以及针对大数据与AI应用的弹性临时盘和跨可用区云盘等高性能存储解决方案。智能运维方面,推出了即时弹性节点池、智能应用弹性策略和可信赖集群托管运维等功能,进一步简化了集群管理和优化了资源利用率。
|
1月前
|
监控 安全 Cloud Native
阿里云容器服务&云安全中心团队荣获信通院“云原生安全标杆案例”奖
2024年12月24日,阿里云容器服务团队与云安全中心团队获得中国信息通信研究院「云原生安全标杆案例」奖。
|
2月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
2月前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统
|
2月前
|
存储 JSON 缓存
【网络原理】——HTTP请求头中的属性
HTTP请求头,HOST、Content-Agent、Content-Type、User-Agent、Referer、Cookie。
|
2月前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
2月前
|
XML JSON 网络协议
【网络原理】——拥塞控制,延时/捎带应答,面向字节流,异常情况
拥塞控制,延时应答,捎带应答,面向字节流(粘包问题),异常情况(心跳包)
|
2月前
|
网络协议 算法 Java
【JavaEE】——初始网络原理
局域网,广域网,局域网连接方式,交换机,集线器,路由器,网络通信,五元组(源IP,源端口,目的IP,目的端口,协议),协议分层,TCP/IP五层网络协议,封装和分用,交换机和路由器的封装和分用

热门文章

最新文章