对于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. 【linux-centos】安装ifstat!

    1.卸载原装ifstat find / -name *ifstat* 把/usr/sbin/ifstat.ifstat的man目录的.gz文件删除 2.下载安装 wget http://gael.ro ...

  2. java中的t怎么用

    <T> T表示返回值是一个泛型,传递啥,就返回啥类型的数据,而单独的T就是表示限制你传递的参数类型,这个案例中,通过一个泛型的返回方式,获取每一个集合中的第一个数据, 通过返回值<T ...

  3. PS矢量工具

    4.1PS矢量及位图 (1)位图就是像素图,由一个个像素点组成:矢量图是记录点到点的连线或者说程序算出来的图. (2)位图放大很多倍之后就会失真,可以看到像素点,类似于马赛克,所以有分辨率这一说. ( ...

  4. JAVA NIO 基础学习

    package com.hrd.netty.demo.jnio; import java.io.BufferedReader; import java.io.IOException; import j ...

  5. 【6】TensorFlow光速入门-python模型转换为tfjs模型并使用

    本文地址:https://www.cnblogs.com/tujia/p/13862365.html 系列文章: [0]TensorFlow光速入门-序 [1]TensorFlow光速入门-tenso ...

  6. lua table面向对象扩展

    一 .table扩展 -- 返回table大小 table.size = function(t) local count = 0 for _ in pairs(t) do count = count ...

  7. F2. Same Sum Blocks (Hard) 解析(思維、前綴和、貪心)

    Codeforce 1141 F2. Same Sum Blocks (Hard) 解析(思維.前綴和.貪心) 今天我們來看看CF1141F2(Hard) 題目連結 題目 給你一個數列\(a\),要你 ...

  8. String字符串性能优化的探究

    一.背景 String 对象是我们使用最频繁的一个对象类型,但它的性能问题却是最容易被忽略的.String 对象作为 Java 语言中重要的数据类型,是内存中占用空间最大的一个对象,高效地使用字符串, ...

  9. Docker知识进阶与容器编排技术

    目录 1 使用Dockerfile定制redis镜像 1.1 环境准备 1.2 编写Dockerfile文件 1.3 通过Dockerfile构建镜像 1.4 通过镜像运行容器 1.5 官方镜像替代我 ...

  10. 16 String类

    java中的所有的字符串文字(例如"abc","123")都可以看做是实现了此类的实例对象 eg: String str = new String(); str ...