以前发现使用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
阅读(5754) | 评论(0) | 转发(0) |