On Jul 24 2007 18:49, Yasuyuki KOZAKAI wrote:
>>
>> From /ws/iptables (svn code dir):
>>
>> make KERNEL_DIR=/ws/linux/linux-2.6.22 PREFIX=/usr
>> LIBIPT_DIR=/ws/iptables/extensions
>>
>> I did not install it, but ran it from
/ws/iptables.
>
>Wow, I didn't expect such usage. But I'm not sure we
should support
>this usage. The reason why I employed symbolic link
instead of iptables
>searching libxt_*.so is to keep codes simple. Actually
I'm not familiar
>of 'tryload' argument of find_{match,target} so I just
kept the behavior of
>them If I come
up with good idea, I will support it.
Something like this
===
Let the iptable tools search for libxt modules first,
then for l3-specific modules (libipt, libip6t)
Signed-off-by: Jan Engelhardt <jengelh gmx.de>
---
include/xtables.h | 6 ++--
ip6tables-save.c | 4 +-
ip6tables.c | 22 +++++++--------
iptables-save.c | 4 +-
iptables.c | 22 +++++++--------
xtables.c | 78
+++++++++++++++++++++++++++++++++---------------------
6 files changed, 78 insertions(+), 58 deletions(-)
Index: iptables/include/xtables.h
============================================================
=======
--- iptables.orig/include/xtables.h
+++ iptables/include/xtables.h
 -191,8
