Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipset supports for ipvs acl and dpvs-agent #971

Merged
merged 11 commits into from
Sep 12, 2024
2 changes: 1 addition & 1 deletion doc/IPset.md
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ bin/dpip: invalid parameter
The hash:ip,port,net set type uses a hash table to store IP address, port number and IP network address triples. Both IPv4 and IPv6 address are supported. The IP address of the IP and net should be of the same family. When adding/deleting entries, ranges are allowed but is transformed to specific host IP and port entries when stored into hash table for the "ip" and "port" segments. IPv4 supports both IP range and IP CIDR, while IPv6 supports IP CIDR only. Network address with zero prefix size is not supported, and is interpreted as host prefix size, i.e., 32 for IPv4 and 128 for IPv6. Option "nomatch" can be used to set exceptions to the set when add/deleting entries. If a test is matched against with a "nomatch" entry, then the result would end with false. The port number is interpreted together with a protocol. Supported protocols include TCP, UDP, ICMP, and ICMPv6, any other protocols are interpreted as unspec type with a protocol number of zero.

```bash
# ./bin/dpip ipset create bar hash:ip,port,net
# ./bin/dpip ipset -6 create bar hash:ip,port,net
# ./bin/dpip ipset add bar 2001::1,8080-8082,2002::/64
# ./bin/dpip ipset add bar 2001::1,8080-8082,2002::aaaa:bbbb:ccc0:0/108 nomatch
# ./bin/dpip ipset -v list bar
Expand Down
10 changes: 5 additions & 5 deletions include/conf/blklst.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@

#include "inet.h"
#include "conf/sockopts.h"
#include "conf/ipset.h"

struct dp_vs_blklst_entry {
union inet_addr addr;
};

typedef struct dp_vs_blklst_conf {
/* identify service */
union inet_addr blklst;
union inet_addr vaddr;
int af;
uint32_t fwmark;
uint16_t vport;
uint8_t proto;
uint8_t padding;
uint8_t af;

/* for set */
/* subject and ipset are mutual exclusive */
union inet_addr subject;
char ipset[IPSET_MAXNAMELEN];
} dpvs_blklst_t;

struct dp_vs_blklst_conf_array {
Expand Down
57 changes: 32 additions & 25 deletions include/conf/ipset.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#define IPSET_F_FORCE 0x0001

enum ipset_op {
IPSET_OP_ADD,
IPSET_OP_ADD = 1,
IPSET_OP_DEL,
IPSET_OP_TEST,
IPSET_OP_CREATE,
Expand All @@ -43,34 +43,36 @@ enum ipset_op {
};

struct ipset_option {
int family;
union {
struct {
bool comment;
int hashsize;
int maxelem;
} create;
int32_t hashsize;
uint32_t maxelem;
uint8_t comment;
} __attribute__((__packed__)) create;
struct {
bool nomatch;
} add;
char padding[8];
uint8_t nomatch;
} __attribute__((__packed__)) add;
};
};
uint8_t family;
} __attribute__((__packed__));

struct ipset_param {
char type[IPSET_MAXNAMELEN];
char name[IPSET_MAXNAMELEN];
char comment[IPSET_MAXCOMLEN];
int opcode;
struct ipset_option option;
uint16_t opcode;
uint16_t flag;
struct ipset_option option;

uint8_t proto;
uint8_t cidr;
struct inet_addr_range range; /* port in host byteorder */
uint8_t mac[6];
char iface[IFNAMSIZ];
uint8_t mac[6];

/* for type with 2 nets */
uint8_t padding;
uint8_t cidr2;
struct inet_addr_range range2;
//uint8_t mac[2];
Expand All @@ -83,43 +85,48 @@ struct ipset_member {
uint8_t cidr;
uint8_t proto;
uint16_t port;
uint8_t mac[6];
char iface[IFNAMSIZ];
bool nomatch;
uint8_t mac[6];
uint8_t nomatch;

/* second net */
union inet_addr addr2;
uint8_t cidr2;
uint16_t port2;
uint8_t padding[2];
union inet_addr addr2;
};

struct ipset_info {
char name[IPSET_MAXNAMELEN];
char type[IPSET_MAXNAMELEN];
bool comment;
uint8_t comment;

uint8_t af;
uint8_t padding[2];

union {
struct ipset_bitmap_header {
struct inet_addr_range range;
uint8_t cidr;
uint8_t padding[3];
struct inet_addr_range range;
} bitmap;
struct ipset_hash_header {
int hashsize;
int maxelem;
uint8_t padding[4]; // aligned for dpvs-agent
int32_t hashsize;
uint32_t maxelem;
} hash;
};

int af;
size_t size;
int entries;
int references;
uint32_t size;
uint32_t entries;
uint32_t references;

void *members;
};

struct ipset_info_array {
int nipset;
struct ipset_info infos[0];
uint32_t nipset;
struct ipset_info infos[0];
} __attribute__((__packed__));

#endif /* __DPVS_IPSET_CONF_H__ */
11 changes: 6 additions & 5 deletions include/conf/whtlst.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,22 @@
#define __DPVS_WHTLST_CONF_H__
#include "inet.h"
#include "conf/sockopts.h"
#include "conf/ipset.h"

struct dp_vs_whtlst_entry {
union inet_addr addr;
};

typedef struct dp_vs_whtlst_conf {
/* identify service */
union inet_addr whtlst;
union inet_addr vaddr;
int af;
uint32_t fwmark;
uint16_t vport;
uint8_t proto;
uint8_t padding;
uint8_t af;

/* for set */
/* subject and ipset are mutual exclusive */
union inet_addr subject;
char ipset[IPSET_MAXNAMELEN];
} dpvs_whtlst_t;

struct dp_vs_whtlst_conf_array {
Expand Down
2 changes: 1 addition & 1 deletion include/ipset/ipset.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#define IPSET
#define RTE_LOGTYPE_IPSET RTE_LOGTYPE_USER1

#define IPSET_ADT_MAX 3
#define IPSET_ADT_MAX IPSET_OP_MAX

struct ipset;

Expand Down
19 changes: 12 additions & 7 deletions include/ipvs/blklst.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@
#ifndef __DPVS_BLKLST_H__
#define __DPVS_BLKLST_H__
#include "conf/common.h"
#include "ipvs/service.h"
#include "timer.h"
#include "ipvs/service.h"
#include "ipset/ipset.h"

struct blklst_entry {
struct list_head list;
int af;
uint8_t proto;
uint16_t vport;

union inet_addr vaddr;
union inet_addr blklst;
uint16_t vport;
uint8_t proto;
uint8_t af;

union inet_addr subject;
struct ipset *set;
bool dst_match; /* internal use for ipset */
};

struct blklst_entry *dp_vs_blklst_lookup(int af, uint8_t proto, const union inet_addr *vaddr,
uint16_t vport, const union inet_addr *blklst);
bool dp_vs_blklst_filtered(int af, uint8_t proto, const union inet_addr *vaddr,
uint16_t vport, const union inet_addr *subject, struct rte_mbuf *mbuf);
void dp_vs_blklst_flush(struct dp_vs_service *svc);

int dp_vs_blklst_init(void);
Expand Down
15 changes: 9 additions & 6 deletions include/ipvs/whtlst.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@
#define __DPVS_WHTLST_H__
#include "conf/common.h"
#include "ipvs/service.h"
#include "ipset/ipset.h"

struct whtlst_entry {
struct list_head list;
int af;

union inet_addr vaddr;
uint16_t vport;
uint8_t proto;
union inet_addr whtlst;
uint8_t af;

union inet_addr subject;
struct ipset *set;
bool dst_match; /* internal use of ipset */
};

struct whtlst_entry *dp_vs_whtlst_lookup(int af, uint8_t proto, const union inet_addr *vaddr,
uint16_t vport, const union inet_addr *whtlst);
bool dp_vs_whtlst_allow(int af, uint8_t proto, const union inet_addr *vaddr,
uint16_t vport, const union inet_addr *whtlst);
bool dp_vs_whtlst_filtered(int af, uint8_t proto, const union inet_addr *vaddr,
uint16_t vport, const union inet_addr *subject, struct rte_mbuf *mbuf);
void dp_vs_whtlst_flush(struct dp_vs_service *svc);

int dp_vs_whtlst_init(void);
Expand Down
13 changes: 10 additions & 3 deletions src/ipset/ipset_bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bitmap_add(struct ipset *set, void *value, uint16_t flag)

/* To avoid same IP, different MAC or other elements */
if (ret || test_bit(e->id, map->members)) {
if (flag & IPSET_F_FORCE)
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_EXIST;
}
Expand All @@ -51,8 +51,11 @@ bitmap_del(struct ipset *set, void *value, uint16_t flag)
if (e->id >= map->elements)
return EDPVS_INVAL;

if (!do(del, value, map))
if (!do(del, value, map)) {
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_NOTEXIST;
}

set->elements--;
return EDPVS_OK;
Expand All @@ -70,7 +73,11 @@ bitmap_test(struct ipset *set, void *value, uint16_t flag)
return do(test, value, map, set->dsize);
}

ipset_adtfn bitmap_adtfn[IPSET_ADT_MAX] = { bitmap_add, bitmap_del, bitmap_test };
ipset_adtfn bitmap_adtfn[IPSET_ADT_MAX] = {
[ IPSET_OP_ADD ] = bitmap_add,
[ IPSET_OP_DEL ] = bitmap_del,
[ IPSET_OP_TEST ] = bitmap_test
};

void
bitmap_flush(struct ipset *set)
Expand Down
8 changes: 7 additions & 1 deletion src/ipset/ipset_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ hash_del(struct ipset *set, void *value, uint16_t flag)
return EDPVS_OK;
}
}
if (flag & IPSET_F_FORCE)
return EDPVS_OK;
return EDPVS_NOTEXIST;
}

Expand Down Expand Up @@ -245,7 +247,11 @@ hash_test(struct ipset *set, void *value, uint16_t flag)
return 0;
}

ipset_adtfn hash_adtfn[IPSET_ADT_MAX] = { hash_add, hash_del, hash_test };
ipset_adtfn hash_adtfn[IPSET_ADT_MAX] = {
[ IPSET_OP_ADD ] = hash_add,
[ IPSET_OP_DEL ] = hash_del,
[ IPSET_OP_TEST ] = hash_test
};

void
hash_flush(struct ipset *set)
Expand Down
10 changes: 5 additions & 5 deletions src/ipset/ipset_hash_ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,14 @@ static int
hash_ip_create(struct ipset *set, struct ipset_param *param)
{
hash_create(set, param);
if (param->option.family == AF_INET) {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ip_variant4;
} else {
if (param->option.family == AF_INET6) {
set->dsize = sizeof(elem6_t);
set->hash_len = offsetof(elem6_t, comment);
set->variant = &hash_ip_variant6;
} else {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ip_variant4;
}

return EDPVS_OK;
Expand Down
10 changes: 5 additions & 5 deletions src/ipset/ipset_hash_ipport.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,14 @@ hash_ipport_create(struct ipset *set, struct ipset_param *param)
{
hash_create(set, param);

if (param->option.family == AF_INET) {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ipport_variant4;
} else {
if (param->option.family == AF_INET6) {
set->dsize = sizeof(elem6_t);
set->hash_len = offsetof(elem6_t, comment);
set->variant = &hash_ipport_variant6;
} else {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ipport_variant4;
}

return EDPVS_OK;
Expand Down
10 changes: 5 additions & 5 deletions src/ipset/ipset_hash_ipportip.c
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,14 @@ hash_ipportip_create(struct ipset *set, struct ipset_param *param)
{
hash_create(set, param);

if (param->option.family == AF_INET) {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ipportip_variant4;
} else {
if (param->option.family == AF_INET6) {
set->dsize = sizeof(elem6_t);
set->hash_len = offsetof(elem6_t, comment);
set->variant = &hash_ipportip_variant6;
} else {
set->dsize = sizeof(elem4_t);
set->hash_len = offsetof(elem4_t, comment);
set->variant = &hash_ipportip_variant4;
}

return EDPVS_OK;
Expand Down
6 changes: 3 additions & 3 deletions src/ipset/ipset_hash_ipportnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,10 @@ hash_ipportnet_create(struct ipset *set, struct ipset_param *param)
set->dsize = sizeof(elem_t);
set->hash_len = offsetof(elem_t, comment);

if (param->option.family == AF_INET)
set->variant = &hash_ipportnet_variant4;
else
if (param->option.family == AF_INET6)
set->variant = &hash_ipportnet_variant6;
else
set->variant = &hash_ipportnet_variant4;

return EDPVS_OK;
}
Expand Down
Loading
Loading