对于netfilter 可以参考 https://netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html

netfilter 框架中包含了:filter mat mangle raw security;

在net结构中的成员struct netns_xt xt,是用来存储所有table的,

netns_xt结构的成员如下,其中tables存储了多种协议对应的table链表,每种协议对应一个链表,多种table存储在自己所属协议的链表上;

struct netns_xt {
struct list_head tables[NFPROTO_NUMPROTO];
bool notrack_deprecated_warning;
bool clusterip_deprecated_warning;
#if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
struct ebt_table *broute_table;
struct ebt_table *frame_filter;
struct ebt_table *frame_nat;
#endif
};

每个具体类型的table如下:

/* Furniture shopping... */
struct xt_table {
struct list_head list;
/* What hooks you will enter on */
unsigned int valid_hooks; /* 该表关注的钩子点 */
/* Man behind the curtain... *//* 私有数据,真正的规则,指向xt_table_info */
struct xt_table_info *private;
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
u_int8_t af; /* address/protocol family */ /* 协议族 */
int priority; /* hook order */ /* 优先级 */
/* called when table is needed in the given netns */
int (*table_init)(struct net *net);
/* A unique name... */
const char name[XT_TABLE_MAXNAMELEN];//表的名字
};

xt_table的private成员又指向了xt_table_info结构,存储真正的规则相关信息,包括入口和偏移

/* The table itself */
struct xt_table_info {
/* Size per table */
unsigned int size; /* 表大小,占用的内存空间 */
/* Number of entries: FIXME. --RR */
unsigned int number; /* 表中规则数量 */
/* Initial number of entries. Needed for module usage count */
unsigned int initial_entries;/* 初始的规则数量,用于模块计数 */ /* Entry points and underflows
* hook_entries:记录所影响的HOOK的规则入口相对于下面的entries变量的偏移量
* underflows:与hook_entry相对应的规则表上限偏移量
*/ unsigned int hook_entry[NF_INET_NUMHOOKS];/* 钩子规则入口,相对于下面的entries偏移量 */
unsigned int underflow[NF_INET_NUMHOOKS]; /* 与hook_entry相对应的规则表上限偏移量,当无规则录入时,hook_entry和underflow均为0 */
/*
* Number of user chains. Since tables cannot have loops, at most
* @stacksize jumps (number of user chains) can possibly be made.
*/
unsigned int stacksize;
void ***jumpstack;
/* 每个cpu的ipt_entry指针,指向ipt_entry的首地址 */
unsigned char entries[0] __aligned(8);
};

xt_table_info结构的entries成员指向了匹配规则的入口,入口的每个数组包含了多个rule;

Netfilter 中规则是顺序存储的,一条rule规则主要包括三个部

  • ipt_entry:标准匹配结构,主要包含数据包的源、目的IP,出、入接口和掩码等;
  • ipt_entry_match:扩展匹配。一条rule规则可能有零个或多个ipt_entry_match结构;
  • ipt_entry_target:一条rule规则有且仅有一个target动作。就是当所有的标准匹配和扩展匹配都符合之后才来执行该target。
      • /*ipt_entry中包含ipt_ip结构,用于标准match,匹配内容为源目的地址,入出口设备,协议等*/
        /* Yes, Virginia, you have to zero the padding. */
        struct ipt_ip {
        /* Source and destination IP addr */
        struct in_addr src, dst; /* 源目的地址 */
        /* Mask for src and dest IP addr */
        struct in_addr smsk, dmsk;/* 源目的掩码 */
        char iniface[IFNAMSIZ], outiface[IFNAMSIZ]; /* 入口出口设备 */
        unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ]; /* 入口出口设备掩码 */ /* Protocol, 0 = ANY */
        __u16 proto;/* 协议号 */ /* Flags word */
        __u8 flags;
        /* Inverse flags */
        __u8 invflags; /* 是否是反转匹配 */
        };
        /* This structure defines each of the firewall rules.  Consists of 3
        parts which are 1) general IP header stuff 2) match specific
        stuff 3) the target to perform if the rule matches */
        struct ipt_entry {
        struct ipt_ip ip; /* Mark with fields that we care about. */
        unsigned int nfcache; /* Size of ipt_entry + matches */
        /* target区的偏移,通常target区位于match区之后,而match区则在ipt_entry的末尾;
        初始化为sizeof(struct ipt_entry),即假定没有match */
        __u16 target_offset;
        /* Size of ipt_entry + matches + target */
        /* 下一条规则相对于本规则的偏移,也即本规则所用空间的总和,
        初始化为sizeof(struct ipt_entry)+sizeof(struct ipt_target),即没有match */ __u16 next_offset; /* Back pointer */
        unsigned int comefrom; /* Packet and byte counters. *//* 记录该规则处理过的报文数和报文总字节数 */
        struct xt_counters counters; /* The matches (if any), then the target. *//*target或者是match的起始位置 */
        unsigned char elems[0];
        };
        /*
        ipt_entry_match将内核态与用户态关联起来,按我的理解,内核和用户在注册和维护match时使用的是各自的match结构ipt_match和iptables_match,
        但在具体应用到某个规则时则需要统一成ipt_entry_match结构。
        前面说过,match区存储在ipt_entry的末尾,target在最后,结合ipt_entry_match的定义,可以知道一条具体的规则中存储的数据结构不是:
        ipt_entry + ipt_match1 + ipt_match2 + ipt_match3 + … + target
        而是:
        ipt_entry + ipt_entry_match1 + ipt_entry_match2 + ipt_entry_match3 + … + target
        */
        struct xt_entry_match {
        union {
        struct {
        __u16 match_size;
        /* Used by userspace */
        char name[XT_EXTENSION_MAXNAMELEN];
        __u8 revision;
        } user;
        struct {
        __u16 match_size;
        /* Used inside the kernel */
        struct xt_match *match;
        } kernel;
        /* Total length */
        __u16 match_size;
        } u;
        unsigned char data[0];
        };
        /*

        在某条规则匹配之后,执行的动作;也分为标准target和扩展target;

        标准target:t->u.kernel.target->target为NULL,则为标准target,根据verdict返回值决定如何进行下一步处理;扩展target:t->u.kernel.target->target不为NULL,则为扩展target,这时候需要执行该target函数

        */
        struct xt_entry_target {
        union {
        struct {
        __u16 target_size;
        /* Used by userspace */
        char name[XT_EXTENSION_MAXNAMELEN];
        __u8 revision;
        } user;
        struct {
        __u16 target_size;
        /* Used inside the kernel */
        struct xt_target *target;
        } kernel;
        /* Total length */
        __u16 target_size;
        } u;
        unsigned char data[0];
        xt_standard_target对xt_entry_target成员进行了封装,增加了verdict,该字段用于返回处理结果
        struct xt_standard_target {
        struct xt_entry_target target;
        int verdict;
        };
        };

        target主要用来处理:当某条规则中的所有match都被数据包匹配后该执行什么样的动作来处理这个报文,最后将处理后结果通过verdict值返回给Netfilter框架

