diff --git a/include/conf/blklst.h b/include/conf/blklst.h index 2b2c9a044..84d7be271 100644 --- a/include/conf/blklst.h +++ b/include/conf/blklst.h @@ -24,6 +24,7 @@ #include "inet.h" #include "conf/sockopts.h" +#include "conf/ipset.h" struct dp_vs_blklst_entry { union inet_addr addr; @@ -31,15 +32,14 @@ struct dp_vs_blklst_entry { 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 { diff --git a/include/ipvs/blklst.h b/include/ipvs/blklst.h index d3326be93..bb9b0cd06 100644 --- a/include/ipvs/blklst.h +++ b/include/ipvs/blklst.h @@ -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); diff --git a/src/ipvs/ip_vs_blklst.c b/src/ipvs/ip_vs_blklst.c index 0afebc6cb..25491a076 100644 --- a/src/ipvs/ip_vs_blklst.c +++ b/src/ipvs/ip_vs_blklst.c @@ -35,86 +35,198 @@ * */ -#define DPVS_BLKLST_TAB_BITS 16 -#define DPVS_BLKLST_TAB_SIZE (1 << DPVS_BLKLST_TAB_BITS) -#define DPVS_BLKLST_TAB_MASK (DPVS_BLKLST_TAB_SIZE - 1) - -#define this_blklst_tab (RTE_PER_LCORE(dp_vs_blklst_tab)) -#define this_num_blklsts (RTE_PER_LCORE(num_blklsts)) +#define DPVS_BLKLST_TAB_BITS 16 +#define DPVS_BLKLST_TAB_SIZE (1 << DPVS_BLKLST_TAB_BITS) +#define DPVS_BLKLST_TAB_MASK (DPVS_BLKLST_TAB_SIZE - 1) +#define this_blklst_tab (RTE_PER_LCORE(dp_vs_blklst_tab)) +#define this_num_blklsts (RTE_PER_LCORE(num_blklsts)) + +#define DPVS_BLKLST_IPSET_TAB_BITS 8 +#define DPVS_BLKLST_IPSET_TAB_SIZE (1 << DPVS_BLKLST_IPSET_TAB_BITS) +#define DPVS_BLKLST_IPSET_TAB_MASK (DPVS_BLKLST_IPSET_TAB_SIZE - 1) +#define this_blklst_ipset_tab (RTE_PER_LCORE(dp_vs_blklst_ipset_tab)) +#define this_num_blklsts_ipset (RTE_PER_LCORE(num_blklsts_ipset)) static RTE_DEFINE_PER_LCORE(struct list_head *, dp_vs_blklst_tab); -static RTE_DEFINE_PER_LCORE(rte_atomic32_t, num_blklsts); +static RTE_DEFINE_PER_LCORE(uint32_t, num_blklsts); + +static RTE_DEFINE_PER_LCORE(struct list_head *, dp_vs_blklst_ipset_tab); +static RTE_DEFINE_PER_LCORE(uint32_t, num_blklsts_ipset); static uint32_t dp_vs_blklst_rnd; +static inline void blklst_fill_conf(const struct blklst_entry *entry, + struct dp_vs_blklst_conf *conf) +{ + memset(conf, 0, sizeof(*conf)); + conf->vaddr = entry->vaddr; + conf->vport = entry->vport; + conf->proto = entry->proto; + conf->af = entry->af; + conf->subject = entry->subject; + if (entry->set) + strncpy(conf->ipset, entry->set->name, sizeof(conf->ipset) - 1); +} + static inline uint32_t blklst_hashkey(const union inet_addr *vaddr, - const union inet_addr *blklst) + uint16_t vport, const union inet_addr *subject, bool ipset) { /* jhash hurts performance, we do not use rte_jhash_2words here */ - return ((rte_be_to_cpu_32(vaddr->in.s_addr) * 31 - + rte_be_to_cpu_32(blklst->in.s_addr)) * 31 - + dp_vs_blklst_rnd) & DPVS_BLKLST_TAB_MASK; + if (ipset) + return ((((vaddr->in.s_addr * 31) ^ vport) * 131) + ^ dp_vs_blklst_rnd) & DPVS_BLKLST_IPSET_TAB_MASK; + + return ((((vaddr->in.s_addr * 31) ^ subject->in.s_addr) * 131) + ^ (vport ^ dp_vs_blklst_rnd)) & DPVS_BLKLST_TAB_MASK; } -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) +static inline struct blklst_entry *dp_vs_blklst_ip_lookup( + int af, uint8_t proto, const union inet_addr *vaddr, + uint16_t vport, const union inet_addr *subject) { unsigned hashkey; - struct blklst_entry *blklst_node; - - hashkey = blklst_hashkey(vaddr, blklst); - list_for_each_entry(blklst_node, &this_blklst_tab[hashkey], list) { - if (blklst_node->af == af && blklst_node->proto == proto && - blklst_node->vport == vport && - inet_addr_equal(af, &blklst_node->vaddr, vaddr) && - inet_addr_equal(af, &blklst_node->blklst, blklst)) - return blklst_node; + struct blklst_entry *entry; + + hashkey = blklst_hashkey(vaddr, vport, subject, false); + list_for_each_entry(entry, &this_blklst_tab[hashkey], list) { + if (entry->af == af && entry->proto == proto && + entry->vport == vport && + inet_addr_equal(af, &entry->vaddr, vaddr) && + inet_addr_equal(af, &entry->subject, subject)) + return entry; } + return NULL; } -static int dp_vs_blklst_add_lcore(int af, uint8_t proto, const union inet_addr *vaddr, - uint16_t vport, const union inet_addr *blklst) +static inline struct blklst_entry *dp_vs_blklst_ipset_lookup( + int af, uint8_t proto, const union inet_addr *vaddr, + uint16_t vport, const char *ipset) { unsigned hashkey; - struct blklst_entry *new, *blklst_node; + struct blklst_entry *entry; - blklst_node = dp_vs_blklst_lookup(af, proto, vaddr, vport, blklst); - if (blklst_node) { - return EDPVS_EXIST; + hashkey = blklst_hashkey(vaddr, vport, NULL, true); + list_for_each_entry(entry, &this_blklst_ipset_tab[hashkey], list) { + if (entry->af == af && entry->proto == proto && entry->vport == vport && + inet_addr_equal(af, &entry->vaddr, vaddr) && + !strncmp(entry->set->name, ipset, sizeof(entry->set->name))) + return entry; + } + + return NULL; +} + +static bool dp_vs_blklst_ip_match_set(int af, uint8_t proto, + const union inet_addr *vaddr, uint16_t vport, + struct rte_mbuf *mbuf) +{ + bool res = false; + unsigned hashkey; + struct blklst_entry *entry; + + hashkey = blklst_hashkey(vaddr, vport, NULL, true); + list_for_each_entry(entry, &this_blklst_ipset_tab[hashkey], list) { + if (entry->af == af && entry->proto == proto && + entry->vport == vport && + inet_addr_equal(af, &entry->vaddr, vaddr)) { + rte_pktmbuf_prepend(mbuf, mbuf->l2_len); + res = elem_in_set(entry->set, mbuf, entry->dst_match); + rte_pktmbuf_adj(mbuf, mbuf->l2_len); + if (res) + break; + } } + return res; +} + +static struct blklst_entry *dp_vs_blklst_lookup(const struct dp_vs_blklst_conf *conf) +{ + struct blklst_entry *entry; - hashkey = blklst_hashkey(vaddr, blklst); + entry = dp_vs_blklst_ip_lookup(conf->af, conf->proto, &conf->vaddr, conf->vport, + &conf->subject); + if (entry) + return entry; + + return dp_vs_blklst_ipset_lookup(conf->af, conf->proto, &conf->vaddr, conf->vport, + conf->ipset); +} + +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) +{ + if (dp_vs_blklst_ip_lookup(af, proto, vaddr, vport, subject)) + return true; + + return dp_vs_blklst_ip_match_set(af, proto, vaddr, vport, mbuf); +} + +static int dp_vs_blklst_add_lcore(const struct dp_vs_blklst_conf *conf) +{ + unsigned hashkey; + struct blklst_entry *new; + bool is_ipset = conf->ipset[0] != '\0'; + + if (dp_vs_blklst_lookup(conf)) + return EDPVS_EXIST; + + hashkey = blklst_hashkey(&conf->vaddr, conf->vport, &conf->subject, is_ipset); new = rte_zmalloc("new_blklst_entry", sizeof(struct blklst_entry), 0); if (unlikely(new == NULL)) return EDPVS_NOMEM; - new->af = af; - new->proto = proto; - new->vport = vport; - memcpy(&new->vaddr, vaddr, sizeof(union inet_addr)); - memcpy(&new->blklst, blklst, sizeof(union inet_addr)); - list_add(&new->list, &this_blklst_tab[hashkey]); - rte_atomic32_inc(&this_num_blklsts); + new->vaddr = conf->vaddr; + new->vport = conf->vport; + new->proto = conf->proto; + new->af = conf->af; + + if (is_ipset) { + new->set = ipset_get(conf->ipset); + if (!new->set) { + RTE_LOG(ERR, SERVICE, "[%2d] %s: ipset %s not found\n", + rte_lcore_id(), __func__, conf->ipset); + rte_free(new); + return EDPVS_INVAL; + } + // Notes: Reassess it when new ipset types added! + if (!strcmp(new->set->type->name, "hash:ip,port,net") || + !strcmp(new->set->type->name, "hash:ip,port,ip") || + !strcmp(new->set->type->name, "hash:net,port,net")) + new->dst_match = true; + else + new->dst_match = false; + list_add(&new->list, &this_blklst_ipset_tab[hashkey]); + ++this_num_blklsts_ipset; + } else { + new->subject = conf->subject; + list_add(&new->list, &this_blklst_tab[hashkey]); + ++this_num_blklsts; + } return EDPVS_OK; } -static int dp_vs_blklst_del_lcore(int af, uint8_t proto, const union inet_addr *vaddr, - uint16_t vport, const union inet_addr *blklst) +static int dp_vs_blklst_del_lcore(const struct dp_vs_blklst_conf *conf) { - struct blklst_entry *blklst_node; - - blklst_node = dp_vs_blklst_lookup(af, proto, vaddr, vport, blklst); - if (blklst_node != NULL) { - list_del(&blklst_node->list); - rte_free(blklst_node); - rte_atomic32_dec(&this_num_blklsts); - return EDPVS_OK; + struct blklst_entry *entry; + + entry = dp_vs_blklst_lookup(conf); + if (!entry) + return EDPVS_NOTEXIST; + + if (entry->set) { /* ipset entry */ + list_del(&entry->list); + ipset_put(entry->set); + --this_num_blklsts_ipset; + } else { /* ip entry */ + list_del(&entry->list); + --this_num_blklsts; } - return EDPVS_NOTEXIST; + rte_free(entry); + return EDPVS_OK; } static uint32_t blklst_msg_seq(void) @@ -123,42 +235,33 @@ static uint32_t blklst_msg_seq(void) return counter++; } -static int dp_vs_blklst_add(int af, uint8_t proto, const union inet_addr *vaddr, - uint16_t vport, const union inet_addr *blklst) +static int dp_vs_blklst_add(const struct dp_vs_blklst_conf *conf) { lcoreid_t cid = rte_lcore_id(); int err; struct dpvs_msg *msg; - struct dp_vs_blklst_conf cf; if (cid != rte_get_main_lcore()) { RTE_LOG(INFO, SERVICE, "%s must set from master lcore\n", __func__); return EDPVS_NOTSUPP; } - memset(&cf, 0, sizeof(struct dp_vs_blklst_conf)); - memcpy(&(cf.vaddr), vaddr,sizeof(union inet_addr)); - memcpy(&(cf.blklst), blklst, sizeof(union inet_addr)); - cf.af = af; - cf.vport = vport; - cf.proto = proto; - - /*set blklst ip on master lcore*/ - err = dp_vs_blklst_add_lcore(af, proto, vaddr, vport, blklst); + /* master lcore */ + err = dp_vs_blklst_add_lcore(conf); if (err && err != EDPVS_EXIST) { - RTE_LOG(ERR, SERVICE, "[%s] fail to set blklst ip -- %s\n", __func__, dpvs_strerror(err)); + RTE_LOG(ERR, SERVICE, "%s: fail to add blklst entry -- %s\n", __func__, dpvs_strerror(err)); return err; } - /*set blklst ip on all slave lcores*/ + /* slave lcores */ msg = msg_make(MSG_TYPE_BLKLST_ADD, blklst_msg_seq(), DPVS_MSG_MULTICAST, - cid, sizeof(struct dp_vs_blklst_conf), &cf); + cid, sizeof(struct dp_vs_blklst_conf), conf); if (unlikely(!msg)) return EDPVS_NOMEM; err = multicast_msg_send(msg, DPVS_MSG_F_ASYNC, NULL); if (err != EDPVS_OK) { msg_destroy(&msg); - RTE_LOG(INFO, SERVICE, "[%s] fail to send multicast message\n", __func__); + RTE_LOG(INFO, SERVICE, "%s: fail to send multicast message\n", __func__); return err; } msg_destroy(&msg); @@ -166,35 +269,27 @@ static int dp_vs_blklst_add(int af, uint8_t proto, const union inet_addr *vaddr, return EDPVS_OK; } -static int dp_vs_blklst_del(int af, uint8_t proto, const union inet_addr *vaddr, - uint16_t vport, const union inet_addr *blklst) +static int dp_vs_blklst_del(const struct dp_vs_blklst_conf *conf) { lcoreid_t cid = rte_lcore_id(); int err; struct dpvs_msg *msg; - struct dp_vs_blklst_conf cf; if (cid != rte_get_main_lcore()) { RTE_LOG(INFO, SERVICE, "%s must set from master lcore\n", __func__); return EDPVS_NOTSUPP; } - memset(&cf, 0, sizeof(struct dp_vs_blklst_conf)); - memcpy(&(cf.vaddr), vaddr,sizeof(union inet_addr)); - memcpy(&(cf.blklst), blklst, sizeof(union inet_addr)); - cf.af = af; - cf.vport = vport; - cf.proto = proto; - - /*del blklst ip on master lcores*/ - err = dp_vs_blklst_del_lcore(af, proto, vaddr, vport, blklst); + /* master lcore */ + err = dp_vs_blklst_del_lcore(conf); if (err) { + RTE_LOG(ERR, SERVICE, "%s: fail to del blklst entry -- %s\n", __func__, dpvs_strerror(err)); return err; } - /*del blklst ip on all slave lcores*/ + /* slave lcores */ msg = msg_make(MSG_TYPE_BLKLST_DEL, blklst_msg_seq(), DPVS_MSG_MULTICAST, - cid, sizeof(struct dp_vs_blklst_conf), &cf); + cid, sizeof(struct dp_vs_blklst_conf), conf); if (!msg) return EDPVS_NOMEM; err = multicast_msg_send(msg, DPVS_MSG_F_ASYNC, NULL); @@ -212,32 +307,52 @@ void dp_vs_blklst_flush(struct dp_vs_service *svc) { int hash; struct blklst_entry *entry, *next; + struct dp_vs_blklst_conf conf; for (hash = 0; hash < DPVS_BLKLST_TAB_SIZE; hash++) { list_for_each_entry_safe(entry, next, &this_blklst_tab[hash], list) { if (entry->af == svc->af - && entry->vport == svc->port - && entry->proto == svc->proto - && inet_addr_equal(svc->af, &entry->vaddr, &svc->addr)) - dp_vs_blklst_del(svc->af, entry->proto, &entry->vaddr, - entry->vport, &entry->blklst); + && entry->vport == svc->port + && entry->proto == svc->proto + && inet_addr_equal(svc->af, &entry->vaddr, &svc->addr)) { + blklst_fill_conf(entry, &conf); + dp_vs_blklst_del(&conf); + } + } + } + + for (hash = 0; hash < DPVS_BLKLST_IPSET_TAB_SIZE; hash++) { + list_for_each_entry_safe(entry, next, &this_blklst_ipset_tab[hash], list) { + if (entry->af == svc->af + && entry->vport == svc->port + && entry->proto == svc->proto + && inet_addr_equal(svc->af, &entry->vaddr, &svc->addr)) { + blklst_fill_conf(entry, &conf); + dp_vs_blklst_del(&conf); + } } } - return; } static void dp_vs_blklst_flush_all(void) { - struct blklst_entry *entry, *next; int hash; + struct blklst_entry *entry, *next; + struct dp_vs_blklst_conf conf; for (hash = 0; hash < DPVS_BLKLST_TAB_SIZE; hash++) { list_for_each_entry_safe(entry, next, &this_blklst_tab[hash], list) { - dp_vs_blklst_del(entry->af, entry->proto, &entry->vaddr, - entry->vport, &entry->blklst); + blklst_fill_conf(entry, &conf); + dp_vs_blklst_del(&conf); + } + } + + for (hash = 0; hash < DPVS_BLKLST_IPSET_TAB_SIZE; hash++) { + list_for_each_entry_safe(entry, next, &this_blklst_ipset_tab[hash], list) { + blklst_fill_conf(entry, &conf); + dp_vs_blklst_del(&conf); } } - return; } /* @@ -245,40 +360,19 @@ static void dp_vs_blklst_flush_all(void) */ static int blklst_sockopt_set(sockoptid_t opt, const void *conf, size_t size) { - const struct dp_vs_blklst_conf *blklst_conf = conf; - int err; - - if (!conf && size < sizeof(*blklst_conf)) + if (!conf && size < sizeof(struct dp_vs_blklst_conf)) return EDPVS_INVAL; switch (opt) { - case SOCKOPT_SET_BLKLST_ADD: - err = dp_vs_blklst_add(blklst_conf->af, - blklst_conf->proto, &blklst_conf->vaddr, - blklst_conf->vport, &blklst_conf->blklst); - break; - case SOCKOPT_SET_BLKLST_DEL: - err = dp_vs_blklst_del(blklst_conf->af, - blklst_conf->proto, &blklst_conf->vaddr, - blklst_conf->vport, &blklst_conf->blklst); - break; - default: - err = EDPVS_NOTSUPP; - break; + case SOCKOPT_SET_BLKLST_ADD: + return dp_vs_blklst_add(conf); + case SOCKOPT_SET_BLKLST_DEL: + return dp_vs_blklst_del(conf); + default: + return EDPVS_NOTSUPP; } - return err; -} - -static void blklst_fill_conf(struct dp_vs_blklst_conf *cf, - const struct blklst_entry *entry) -{ - memset(cf, 0 ,sizeof(*cf)); - cf->af = entry->af; - cf->vaddr = entry->vaddr; - cf->blklst = entry->blklst; - cf->proto = entry->proto; - cf->vport = entry->vport; + return EDPVS_OK; } static int blklst_sockopt_get(sockoptid_t opt, const void *conf, size_t size, @@ -289,7 +383,7 @@ static int blklst_sockopt_get(sockoptid_t opt, const void *conf, size_t size, size_t naddr, hash; int off = 0; - naddr = rte_atomic32_read(&this_num_blklsts); + naddr = this_num_blklsts + this_num_blklsts_ipset; *outsize = sizeof(struct dp_vs_blklst_conf_array) + naddr * sizeof(struct dp_vs_blklst_conf); *out = rte_calloc(NULL, 1, *outsize, 0); @@ -302,45 +396,52 @@ static int blklst_sockopt_get(sockoptid_t opt, const void *conf, size_t size, list_for_each_entry(entry, &this_blklst_tab[hash], list) { if (off >= naddr) break; - blklst_fill_conf(&array->blklsts[off++], entry); + blklst_fill_conf(entry, &array->blklsts[off++]); + } + } + + for (hash = 0; hash < DPVS_BLKLST_IPSET_TAB_SIZE; hash++) { + list_for_each_entry(entry, &this_blklst_ipset_tab[hash], list) { + if (off >= naddr) + break; + blklst_fill_conf(entry, &array->blklsts[off++]); } } return EDPVS_OK; } - static int blklst_msg_process(bool add, struct dpvs_msg *msg) { - struct dp_vs_blklst_conf *cf; + struct dp_vs_blklst_conf *conf; int err; assert(msg); if (msg->len != sizeof(struct dp_vs_blklst_conf)){ - RTE_LOG(ERR, SERVICE, "%s: bad message.\n", __func__); + RTE_LOG(ERR, SERVICE, "%s: bad message\n", __func__); return EDPVS_INVAL; } - cf = (struct dp_vs_blklst_conf *)msg->data; + conf = (struct dp_vs_blklst_conf *)msg->data; if (add) { - err = dp_vs_blklst_add_lcore(cf->af, cf->proto, &cf->vaddr, cf->vport, &cf->blklst); - if (err && err != EDPVS_EXIST) { - RTE_LOG(ERR, SERVICE, "%s: fail to add blklst: %s.\n", __func__, dpvs_strerror(err)); - } - } - else { - err = dp_vs_blklst_del_lcore(cf->af, cf->proto, &cf->vaddr, cf->vport, &cf->blklst); + err = dp_vs_blklst_add_lcore(conf); + if (err && err != EDPVS_EXIST) + RTE_LOG(ERR, SERVICE, "%s: fail to add blklst: %s\n", __func__, dpvs_strerror(err)); + } else { + err = dp_vs_blklst_del_lcore(conf); + if (err && err != EDPVS_NOTEXIST) + RTE_LOG(ERR, SERVICE, "%s: fail to del blklst: %s\n", __func__, dpvs_strerror(err)); } return err; } -inline static int blklst_add_msg_cb(struct dpvs_msg *msg) +static inline int blklst_add_msg_cb(struct dpvs_msg *msg) { return blklst_msg_process(true, msg); } -inline static int blklst_del_msg_cb(struct dpvs_msg *msg) +static inline int blklst_del_msg_cb(struct dpvs_msg *msg) { return blklst_msg_process(false, msg); } @@ -358,17 +459,29 @@ static struct dpvs_sockopts blklst_sockopts = { static int blklst_lcore_init(void *args) { int i; + if (!rte_lcore_is_enabled(rte_lcore_id())) - return EDPVS_DISABLED; - this_blklst_tab = rte_malloc(NULL, - sizeof(struct list_head) * DPVS_BLKLST_TAB_SIZE, - RTE_CACHE_LINE_SIZE); + return EDPVS_DISABLED; + + this_num_blklsts = 0; + this_num_blklsts_ipset = 0; + + this_blklst_tab = rte_malloc(NULL, sizeof(struct list_head) * + DPVS_BLKLST_TAB_SIZE, RTE_CACHE_LINE_SIZE); if (!this_blklst_tab) return EDPVS_NOMEM; - for (i = 0; i < DPVS_BLKLST_TAB_SIZE; i++) INIT_LIST_HEAD(&this_blklst_tab[i]); + this_blklst_ipset_tab = rte_malloc(NULL, sizeof(struct list_head) * + DPVS_BLKLST_IPSET_TAB_SIZE, RTE_CACHE_LINE_SIZE); + if (!this_blklst_ipset_tab) { + rte_free(this_blklst_tab); + return EDPVS_NOMEM; + } + for (i = 0; i < DPVS_BLKLST_IPSET_TAB_SIZE; i++) + INIT_LIST_HEAD(&this_blklst_ipset_tab[i]); + return EDPVS_OK; } @@ -383,6 +496,12 @@ static int blklst_lcore_term(void *args) rte_free(this_blklst_tab); this_blklst_tab = NULL; } + + if (this_blklst_ipset_tab) { + rte_free(this_blklst_ipset_tab); + this_blklst_ipset_tab = NULL; + } + return EDPVS_OK; } @@ -392,13 +511,11 @@ int dp_vs_blklst_init(void) lcoreid_t cid; struct dpvs_msg_type msg_type; - rte_atomic32_set(&this_num_blklsts, 0); - rte_eal_mp_remote_launch(blklst_lcore_init, NULL, CALL_MAIN); RTE_LCORE_FOREACH_WORKER(cid) { if ((err = rte_eal_wait_lcore(cid)) < 0) { - RTE_LOG(WARNING, SERVICE, "%s: lcore %d: %s.\n", - __func__, cid, dpvs_strerror(err)); + RTE_LOG(WARNING, SERVICE, "[%02d] %s: blklst init failed -- %s\n", + cid, __func__, dpvs_strerror(err)); return err; } } @@ -411,7 +528,8 @@ int dp_vs_blklst_init(void) msg_type.unicast_msg_cb = blklst_add_msg_cb; err = msg_type_mc_register(&msg_type); if (err != EDPVS_OK) { - RTE_LOG(ERR, SERVICE, "%s: fail to register msg.\n", __func__); + RTE_LOG(ERR, SERVICE, "%s: register BLKLST_ADD msg failed -- %s\n", + __func__, dpvs_strerror(err)); return err; } @@ -423,12 +541,17 @@ int dp_vs_blklst_init(void) msg_type.unicast_msg_cb = blklst_del_msg_cb; err = msg_type_mc_register(&msg_type); if (err != EDPVS_OK) { - RTE_LOG(ERR, SERVICE, "%s: fail to register msg.\n", __func__); + RTE_LOG(ERR, SERVICE, "%s: register BLKLST_DEL msg failed -- %s\n", + __func__, dpvs_strerror(err)); return err; } - if ((err = sockopt_register(&blklst_sockopts)) != EDPVS_OK) + if ((err = sockopt_register(&blklst_sockopts)) != EDPVS_OK) { + RTE_LOG(ERR, SERVICE, "%s: register sockopts failed -- %s\n", + __func__, dpvs_strerror(err)); return err; + } + dp_vs_blklst_rnd = (uint32_t)random(); return EDPVS_OK; @@ -438,15 +561,42 @@ int dp_vs_blklst_term(void) { int err; lcoreid_t cid; + struct dpvs_msg_type msg_type; - if ((err = sockopt_unregister(&blklst_sockopts)) != EDPVS_OK) - return err; + if ((err = sockopt_unregister(&blklst_sockopts)) != EDPVS_OK) { + RTE_LOG(WARNING, SERVICE, "%s: unregister sockopts failed -- %s\n", + __func__, dpvs_strerror(err)); + } + + memset(&msg_type, 0, sizeof(struct dpvs_msg_type)); + msg_type.type = MSG_TYPE_BLKLST_DEL; + msg_type.mode = DPVS_MSG_MULTICAST; + msg_type.prio = MSG_PRIO_NORM; + msg_type.cid = rte_lcore_id(); + msg_type.unicast_msg_cb = blklst_del_msg_cb; + err = msg_type_mc_unregister(&msg_type); + if (err != EDPVS_OK) { + RTE_LOG(ERR, SERVICE, "%s: unregister BLKLST_DEL msg failed -- %s\n", + __func__, dpvs_strerror(err)); + } + + memset(&msg_type, 0, sizeof(struct dpvs_msg_type)); + msg_type.type = MSG_TYPE_BLKLST_ADD; + msg_type.mode = DPVS_MSG_MULTICAST; + msg_type.prio = MSG_PRIO_NORM; + msg_type.cid = rte_lcore_id(); + msg_type.unicast_msg_cb = blklst_add_msg_cb; + err = msg_type_mc_unregister(&msg_type); + if (err != EDPVS_OK) { + RTE_LOG(ERR, SERVICE, "%s: unregister BLKLST_ADD msg failed -- %s\n", + __func__, dpvs_strerror(err)); + } rte_eal_mp_remote_launch(blklst_lcore_term, NULL, CALL_MAIN); RTE_LCORE_FOREACH_WORKER(cid) { if ((err = rte_eal_wait_lcore(cid)) < 0) { - RTE_LOG(WARNING, SERVICE, "%s: lcore %d: %s.\n", - __func__, cid, dpvs_strerror(err)); + RTE_LOG(WARNING, SERVICE, "[%02d] %s: blklst termination failed -- %s\n", + cid, __func__, dpvs_strerror(err)); } } diff --git a/src/ipvs/ip_vs_proto_sctp.c b/src/ipvs/ip_vs_proto_sctp.c index 28b067ae1..d46184110 100644 --- a/src/ipvs/ip_vs_proto_sctp.c +++ b/src/ipvs/ip_vs_proto_sctp.c @@ -70,8 +70,8 @@ static struct dp_vs_conn *sctp_conn_lookup(struct dp_vs_proto *proto, if (unlikely(!sch)) return NULL; - if (dp_vs_blklst_lookup(iph->af, iph->proto, &iph->daddr, sh->dest_port, - &iph->saddr)) { + if (dp_vs_blklst_filtered(iph->af, iph->proto, &iph->daddr, sh->dest_port, + &iph->saddr, mbuf)) { *drop = true; return NULL; } diff --git a/src/ipvs/ip_vs_proto_tcp.c b/src/ipvs/ip_vs_proto_tcp.c index 8c7edb501..d28f22cd4 100644 --- a/src/ipvs/ip_vs_proto_tcp.c +++ b/src/ipvs/ip_vs_proto_tcp.c @@ -831,8 +831,8 @@ tcp_conn_lookup(struct dp_vs_proto *proto, const struct dp_vs_iphdr *iph, if (unlikely(!th)) return NULL; - if (dp_vs_blklst_lookup(iph->af, iph->proto, &iph->daddr, - th->dest, &iph->saddr)) { + if (dp_vs_blklst_filtered(iph->af, iph->proto, &iph->daddr, + th->dest, &iph->saddr, mbuf)) { *drop = true; return NULL; } diff --git a/src/ipvs/ip_vs_proto_udp.c b/src/ipvs/ip_vs_proto_udp.c index df58fc924..27275224d 100644 --- a/src/ipvs/ip_vs_proto_udp.c +++ b/src/ipvs/ip_vs_proto_udp.c @@ -235,8 +235,8 @@ udp_conn_lookup(struct dp_vs_proto *proto, if (unlikely(!uh)) return NULL; - if (dp_vs_blklst_lookup(iph->af, iph->proto, &iph->daddr, - uh->dst_port, &iph->saddr)) { + if (dp_vs_blklst_filtered(iph->af, iph->proto, &iph->daddr, + uh->dst_port, &iph->saddr, mbuf)) { *drop = true; return NULL; } diff --git a/src/ipvs/ip_vs_synproxy.c b/src/ipvs/ip_vs_synproxy.c index 5378083b7..815dc9096 100644 --- a/src/ipvs/ip_vs_synproxy.c +++ b/src/ipvs/ip_vs_synproxy.c @@ -758,8 +758,8 @@ int dp_vs_synproxy_syn_rcv(int af, struct rte_mbuf *mbuf, } /* drop packet from blacklist */ - if (dp_vs_blklst_lookup(iph->af, iph->proto, &iph->daddr, - th->dest, &iph->saddr)) { + if (dp_vs_blklst_filtered(iph->af, iph->proto, &iph->daddr, + th->dest, &iph->saddr, mbuf)) { goto syn_rcv_out; } diff --git a/tools/ipvsadm/ipvsadm.c b/tools/ipvsadm/ipvsadm.c index 6e8923d49..69c8e81c4 100644 --- a/tools/ipvsadm/ipvsadm.c +++ b/tools/ipvsadm/ipvsadm.c @@ -902,15 +902,19 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce, { dpvs_service_compat_t dpvs_svc; set_option(options,OPT_BLKLST_ADDRESS); - parse = parse_service(optarg, - &dpvs_svc); - if (!(parse & SERVICE_ADDR)) - fail(2, "illegal blacklist address"); - - ce->dpvs_blklst.af = dpvs_svc.af; - ce->dpvs_blklst.blklst = dpvs_svc.addr; + if (!strncmp(optarg, "ipset:", strlen("ipset:"))) { + strncpy(ce->dpvs_blklst.ipset, &optarg[strlen("ipset:")], + sizeof(ce->dpvs_blklst.ipset) - 1); + } else { + parse = parse_service(optarg, &dpvs_svc); + if (parse & SERVICE_ADDR) { + ce->dpvs_blklst.af = dpvs_svc.af; + ce->dpvs_blklst.subject = dpvs_svc.addr; + } else { + fail(2, "illegal blacklist entry format, require [ IP | ipset:NAME ]"); + } + } break; - } case '2': { @@ -1682,9 +1686,9 @@ static void usage_exit(const char *program, const int exit_status) " --add-laddr -P add local address\n" " --del-laddr -Q del local address\n" " --get-laddr -G get local address\n" - " --add-blklst -U add blacklist address\n" - " --del-blklst -V del blacklist address\n" - " --get-blklst -B get blacklist address\n" + " --add-blklst -U add blacklist address or ipset\n" + " --del-blklst -V del blacklist address or ipset\n" + " --get-blklst -B get blacklist address or ipset\n" " --add-whtlst -O add whitelist address\n" " --del-whtlst -Y del whitelist address\n" " --get-whtlst -W get whitelist address\n" @@ -1752,7 +1756,7 @@ static void usage_exit(const char *program, const int exit_status) " UPDOWN:=down_retry,up_confirm,down_wait,inhibit_min-inhibit_max, for example, the default is 1,1,3s,5-3600s\n" " DOWNONLY:=down_retry,down_wait, for example, --dest-check=1,3s\n" " --laddr -z local-ip local IP\n" - " --blklst -k blacklist-ip blacklist IP for specific service\n" + " --blklst -k blacklist-ip specify blacklist ip address or ipset(format: \"ipset:NAME\")\n" " --whtlst -2 whitelist-ip whitelist IP for specific service\n" " --quic itef quic protocol service\n", DEF_SCHED); @@ -2423,17 +2427,17 @@ static int list_all_laddrs(lcoreid_t index) static void list_blklsts_print_title(void) { - printf("%-20s %-8s %-20s\n", - "VIP:VPORT" , + printf("%-8s %-30s %-30s\n", "PROTO" , + "VIP:VPORT" , "BLACKLIST"); } -static void print_service_and_blklsts(struct dp_vs_blklst_conf *blklst) +static void print_service_and_blklsts(const struct dp_vs_blklst_conf *blklst) { - char vip[64], bip[64], port[8], proto[8]; + char subject[64], vip[64], vport[8], proto[8], vip_port[64]; const char *pattern = (blklst->af == AF_INET ? - "%s:%-8s %-8s %-20s\n" : "[%s]:%-8s %-8s %-20s\n"); + "%-8s %-30s %-30s\n" : "%-8s %-30s %-30s\n"); switch (blklst->proto) { case IPPROTO_TCP: @@ -2455,10 +2459,19 @@ static void print_service_and_blklsts(struct dp_vs_blklst_conf *blklst) break; } - snprintf(port, sizeof(port), "%u", ntohs(blklst->vport)); + snprintf(vport, sizeof(vport), "%u", ntohs(blklst->vport)); + inet_ntop(blklst->af, (const void *)&blklst->vaddr, vip, sizeof(vip)); + if (blklst->af == AF_INET6) + snprintf(vip_port, sizeof(vip_port), "[%s]:%s", vip, vport); + else + snprintf(vip_port, sizeof(vip_port), "%s:%s", vip, vport); - printf(pattern, inet_ntop(blklst->af, (const void *)&blklst->vaddr, vip, sizeof(vip)), - port, proto, inet_ntop(blklst->af, (const void *)&blklst->blklst, bip, sizeof(bip))); + if (blklst->ipset[0] == '\0') + inet_ntop(blklst->af, (const void *)&blklst->subject, subject, sizeof(subject)); + else + snprintf(subject, sizeof(subject), "ipset:%s", blklst->ipset); + + printf(pattern, proto, vip_port, subject); } static bool inet_addr_equal(int af, const union inet_addr *a1, const union inet_addr *a2) @@ -2473,9 +2486,19 @@ static bool inet_addr_equal(int af, const union inet_addr *a1, const union inet_ } } +static inline void __list_blklst(int af, const union inet_addr *addr, uint16_t port, + uint16_t protocol, const struct dp_vs_blklst_conf_array *cfarr) { + int i; + for (i = 0; i < cfarr->naddr; i++) { + if (inet_addr_equal(af, addr, (const union inet_addr *) &cfarr->blklsts[i].vaddr) && + port == cfarr->blklsts[i].vport && protocol == cfarr->blklsts[i].proto) { + print_service_and_blklsts(&cfarr->blklsts[i]); + } + } +} + static int list_blklst(int af, const union inet_addr *addr, uint16_t port, uint16_t protocol) { - int i; struct dp_vs_blklst_conf_array *get; if (!(get = dpvs_get_blklsts())) { @@ -2483,14 +2506,9 @@ static int list_blklst(int af, const union inet_addr *addr, uint16_t port, uint1 return -1; } - for (i = 0; i < get->naddr; i++) { - if (inet_addr_equal(af, addr,(const union inet_addr *) &get->blklsts[i].vaddr) && - port == get->blklsts[i].vport && protocol == get->blklsts[i].proto) { - print_service_and_blklsts(&get->blklsts[i]); - } - } - free(get); + __list_blklst(af, addr, port, protocol, get); + free(get); return 0; } @@ -2498,6 +2516,7 @@ static int list_all_blklsts(void) { int i; dpvs_services_front_t* table; + struct dp_vs_blklst_conf_array *barray; table = (dpvs_services_front_t*)malloc(sizeof(dpvs_services_front_t)+sizeof(dpvs_service_compat_t)*g_ipvs_info.num_services); if (!table) { @@ -2513,12 +2532,18 @@ static int list_all_blklsts(void) exit(1); } + if(!(barray = dpvs_get_blklsts())) { + fprintf(stderr, "%s\n", ipvs_strerror(errno)); + exit(1); + } + list_blklsts_print_title(); for (i = 0; i < table->count; i++) { - list_blklst(table->entrytable[i].af, &table->entrytable[i].addr, - table->entrytable[i].port, table->entrytable[i].proto); + __list_blklst(table->entrytable[i].af, &table->entrytable[i].addr, + table->entrytable[i].port, table->entrytable[i].proto, barray); } + free(barray); free(table); return 0; diff --git a/tools/keepalived/keepalived/check/check_data.c b/tools/keepalived/keepalived/check/check_data.c index 95db23d39..b696de6de 100644 --- a/tools/keepalived/keepalived/check/check_data.c +++ b/tools/keepalived/keepalived/check/check_data.c @@ -732,7 +732,9 @@ dump_blklst_entry(FILE *fp, const void *data) { const blklst_addr_entry *blklst_entry = data; - if (blklst_entry->range) + if (!strncmp(blklst_entry->ipset, "ipset:", sizeof("ipset:") - 1)) + conf_write(fp, " IPSET = %s", blklst_entry->ipset); + else if (blklst_entry->range) conf_write(fp, " IP Range = %s-%d" , inet_sockaddrtos(&blklst_entry->addr) , blklst_entry->range); @@ -752,6 +754,7 @@ alloc_blklst_group(char *gname) memcpy(new->gname, gname, size); new->addr_ip = alloc_list(free_blklst_entry, dump_blklst_entry); new->range = alloc_list(free_blklst_entry, dump_blklst_entry); + new->ipset = alloc_list(free_blklst_entry, dump_blklst_entry); list_add(check_data->blklst_group, new); } @@ -761,14 +764,22 @@ alloc_blklst_entry(const vector_t *strvec) { blklst_addr_group *blklst_group = LIST_TAIL_DATA(check_data->blklst_group); blklst_addr_entry *new; + const char *str_entry; new = (blklst_addr_entry *) MALLOC(sizeof (blklst_addr_entry)); + str_entry = strvec_slot(strvec, 0); - inet_stor(vector_slot(strvec, 0), &new->range); + if (!strncmp(str_entry, "ipset:", sizeof("ipset:") - 1)) { + strncpy(new->ipset, &str_entry[sizeof("ipset:")-1], sizeof(new->ipset) - 1); + list_add(blklst_group->ipset, new); + return; + } + + inet_stor(str_entry, &new->range); /* If no range specified, new->range == UINT32_MAX */ if (new->range == UINT32_MAX) new->range = 0; - inet_stosockaddr(vector_slot(strvec, 0), NULL, &new->addr); + inet_stosockaddr(str_entry, NULL, &new->addr); if (!new->range) list_add(blklst_group->addr_ip, new); diff --git a/tools/keepalived/keepalived/check/ipvswrapper.c b/tools/keepalived/keepalived/check/ipvswrapper.c index d3cb4dbd4..5183f11d6 100755 --- a/tools/keepalived/keepalived/check/ipvswrapper.c +++ b/tools/keepalived/keepalived/check/ipvswrapper.c @@ -615,8 +615,8 @@ ipvs_blklst_range_cmd(int cmd, blklst_addr_entry *blklst_entry, dpvs_service_com memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); blklst_rule.af = blklst_entry->addr.ss_family; if (blklst_entry->addr.ss_family == AF_INET6) { - inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.blklst.in6); - ip = blklst_rule.blklst.in6.s6_addr32[3]; + inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.subject.in6); + ip = blklst_rule.subject.in6.s6_addr32[3]; } else { ip = inet_sockaddrip4(&blklst_entry->addr); } @@ -625,9 +625,9 @@ ipvs_blklst_range_cmd(int cmd, blklst_addr_entry *blklst_entry, dpvs_service_com ((addr_ip >> 24) & 0xFF) <= blklst_entry->range; addr_ip += 0x01000000) { if (blklst_entry->addr.ss_family == AF_INET6) - blklst_rule.blklst.in6.s6_addr32[3] = addr_ip; + blklst_rule.subject.in6.s6_addr32[3] = addr_ip; else - blklst_rule.blklst.in.s_addr = addr_ip; + blklst_rule.subject.in.s_addr = addr_ip; ipvs_talk(cmd, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); } @@ -649,9 +649,9 @@ ipvs_blklst_group_cmd(int cmd, blklst_addr_group *blklst_group, dpvs_service_com memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); blklst_rule.af = blklst_entry->addr.ss_family; if (blklst_entry->addr.ss_family == AF_INET6) - inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.blklst.in6); + inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.subject.in6); else - blklst_rule.blklst.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); + blklst_rule.subject.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); ipvs_talk(cmd, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); } @@ -659,6 +659,13 @@ ipvs_blklst_group_cmd(int cmd, blklst_addr_group *blklst_group, dpvs_service_com LIST_FOREACH(l, blklst_entry, e) { ipvs_blklst_range_cmd(cmd, blklst_entry, srule); } + + l = blklst_group->ipset; + LIST_FOREACH(l, blklst_entry, e) { + memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); + strncpy(blklst_rule.ipset, blklst_entry->ipset, sizeof(blklst_rule.ipset) - 1); + ipvs_talk(cmd, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); + } } static void @@ -1281,15 +1288,19 @@ ipvs_rm_bentry_from_vsg(blklst_addr_entry *blklst_entry, whtlst_addr_entry *whtl srule->addr.in.s_addr = ip; if (blklst_entry != NULL) { - if (blklst_entry->range) + if(blklst_entry->ipset[0] != '\0') { + memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); + strncpy(blklst_rule.ipset, blklst_entry->ipset, sizeof(blklst_rule.ipset) - 1); + ipvs_talk(IP_VS_SO_SET_DELBLKLST, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); + } else if (blklst_entry->range) { ipvs_blklst_range_cmd(IP_VS_SO_SET_DELBLKLST, blklst_entry, srule); - else { + } else { memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); blklst_rule.af = blklst_entry->addr.ss_family; if (blklst_entry->addr.ss_family == AF_INET6) - inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.blklst.in6); + inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.subject.in6); else - blklst_rule.blklst.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); + blklst_rule.subject.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); ipvs_talk(IP_VS_SO_SET_DELBLKLST, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); } } @@ -1319,15 +1330,19 @@ ipvs_rm_bentry_from_vsg(blklst_addr_entry *blklst_entry, whtlst_addr_entry *whtl srule->addr.in.s_addr = addr_ip; if (blklst_entry != NULL) { - if (blklst_entry->range) + if(blklst_entry->ipset[0] != '\0') { + memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); + strncpy(blklst_rule.ipset, blklst_entry->ipset, sizeof(blklst_rule.ipset) - 1); + ipvs_talk(IP_VS_SO_SET_DELBLKLST, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); + } else if (blklst_entry->range) { ipvs_blklst_range_cmd(IP_VS_SO_SET_DELBLKLST, blklst_entry, srule); - else { + } else { memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); blklst_rule.af = blklst_entry->addr.ss_family; if (blklst_entry->addr.ss_family == AF_INET6) - inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.blklst.in6); + inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.subject.in6); else - blklst_rule.blklst.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); + blklst_rule.subject.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); ipvs_talk(IP_VS_SO_SET_DELBLKLST, srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); } @@ -1373,15 +1388,19 @@ ipvs_blklst_remove_entry(virtual_server_t *vs, blklst_addr_entry *blklst_entry) } srule.port = inet_sockaddrport(&vs->addr); - if (blklst_entry->range) { + if(blklst_entry->ipset[0] != '\0') { + memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); + strncpy(blklst_rule.ipset, blklst_entry->ipset, sizeof(blklst_rule.ipset) - 1); + ipvs_talk(IP_VS_SO_SET_DELBLKLST, &srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); + } else if (blklst_entry->range) { ipvs_blklst_range_cmd(IP_VS_SO_SET_DELBLKLST, blklst_entry, &srule); } else { memset(&blklst_rule, 0, sizeof(dpvs_blklst_t)); blklst_rule.af = blklst_entry->addr.ss_family; if (blklst_entry->addr.ss_family == AF_INET6) - inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.blklst.in6); + inet_sockaddrip6(&blklst_entry->addr, &blklst_rule.subject.in6); else - blklst_rule.blklst.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); + blklst_rule.subject.in.s_addr = inet_sockaddrip4(&blklst_entry->addr); ipvs_talk(IP_VS_SO_SET_DELBLKLST, &srule, NULL, NULL, NULL, &blklst_rule, NULL, NULL, false); } diff --git a/tools/keepalived/keepalived/check/ipwrapper.c b/tools/keepalived/keepalived/check/ipwrapper.c index 7bc45d1c2..1f8706a51 100755 --- a/tools/keepalived/keepalived/check/ipwrapper.c +++ b/tools/keepalived/keepalived/check/ipwrapper.c @@ -1253,6 +1253,8 @@ clear_diff_blklst(virtual_server_t * old_vs, virtual_server_t * new_vs) return 0; if (!clear_diff_blklst_entry(old->range, new->range, old_vs)) return 0; + if (!clear_diff_blklst_entry(old->ipset, new->ipset, old_vs)) + return 0; return 1; } diff --git a/tools/keepalived/keepalived/check/libipvs.c b/tools/keepalived/keepalived/check/libipvs.c index 849ac51ad..8d9096795 100644 --- a/tools/keepalived/keepalived/check/libipvs.c +++ b/tools/keepalived/keepalived/check/libipvs.c @@ -299,17 +299,10 @@ int dpvs_del_laddr(dpvs_service_compat_t *svc, dpvs_laddr_table_t *laddr) /*for black list*/ static void dpvs_fill_blklst_conf(dpvs_service_compat_t *svc, dpvs_blklst_t *blklst) { - blklst->af = svc->af; - blklst->proto = svc->proto; - blklst->vport = svc->port; - blklst->fwmark = svc->fwmark; - if (svc->af == AF_INET) { - blklst->vaddr.in = svc->addr.in; - } else { - blklst->vaddr.in6 = svc->addr.in6; - } - - return; + blklst->af = svc->af; + blklst->proto = svc->proto; + blklst->vport = svc->port; + blklst->vaddr = svc->addr; } int dpvs_add_blklst(dpvs_service_compat_t* svc, dpvs_blklst_t *blklst) diff --git a/tools/keepalived/keepalived/include/check_data.h b/tools/keepalived/keepalived/include/check_data.h index 14650b644..28aec2258 100644 --- a/tools/keepalived/keepalived/include/check_data.h +++ b/tools/keepalived/keepalived/include/check_data.h @@ -132,6 +132,7 @@ typedef struct _local_addr_group { typedef struct _blklst_addr_entry { struct sockaddr_storage addr; uint32_t range; + char ipset[IPSET_MAXNAMELEN]; } blklst_addr_entry; @@ -139,6 +140,7 @@ typedef struct _blklst_addr_group { char *gname; list addr_ip; list range; + list ipset; } blklst_addr_group; /* whitelist ip group*/