]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: handling notifications upon ipset creation/destruction done
authorPhilippe Guibert <philippe.guibert@6wind.com>
Wed, 7 Mar 2018 14:46:00 +0000 (15:46 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 16 Apr 2018 12:40:43 +0000 (14:40 +0200)
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>
lib/zclient.c
lib/zclient.h
zebra/zebra_pbr.c
zebra/zebra_pbr.h
zebra/zserv.c
zebra/zserv.h

index 07029c1f5d99b9e8503aeb5b98f9c6b74541d787..34f49c0b470bf25eb028d54c4af2901697583993 100644 (file)
@@ -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();
index 3c6e1b32089bdafc0d14a00b28b6f94573110e30..b8896f6b990a7373c5a0c686155a55f4ae37fcf0 100644 (file)
@@ -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);
index cec891b7f3c6414435968858d62a0c5321d73fe9..9cc7ce905c6f10e7c0bd2dd7bfbe1e43b2da25db 100644 (file)
@@ -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
@@ -396,6 +396,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.
  */
index 2060cc25ec9f1a831a9bf1f83624bba55638fa41..c4af66b05626f699856386b5a3142e9b46174058 100644 (file)
@@ -182,6 +182,16 @@ enum southbound_results;
 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.
  */
@@ -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);
index 942e60c798318fe394bc607868673eeae8443cde..f38ea81adb5daef96c47407b8b52cf5e98a5860b 100644 (file)
@@ -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)
index 947e11e35bf6c05d7e75c1b07ba81ac0e9ffddec..e66c1811ca913c6e1028dce2a5f0563cd1b3a7e7 100644 (file)
@@ -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);