summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-03-07 15:46:00 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-04-16 14:40:43 +0200
commit425bdd6bf10123c2027ed602536490aeb5fb72a0 (patch)
treec4247c9a59e7a103f1b26d62763912e558a5e74d
parentlib: add ZEBRA IPSET defines (diff)
downloadfrr-425bdd6bf10123c2027ed602536490aeb5fb72a0.tar.xz
frr-425bdd6bf10123c2027ed602536490aeb5fb72a0.zip
zebra: handling notifications upon ipset creation/destruction done
Once ipset entries are injected in the kernel, the relevant daemon is informed with a zebra message sent back. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
-rw-r--r--lib/zclient.c44
-rw-r--r--lib/zclient.h31
-rw-r--r--zebra/zebra_pbr.c51
-rw-r--r--zebra/zebra_pbr.h15
-rw-r--r--zebra/zserv.c67
-rw-r--r--zebra/zserv.h8
6 files changed, 209 insertions, 7 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index 07029c1f5..34f49c0b4 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1279,6 +1279,50 @@ stream_failure:
return false;
}
+bool zapi_ipset_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_ipset_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
+bool zapi_ipset_entry_notify_decode(struct stream *s,
+ uint32_t *unique,
+ char *ipset_name,
+ enum zapi_ipset_entry_notify_owner *note)
+{
+ uint32_t uni;
+
+ STREAM_GET(note, s, sizeof(*note));
+
+ STREAM_GETL(s, uni);
+
+ STREAM_GET(ipset_name, s,
+ ZEBRA_IPSET_NAME_SIZE);
+
+ if (zclient_debug)
+ zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
+ *unique = uni;
+
+ return true;
+
+stream_failure:
+ return false;
+}
+
struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
{
struct nexthop *n = nexthop_new();
diff --git a/lib/zclient.h b/lib/zclient.h
index 3c6e1b320..b8896f6b9 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -144,6 +144,8 @@ typedef enum {
ZEBRA_IPSET_DESTROY,
ZEBRA_IPSET_ENTRY_ADD,
ZEBRA_IPSET_ENTRY_DELETE,
+ ZEBRA_IPSET_NOTIFY_OWNER,
+ ZEBRA_IPSET_ENTRY_NOTIFY_OWNER,
} zebra_message_types_t;
struct redist_proto {
@@ -234,6 +236,12 @@ struct zclient {
uint16_t length, vrf_id_t vrf_id);
void (*label_chunk)(int command, struct zclient *zclient,
uint16_t length, vrf_id_t vrf_id);
+ int (*ipset_notify_owner)(int command, struct zclient *zclient,
+ uint16_t length, vrf_id_t vrf_id);
+ int (*ipset_entry_notify_owner)(int command,
+ struct zclient *zclient,
+ uint16_t length,
+ vrf_id_t vrf_id);
};
/* Zebra API message flag. */
@@ -389,6 +397,18 @@ enum zapi_rule_notify_owner {
ZAPI_RULE_REMOVED,
};
+enum zapi_ipset_notify_owner {
+ ZAPI_IPSET_FAIL_INSTALL,
+ ZAPI_IPSET_INSTALLED,
+ ZAPI_IPSET_REMOVED,
+};
+
+enum zapi_ipset_entry_notify_owner {
+ ZAPI_IPSET_ENTRY_FAIL_INSTALL,
+ ZAPI_IPSET_ENTRY_INSTALLED,
+ ZAPI_IPSET_ENTRY_REMOVED,
+};
+
/* Zebra MAC types */
#define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/
#define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/
@@ -628,6 +648,17 @@ bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
uint32_t *priority, uint32_t *unique,
ifindex_t *ifindex,
enum zapi_rule_notify_owner *note);
+bool zapi_ipset_notify_decode(struct stream *s,
+ uint32_t *unique,
+ enum zapi_ipset_notify_owner *note);
+
+#define ZEBRA_IPSET_NAME_SIZE 32
+
+bool zapi_ipset_entry_notify_decode(struct stream *s,
+ uint32_t *unique,
+ char *ipset_name,
+ enum zapi_ipset_entry_notify_owner *note);
+
extern struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh);
extern bool zapi_nexthop_update_decode(struct stream *s,
struct zapi_route *nhr);
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index cec891b7f..9cc7ce905 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -141,9 +141,9 @@ void zebra_pbr_ipset_free(void *arg)
uint32_t zebra_pbr_ipset_hash_key(void *arg)
{
struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg;
- uint32_t *pnt = (uint32_t *)ipset->ipset_name;
+ uint32_t *pnt = (uint32_t *)&ipset->ipset_name;
- return jhash2(pnt, ZEBRA_IPSET_NAME_SIZE, 0x63ab42de);
+ return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, 0x63ab42de);
}
int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
@@ -319,7 +319,7 @@ void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
if (lookup)
XFREE(MTYPE_TMP, lookup);
else
- zlog_warn("%s: IPSet being deleted we know nothing about",
+ zlog_warn("%s: IPSet Entry being deleted we know nothing about",
__PRETTY_FUNCTION__);
}
@@ -363,7 +363,7 @@ void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
{
struct zebra_pbr_ipset_entry *lookup;
- lookup = hash_lookup(zns->ipset_hash, ipset);
+ lookup = hash_lookup(zns->ipset_entry_hash, ipset);
/* TODO:
* - Netlink destroy
* - detach from ipset list
@@ -397,6 +397,49 @@ void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
}
/*
+ * Handle success or failure of ipset (un)install in the kernel.
+ */
+void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset *ipset,
+ enum southbound_results res)
+{
+ switch (res) {
+ case SOUTHBOUND_INSTALL_SUCCESS:
+ zsend_ipset_notify_owner(ipset, ZAPI_IPSET_INSTALLED);
+ break;
+ case SOUTHBOUND_INSTALL_FAILURE:
+ zsend_ipset_notify_owner(ipset, ZAPI_IPSET_FAIL_INSTALL);
+ break;
+ case SOUTHBOUND_DELETE_SUCCESS:
+ case SOUTHBOUND_DELETE_FAILURE:
+ /* TODO : handling of delete event */
+ break;
+ }
+}
+
+/*
+ * Handle success or failure of ipset (un)install in the kernel.
+ */
+void kernel_pbr_ipset_entry_add_del_status(
+ struct zebra_pbr_ipset_entry *ipset,
+ enum southbound_results res)
+{
+ switch (res) {
+ case SOUTHBOUND_INSTALL_SUCCESS:
+ zsend_ipset_entry_notify_owner(ipset,
+ ZAPI_IPSET_ENTRY_INSTALLED);
+ break;
+ case SOUTHBOUND_INSTALL_FAILURE:
+ zsend_ipset_entry_notify_owner(ipset,
+ ZAPI_IPSET_ENTRY_FAIL_INSTALL);
+ break;
+ case SOUTHBOUND_DELETE_SUCCESS:
+ case SOUTHBOUND_DELETE_FAILURE:
+ /* TODO : handling of delete event */
+ break;
+ }
+}
+
+/*
* Handle rule delete notification from kernel.
*/
int kernel_pbr_rule_del(struct zebra_pbr_rule *rule)
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 2060cc25e..c4af66b05 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -183,6 +183,16 @@ extern void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
enum southbound_results res);
/*
+ * Handle success or failure of ipset kinds (un)install in the kernel.
+ */
+extern void kernel_pbr_ipset_add_del_status(struct zebra_pbr_ipset *ipset,
+ enum southbound_results res);
+
+extern void kernel_pbr_ipset_entry_add_del_status(
+ struct zebra_pbr_ipset_entry *ipset,
+ enum southbound_results res);
+
+/*
* Handle rule delete notification from kernel.
*/
extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule);
@@ -193,6 +203,11 @@ extern void zebra_pbr_rules_free(void *arg);
extern uint32_t zebra_pbr_rules_hash_key(void *arg);
extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
+/* has operates on 32bit pointer
+ * and field is a string of 8bit
+ */
+#define ZEBRA_IPSET_NAME_HASH_SIZE (ZEBRA_IPSET_NAME_SIZE / 4)
+
extern void zebra_pbr_ipset_free(void *arg);
extern uint32_t zebra_pbr_ipset_hash_key(void *arg);
extern int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 942e60c79..f38ea81ad 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -725,10 +725,9 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
struct zserv *client;
struct stream *s;
- if (IS_ZEBRA_DEBUG_PACKET) {
+ if (IS_ZEBRA_DEBUG_PACKET)
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
rule->unique);
- }
for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
if (rule->sock == client->sock)
@@ -739,7 +738,6 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
return;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- stream_reset(s);
zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT);
stream_put(s, &note, sizeof(note));
@@ -756,6 +754,69 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
zebra_server_send_message(client, s);
}
+void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
+ enum zapi_ipset_notify_owner note)
+{
+ struct listnode *node;
+ struct zserv *client;
+ struct stream *s;
+
+ if (IS_ZEBRA_DEBUG_PACKET)
+ zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
+ ipset->unique);
+
+ for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ if (ipset->sock == client->sock)
+ break;
+ }
+
+ if (!client)
+ return;
+
+ s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+
+ zclient_create_header(s, ZEBRA_IPSET_NOTIFY_OWNER, VRF_DEFAULT);
+ stream_put(s, &note, sizeof(note));
+ stream_putl(s, ipset->unique);
+ stream_put(s, ipset->ipset_name, ZEBRA_IPSET_NAME_SIZE);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ zebra_server_send_message(client, s);
+}
+
+void zsend_ipset_entry_notify_owner(
+ struct zebra_pbr_ipset_entry *ipset,
+ enum zapi_ipset_entry_notify_owner note)
+{
+ struct listnode *node;
+ struct zserv *client;
+ struct stream *s;
+
+ if (IS_ZEBRA_DEBUG_PACKET)
+ zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
+ ipset->unique);
+
+ for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ if (ipset->sock == client->sock)
+ break;
+ }
+
+ if (!client)
+ return;
+
+ s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+
+ zclient_create_header(s, ZEBRA_IPSET_ENTRY_NOTIFY_OWNER,
+ VRF_DEFAULT);
+ stream_put(s, &note, sizeof(note));
+ stream_putl(s, ipset->unique);
+ stream_put(s, ipset->backpointer->ipset_name,
+ ZEBRA_IPSET_NAME_SIZE);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ zebra_server_send_message(client, s);
+}
+
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
int zsend_router_id_update(struct zserv *client, struct prefix *p,
vrf_id_t vrf_id)
diff --git a/zebra/zserv.h b/zebra/zserv.h
index 947e11e35..e66c1811c 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -188,8 +188,16 @@ extern int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
enum zapi_route_notify_owner note);
struct zebra_pbr_rule;
+struct zebra_pbr_ipset;
+struct zebra_pbr_ipset_entry;
extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
enum zapi_rule_notify_owner note);
+extern void zsend_ipset_notify_owner(
+ struct zebra_pbr_ipset *ipset,
+ enum zapi_ipset_notify_owner note);
+extern void zsend_ipset_entry_notify_owner(
+ struct zebra_pbr_ipset_entry *ipset,
+ enum zapi_ipset_entry_notify_owner note);
extern void zserv_nexthop_num_warn(const char *, const struct prefix *,
const unsigned int);