diff -Nru linux-2.6.16/net/netfilter/xt_condition.c linux-2.6.17-entry_data/net/netfilter/xt_condition.c --- linux-2.6.16/net/netfilter/xt_condition.c 2006-04-26 12:07:52.000000000 +0200 +++ linux-2.6.17-entry_data/net/netfilter/xt_condition.c 2006-06-12 01:49:05.000000000 +0200 @@ -116,42 +116,32 @@ static int match(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, + unsigned int protoff, int *hotdrop, void *entry_data) { const struct condition_info *info = - (const struct condition_info *) matchinfo; - struct condition_variable *var; - int condition_status = 0; + (const struct condition_info *) matchinfo; + struct condition_variable *var= + (struct condition_variable *)entry_data; - rcu_read_lock(); - list_for_each_entry_rcu(var, &conditions_list, list) { - if (strcmp(info->name, var->status_proc->name) == 0) { - condition_status = var->enabled; - break; - } - } - rcu_read_unlock(); - - return condition_status ^ info->invert; + return var->enabled ^ info->invert; } static int checkentry(const char *tablename, const void *ip, - void *matchinfo, unsigned int matchsize, unsigned int hook_mask) + const struct xt_match *match, + void *matchinfo, unsigned int matchsize, + unsigned int hook_mask, void **entry_data) { static const char * const forbidden_names[]={ "", ".", ".." }; struct condition_info *info = (struct condition_info *) matchinfo; struct list_head *pos; struct condition_variable *var, *newvar; - int i; - if (matchsize != XT_ALIGN(sizeof(struct condition_info))) - return 0; - /* We don't want a '/' in a proc file name. */ for (i=0; i < CONDITION_NAME_LEN && info->name[i] != '\0'; i++) if (info->name[i] == '/') @@ -175,6 +165,7 @@ var = list_entry(pos, struct condition_variable, list); if (strcmp(info->name, var->status_proc->name) == 0) { var->refcount++; + *entry_data=(void *)var; up(&proc_lock); return 1; } @@ -212,38 +203,34 @@ up(&proc_lock); + *entry_data=(void *)newvar; + return 1; } static void -destroy(void *matchinfo, unsigned int matchsize) +destroy(const struct xt_match *match, void *matchinfo, + unsigned int matchsize, void *entry_data) { struct condition_info *info = (struct condition_info *) matchinfo; - struct list_head *pos; - struct condition_variable *var; + struct condition_variable *var= + (struct condition_variable *)entry_data; - if (matchsize != XT_ALIGN(sizeof(struct condition_info))) - return; + BUG_ON(entry_data==NULL); down(&proc_lock); - list_for_each(pos, &conditions_list) { - var = list_entry(pos, struct condition_variable, list); - if (strcmp(info->name, var->status_proc->name) == 0) { - if (--var->refcount == 0) { - list_del_rcu(pos); - remove_proc_entry(var->status_proc->name, proc_net_condition); - up(&proc_lock); - /* synchronize_rcu() would be goog enough, but synchronize_net() */ - /* guarantees that no packet will go out with the old rule after */ - /* succesful removal. */ - synchronize_net(); - kfree(var); - return; - } - break; - } + if (--var->refcount == 0) { + list_del_rcu(&var->list); + remove_proc_entry(var->status_proc->name, proc_net_condition); + up(&proc_lock); + /* synchronize_rcu() would be goog enough, but synchronize_net() */ + /* guarantees that no packet will go out with the old rule after */ + /* succesful removal. */ + synchronize_net(); + kfree(var); + return; } up(&proc_lock); @@ -252,6 +239,8 @@ static struct xt_match condition_match = { .name = "condition", + .family = AF_INET, + .matchsize = sizeof(struct condition_info), .match = &match, .checkentry = &checkentry, .destroy = &destroy, @@ -260,6 +249,8 @@ static struct xt_match condition6_match = { .name = "condition", + .family = AF_INET, + .matchsize = sizeof(struct condition_info), .match = &match, .checkentry = &checkentry, .destroy = &destroy, @@ -279,17 +270,17 @@ return -EACCES; } - errorcode = xt_register_match(AF_INET, &condition_match); + errorcode = xt_register_match(&condition_match); if (errorcode) { - xt_unregister_match(AF_INET, &condition_match); + xt_unregister_match(&condition_match); remove_proc_entry(dir_name, proc_net); return errorcode; } - errorcode = xt_register_match(AF_INET6, &condition6_match); + errorcode = xt_register_match(&condition6_match); if (errorcode) { - xt_unregister_match(AF_INET6, &condition6_match); - xt_unregister_match(AF_INET, &condition_match); + xt_unregister_match(&condition6_match); + xt_unregister_match(&condition_match); remove_proc_entry(dir_name, proc_net); return errorcode; } @@ -301,8 +292,8 @@ static void __exit fini(void) { - xt_unregister_match(AF_INET6, &condition6_match); - xt_unregister_match(AF_INET, &condition_match); + xt_unregister_match(&condition6_match); + xt_unregister_match(&condition_match); remove_proc_entry(dir_name, proc_net); }