summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-03-07 13:21:14 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-04-16 14:40:16 +0200
commitd59c13af5ca0913f16eff966baaa01b1531f86e7 (patch)
treea31f413e9be31b70291f87bb0c6955533e683c37
parent7661461a3a2e8a6c9feb539d41ba4e454fccb037 (diff)
lib: add ZEBRA IPSET defines
ZEBRA IPSET defines are added for creating/deleting ipset contexts. Ans also create ipset hash sets. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r--lib/log.c4
-rw-r--r--lib/zclient.h4
-rw-r--r--zebra/zebra_pbr.c24
-rw-r--r--zebra/zebra_pbr.h2
-rw-r--r--zebra/zserv.c82
5 files changed, 115 insertions, 1 deletions
diff --git a/lib/log.c b/lib/log.c
index f5aff756dd..dbfc95da86 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -968,6 +968,10 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_TABLE_MANAGER_CONNECT),
DESC_ENTRY(ZEBRA_GET_TABLE_CHUNK),
DESC_ENTRY(ZEBRA_RELEASE_TABLE_CHUNK),
+ DESC_ENTRY(ZEBRA_IPSET_CREATE),
+ DESC_ENTRY(ZEBRA_IPSET_DESTROY),
+ DESC_ENTRY(ZEBRA_IPSET_ENTRY_ADD),
+ DESC_ENTRY(ZEBRA_IPSET_ENTRY_DELETE),
};
#undef DESC_ENTRY
diff --git a/lib/zclient.h b/lib/zclient.h
index a77b1c1f94..3c6e1b3208 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -140,6 +140,10 @@ typedef enum {
ZEBRA_TABLE_MANAGER_CONNECT,
ZEBRA_GET_TABLE_CHUNK,
ZEBRA_RELEASE_TABLE_CHUNK,
+ ZEBRA_IPSET_CREATE,
+ ZEBRA_IPSET_DESTROY,
+ ZEBRA_IPSET_ENTRY_ADD,
+ ZEBRA_IPSET_ENTRY_DELETE,
} zebra_message_types_t;
struct redist_proto {
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 1855b54371..cec891b7f3 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -283,6 +283,20 @@ static void *pbr_ipset_alloc_intern(void *arg)
return new;
}
+static struct zebra_pbr_ipset *zpi_found;
+
+static int zebra_pbr_ipset_pername_walkcb(struct hash_backet *backet, void *arg)
+{
+ struct zebra_pbr_ipset *zpi = (struct zebra_pbr_ipset *)backet->data;
+ char *ipset_name = (char *)arg;
+
+ if (!strncmp(ipset_name, zpi->ipset_name, ZEBRA_IPSET_NAME_SIZE)) {
+ zpi_found = zpi;
+ return HASHWALK_ABORT;
+ }
+ return HASHWALK_CONTINUE;
+}
+
void zebra_pbr_create_ipset(struct zebra_ns *zns,
struct zebra_pbr_ipset *ipset)
{
@@ -309,6 +323,16 @@ void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
__PRETTY_FUNCTION__);
}
+struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns,
+ char *ipsetname)
+{
+ if (!ipsetname)
+ return NULL;
+ zpi_found = NULL;
+ hash_walk(zns->ipset_hash, zebra_pbr_ipset_pername_walkcb, ipsetname);
+ return zpi_found;
+}
+
static void *pbr_ipset_entry_alloc_intern(void *arg)
{
struct zebra_pbr_ipset_entry *zpi;
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 31e20a3078..2060cc25ec 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -150,6 +150,8 @@ void zebra_pbr_create_ipset(struct zebra_ns *zns,
struct zebra_pbr_ipset *ipset);
void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
struct zebra_pbr_ipset *ipset);
+struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns,
+ char *ipsetname);
void zebra_pbr_add_ipset_entry(struct zebra_ns *zns,
struct zebra_pbr_ipset_entry *ipset);
void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
diff --git a/zebra/zserv.c b/zebra/zserv.c
index c06efbfb4b..942e60c798 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -2685,7 +2685,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
zpr.ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN);
if (!zpr.ifp) {
- zlog_debug("FAiled to lookup ifindex: %u", ifindex);
+ zlog_debug("Failed to lookup ifindex: %u", ifindex);
return;
}
@@ -2711,6 +2711,82 @@ stream_failure:
return;
}
+
+static inline void zread_ipset(ZAPI_HANDLER_ARGS)
+{
+ struct zebra_pbr_ipset zpi;
+ struct stream *s;
+ uint32_t total, i;
+
+ s = msg;
+ STREAM_GETL(s, total);
+
+ for (i = 0; i < total; i++) {
+ memset(&zpi, 0, sizeof(zpi));
+
+ zpi.sock = client->sock;
+ STREAM_GETL(s, zpi.unique);
+ STREAM_GETL(s, zpi.type);
+ STREAM_GET(&zpi.ipset_name, s,
+ ZEBRA_IPSET_NAME_SIZE);
+
+ if (hdr->command == ZEBRA_IPSET_CREATE)
+ zebra_pbr_create_ipset(zvrf->zns, &zpi);
+ else
+ zebra_pbr_destroy_ipset(zvrf->zns, &zpi);
+ }
+
+stream_failure:
+ return;
+}
+
+static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
+{
+ struct zebra_pbr_ipset_entry zpi;
+ struct zebra_pbr_ipset ipset;
+ struct stream *s;
+ uint32_t total, i;
+
+ s = msg;
+ STREAM_GETL(s, total);
+
+ for (i = 0; i < total; i++) {
+ memset(&zpi, 0, sizeof(zpi));
+ memset(&ipset, 0, sizeof(ipset));
+
+ zpi.sock = client->sock;
+ STREAM_GETL(s, zpi.unique);
+ STREAM_GET(&ipset.ipset_name, s,
+ ZEBRA_IPSET_NAME_SIZE);
+ STREAM_GETC(s, zpi.src.family);
+ STREAM_GETC(s, zpi.src.prefixlen);
+ STREAM_GET(&zpi.src.u.prefix, s,
+ prefix_blen(&zpi.src));
+ STREAM_GETC(s, zpi.dst.family);
+ STREAM_GETC(s, zpi.dst.prefixlen);
+ STREAM_GET(&zpi.dst.u.prefix, s,
+ prefix_blen(&zpi.dst));
+
+ if (!is_default_prefix(&zpi.src))
+ zpi.filter_bm |= PBR_FILTER_SRC_IP;
+
+ if (!is_default_prefix(&zpi.dst))
+ zpi.filter_bm |= PBR_FILTER_DST_IP;
+
+ /* calculate backpointer */
+ zpi.backpointer = zebra_pbr_lookup_ipset_pername(zvrf->zns,
+ ipset.ipset_name);
+ if (hdr->command == ZEBRA_IPSET_ENTRY_ADD)
+ zebra_pbr_add_ipset_entry(zvrf->zns, &zpi);
+ else
+ zebra_pbr_del_ipset_entry(zvrf->zns, &zpi);
+ }
+
+stream_failure:
+ return;
+}
+
+
void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
[ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
@@ -2771,6 +2847,10 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_TABLE_MANAGER_CONNECT] = zread_table_manager_request,
[ZEBRA_GET_TABLE_CHUNK] = zread_table_manager_request,
[ZEBRA_RELEASE_TABLE_CHUNK] = zread_table_manager_request,
+ [ZEBRA_IPSET_CREATE] = zread_ipset,
+ [ZEBRA_IPSET_DESTROY] = zread_ipset,
+ [ZEBRA_IPSET_ENTRY_ADD] = zread_ipset_entry,
+ [ZEBRA_IPSET_ENTRY_DELETE] = zread_ipset_entry,
};
static inline void zserv_handle_commands(struct zserv *client,