linux netfilter rule match target 数据结构的更多相关文章

  1. linux Netfilterr中扩展match target

    Match: netfilter定义了一个通用的match数据结构struct xt_match /* 每个struct xt_match代表一个扩展match,netfilter中各个扩展match ...

  2. linux netfilter ----iptable_filter

    内核中将filter模块被组织成了一个独立的模块,每个这样独立的模块中都有个类似的init()初始化函数:首先来看一下filter模块是如何将自己的钩子函数注册到netfilter所管辖的几个hook ...

  3. linux netfilter nat2

    linux netfilter nat1 后面在上传

  4. linux netfilter nat1

    linux netfilter nat1 2020整理云笔记上传

  5. Linux内核中常用的数据结构和算法(转)

    知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...

  6. Linux tgtadm: Setup iSCSI Target ( SAN )

    Linux target framework (tgt) aims to simplify various SCSI target driver (iSCSI, Fibre Channel, SRP, ...

  7. Linux VFS的主要的数据结构

    先说明一下,linux内核中各种数据结构也不停的在变,所以不同版本的内核各个数据结构的定义可能会差别很大,这一组关于linux 文件系统的文章中的代码都摘自linux-2.6.34.1. VFS依赖于 ...

  8. linux驱动移植的重要数据结构

    转载:http://www.embeddedlinux.org.cn/html/jishuzixun/201304/14-2538.html 对于嵌入式 Linux 系统来说,有各种体系结构的处理器和 ...

  9. linux netfilter 五个钩子点

    参考http://www.linuxtcpipstack.com/685.html#NF_INET_PRE_ROUTING https://opengers.github.io/openstack/o ...

随机推荐

  1. 习题3-5 谜题(Puzzle, ACM/ICPC World Finals 1993, UVa227)

    #include<stdio.h> #include<string.h> char s[5][5]; int main() { while(gets(s[0])) { int ...

  2. 用python you-get下载视频

    安装python3后 安装you-get包: pip3 install you-get 下载视频: 打开windows终端:运行 you-get url 查看视频信息: you-get -i url ...

  3. centOS7 查看防火墙状态 开放端口

    一.防火墙的开启.关闭.禁用命令 (1)设置开机启用防火墙:systemctl enable firewalld.service (2)设置开机禁用防火墙:systemctl disable fire ...

  4. vue知识点15

    1.回调地狱的三种方案:函数    promise     async await          2. 子组件与子组件之间的传递: 可以借用公共父元素.子组件A  this.$emit(" ...

  5. JS之关于函数

    Javascript的函数也是一个对象 function test() { ... } var test = function(){ ... } 函数内部一旦执行return,则函数执行完毕,如果没有 ...

  6. linux系统软件启动sh脚本

    在系统维护中,编写脚本会帮助运维提高效率,现记录一个通用的软件启动脚本.脚本内容如下: #!/bin/bash # 软件启动程序包名称 APP_NAME=datadog-4.2.0.jar # 软件名 ...

  7. 华为云FusionInsight湖仓一体解决方案的前世今生

    摘要:华为云发布新一代智能数据湖华为云FusionInsight时再次提到了湖仓一体理念,那我们就来看看湖仓一体的来世今生. 伴随5G.大数据.AI.IoT的飞速发展,数据呈现大规模.多样性的极速增长 ...

  8. Js模块化开发的理解

    Js模块化开发的理解 模块化是一个语言发展的必经之路,其能够帮助开发者拆分和组织代码,随着前端技术的发展,前端编写的代码量也越来越大,就需要对代码有很好的管理,而模块化能够帮助开发者解决命名冲突.管理 ...

  9. WC2019 自闭记

    不咕了 Day 1 2019/1/24 辣么快就到冬令营了,还沉迷于被柿子吊打的状态的菜鸡一时半会还反应不过来.我们学校这次分头去的冬令营,差点上不了车.这次做的动车居然直达广州,强啊. 然鹅还是到太 ...

  10. 对Python"一切皆对象"的小参悟

    写在前面 若有误区请大神不吝指正,以免带偏了如我者的弱鸡们 据闻对此不再懵逼后,于函数以及高阶函数编程的进阶有益 类:又称对象,由类创建的个体被称为实例 名言名句"一切皆对象(一切皆类,一切 ...