]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: PBR config and monitor IPSET/IPTABLE hooks declared
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 4 May 2018 11:57:31 +0000 (13:57 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 25 May 2018 13:49:38 +0000 (15:49 +0200)
The following PBR handlers: ipset, and iptables will prioritary
call the hook from a possible plugin.
If a plugin is attached, then it will return a positive value.
That is why the return status is tested against 0 value, since that
means that there are no plugin module plugged

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
zebra/zebra_pbr.c
zebra/zebra_pbr.h

index 606f4d6eb5b6f9a491878ceb7aa242af0dc09acd..0355f3c042634825590f31e8d2eeebe8c8a1d4d9 100644 (file)
 #include <jhash.h>
 #include <hash.h>
 #include <memory.h>
+#include <hook.h>
 
 #include "zebra/zebra_pbr.h"
 #include "zebra/rt.h"
 #include "zebra/zapi_msg.h"
 #include "zebra/zebra_memory.h"
-#include "zebra_pbr.h"
 
 /* definitions */
 DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list")
@@ -44,6 +44,30 @@ static const struct message ipset_type_msg[] = {
 };
 
 /* static function declarations */
+DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns,
+                                   struct zebra_pbr_ipset_entry *ipset,
+                                   uint64_t *pkts, uint64_t *bytes),
+                                    (zns, ipset, pkts, bytes))
+
+DEFINE_HOOK(zebra_pbr_iptable_wrap_script_get_stat, (struct zebra_ns *zns,
+                                   struct zebra_pbr_iptable *iptable,
+                                   uint64_t *pkts, uint64_t *bytes),
+                                    (zns, iptable, pkts, bytes))
+
+DEFINE_HOOK(zebra_pbr_iptable_wrap_script_update, (struct zebra_ns *zns,
+                                            int cmd,
+                                            struct zebra_pbr_iptable *iptable),
+                                           (zns, cmd, iptable));
+
+DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_update, (struct zebra_ns *zns,
+                                 int cmd,
+                                 struct zebra_pbr_ipset_entry *ipset),
+                                 (zns, cmd, ipset));
+
+DEFINE_HOOK(zebra_pbr_ipset_wrap_script_update, (struct zebra_ns *zns,
+                                 int cmd,
+                                 struct zebra_pbr_ipset *ipset),
+                                 (zns, cmd, ipset));
 
 /* Private functions */
 
@@ -158,9 +182,15 @@ static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns,
 void zebra_pbr_ipset_free(void *arg)
 {
        struct zebra_pbr_ipset *ipset;
+       struct zebra_ns *zns;
 
        ipset = (struct zebra_pbr_ipset *)arg;
-
+       if (vrf_is_backend_netns())
+               zns = zebra_ns_lookup(ipset->vrf_id);
+       else
+               zns = zebra_ns_lookup(NS_DEFAULT);
+       hook_call(zebra_pbr_ipset_wrap_script_update,
+                 zns, 0, ipset);
        XFREE(MTYPE_TMP, ipset);
 }
 
@@ -192,8 +222,17 @@ int zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2)
 void zebra_pbr_ipset_entry_free(void *arg)
 {
        struct zebra_pbr_ipset_entry *ipset;
+       struct zebra_ns *zns;
 
        ipset = (struct zebra_pbr_ipset_entry *)arg;
+       if (ipset->backpointer && vrf_is_backend_netns()) {
+               struct zebra_pbr_ipset *ips = ipset->backpointer;
+
+               zns = zebra_ns_lookup((ns_id_t)ips->vrf_id);
+       } else
+               zns = zebra_ns_lookup(NS_DEFAULT);
+       hook_call(zebra_pbr_ipset_entry_wrap_script_update,
+                 zns, 0, ipset);
 
        XFREE(MTYPE_TMP, ipset);
 }
@@ -254,8 +293,15 @@ void zebra_pbr_iptable_free(void *arg)
        struct zebra_pbr_iptable *iptable;
        struct listnode *node, *nnode;
        char *name;
+       struct zebra_ns *zns;
 
        iptable = (struct zebra_pbr_iptable *)arg;
