王阳明大传 百度网盘:iptables自动加载内核模块的原理|iptables,内核模块

来源:百度文库 编辑:中财网 时间:2024/04/28 14:31:06

iptables自动加载内核模块的原理

作者:      来源:zz     发表时间:2006-08-28     浏览次数: 6699      字号:大  中  小

中国源码网内相关主题链接
  • Nfs 穿过iptables
  • iptables整体模块结构图
  • iptables下udp穿越--iptables...
  • Linux下IpTables的配置
  • 内核模块如何被调入内核工作
  • 如何用Netfilter/IPtables限制...
  • 简释iptables防火墙
  • iptables自动加载内核模块的原理
  • 以前发现使用iptables时,系统所用的模块都会自动加载。比如说使用iptables -t nat -L
    系统会自动加载ip_tables,ip_nat, iptables_nat等模块。看了源码(2.6.14),终于找到了原因。

    当使用iptables进行配置的时候,内核会调用相应的match,
    在net/ipv4/netfilter/ip_tables.c中调用了try_then_request_module()
    702 static inline int
    703 check_match(struct ipt_entry_match *m,
    704             const char *name,
    705             const struct ipt_ip *ip,
    706             unsigned int hookmask,
    707             unsigned int *i)
    708 {
    709         struct ipt_match *match;
    710
    711         match = try_then_request_module(find_match(m->u.user.name,
    712                                                    m->u.user.revision),
    713                                         "ipt_%s", m->u.user.name);
    714 。。。。。。


    try_then_request_module在include/linux/kmod.h中
     36
     37 #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
     38

    try_then_request_module先检查模块是否已经存在,如果不存在使用request_module(mod)加载mod.
    request_module在kernel/kmod.c中。

     51
     52 /**
     53  * request_module - try to load a kernel module
     54  * @fmt:     printf style format string for the name of the module
     55  * @varargs: arguements as specified in the format string
     56  *
     57  * Load a module using the user mode module loader. The function returns
     58  * zero on success or a negative errno code on failure. Note that a
     59  * successful module load does not mean the module did not then unload
     60  * and exit on an error of its own. Callers must check that the service
     61  * they requested is now available not blindly invoke it.
     62  *
     63  * If module auto-loading support is disabled then this function
     64  * becomes a no-operation.
     65  */
     66 int request_module(const char *fmt, ...)
     67 {
     68         va_list args;
     69         char module_name[MODULE_NAME_LEN];
     70         unsigned int max_modprobes;
     71         int ret;
     72         char *argv[] = { modprobe_path, "-q", "--", module_name, NULL };
     73         static char *envp[] = { "HOME=/",
     74                                 "TERM=linux",
     75                                 "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
     76                                 NULL };
     77         static atomic_t kmod_concurrent = ATOMIC_INIT(0);
     78 #define MAX_KMOD_CONCURRENT 50  /* Completely arbitrary value - KAO */
     79         static int kmod_loop_msg;
     80
     81         va_start(args, fmt);
     82         ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
     83         va_end(args);
     84         if (ret >= MODULE_NAME_LEN)
     85                 return -ENAMETOOLONG;
     86
     87         /* If modprobe needs a service that is in a module, we get a recursive
     88          * loop.  Limit the number of running kmod threads to max_threads/2 or
     89          * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
     90          * would be to run the parents of this process, counting how many times
     91          * kmod was invoked.  That would mean accessing the internals of the
     92          * process tables to get the command line, proc_pid_cmdline is static
     93          * and it is not worth changing the proc code just to handle this case.
     94          * KAO.
     95          *
     96          * "trace the ppid" is simple, but will fail if someone's
     97          * parent exits.  I think this is as good as it gets. --RR
     98          */
     99         max_modprobes = min(max_threads/2, MAX_KMOD_CONCURRENT);
    100         atomic_inc(&kmod_concurrent);
    101         if (atomic_read(&kmod_concurrent) > max_modprobes) {
    102                 /* We may be blaming an innocent here, but unlikely */
    103                 if (kmod_loop_msg++ < 5)
    104                         printk(KERN_ERR
    105                                "request_module: runaway loop modprobe %s\n",
    106                                module_name);
    107                 atomic_dec(&kmod_concurrent);
    108                 return -ENOMEM;
    109         }
    110
    111         ret = call_usermodehelper(modprobe_path, argv, envp, 1);
    112         atomic_dec(&kmod_concurrent);
    113         return ret;
    114 }
    115 EXPORT_SYMBOL(request_module);
    116 #endif /* CONFIG_KMOD */
    117