netfilter: ipset: Add wildcard support to net,iface
The net,iface equal functions currently compares the full interface names. In several cases, wildcard (or prefix) matching is useful. For example, when converting a large iptables rule-set to make use of ipset, I was able to significantly reduce the number of set elements by making use of wildcard matching. Wildcard matching is enabled by adding "wildcard" when adding an element to a set. Internally, this causes the IPSET_FLAG_IFACE_WILDCARD-flag to be set. When this flag is set, only the initial part of the interface name is used for comparison. Wildcard matching is done per element and not per set, as there are many cases where mixing wildcard and non-wildcard elements are useful. This means that is up to the user to handle (avoid) overlapping interface names. Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com> Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
This commit is contained in:
Родитель
d5a721c96a
Коммит
b6520fce07
|
@ -205,6 +205,8 @@ enum ipset_cadt_flags {
|
|||
IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
|
||||
IPSET_FLAG_BIT_WITH_SKBINFO = 6,
|
||||
IPSET_FLAG_WITH_SKBINFO = (1 << IPSET_FLAG_BIT_WITH_SKBINFO),
|
||||
IPSET_FLAG_BIT_IFACE_WILDCARD = 7,
|
||||
IPSET_FLAG_IFACE_WILDCARD = (1 << IPSET_FLAG_BIT_IFACE_WILDCARD),
|
||||
IPSET_FLAG_CADT_MAX = 15,
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
/* 3 Counters support added */
|
||||
/* 4 Comments support added */
|
||||
/* 5 Forceadd support added */
|
||||
#define IPSET_TYPE_REV_MAX 6 /* skbinfo support added */
|
||||
/* 6 skbinfo support added */
|
||||
#define IPSET_TYPE_REV_MAX 7 /* interface wildcard support added */
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
|
||||
|
@ -57,6 +58,7 @@ struct hash_netiface4_elem {
|
|||
u8 cidr;
|
||||
u8 nomatch;
|
||||
u8 elem;
|
||||
u8 wildcard;
|
||||
char iface[IFNAMSIZ];
|
||||
};
|
||||
|
||||
|
@ -71,7 +73,9 @@ hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
|
|||
ip1->cidr == ip2->cidr &&
|
||||
(++*multi) &&
|
||||
ip1->physdev == ip2->physdev &&
|
||||
strcmp(ip1->iface, ip2->iface) == 0;
|
||||
(ip1->wildcard ?
|
||||
strncmp(ip1->iface, ip2->iface, strlen(ip1->iface)) == 0 :
|
||||
strcmp(ip1->iface, ip2->iface) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -103,7 +107,8 @@ static bool
|
|||
hash_netiface4_data_list(struct sk_buff *skb,
|
||||
const struct hash_netiface4_elem *data)
|
||||
{
|
||||
u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
|
||||
u32 flags = (data->physdev ? IPSET_FLAG_PHYSDEV : 0) |
|
||||
(data->wildcard ? IPSET_FLAG_IFACE_WILDCARD : 0);
|
||||
|
||||
if (data->nomatch)
|
||||
flags |= IPSET_FLAG_NOMATCH;
|
||||
|
@ -229,6 +234,8 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
|
|||
e.physdev = 1;
|
||||
if (cadt_flags & IPSET_FLAG_NOMATCH)
|
||||
flags |= (IPSET_FLAG_NOMATCH << 16);
|
||||
if (cadt_flags & IPSET_FLAG_IFACE_WILDCARD)
|
||||
e.wildcard = 1;
|
||||
}
|
||||
if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
|
||||
e.ip = htonl(ip & ip_set_hostmask(e.cidr));
|
||||
|
@ -280,6 +287,7 @@ struct hash_netiface6_elem {
|
|||
u8 cidr;
|
||||
u8 nomatch;
|
||||
u8 elem;
|
||||
u8 wildcard;
|
||||
char iface[IFNAMSIZ];
|
||||
};
|
||||
|
||||
|
@ -294,7 +302,9 @@ hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
|
|||
ip1->cidr == ip2->cidr &&
|
||||
(++*multi) &&
|
||||
ip1->physdev == ip2->physdev &&
|
||||
strcmp(ip1->iface, ip2->iface) == 0;
|
||||
(ip1->wildcard ?
|
||||
strncmp(ip1->iface, ip2->iface, strlen(ip1->iface)) == 0 :
|
||||
strcmp(ip1->iface, ip2->iface) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -326,7 +336,8 @@ static bool
|
|||
hash_netiface6_data_list(struct sk_buff *skb,
|
||||
const struct hash_netiface6_elem *data)
|
||||
{
|
||||
u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
|
||||
u32 flags = (data->physdev ? IPSET_FLAG_PHYSDEV : 0) |
|
||||
(data->wildcard ? IPSET_FLAG_IFACE_WILDCARD : 0);
|
||||
|
||||
if (data->nomatch)
|
||||
flags |= IPSET_FLAG_NOMATCH;
|
||||
|
@ -440,6 +451,8 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
|
|||
e.physdev = 1;
|
||||
if (cadt_flags & IPSET_FLAG_NOMATCH)
|
||||
flags |= (IPSET_FLAG_NOMATCH << 16);
|
||||
if (cadt_flags & IPSET_FLAG_IFACE_WILDCARD)
|
||||
e.wildcard = 1;
|
||||
}
|
||||
|
||||
ret = adtfn(set, &e, &ext, &ext, flags);
|
||||
|
|
Загрузка…
Ссылка в новой задаче