+       if (vrf_is_backend_netns())
+               zns = zebra_ns_lookup((ns_id_t)iptable->vrf_id);
+       else
+               zns =  zebra_ns_lookup(NS_DEFAULT);
+       hook_call(zebra_pbr_iptable_wrap_script_update,
+                 zns, 0, iptable);
 
        for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
                                        node, nnode, name)) {
@@ -323,7 +369,6 @@ void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
 
        (void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
        kernel_add_pbr_rule(rule);
-
        /*
         * Rule Replace semantics, if we have an old, install the
         * new rule, look above, and then delete the old
@@ -366,8 +411,11 @@ static void zebra_pbr_cleanup_ipset(struct hash_backet *b, void *data)
        struct zebra_pbr_ipset *ipset = b->data;
        int *sock = data;
 
-       if (ipset->sock == *sock)
+       if (ipset->sock == *sock) {
+               hook_call(zebra_pbr_ipset_wrap_script_update,
+                         zns, 0, ipset);
                hash_release(zns->ipset_hash, ipset);
+       }
 }
 
 static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data)
@@ -376,8 +424,11 @@ static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data)
        struct zebra_pbr_ipset_entry *ipset = b->data;
        int *sock = data;
 
-       if (ipset->sock == *sock)
+       if (ipset->sock == *sock) {
+               hook_call(zebra_pbr_ipset_entry_wrap_script_update,
+                         zns, 0, ipset);
                hash_release(zns->ipset_entry_hash, ipset);
+       }
 }
 
 static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data)
@@ -386,8 +437,11 @@ static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data)
        struct zebra_pbr_iptable *iptable = b->data;
        int *sock = data;
 
-       if (iptable->sock == *sock)
+       if (iptable->sock == *sock) {
+               hook_call(zebra_pbr_iptable_wrap_script_update,
+                         zns, 0, iptable);
                hash_release(zns->iptable_hash, iptable);
+       }
 }
 
 static int zebra_pbr_client_close_cleanup(struct zserv *client)
@@ -429,10 +483,14 @@ static void *pbr_ipset_alloc_intern(void *arg)
 void zebra_pbr_create_ipset(struct zebra_ns *zns,
                            struct zebra_pbr_ipset *ipset)
 {
+       int ret;
+
        (void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern);
-       /* TODO:
-        * - Netlink call
-        */
+       ret = hook_call(zebra_pbr_ipset_wrap_script_update,
+                 zns, 1, ipset);
+       kernel_pbr_ipset_add_del_status(ipset,
+                                       ret ? SOUTHBOUND_INSTALL_SUCCESS
+                                       : SOUTHBOUND_INSTALL_FAILURE);
 }
 
 void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
@@ -441,9 +499,8 @@ void zebra_pbr_destroy_ipset(struct zebra_ns *zns,
        struct zebra_pbr_ipset *lookup;
 
        lookup = hash_lookup(zns->ipset_hash, ipset);
-       /* TODO:
-        * - Netlink destroy from kernel
-        */
+       hook_call(zebra_pbr_ipset_wrap_script_update,
+                 zns, 0, ipset);
        if (lookup) {
                hash_release(zns->ipset_hash, lookup);
                XFREE(MTYPE_TMP, lookup);
@@ -509,11 +566,15 @@ static void *pbr_ipset_entry_alloc_intern(void *arg)
 void zebra_pbr_add_ipset_entry(struct zebra_ns *zns,
                               struct zebra_pbr_ipset_entry *ipset)
 {
+       int ret;
+
        (void)hash_get(zns->ipset_entry_hash, ipset,
                       pbr_ipset_entry_alloc_intern);
-       /* TODO:
-        * - Netlink add to kernel
-        */
+       ret = hook_call(zebra_pbr_ipset_entry_wrap_script_update,
+                 zns, 1, ipset);
+       kernel_pbr_ipset_entry_add_del_status(ipset,
+                                       ret ? SOUTHBOUND_INSTALL_SUCCESS
+                                       : SOUTHBOUND_INSTALL_FAILURE);
 }
 
 void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
@@ -522,9 +583,8 @@ void zebra_pbr_del_ipset_entry(struct zebra_ns *zns,
        struct zebra_pbr_ipset_entry *lookup;
 
        lookup = hash_lookup(zns->ipset_entry_hash, ipset);
-       /* TODO:
-        * - Netlink destroy
-        */
+       hook_call(zebra_pbr_ipset_entry_wrap_script_update,
+                 zns, 0, ipset);
        if (lookup) {
                hash_release(zns->ipset_entry_hash, lookup);
                XFREE(MTYPE_TMP, lookup);
@@ -550,9 +610,14 @@ static void *pbr_iptable_alloc_intern(void *arg)
 void zebra_pbr_add_iptable(struct zebra_ns *zns,
                           struct zebra_pbr_iptable *iptable)
 {
+       int ret;
+
        (void)hash_get(zns->iptable_hash, iptable,
                       pbr_iptable_alloc_intern);
-       /* TODO call ioctl layer */
+       ret = hook_call(zebra_pbr_iptable_wrap_script_update, zns, 1, iptable);
+       kernel_pbr_iptable_add_del_status(iptable,
+                                         ret ? SOUTHBOUND_INSTALL_SUCCESS
+                                         : SOUTHBOUND_INSTALL_FAILURE);
 }
 
 void zebra_pbr_del_iptable(struct zebra_ns *zns,
@@ -561,9 +626,7 @@ void zebra_pbr_del_iptable(struct zebra_ns *zns,
        struct zebra_pbr_iptable *lookup;
 
        lookup = hash_lookup(zns->iptable_hash, iptable);
-       /* TODO:
-        * - call ioctl layer
-        */
+       hook_call(zebra_pbr_iptable_wrap_script_update, zns, 0, iptable);
        if (lookup) {
                struct listnode *node, *nnode;
                char *name;
@@ -687,6 +750,7 @@ int kernel_pbr_rule_del(struct zebra_pbr_rule *rule)
 struct zebra_pbr_ipset_entry_unique_display {
        struct zebra_pbr_ipset *zpi;
        struct vty *vty;
+       struct zebra_ns *zns;
 };
 
 struct zebra_pbr_env_display {
@@ -738,6 +802,9 @@ static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet,
        struct vty *vty = unique->vty;
        struct zebra_pbr_ipset_entry *zpie =
                (struct zebra_pbr_ipset_entry *)backet->data;
+       uint64_t pkts = 0, bytes = 0;
+       struct zebra_ns *zns = unique->zns;
+       int ret = 0;
 
        if (zpie->backpointer != zpi)
                return HASHWALK_CONTINUE;
@@ -786,6 +853,11 @@ static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet,
        }
        vty_out(vty, " (%u)\n", zpie->unique);
 
+       ret = hook_call(zebra_pbr_ipset_entry_wrap_script_get_stat,
+                       zns, zpie, &pkts, &bytes);
+       if (ret && pkts > 0)
+               vty_out(vty, "\t pkts %" PRIu64 ", bytes %" PRIu64"\n",
+                       pkts, bytes);
        return HASHWALK_CONTINUE;
 }
 
@@ -802,7 +874,7 @@ static int zebra_pbr_show_ipset_walkcb(struct hash_backet *backet, void *arg)
                zebra_pbr_ipset_type2str(zpi->type));
        unique.vty = vty;
        unique.zpi = zpi;
-
+       unique.zns = zns;
        hash_walk(zns->ipset_entry_hash, zebra_pbr_show_ipset_entry_walkcb,
                  &unique);
        vty_out(vty, "\n");
@@ -829,7 +901,7 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
 
                unique.vty = vty;
                unique.zpi = zpi;
-
+               unique.zns = zns;
                hash_walk(zns->ipset_entry_hash,
                          zebra_pbr_show_ipset_entry_walkcb,
                          &unique);
@@ -867,11 +939,18 @@ static int zebra_pbr_show_iptable_walkcb(struct hash_backet *backet, void *arg)
        struct zebra_pbr_env_display *env = (struct zebra_pbr_env_display *)arg;
        struct vty *vty = env->vty;
        struct zebra_ns *zns = env->zns;
+       int ret;
+       uint64_t pkts = 0, bytes = 0;
 
        vty_out(vty, "IPtable %s action %s (%u)\n", iptable->ipset_name,
                iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
                iptable->unique);
 
+       ret = hook_call(zebra_pbr_iptable_wrap_script_get_stat,
+                       zns, iptable, &pkts, &bytes);
+       if (ret && pkts > 0)
+               vty_out(vty, "\t pkts %" PRIu64 ", bytes %" PRIu64"\n",
+                       pkts, bytes);
        if (iptable->action != ZEBRA_IPTABLES_DROP) {
                struct pbr_rule_fwmark_lookup prfl;
 
index f5a5d5d2944744e100f52bf9a70aa1a072a13d3f..31fc553581f8911f2f804bf8a72feb3d0c68fb5f 100644 (file)
@@ -226,4 +226,26 @@ extern void zebra_pbr_show_iptable(struct vty *vty);
 extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
                                   struct zebra_pbr_iptable *zpi);
 
+DECLARE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns,
+                                   struct zebra_pbr_ipset_entry *ipset,
+                                   uint64_t *pkts, uint64_t *bytes),
+                                    (zns, ipset, pkts, bytes))
+DECLARE_HOOK(zebra_pbr_iptable_wrap_script_get_stat, (struct zebra_ns *zns,
+                                   struct zebra_pbr_iptable *iptable,
+                                   uint64_t *pkts, uint64_t *bytes),
+                                    (zns, iptable, pkts, bytes))
+DECLARE_HOOK(zebra_pbr_iptable_wrap_script_update, (struct zebra_ns *zns,
+                                            int cmd,
+                                            struct zebra_pbr_iptable *iptable),
+                                            (zns, cmd, iptable));
+
+DECLARE_HOOK(zebra_pbr_ipset_entry_wrap_script_update, (struct zebra_ns *zns,
+                                 int cmd,
+                                 struct zebra_pbr_ipset_entry *ipset),
+                                    (zns, cmd, ipset));
+DECLARE_HOOK(zebra_pbr_ipset_wrap_script_update, (struct zebra_ns *zns,
+                                 int cmd,
+                                 struct zebra_pbr_ipset *ipset),
+                                    (zns, cmd, ipset));
+
 #endif /* _ZEBRA_PBR_H */