Commit 1226cfe3 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

Merge branch 'master' of git://blackhole.kfki.hu/nf-next

Jozsef Kadlecsik says:

====================
- Introduction of new commands and thus protocol version 7. The
  new commands makes possible to eliminate the getsockopt interface
  of ipset and use solely netlink to communicate with the kernel.
  Due to the strict attribute checking both in user/kernel space,
  a new protocol number was introduced. Both the kernel/userspace is
  fully backward compatible.
- Make invalid MAC address checks consisten, from Stefano Brivio.
  The patch depends on the next one.
- Allow matching on destination MAC address for mac and ipmac sets,
  also from Stefano Brivio.
====================
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parents 30beabb3 23c42a40
...@@ -303,11 +303,11 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set) ...@@ -303,11 +303,11 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
/* Netlink CB args */ /* Netlink CB args */
enum { enum {
IPSET_CB_NET = 0, /* net namespace */ IPSET_CB_NET = 0, /* net namespace */
IPSET_CB_PROTO, /* ipset protocol */
IPSET_CB_DUMP, /* dump single set/all sets */ IPSET_CB_DUMP, /* dump single set/all sets */
IPSET_CB_INDEX, /* set index */ IPSET_CB_INDEX, /* set index */
IPSET_CB_PRIVATE, /* set private data */ IPSET_CB_PRIVATE, /* set private data */
IPSET_CB_ARG0, /* type specific */ IPSET_CB_ARG0, /* type specific */
IPSET_CB_ARG1,
}; };
/* register and unregister set references */ /* register and unregister set references */
......
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
#include <linux/types.h> #include <linux/types.h>
/* The protocol version */ /* The protocol versions */
#define IPSET_PROTOCOL 6 #define IPSET_PROTOCOL 7
#define IPSET_PROTOCOL_MIN 6
/* The max length of strings including NUL: set and type identifiers */ /* The max length of strings including NUL: set and type identifiers */
#define IPSET_MAXNAMELEN 32 #define IPSET_MAXNAMELEN 32
...@@ -38,17 +39,19 @@ enum ipset_cmd { ...@@ -38,17 +39,19 @@ enum ipset_cmd {
IPSET_CMD_TEST, /* 11: Test an element in a set */ IPSET_CMD_TEST, /* 11: Test an element in a set */
IPSET_CMD_HEADER, /* 12: Get set header data only */ IPSET_CMD_HEADER, /* 12: Get set header data only */
IPSET_CMD_TYPE, /* 13: Get set type */ IPSET_CMD_TYPE, /* 13: Get set type */
IPSET_CMD_GET_BYNAME, /* 14: Get set index by name */
IPSET_CMD_GET_BYINDEX, /* 15: Get set name by index */
IPSET_MSG_MAX, /* Netlink message commands */ IPSET_MSG_MAX, /* Netlink message commands */
/* Commands in userspace: */ /* Commands in userspace: */
IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */ IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 16: Enter restore mode */
IPSET_CMD_HELP, /* 15: Get help */ IPSET_CMD_HELP, /* 17: Get help */
IPSET_CMD_VERSION, /* 16: Get program version */ IPSET_CMD_VERSION, /* 18: Get program version */
IPSET_CMD_QUIT, /* 17: Quit from interactive mode */ IPSET_CMD_QUIT, /* 19: Quit from interactive mode */
IPSET_CMD_MAX, IPSET_CMD_MAX,
IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */ IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 20: Commit buffered commands */
}; };
/* Attributes at command level */ /* Attributes at command level */
...@@ -66,6 +69,7 @@ enum { ...@@ -66,6 +69,7 @@ enum {
IPSET_ATTR_LINENO, /* 9: Restore lineno */ IPSET_ATTR_LINENO, /* 9: Restore lineno */
IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */ IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */
IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */ IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN, /* type rev min */
IPSET_ATTR_INDEX, /* 11: Kernel index of set */
__IPSET_ATTR_CMD_MAX, __IPSET_ATTR_CMD_MAX,
}; };
#define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1) #define IPSET_ATTR_CMD_MAX (__IPSET_ATTR_CMD_MAX - 1)
...@@ -223,6 +227,7 @@ enum ipset_adt { ...@@ -223,6 +227,7 @@ enum ipset_adt {
/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t /* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
* and IPSET_INVALID_ID if you want to increase the max number of sets. * and IPSET_INVALID_ID if you want to increase the max number of sets.
* Also, IPSET_ATTR_INDEX must be changed.
*/ */
typedef __u16 ip_set_id_t; typedef __u16 ip_set_id_t;
......
...@@ -219,10 +219,6 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -219,10 +219,6 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
u32 ip; u32 ip;
/* MAC can be src only */
if (!(opt->flags & IPSET_DIM_TWO_SRC))
return 0;
ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -IPSET_ERR_BITMAP_RANGE; return -IPSET_ERR_BITMAP_RANGE;
...@@ -233,7 +229,14 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -233,7 +229,14 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
return -EINVAL; return -EINVAL;
e.id = ip_to_id(map, ip); e.id = ip_to_id(map, ip);
memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN);
if (opt->flags & IPSET_DIM_ONE_SRC)
ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
else
ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
if (is_zero_ether_addr(e.ether))
return -EINVAL;
return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
} }
......
This diff is collapsed.
...@@ -36,9 +36,6 @@ MODULE_ALIAS("ip_set_hash:ip,mac"); ...@@ -36,9 +36,6 @@ MODULE_ALIAS("ip_set_hash:ip,mac");
/* Type specific function prefix */ /* Type specific function prefix */
#define HTYPE hash_ipmac #define HTYPE hash_ipmac
/* Zero valued element is not supported */
static const unsigned char invalid_ether[ETH_ALEN] = { 0 };
/* IPv4 variant */ /* IPv4 variant */
/* Member elements */ /* Member elements */
...@@ -103,8 +100,12 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -103,8 +100,12 @@ hash_ipmac4_kadt(struct ip_set *set, const struct sk_buff *skb,
(skb_mac_header(skb) + ETH_HLEN) > skb->data) (skb_mac_header(skb) + ETH_HLEN) > skb->data)
return -EINVAL; return -EINVAL;
memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN); if (opt->flags & IPSET_DIM_ONE_SRC)
if (ether_addr_equal(e.ether, invalid_ether)) ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
else
ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
if (is_zero_ether_addr(e.ether))
return -EINVAL; return -EINVAL;
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip); ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
...@@ -140,7 +141,7 @@ hash_ipmac4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -140,7 +141,7 @@ hash_ipmac4_uadt(struct ip_set *set, struct nlattr *tb[],
if (ret) if (ret)
return ret; return ret;
memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN); memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN);
if (ether_addr_equal(e.ether, invalid_ether)) if (is_zero_ether_addr(e.ether))
return -IPSET_ERR_HASH_ELEM; return -IPSET_ERR_HASH_ELEM;
return adtfn(set, &e, &ext, &ext, flags); return adtfn(set, &e, &ext, &ext, flags);
...@@ -211,16 +212,16 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -211,16 +212,16 @@ hash_ipmac6_kadt(struct ip_set *set, const struct sk_buff *skb,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
/* MAC can be src only */
if (!(opt->flags & IPSET_DIM_TWO_SRC))
return 0;
if (skb_mac_header(skb) < skb->head || if (skb_mac_header(skb) < skb->head ||
(skb_mac_header(skb) + ETH_HLEN) > skb->data) (skb_mac_header(skb) + ETH_HLEN) > skb->data)
return -EINVAL; return -EINVAL;
memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN); if (opt->flags & IPSET_DIM_ONE_SRC)
if (ether_addr_equal(e.ether, invalid_ether)) ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
else
ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
if (is_zero_ether_addr(e.ether))
return -EINVAL; return -EINVAL;
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
...@@ -260,7 +261,7 @@ hash_ipmac6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -260,7 +261,7 @@ hash_ipmac6_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN); memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN);
if (ether_addr_equal(e.ether, invalid_ether)) if (is_zero_ether_addr(e.ether))
return -IPSET_ERR_HASH_ELEM; return -IPSET_ERR_HASH_ELEM;
return adtfn(set, &e, &ext, &ext, flags); return adtfn(set, &e, &ext, &ext, flags);
......
...@@ -81,15 +81,15 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -81,15 +81,15 @@ hash_mac4_kadt(struct ip_set *set, const struct sk_buff *skb,
struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } }; struct hash_mac4_elem e = { { .foo[0] = 0, .foo[1] = 0 } };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
/* MAC can be src only */
if (!(opt->flags & IPSET_DIM_ONE_SRC))
return 0;
if (skb_mac_header(skb) < skb->head || if (skb_mac_header(skb) < skb->head ||
(skb_mac_header(skb) + ETH_HLEN) > skb->data) (skb_mac_header(skb) + ETH_HLEN) > skb->data)
return -EINVAL; return -EINVAL;
ether_addr_copy(e.ether, eth_hdr(skb)->h_source); if (opt->flags & IPSET_DIM_ONE_SRC)
ether_addr_copy(e.ether, eth_hdr(skb)->h_source);
else
ether_addr_copy(e.ether, eth_hdr(skb)->h_dest);
if (is_zero_ether_addr(e.ether)) if (is_zero_ether_addr(e.ether))
return -EINVAL; return -EINVAL;
return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment