From 3fd6b24ace319b139ec3c4e3031a5f05d21e304e Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Tue, 15 Jun 2010 13:30:55 +0200 Subject: ipset 5 in an almost ready state - milestone Reworked protocol and internal interfaces, missing set types added, backward compatibility verified, lots of tests added (and thanks to the tests, bugs fixed), even the manpage is rewritten ;-). Countless changes everywhere... The missing bits before announcing ipset 5: - net namespace support - new iptables/ip6tables extension library - iptables/ip6tables match and target tests (backward/forward compatibility) - tests on catching syntax errors --- include/libipset/data.h | 11 ++++++-- include/libipset/debug.h | 35 +++++++++++++++++++++++++ include/libipset/linux_ip_set.h | 51 +++++++++++------------------------- include/libipset/linux_ip_set_list.h | 14 ++++++++++ include/libipset/parse.h | 24 ++++++++++++++++- include/libipset/print.h | 6 ++++- include/libipset/session.h | 22 ++++++++++++---- include/libipset/types.h | 36 +++++++++---------------- include/libipset/ui.h | 24 +++++++---------- include/libipset/utils.h | 6 ----- 10 files changed, 139 insertions(+), 90 deletions(-) create mode 100644 include/libipset/debug.h create mode 100644 include/libipset/linux_ip_set_list.h (limited to 'include/libipset') diff --git a/include/libipset/data.h b/include/libipset/data.h index 0ebc1eb..936b807 100644 --- a/include/libipset/data.h +++ b/include/libipset/data.h @@ -50,7 +50,8 @@ enum ipset_opt { IPSET_OPT_EXIST, IPSET_OPT_BEFORE, /* Internal options */ - IPSET_OPT_FLAGS = 48, + IPSET_OPT_FLAGS = 48, /* IPSET_FLAG_EXIST| */ + IPSET_OPT_CADT_FLAGS, /* IPSET_FLAG_BEFORE| */ IPSET_OPT_ELEM, IPSET_OPT_TYPE, IPSET_OPT_LINENO, @@ -63,7 +64,10 @@ enum ipset_opt { #define IPSET_FLAGS_ALL (~0LL) #define IPSET_CREATE_FLAGS \ - ( IPSET_FLAG(IPSET_OPT_IP) \ + ( IPSET_FLAG(IPSET_OPT_FAMILY) \ + | IPSET_FLAG(IPSET_OPT_TYPENAME)\ + | IPSET_FLAG(IPSET_OPT_TYPE) \ + | IPSET_FLAG(IPSET_OPT_IP) \ | IPSET_FLAG(IPSET_OPT_IP_TO) \ | IPSET_FLAG(IPSET_OPT_CIDR) \ | IPSET_FLAG(IPSET_OPT_PORT) \ @@ -89,14 +93,17 @@ enum ipset_opt { | IPSET_FLAG(IPSET_OPT_NAMEREF) \ | IPSET_FLAG(IPSET_OPT_IP2) \ | IPSET_FLAG(IPSET_OPT_CIDR2) \ + | IPSET_FLAG(IPSET_OPT_CADT_FLAGS)\ | IPSET_FLAG(IPSET_OPT_BEFORE)) struct ipset_data; +extern void ipset_strncpy(char *dst, const char *src, size_t len); extern bool ipset_data_flags_test(const struct ipset_data *data, uint64_t flags); extern void ipset_data_flags_set(struct ipset_data *data, uint64_t flags); extern void ipset_data_flags_unset(struct ipset_data *data, uint64_t flags); +extern bool ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt); extern int ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value); diff --git a/include/libipset/debug.h b/include/libipset/debug.h new file mode 100644 index 0000000..1e32ce2 --- /dev/null +++ b/include/libipset/debug.h @@ -0,0 +1,35 @@ +/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef LIBIPSET_DEBUG_H +#define LIBIPSET_DEBUG_H + +#define IPSET_DEBUG + +#ifdef IPSET_DEBUG +#include +#include +#include +#define D(fmt, args...) \ + fprintf(stderr, "%s: %s: " fmt "\n", __FILE__, __FUNCTION__ , ## args) +#define IF_D(test, fmt, args...) \ + if (test) \ + D(fmt , ## args) + +static inline void +dump_nla(struct nlattr *nla[], int maxlen) +{ + int i; + for (i = 0; i < maxlen; i++) + D("nla[%u] does%s exist", i, nla[i] ? "" : " NOT"); +} +#else +#define D(fmt, args...) +#define IF_D(test, fmt, args...) +#define dump_nla(nla, maxlen) +#endif + +#endif /* LIBIPSET_DEBUG_H */ diff --git a/include/libipset/linux_ip_set.h b/include/libipset/linux_ip_set.h index 254fb21..4af75ba 100644 --- a/include/libipset/linux_ip_set.h +++ b/include/libipset/linux_ip_set.h @@ -11,14 +11,10 @@ * published by the Free Software Foundation. */ -#if 1 -#define IP_SET_DEBUG -#endif - /* The protocol version */ #define IPSET_PROTOCOL 5 -/* The max length of strings: set and type identifiers */ +/* The max length of strings including NUL: set and type identifiers */ #define IPSET_MAXNAMELEN 32 /* Message types and commands */ @@ -43,6 +39,7 @@ enum ipset_cmd { IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* Enter restore mode */ IPSET_CMD_HELP, /* Get help */ IPSET_CMD_VERSION, /* Get program version */ + IPSET_CMD_QUIT, /* Quit from interactive mode */ IPSET_CMD_MAX, @@ -58,6 +55,7 @@ enum { IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* rename/swap */ IPSET_ATTR_REVISION, /* Settype revision */ IPSET_ATTR_FAMILY, /* Settype family */ + IPSET_ATTR_FLAGS, /* Flags at command level */ IPSET_ATTR_DATA, /* Nested attributes */ IPSET_ATTR_ADT, /* Multiple data containers */ IPSET_ATTR_LINENO, /* Restore lineno */ @@ -77,8 +75,8 @@ enum { IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT, IPSET_ATTR_PORT_TO, IPSET_ATTR_TIMEOUT, - IPSET_ATTR_FLAGS, - /* IPSET_ATTR_LINENO */ + IPSET_ATTR_CADT_FLAGS, + IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* Reserve empty slots */ IPSET_ATTR_CADT_MAX = 16, /* Create-only specific attributes */ @@ -123,15 +121,19 @@ enum ipset_errno { IPSET_ERR_INVALID_NETMASK, IPSET_ERR_INVALID_FAMILY, IPSET_ERR_TIMEOUT, + IPSET_ERR_REFERENCED, + /* Type specific error codes */ IPSET_ERR_TYPE_SPECIFIC = 160, }; - -enum ipset_data_flags { + +enum ipset_cmd_flags { IPSET_FLAG_BIT_EXIST = 0, IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST), - - IPSET_FLAG_BIT_BEFORE = 2, +}; + +enum ipset_cadt_flags { + IPSET_FLAG_BIT_BEFORE = 0, IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE), }; @@ -140,32 +142,9 @@ enum ipset_adt { IPSET_ADD, IPSET_DEL, IPSET_TEST, - IPSET_CREATE, + IPSET_ADT_MAX, + IPSET_CREATE = IPSET_ADT_MAX, IPSET_CADT_MAX, }; -#ifndef __KERNEL__ -#ifdef IP_SET_DEBUG -#include -#include -#include -#define D(format, args...) do { \ - fprintf(stderr, "%s: %s: ", __FILE__, __FUNCTION__); \ - fprintf(stderr, format "\n" , ## args); \ -} while (0) -static inline void -dump_nla(struct nlattr *nla[], int maxlen) -{ - int i; - - for (i = 0; i < maxlen; i++) - D("nla[%u] does%s exist", i, !nla[i] ? " NOT" : ""); -} - -#else -#define D(format, args...) -#define dump_nla(nla, maxlen) -#endif -#endif /* !__KERNEL__ */ - #endif /* __IP_SET_H */ diff --git a/include/libipset/linux_ip_set_list.h b/include/libipset/linux_ip_set_list.h new file mode 100644 index 0000000..cf282c5 --- /dev/null +++ b/include/libipset/linux_ip_set_list.h @@ -0,0 +1,14 @@ +#ifndef __IP_SET_LIST_H +#define __IP_SET_LIST_H + +/* List type specific error codes */ +enum { + IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC, + IPSET_ERR_LOOP, + IPSET_ERR_BEFORE, + IPSET_ERR_NAMEREF, + IPSET_ERR_LIST_FULL, + IPSET_ERR_REF_EXIST, +}; + +#endif /* __IP_SET_LIST_H */ diff --git a/include/libipset/parse.h b/include/libipset/parse.h index 09c1db4..143e2b3 100644 --- a/include/libipset/parse.h +++ b/include/libipset/parse.h @@ -17,6 +17,9 @@ struct ipset_session; +typedef int (*ipset_parsefn)(struct ipset_session *s, + enum ipset_opt opt, const char *str); + extern int ipset_parse_ether(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_single_port(struct ipset_session *session, @@ -24,7 +27,7 @@ extern int ipset_parse_single_port(struct ipset_session *session, extern int ipset_parse_port(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_family(struct ipset_session *session, - int opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_ip(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_single_ip(struct ipset_session *session, @@ -35,8 +38,16 @@ extern int ipset_parse_range(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_netrange(struct ipset_session *session, enum ipset_opt opt, const char *str); +extern int ipset_parse_iprange(struct ipset_session *session, + enum ipset_opt opt, const char *str); +extern int ipset_parse_ipnet(struct ipset_session *session, + enum ipset_opt opt, const char *str); extern int ipset_parse_name(struct ipset_session *session, enum ipset_opt opt, const char *str); +extern int ipset_parse_before(struct ipset_session *session, + enum ipset_opt opt, const char *str); +extern int ipset_parse_after(struct ipset_session *session, + enum ipset_opt opt, const char *str); extern int ipset_parse_setname(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_uint32(struct ipset_session *session, @@ -51,7 +62,18 @@ extern int ipset_parse_typename(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_output(struct ipset_session *session, int opt, const char *str); +extern int ipset_parse_ignored(struct ipset_session *session, + enum ipset_opt opt, const char *str); extern int ipset_parse_elem(struct ipset_session *session, enum ipset_opt opt, const char *str); +extern int ipset_call_parser(struct ipset_session *session, + ipset_parsefn parse, const char *optstr, + enum ipset_opt optional, const char *str); + +/* Compatibility parser functions */ +extern int ipset_parse_iptimeout(struct ipset_session *session, + enum ipset_opt opt, const char *str); +extern int ipset_parse_name_compat(struct ipset_session *session, + enum ipset_opt opt, const char *str); #endif /* LIBIPSET_PARSE_H */ diff --git a/include/libipset/print.h b/include/libipset/print.h index 343386b..dbb70f3 100644 --- a/include/libipset/print.h +++ b/include/libipset/print.h @@ -9,11 +9,15 @@ #include /* enum ipset_opt */ +typedef int (*ipset_printfn)(char *buf, unsigned int len, + const struct ipset_data *data, enum ipset_opt opt, + uint8_t env); + extern int ipset_print_ether(char *buf, unsigned int len, const struct ipset_data *data, enum ipset_opt opt, uint8_t env); extern int ipset_print_family(char *buf, unsigned int len, - const struct ipset_data *data, int opt, + const struct ipset_data *data, enum ipset_opt opt, uint8_t env); extern int ipset_print_type(char *buf, unsigned int len, const struct ipset_data *data, enum ipset_opt opt, diff --git a/include/libipset/session.h b/include/libipset/session.h index 71b8e02..cc0940e 100644 --- a/include/libipset/session.h +++ b/include/libipset/session.h @@ -12,7 +12,6 @@ #include /* printf */ #include /* enum ipset_cmd */ -#include /* enum ipset_envopt */ /* Report and output buffer sizes */ #define IPSET_ERRORBUFLEN 1024 @@ -54,6 +53,23 @@ extern const char * ipset_session_warning(const struct ipset_session *session); #define ipset_session_data_get(session, opt) \ ipset_data_get(ipset_session_data(session), opt) +/* Environment option flags */ +enum ipset_envopt { + IPSET_ENV_BIT_SORTED = 0, + IPSET_ENV_SORTED = (1 << IPSET_ENV_BIT_SORTED), + IPSET_ENV_BIT_QUIET = 1, + IPSET_ENV_QUIET = (1 << IPSET_ENV_BIT_QUIET), + IPSET_ENV_BIT_RESOLVE = 2, + IPSET_ENV_RESOLVE = (1 << IPSET_ENV_BIT_RESOLVE), + IPSET_ENV_BIT_EXIST = 3, + IPSET_ENV_EXIST = (1 << IPSET_ENV_BIT_EXIST), +}; + +extern int ipset_envopt_parse(struct ipset_session *session, + int env, const char *str); +extern bool ipset_envopt_test(struct ipset_session *session, + enum ipset_envopt env); + enum ipset_output_mode { IPSET_LIST_NONE, IPSET_LIST_PLAIN, @@ -61,10 +77,6 @@ enum ipset_output_mode { IPSET_LIST_XML, }; -extern int ipset_envopt_parse(struct ipset_session *session, - int env, const char *str); -extern bool ipset_envopt_test(struct ipset_session *session, - enum ipset_envopt env); extern int ipset_session_output(struct ipset_session *session, enum ipset_output_mode mode); diff --git a/include/libipset/types.h b/include/libipset/types.h index 461931a..45d5e3d 100644 --- a/include/libipset/types.h +++ b/include/libipset/types.h @@ -10,6 +10,8 @@ #include /* uintxx_t */ #include /* enum ipset_opt */ +#include /* ipset_parsefn */ +#include /* ipset_printfn */ #include /* IPSET_MAXNAMELEN */ #define AF_INET46 255 @@ -39,15 +41,9 @@ enum { struct ipset_session; -typedef int (*ipset_parsefn)(struct ipset_session *s, - enum ipset_opt opt, const char *str); -typedef int (*ipset_printfn)(char *buf, unsigned int len, - const struct ipset_data *data, enum ipset_opt opt, - uint8_t env); - /* Parse and print type-specific arguments */ struct ipset_arg { - const char *name[3]; /* option names */ + const char *name[2]; /* option names */ int has_arg; /* mandatory/optional/no arg */ enum ipset_opt opt; /* argumentum type */ ipset_parsefn parse; /* parser function */ @@ -81,13 +77,13 @@ struct ipset_elem { */ struct ipset_type { char name[IPSET_MAXNAMELEN]; /* type name */ - char alias[IPSET_MAXNAMELEN]; /* name alias */ uint8_t revision; /* revision number */ uint8_t family; /* supported family */ uint8_t dimension; /* elem dimension */ int8_t kernel_check; /* kernel check */ bool last_elem_optional; /* last element optional */ struct ipset_elem elem[IPSET_DIM_MAX]; /* parse elem */ + ipset_parsefn compat_parse_elem; /* compatibility parser */ const struct ipset_arg *args[IPSET_CADT_MAX]; /* create/ADT args except elem */ uint64_t mandatory[IPSET_CADT_MAX]; /* create/ADT mandatory flags */ uint64_t full[IPSET_CADT_MAX]; /* full args flags */ @@ -95,13 +91,18 @@ struct ipset_type { const char *usage; /* terse usage */ struct ipset_type *next; + const char *alias[]; /* name alias(es) */ }; -extern int ipset_cache_add(const char *name, const struct ipset_type *type); +extern int ipset_cache_add(const char *name, const struct ipset_type *type, + uint8_t family); extern int ipset_cache_del(const char *name); extern int ipset_cache_rename(const char *from, const char *to); extern int ipset_cache_swap(const char *from, const char *to); +extern int ipset_cache_init(void); +extern void ipset_cache_fini(void); + extern const struct ipset_type * ipset_type_get(struct ipset_session *session, enum ipset_cmd cmd); extern const struct ipset_type * ipset_type_check(struct ipset_session *session); @@ -109,20 +110,7 @@ extern const struct ipset_type * ipset_type_check(struct ipset_session *session) extern int ipset_type_add(struct ipset_type *type); extern const struct ipset_type * ipset_types(void); extern const char * ipset_typename_resolve(const char *str); - -extern int ipset_types_init(void); -extern void ipset_types_fini(void); - -/* The known set types: (typename, revision, family) is unique */ -extern struct ipset_type ipset_bitmap_ip0; -extern struct ipset_type ipset_bitmap_ipmac0; -extern struct ipset_type ipset_bitmap_port0; -extern struct ipset_type ipset_hash_ip0; -extern struct ipset_type ipset_hash_net0; -extern struct ipset_type ipset_hash_ipport0; -extern struct ipset_type ipset_hash_ipportip0; -extern struct ipset_type ipset_hash_ipportnet0; -extern struct ipset_type ipset_tree_ip0; -extern struct ipset_type ipset_list_set0; +extern bool ipset_match_typename(const char *str, + const struct ipset_type *t); #endif /* LIBIPSET_TYPES_H */ diff --git a/include/libipset/ui.h b/include/libipset/ui.h index 044e586..f8eeae0 100644 --- a/include/libipset/ui.h +++ b/include/libipset/ui.h @@ -9,25 +9,14 @@ /* Commands in userspace */ struct ipset_commands { - const char *name[6]; - const char *help; + enum ipset_cmd cmd; int has_arg; + const char *name[2]; + const char *help; }; extern const struct ipset_commands ipset_commands[]; -/* Environment option flags */ -enum ipset_envopt { - IPSET_ENV_BIT_SORTED = 0, - IPSET_ENV_SORTED = (1 << IPSET_ENV_BIT_SORTED), - IPSET_ENV_BIT_QUIET = 1, - IPSET_ENV_QUIET = (1 << IPSET_ENV_BIT_QUIET), - IPSET_ENV_BIT_RESOLVE = 2, - IPSET_ENV_RESOLVE = (1 << IPSET_ENV_BIT_RESOLVE), - IPSET_ENV_BIT_EXIST = 3, - IPSET_ENV_EXIST = (1 << IPSET_ENV_BIT_EXIST), -}; - struct ipset_session; struct ipset_data; @@ -35,7 +24,7 @@ struct ipset_data; struct ipset_envopts { int flag; int has_arg; - const char *name[3]; + const char *name[2]; const char *help; int (*parse)(struct ipset_session *s, int flag, const char *str); int (*print)(char *buf, unsigned int len, @@ -44,4 +33,9 @@ struct ipset_envopts { extern const struct ipset_envopts ipset_envopts[]; +extern bool ipset_match_cmd(const char *arg, const char * const name[]); +extern bool ipset_match_option(const char *arg, const char * const name[]); +extern bool ipset_match_envopt(const char *arg, const char * const name[]); +extern void ipset_shift_argv(int *argc, char *argv[], int from); + #endif /* LIBIPSET_UI_H */ diff --git a/include/libipset/utils.h b/include/libipset/utils.h index 2d12e91..672bfa9 100644 --- a/include/libipset/utils.h +++ b/include/libipset/utils.h @@ -7,7 +7,6 @@ #ifndef LIBIPSET_UTILS_H #define LIBIPSET_UTILS_H -#include /* bool */ #include /* strcmp */ #include /* struct in[6]_addr */ @@ -37,9 +36,4 @@ in6cpy(struct in6_addr *dest, const struct in6_addr *src) memcpy(dest, src, sizeof(struct in6_addr)); } -extern char * ipset_strchr(const char *str, const char *sep); -extern bool ipset_name_match(const char *arg, const char * const name[]); -extern void ipset_shift_argv(int *argc, char *argv[], int from); -extern void ipset_strncpy(char *dst, const char *src, size_t len); - #endif /* LIBIPSET_UTILS_H */ -- cgit v1.2.3