对于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框架

最新文章

  1. phpstorm 配置 xdebug调试工具
  2. Objective-C语言--属性和实例变量
  3. Java当中的反射
  4. 又来了,SDE非直连
  5. IOS学习-报错误 Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
  6. codeforces 675D Tree Construction set
  7. slf4j-api-1.7.5日志打印实验
  8. DLL技术应用04 - 零基础入门学习Delphi47
  9. Office转HTML
  10. MVC中AuthConfig的作用 -- ASP.NET MVC 4 使用 OAuth
  11. [Open Source] 负载均衡之Nginx
  12. javascript DOM操作 节点的遍历
  13. Jenkins环境搭建(3)-配置自动发送邮件
  14. linux 安装 Python
  15. PHP编译安装时常见错误解决办法,php编译常见错误
  16. IDEA用maven打war包
  17. Kernel space是啥?
  18. 10-09 Linux的文件系统介绍以及各种设备的说明
  19. Content Editor Webpart(三)使用JSOM
  20. HashMap与ConcurrentHashMap的区别(转)

热门文章

  1. Idea 配置codeTemplate
  2. EDI模拟实验
  3. MacBook连接蓝牙鼠标、蓝牙键盘失败的解决方案
  4. day25 Pyhton学习 MD5加密.日志
  5. kettle学习笔记(三)— 定时任务的脚本执行
  6. Java jvm 类加载 反射
  7. 前端在开发过程中怎么提高网站的seo?
  8. 使用js模拟点击,点击a链接 $("#abc ").click(); 无效的解决方案
  9. 4G工业路由器的信号强度应该怎么保证呢?
  10. scrapy反反爬虫策略和settings配置解析