From: Philippe Guibert Date: Fri, 4 May 2018 11:57:31 +0000 (+0200) Subject: zebra: PBR config and monitor IPSET/IPTABLE hooks declared X-Git-Tag: frr-6.1-dev~395^2~10 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=73a829f709dcdac1a414be43216d7dbce8d0e428;p=matthieu%2Ffrr.git zebra: PBR config and monitor IPSET/IPTABLE hooks declared 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 --- diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 606f4d6eb5..0355f3c042 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -24,12 +24,12 @@ #include #include #include +#include #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; diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index f5a5d5d294..31fc553581 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -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 */