+191,10  extern void xtables_register_match(struc
extern void xtables_register_target(struct xtables_target
*me);
extern struct xtables_match *find_match(const char *name,
enum xt_tryload,
- struct xtables_rule_match **match);
-extern struct xtables_target *find_target(const char *name,
enum xt_tryload);
+ struct xtables_rule_match **match,
+ unsigned int family);
+extern struct xtables_target *find_target(const char *name,
enum xt_tryload,
+ unsigned int
family);
extern int string_to_number_ll(const char *s,
unsigned long long min,
Index: iptables/ip6tables-save.c
============================================================
=======
--- iptables.orig/ip6tables-save.c
+++ iptables/ip6tables-save.c
 -100,7
+100,7  static int print_match(const struct ip6t
const struct ip6t_ip6 *ip)
{
struct ip6tables_match *match
- = find_match(e->u.user.name, TRY_LOAD, NULL);
+ = find_match(e->u.user.name, TRY_LOAD, NULL,
"ip6t");
if (match) {
printf("-m %s ", e->u.user.name);
 -196,7
+196,7  static void print_rule(const struct ip6t
t = ip6t_get_target((struct ip6t_entry *)e);
if (t->u.user.name[0]) {
struct ip6tables_target *target
- = find_target(t->u.user.name, TRY_LOAD);
+ = find_target(t->u.user.name, TRY_LOAD, AF_INET6);
if (!target) {
fprintf(stderr, "Can't find library for target
`%s'n",
Index: iptables/ip6tables.c
============================================================
=======
--- iptables.orig/ip6tables.c
+++ iptables/ip6tables.c
 -700,9
+700,9  find_proto(const char *pname, enum ip6t_
char *protoname = proto_to_name(proto, nolookup);
if (protoname)
- return find_match(protoname, tryload, matches);
+ return find_match(protoname, tryload, matches,
AF_INET6);
} else
- return find_match(pname, tryload, matches);
+ return find_match(pname, tryload, matches, AF_INET6);
return NULL;
}
 -926,7
+926,7  print_match(const struct ip6t_entry_matc
const struct ip6t_ip6 *ip,
int numeric)
{
- struct ip6tables_match *match =
find_match(m->u.user.name, TRY_LOAD, NULL);
+ struct ip6tables_match *match =
find_match(m->u.user.name, TRY_LOAD, NULL, AF_INET6);
if (match) {
if (match->print)
 -955,9
+955,9  print_firewall(const struct ip6t_entry *
char buf[BUFSIZ];
if (!ip6tc_is_chain(targname, handle))
- target = find_target(targname, TRY_LOAD);
+ target = find_target(targname, TRY_LOAD, AF_INET6);
else
- target = find_target(IP6T_STANDARD_TARGET,
LOAD_MUST_SUCCEED);
+ target = find_target(IP6T_STANDARD_TARGET,
LOAD_MUST_SUCCEED, AF_INET6);
t = ip6t_get_target((struct ip6t_entry *)fw);
flags = fw->ipv6.flags;
 -1510,7
+1510,7  int do_command6(int argc, char *argv[],
exit_error(PARAMETER_PROBLEM,
"chain name not allowed to start "
"with `%c'n", *optarg);
- if (find_target(optarg, TRY_LOAD))
+ if (find_target(optarg, TRY_LOAD, AF_INET6))
exit_error(PARAMETER_PROBLEM,
"chain name may not clash "
"with target namen");
 -1561,7
+1561,7  int do_command6(int argc, char *argv[],
/* ip6tables -p icmp -h */
if (!matches && protocol)
- find_match(protocol, TRY_LOAD, &matches);
+ find_match(protocol, TRY_LOAD, &matches,
AF_INET6);
exit_printhelp(matches);
 -1612,7
+1612,7  int do_command6(int argc, char *argv[],
invert);
jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
- target = find_target(jumpto, TRY_LOAD);
+ target = find_target(jumpto, TRY_LOAD, AF_INET6);
if (target) {
size_t size;
 -1662,7
+1662,7  int do_command6(int argc, char *argv[],
exit_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
- m = find_match(optarg, LOAD_MUST_SUCCEED,
&matches);
+ m = find_match(optarg, LOAD_MUST_SUCCEED, &matches,
AF_INET6);
size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+ m->size;
m->m = fw_calloc(1, size);
 -1937,7
+1937,7  int do_command6(int argc, char *argv[],
size_t size;
target = find_target(IP6T_STANDARD_TARGET,
- LOAD_MUST_SUCCEED);
+ LOAD_MUST_SUCCEED, AF_INET6);
size = sizeof(struct ip6t_entry_target)
+ target->size;
 -1953,7
+1953,7  int do_command6(int argc, char *argv[],
* We cannot know if the plugin is corrupt, non
* existant OR if the user just misspelled a
* chain. */
- find_target(jumpto, LOAD_MUST_SUCCEED);
+ find_target(jumpto, LOAD_MUST_SUCCEED, AF_INET6);
} else {
e = generate_entry(&fw, matches, target->t);
free(target->t);
Index: iptables/iptables-save.c
============================================================
=======
--- iptables.orig/iptables-save.c
+++ iptables/iptables-save.c
 -119,7
+119,7  static int print_match(const struct ipt_
const struct ipt_ip *ip)
{
struct iptables_match *match
- = find_match(e->u.user.name, TRY_LOAD, NULL);
+ = find_match(e->u.user.name, TRY_LOAD, NULL,
AF_INET);
if (match) {
printf("-m %s ", e->u.user.name);
 -207,7
+207,7  static void print_rule(const struct ipt_
t = ipt_get_target((struct ipt_entry *)e);
if (t->u.user.name[0]) {
struct iptables_target *target
- = find_target(t->u.user.name, TRY_LOAD);
+ = find_target(t->u.user.name, TRY_LOAD, AF_INET);
if (!target) {
fprintf(stderr, "Can't find library for target
`%s'n",
Index: iptables/iptables.c
============================================================
=======
--- iptables.orig/iptables.c
+++ iptables/iptables.c
 -687,9
+687,9  find_proto(const char *pname, enum ipt_t
char *protoname = proto_to_name(proto, nolookup);
if (protoname)
- return find_match(protoname, tryload, matches);
+ return find_match(protoname, tryload, matches,
AF_INET);
} else
- return find_match(pname, tryload, matches);
+ return find_match(pname, tryload, matches, AF_INET);
return NULL;
}
 -964,7
+964,7  print_match(const struct ipt_entry_match
const struct ipt_ip *ip,
int numeric)
{
- struct iptables_match *match =
find_match(m->u.user.name, TRY_LOAD, NULL);
+ struct iptables_match *match =
find_match(m->u.user.name, TRY_LOAD, NULL, AF_INET);
if (match) {
if (match->print)
 -993,9
+993,9  print_firewall(const struct ipt_entry *f
char buf[BUFSIZ];
if (!iptc_is_chain(targname, handle))
- target = find_target(targname, TRY_LOAD);
+ target = find_target(targname, TRY_LOAD, AF_INET);
else
- target = find_target(IPT_STANDARD_TARGET,
LOAD_MUST_SUCCEED);
+ target = find_target(IPT_STANDARD_TARGET,
LOAD_MUST_SUCCEED, AF_INET);
t = ipt_get_target((struct ipt_entry *)fw);
flags = fw->ip.flags;
 -1566,7
+1566,7  int do_command(int argc, char *argv[], c
exit_error(PARAMETER_PROBLEM,
"chain name not allowed to start "
"with `%c'n", *optarg);
- if (find_target(optarg, TRY_LOAD))
+ if (find_target(optarg, TRY_LOAD, AF_INET))
exit_error(PARAMETER_PROBLEM,
"chain name may not clash "
"with target namen");
 -1617,7
+1617,7  int do_command(int argc, char *argv[], c
/* iptables -p icmp -h */
if (!matches && protocol)
- find_match(protocol, TRY_LOAD, &matches);
+ find_match(protocol, TRY_LOAD, &matches, AF_INET);
exit_printhelp(matches);
 -1670,7
+1670,7  int do_command(int argc, char *argv[], c
invert);
jumpto = parse_target(optarg);
/* TRY_LOAD (may be chain name) */
- target = find_target(jumpto, TRY_LOAD);
+ target = find_target(jumpto, TRY_LOAD, AF_INET);
if (target) {
size_t size;
 -1728,7
+1728,7  int do_command(int argc, char *argv[], c
exit_error(PARAMETER_PROBLEM,
"unexpected ! flag before --match");
- m = find_match(optarg, LOAD_MUST_SUCCEED,
&matches);
+ m = find_match(optarg, LOAD_MUST_SUCCEED, &matches,
AF_INET);
size = IPT_ALIGN(sizeof(struct ipt_entry_match))
+ m->size;
m->m = fw_calloc(1, size);
 -2002,7
+2002,7  int do_command(int argc, char *argv[], c
size_t size;
target = find_target(IPT_STANDARD_TARGET,
- LOAD_MUST_SUCCEED);
+ LOAD_MUST_SUCCEED, AF_INET);
size = sizeof(struct ipt_entry_target)
+ target->size;
 -2026,7
+2026,7  int do_command(int argc, char *argv[], c
exit_error(PARAMETER_PROBLEM,
"goto '%s' is not a chainn", jumpto);
#endif
- find_target(jumpto, LOAD_MUST_SUCCEED);
+ find_target(jumpto, LOAD_MUST_SUCCEED, AF_INET);
} else {
e = generate_entry(&fw, matches, target->t);
free(target->t);
Index: iptables/xtables.c
============================================================
=======
--- iptables.orig/xtables.c
+++ iptables/xtables.c
 -31,6
+31,7 
#include <xtables.h>
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define NPROTO 255
#ifndef PROC_SYS_MODPROBE
 -255,8
+256,15  void parse_interface(const char *arg, ch
}
}
+static const char *const family_prefix[] = {
+ [AF_UNSPEC] = "xt",
+ [AF_INET] = "ipt",
+ [AF_INET6] = "ip6t",
+};
+
struct xtables_match *find_match(const char *name, enum
xt_tryload tryload,
- struct xtables_rule_match **matches)
+ struct xtables_rule_match **matches,
+ unsigned int family)
{
struct xtables_match *ptr;
const char *icmp6 = "icmp6";
 -292,21
+300,27  struct xtables_match *find_match(const c
if (!ptr && tryload != DONT_LOAD &&
tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/.so")
+ strlen(afinfo.libprefix) + strlen(name)];
- sprintf(path, "%s/%s%s.so", lib_dir,
afinfo.libprefix,
- name);
- if (dlopen(path, RTLD_NOW)) {
- /* Found library. If it didn't register itself,
- maybe they specified target as match. */
- ptr = find_match(name, DONT_LOAD, NULL);
-
- if (!ptr)
- exit_error(PARAMETER_PROBLEM,
- "Couldn't load match `%s'n",
- name);
- } else if (tryload == LOAD_MUST_SUCCEED)
+
+ snprintf(path, sizeof(path), "%s/lib%s_%s.so",
lib_dir,
+ family_prefix[AF_UNSPEC], name);
+ if (dlopen(path, RTLD_NOW) != NULL)
+ /*
+ * Library loaded (and its constructors run).
+ * Try to grab the pointer to the struct.
+ */
+ ptr = find_match(name, DONT_LOAD, NULL, family);
+
+ if (ptr == NULL && family <
ARRAY_SIZE(family_prefix) &&
+ family_prefix[family] != NULL) {
+ snprintf(path, sizeof(path),
"%s/lib%s_%s.so",
+ lib_dir, family_prefix[family], name);
+ if (dlopen(path, RTLD_NOW) != NULL)
+ ptr = find_match(name, DONT_LOAD, NULL, family);
+ }
+
+ if (ptr == NULL && tryload == LOAD_MUST_SUCCEED)
exit_error(PARAMETER_PROBLEM,
- "Couldn't load match `%s':%sn",
- name, dlerror());
+ "Couldn't load match `%s'n", name);
}
#else
if (ptr && !ptr->loaded) {
 -341,7
+355,8  struct xtables_match *find_match(const c
}
-struct xtables_target *find_target(const char *name, enum
xt_tryload tryload)
+struct xtables_target *find_target(const char *name, enum
xt_tryload tryload,
+ unsigned int family)
{
struct xtables_target *ptr;
 -362,19
+377,22  struct xtables_target *find_target(const
if (!ptr && tryload != DONT_LOAD &&
tryload != DURING_LOAD) {
char path[strlen(lib_dir) + sizeof("/.so")
+ strlen(afinfo.libprefix) + strlen(name)];
- sprintf(path, "%s/%s%s.so", lib_dir,
afinfo.libprefix, name);
- if (dlopen(path, RTLD_NOW)) {
- /* Found library. If it didn't register itself,
- maybe they specified match as a target. */
- ptr = find_target(name, DONT_LOAD);
- if (!ptr)
- exit_error(PARAMETER_PROBLEM,
- "Couldn't load target `%s'n",
- name);
- } else if (tryload == LOAD_MUST_SUCCEED)
+
+ snprintf(path, sizeof(path), "%s/lib%s_%s.so",
lib_dir,
+ family_prefix[AF_UNSPEC], name);
+ if (dlopen(path, RTLD_NOW) != NULL)
+ ptr = find_target(name, DONT_LOAD, family);
+
+ if (ptr == NULL && family <
ARRAY_SIZE(family_prefix) &&
+ family_prefix[family] != NULL) {
+ snprintf(path, sizeof(path),
"%s/lib%s_%s.so",
+ lib_dir, family_prefix[family], name);
+ if (dlopen(path, RTLD_NOW) != NULL)
+ ptr = find_target(name, DONT_LOAD, family);
+ }
+ if (ptr == NULL && tryload == LOAD_MUST_SUCCEED)
exit_error(PARAMETER_PROBLEM,
- "Couldn't load target `%s':%sn",
- name, dlerror());
+ "Couldn't load target `%s'n", name);
}
#else
if (ptr && !ptr->loaded) {
 -472,7
+490,7  void xtables_register_match(struct xtabl
if (me->family != afinfo.family)
return;
- old = find_match(me->name, DURING_LOAD, NULL);
+ old = find_match(me->name, DURING_LOAD, NULL,
me->family);
if (old) {
if (old->revision == me->revision) {
fprintf(stderr,
 -538,7
+556,7  void xtables_register_target(struct xtab
if (me->family != afinfo.family)
return;
- old = find_target(me->name, DURING_LOAD);
+ old = find_target(me->name, DURING_LOAD,
me->family);
if (old) {
struct xtables_target **i;
|