diff options
author | Philippe Guibert <philippe.guibert@6wind.com> | 2018-03-07 15:46:00 +0100 |
---|---|---|
committer | Philippe Guibert <philippe.guibert@6wind.com> | 2018-04-16 14:40:43 +0200 |
commit | 425bdd6bf10123c2027ed602536490aeb5fb72a0 (patch) | |
tree | c4247c9a59e7a103f1b26d62763912e558a5e74d | |
parent | lib: add ZEBRA IPSET defines (diff) | |
download | frr-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.c | 44 | ||||
-rw-r--r-- | lib/zclient.h | 31 | ||||
-rw-r--r-- | zebra/zebra_pbr.c | 51 | ||||
-rw-r--r-- | zebra/zebra_pbr.h | 15 | ||||
-rw-r--r-- | zebra/zserv.c | 67 | ||||
-rw-r--r-- | zebra/zserv.h | 8 |
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, ¬e, 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, ¬e, 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, ¬e, 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); |