#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")
};
/* 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 */
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);
}
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);
}
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)) {
(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
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)
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)
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)
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,
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);
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,
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);
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,
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;
struct zebra_pbr_ipset_entry_unique_display {
struct zebra_pbr_ipset *zpi;
struct vty *vty;
+ struct zebra_ns *zns;
};
struct zebra_pbr_env_display {
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;
}
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;
}
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");
unique.vty = vty;
unique.zpi = zpi;
-
+ unique.zns = zns;
hash_walk(zns->ipset_entry_hash,
zebra_pbr_show_ipset_entry_walkcb,
&unique);
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;