diff options
| -rw-r--r-- | include/net/netfilter/nf_conntrack.h | 4 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 1 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_core.c | 31 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_standalone.c | 2 | ||||
| -rw-r--r-- | net/netfilter/xt_connmark.c | 17 | ||||
| -rw-r--r-- | net/netfilter/xt_conntrack.c | 28 | ||||
| -rw-r--r-- | net/netfilter/xt_helper.c | 17 | ||||
| -rw-r--r-- | net/netfilter/xt_state.c | 29 |
9 files changed, 130 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 2743c156caa0..b6f0905a4ee2 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
| @@ -195,6 +195,10 @@ static inline void nf_ct_put(struct nf_conn *ct) | |||
| 195 | nf_conntrack_put(&ct->ct_general); | 195 | nf_conntrack_put(&ct->ct_general); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | /* Protocol module loading */ | ||
| 199 | extern int nf_ct_l3proto_try_module_get(unsigned short l3proto); | ||
| 200 | extern void nf_ct_l3proto_module_put(unsigned short l3proto); | ||
| 201 | |||
| 198 | extern struct nf_conntrack_tuple_hash * | 202 | extern struct nf_conntrack_tuple_hash * |
| 199 | __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, | 203 | __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, |
| 200 | const struct nf_conn *ignored_conntrack); | 204 | const struct nf_conn *ignored_conntrack); |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index cb9c661f3f33..c8abc9d859b9 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -568,6 +568,7 @@ static int init_or_cleanup(int init) | |||
| 568 | return ret; | 568 | return ret; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); | ||
| 571 | MODULE_LICENSE("GPL"); | 572 | MODULE_LICENSE("GPL"); |
| 572 | 573 | ||
| 573 | static int __init init(void) | 574 | static int __init init(void) |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ac35f9526368..c16f62934bd9 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -584,6 +584,7 @@ static int init_or_cleanup(int init) | |||
| 584 | return ret; | 584 | return ret; |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); | ||
| 587 | MODULE_LICENSE("GPL"); | 588 | MODULE_LICENSE("GPL"); |
| 588 | MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); | 589 | MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); |
| 589 | 590 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index c28840656451..0ae281d9bfc3 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | * 26 Jan 2006: Harald Welte <laforge@netfilter.org> | 23 | * 26 Jan 2006: Harald Welte <laforge@netfilter.org> |
| 24 | * - restructure nf_conn (introduce nf_conn_help) | 24 | * - restructure nf_conn (introduce nf_conn_help) |
| 25 | * - redesign 'features' how they were originally intended | 25 | * - redesign 'features' how they were originally intended |
| 26 | * 26 Feb 2006: Pablo Neira Ayuso <pablo@eurodev.net> | ||
| 27 | * - add support for L3 protocol module load on demand. | ||
| 26 | * | 28 | * |
| 27 | * Derived from net/ipv4/netfilter/ip_conntrack_core.c | 29 | * Derived from net/ipv4/netfilter/ip_conntrack_core.c |
| 28 | */ | 30 | */ |
| @@ -241,6 +243,35 @@ void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p) | |||
| 241 | module_put(p->me); | 243 | module_put(p->me); |
| 242 | } | 244 | } |
| 243 | 245 | ||
| 246 | int | ||
| 247 | nf_ct_l3proto_try_module_get(unsigned short l3proto) | ||
| 248 | { | ||
| 249 | int ret; | ||
| 250 | struct nf_conntrack_l3proto *p; | ||
| 251 | |||
| 252 | retry: p = nf_ct_l3proto_find_get(l3proto); | ||
| 253 | if (p == &nf_conntrack_generic_l3proto) { | ||
| 254 | ret = request_module("nf_conntrack-%d", l3proto); | ||
| 255 | if (!ret) | ||
| 256 | goto retry; | ||
| 257 | |||
| 258 | return -EPROTOTYPE; | ||
| 259 | } | ||
| 260 | |||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | |||
| 264 | void nf_ct_l3proto_module_put(unsigned short l3proto) | ||
| 265 | { | ||
| 266 | struct nf_conntrack_l3proto *p; | ||
| 267 | |||
| 268 | preempt_disable(); | ||
| 269 | p = __nf_ct_l3proto_find(l3proto); | ||
| 270 | preempt_enable(); | ||
| 271 | |||
| 272 | module_put(p->me); | ||
| 273 | } | ||
| 274 | |||
| 244 | static int nf_conntrack_hash_rnd_initted; | 275 | static int nf_conntrack_hash_rnd_initted; |
| 245 | static unsigned int nf_conntrack_hash_rnd; | 276 | static unsigned int nf_conntrack_hash_rnd; |
| 246 | 277 | ||
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 290d5a0c559b..75577e175b35 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c | |||
| @@ -834,6 +834,8 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init); | |||
| 834 | EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); | 834 | EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache); |
| 835 | EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); | 835 | EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); |
| 836 | #endif | 836 | #endif |
| 837 | EXPORT_SYMBOL(nf_ct_l3proto_try_module_get); | ||
| 838 | EXPORT_SYMBOL(nf_ct_l3proto_module_put); | ||
| 837 | EXPORT_SYMBOL(nf_conntrack_l3proto_register); | 839 | EXPORT_SYMBOL(nf_conntrack_l3proto_register); |
| 838 | EXPORT_SYMBOL(nf_conntrack_l3proto_unregister); | 840 | EXPORT_SYMBOL(nf_conntrack_l3proto_unregister); |
| 839 | EXPORT_SYMBOL(nf_conntrack_protocol_register); | 841 | EXPORT_SYMBOL(nf_conntrack_protocol_register); |
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c index e810600345e3..7b16f1ee16b4 100644 --- a/net/netfilter/xt_connmark.c +++ b/net/netfilter/xt_connmark.c | |||
| @@ -64,14 +64,30 @@ checkentry(const char *tablename, | |||
| 64 | printk(KERN_WARNING "connmark: only support 32bit mark\n"); | 64 | printk(KERN_WARNING "connmark: only support 32bit mark\n"); |
| 65 | return 0; | 65 | return 0; |
| 66 | } | 66 | } |
| 67 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 68 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | ||
| 69 | printk(KERN_WARNING "can't load nf_conntrack support for " | ||
| 70 | "proto=%d\n", match->family); | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | #endif | ||
| 67 | return 1; | 74 | return 1; |
| 68 | } | 75 | } |
| 69 | 76 | ||
| 77 | static void | ||
| 78 | destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) | ||
| 79 | { | ||
| 80 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 81 | nf_ct_l3proto_module_put(match->family); | ||
| 82 | #endif | ||
| 83 | } | ||
| 84 | |||
| 70 | static struct xt_match connmark_match = { | 85 | static struct xt_match connmark_match = { |
| 71 | .name = "connmark", | 86 | .name = "connmark", |
| 72 | .match = match, | 87 | .match = match, |
| 73 | .matchsize = sizeof(struct xt_connmark_info), | 88 | .matchsize = sizeof(struct xt_connmark_info), |
| 74 | .checkentry = checkentry, | 89 | .checkentry = checkentry, |
| 90 | .destroy = destroy, | ||
| 75 | .family = AF_INET, | 91 | .family = AF_INET, |
| 76 | .me = THIS_MODULE | 92 | .me = THIS_MODULE |
| 77 | }; | 93 | }; |
| @@ -81,6 +97,7 @@ static struct xt_match connmark6_match = { | |||
| 81 | .match = match, | 97 | .match = match, |
| 82 | .matchsize = sizeof(struct xt_connmark_info), | 98 | .matchsize = sizeof(struct xt_connmark_info), |
| 83 | .checkentry = checkentry, | 99 | .checkentry = checkentry, |
| 100 | .destroy = destroy, | ||
| 84 | .family = AF_INET6, | 101 | .family = AF_INET6, |
| 85 | .me = THIS_MODULE | 102 | .me = THIS_MODULE |
| 86 | }; | 103 | }; |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 7d20caa0d605..65a84809fd30 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
| @@ -203,9 +203,37 @@ match(const struct sk_buff *skb, | |||
| 203 | 203 | ||
| 204 | #endif /* CONFIG_NF_IP_CONNTRACK */ | 204 | #endif /* CONFIG_NF_IP_CONNTRACK */ |
| 205 | 205 | ||
| 206 | static int | ||
| 207 | checkentry(const char *tablename, | ||
| 208 | const void *ip, | ||
| 209 | const struct xt_match *match, | ||
| 210 | void *matchinfo, | ||
| 211 | unsigned int matchsize, | ||
| 212 | unsigned int hook_mask) | ||
| 213 | { | ||
| 214 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 215 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | ||
| 216 | printk(KERN_WARNING "can't load nf_conntrack support for " | ||
| 217 | "proto=%d\n", match->family); | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | #endif | ||
| 221 | return 1; | ||
| 222 | } | ||
| 223 | |||
| 224 | static void | ||
| 225 | destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) | ||
| 226 | { | ||
| 227 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 228 | nf_ct_l3proto_module_put(match->family); | ||
| 229 | #endif | ||
| 230 | } | ||
| 231 | |||
| 206 | static struct xt_match conntrack_match = { | 232 | static struct xt_match conntrack_match = { |
| 207 | .name = "conntrack", | 233 | .name = "conntrack", |
| 208 | .match = match, | 234 | .match = match, |
| 235 | .checkentry = checkentry, | ||
| 236 | .destroy = destroy, | ||
| 209 | .matchsize = sizeof(struct xt_conntrack_info), | 237 | .matchsize = sizeof(struct xt_conntrack_info), |
| 210 | .family = AF_INET, | 238 | .family = AF_INET, |
| 211 | .me = THIS_MODULE, | 239 | .me = THIS_MODULE, |
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c index 7d2d68b9155f..101f0005e987 100644 --- a/net/netfilter/xt_helper.c +++ b/net/netfilter/xt_helper.c | |||
| @@ -144,15 +144,31 @@ static int check(const char *tablename, | |||
| 144 | { | 144 | { |
| 145 | struct xt_helper_info *info = matchinfo; | 145 | struct xt_helper_info *info = matchinfo; |
| 146 | 146 | ||
| 147 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 148 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | ||
| 149 | printk(KERN_WARNING "can't load nf_conntrack support for " | ||
| 150 | "proto=%d\n", match->family); | ||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | #endif | ||
| 147 | info->name[29] = '\0'; | 154 | info->name[29] = '\0'; |
| 148 | return 1; | 155 | return 1; |
| 149 | } | 156 | } |
| 150 | 157 | ||
| 158 | static void | ||
| 159 | destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) | ||
| 160 | { | ||
| 161 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 162 | nf_ct_l3proto_module_put(match->family); | ||
| 163 | #endif | ||
| 164 | } | ||
| 165 | |||
| 151 | static struct xt_match helper_match = { | 166 | static struct xt_match helper_match = { |
| 152 | .name = "helper", | 167 | .name = "helper", |
| 153 | .match = match, | 168 | .match = match, |
| 154 | .matchsize = sizeof(struct xt_helper_info), | 169 | .matchsize = sizeof(struct xt_helper_info), |
| 155 | .checkentry = check, | 170 | .checkentry = check, |
| 171 | .destroy = destroy, | ||
| 156 | .family = AF_INET, | 172 | .family = AF_INET, |
| 157 | .me = THIS_MODULE, | 173 | .me = THIS_MODULE, |
| 158 | }; | 174 | }; |
| @@ -161,6 +177,7 @@ static struct xt_match helper6_match = { | |||
| 161 | .match = match, | 177 | .match = match, |
| 162 | .matchsize = sizeof(struct xt_helper_info), | 178 | .matchsize = sizeof(struct xt_helper_info), |
| 163 | .checkentry = check, | 179 | .checkentry = check, |
| 180 | .destroy = destroy, | ||
| 164 | .family = AF_INET6, | 181 | .family = AF_INET6, |
| 165 | .me = THIS_MODULE, | 182 | .me = THIS_MODULE, |
| 166 | }; | 183 | }; |
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index 7cd557c932ba..e6c0be9d94d2 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c | |||
| @@ -44,9 +44,36 @@ match(const struct sk_buff *skb, | |||
| 44 | return (sinfo->statemask & statebit); | 44 | return (sinfo->statemask & statebit); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | static int check(const char *tablename, | ||
| 48 | const void *inf, | ||
| 49 | const struct xt_match *match, | ||
| 50 | void *matchinfo, | ||
| 51 | unsigned int matchsize, | ||
| 52 | unsigned int hook_mask) | ||
| 53 | { | ||
| 54 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 55 | if (nf_ct_l3proto_try_module_get(match->family) < 0) { | ||
| 56 | printk(KERN_WARNING "can't load nf_conntrack support for " | ||
| 57 | "proto=%d\n", match->family); | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | #endif | ||
| 61 | return 1; | ||
| 62 | } | ||
| 63 | |||
| 64 | static void | ||
| 65 | destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize) | ||
| 66 | { | ||
| 67 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
| 68 | nf_ct_l3proto_module_put(match->family); | ||
| 69 | #endif | ||
| 70 | } | ||
| 71 | |||
| 47 | static struct xt_match state_match = { | 72 | static struct xt_match state_match = { |
| 48 | .name = "state", | 73 | .name = "state", |
| 49 | .match = match, | 74 | .match = match, |
| 75 | .checkentry = check, | ||
| 76 | .destroy = destroy, | ||
| 50 | .matchsize = sizeof(struct xt_state_info), | 77 | .matchsize = sizeof(struct xt_state_info), |
| 51 | .family = AF_INET, | 78 | .family = AF_INET, |
| 52 | .me = THIS_MODULE, | 79 | .me = THIS_MODULE, |
| @@ -55,6 +82,8 @@ static struct xt_match state_match = { | |||
| 55 | static struct xt_match state6_match = { | 82 | static struct xt_match state6_match = { |
| 56 | .name = "state", | 83 | .name = "state", |
| 57 | .match = match, | 84 | .match = match, |
| 85 | .checkentry = check, | ||
| 86 | .destroy = destroy, | ||
| 58 | .matchsize = sizeof(struct xt_state_info), | 87 | .matchsize = sizeof(struct xt_state_info), |
| 59 | .family = AF_INET6, | 88 | .family = AF_INET6, |
| 60 | .me = THIS_MODULE, | 89 | .me = THIS_MODULE, |
