mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 20:13:53 +00:00
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 <philippe.guibert@6wind.com>
This commit is contained in:
parent
8cda910629
commit
73a829f709
@ -24,12 +24,12 @@
|
|||||||
#include <jhash.h>
|
#include <jhash.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <hook.h>
|
||||||
|
|
||||||
#include "zebra/zebra_pbr.h"
|
#include "zebra/zebra_pbr.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
#include "zebra/zapi_msg.h"
|
#include "zebra/zapi_msg.h"
|
||||||
#include "zebra/zebra_memory.h"
|
#include "zebra/zebra_memory.h"
|
||||||
#include "zebra_pbr.h"
|
|
||||||
|
|
||||||
/* definitions */
|
/* definitions */
|
||||||
DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list")
|
DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list")
|
||||||
@ -44,6 +44,30 @@ static const struct message ipset_type_msg[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* static function declarations */
|
/* 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 */
|
/* 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)
|
void zebra_pbr_ipset_free(void *arg)
|
||||||
{
|
{
|
||||||
struct zebra_pbr_ipset *ipset;
|
struct zebra_pbr_ipset *ipset;
|
||||||
|
struct zebra_ns *zns;
|
||||||
|
|
||||||
ipset = (struct zebra_pbr_ipset *)arg;
|
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);
|
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)
|
void zebra_pbr_ipset_entry_free(void *arg)
|
||||||
{
|
{
|
||||||
struct zebra_pbr_ipset_entry *ipset;
|
struct zebra_pbr_ipset_entry *ipset;
|
||||||
|
struct zebra_ns *zns;
|
||||||
|
|
||||||
ipset = (struct zebra_pbr_ipset_entry *)arg;
|
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);
|
XFREE(MTYPE_TMP, ipset);
|
||||||
}
|
}
|
||||||
@ -254,8 +293,15 @@ void zebra_pbr_iptable_free(void *arg)
|
|||||||
struct zebra_pbr_iptable *iptable;
|
struct zebra_pbr_iptable *iptable;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
char *name;
|
char *name;
|
||||||
|
struct zebra_ns *zns;
|
||||||
|
|
||||||
iptable = (struct zebra_pbr_iptable *)arg;
|
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,
|
for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
|
||||||
node, nnode, name)) {
|
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);
|
(void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
|
||||||
kernel_add_pbr_rule(rule);
|
kernel_add_pbr_rule(rule);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rule Replace semantics, if we have an old, install the
|
* Rule Replace semantics, if we have an old, install the
|
||||||
* new rule, look above, and then delete the old
|
* new rule, look above, and then delete the old
|
||||||
@ -366,9 +411,12 @@ static void zebra_pbr_cleanup_ipset(struct hash_backet *b, void *data)
|
|||||||
struct zebra_pbr_ipset *ipset = b->data;
|
struct zebra_pbr_ipset *ipset = b->data;
|
||||||
int *sock = 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);
|
hash_release(zns->ipset_hash, ipset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data)
|
static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data)
|
||||||
{
|
{
|
||||||
@ -376,9 +424,12 @@ static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data)
|
|||||||
struct zebra_pbr_ipset_entry *ipset = b->data;
|
struct zebra_pbr_ipset_entry *ipset = b->data;
|
||||||
int *sock = 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);
|
hash_release(zns->ipset_entry_hash, ipset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data)
|
static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data)
|
||||||
{
|
{
|
||||||
@ -386,9 +437,12 @@ static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data)
|
|||||||
struct zebra_pbr_iptable *iptable = b->data;
|
struct zebra_pbr_iptable *iptable = b->data;
|
||||||
int *sock = 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);
|
hash_release(zns->iptable_hash, iptable);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int zebra_pbr_client_close_cleanup(struct zserv *client)
|
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,
|
void zebra_pbr_create_ipset(struct zebra_ns *zns,
|
||||||
struct zebra_pbr_ipset *ipset)
|
struct zebra_pbr_ipset *ipset)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
(void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern);
|
(void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern);
|
||||||
/* TODO:
|
ret = hook_call(zebra_pbr_ipset_wrap_script_update,
|
||||||
* - Netlink call
|
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,
|
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;
|
struct zebra_pbr_ipset *lookup;
|
||||||
|
|
||||||
lookup = hash_lookup(zns->ipset_hash, ipset);
|
lookup = hash_lookup(zns->ipset_hash, ipset);
|
||||||
/* TODO:
|
hook_call(zebra_pbr_ipset_wrap_script_update,
|
||||||
* - Netlink destroy from kernel
|
zns, 0, ipset);
|
||||||
*/
|
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
hash_release(zns->ipset_hash, lookup);
|
hash_release(zns->ipset_hash, lookup);
|
||||||
XFREE(MTYPE_TMP, 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,
|
void zebra_pbr_add_ipset_entry(struct zebra_ns *zns,
|
||||||
struct zebra_pbr_ipset_entry *ipset)
|
struct zebra_pbr_ipset_entry *ipset)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
(void)hash_get(zns->ipset_entry_hash, ipset,
|
(void)hash_get(zns->ipset_entry_hash, ipset,
|
||||||
pbr_ipset_entry_alloc_intern);
|
pbr_ipset_entry_alloc_intern);
|
||||||
/* TODO:
|
ret = hook_call(zebra_pbr_ipset_entry_wrap_script_update,
|
||||||
* - Netlink add to kernel
|
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,
|
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;
|
struct zebra_pbr_ipset_entry *lookup;
|
||||||
|
|
||||||
lookup = hash_lookup(zns->ipset_entry_hash, ipset);
|
lookup = hash_lookup(zns->ipset_entry_hash, ipset);
|
||||||
/* TODO:
|
hook_call(zebra_pbr_ipset_entry_wrap_script_update,
|
||||||
* - Netlink destroy
|
zns, 0, ipset);
|
||||||
*/
|
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
hash_release(zns->ipset_entry_hash, lookup);
|
hash_release(zns->ipset_entry_hash, lookup);
|
||||||
XFREE(MTYPE_TMP, 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,
|
void zebra_pbr_add_iptable(struct zebra_ns *zns,
|
||||||
struct zebra_pbr_iptable *iptable)
|
struct zebra_pbr_iptable *iptable)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
(void)hash_get(zns->iptable_hash, iptable,
|
(void)hash_get(zns->iptable_hash, iptable,
|
||||||
pbr_iptable_alloc_intern);
|
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,
|
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;
|
struct zebra_pbr_iptable *lookup;
|
||||||
|
|
||||||
lookup = hash_lookup(zns->iptable_hash, iptable);
|
lookup = hash_lookup(zns->iptable_hash, iptable);
|
||||||
/* TODO:
|
hook_call(zebra_pbr_iptable_wrap_script_update, zns, 0, iptable);
|
||||||
* - call ioctl layer
|
|
||||||
*/
|
|
||||||
if (lookup) {
|
if (lookup) {
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
char *name;
|
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_entry_unique_display {
|
||||||
struct zebra_pbr_ipset *zpi;
|
struct zebra_pbr_ipset *zpi;
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
|
struct zebra_ns *zns;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zebra_pbr_env_display {
|
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 vty *vty = unique->vty;
|
||||||
struct zebra_pbr_ipset_entry *zpie =
|
struct zebra_pbr_ipset_entry *zpie =
|
||||||
(struct zebra_pbr_ipset_entry *)backet->data;
|
(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)
|
if (zpie->backpointer != zpi)
|
||||||
return HASHWALK_CONTINUE;
|
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);
|
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;
|
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));
|
zebra_pbr_ipset_type2str(zpi->type));
|
||||||
unique.vty = vty;
|
unique.vty = vty;
|
||||||
unique.zpi = zpi;
|
unique.zpi = zpi;
|
||||||
|
unique.zns = zns;
|
||||||
hash_walk(zns->ipset_entry_hash, zebra_pbr_show_ipset_entry_walkcb,
|
hash_walk(zns->ipset_entry_hash, zebra_pbr_show_ipset_entry_walkcb,
|
||||||
&unique);
|
&unique);
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
@ -829,7 +901,7 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname)
|
|||||||
|
|
||||||
unique.vty = vty;
|
unique.vty = vty;
|
||||||
unique.zpi = zpi;
|
unique.zpi = zpi;
|
||||||
|
unique.zns = zns;
|
||||||
hash_walk(zns->ipset_entry_hash,
|
hash_walk(zns->ipset_entry_hash,
|
||||||
zebra_pbr_show_ipset_entry_walkcb,
|
zebra_pbr_show_ipset_entry_walkcb,
|
||||||
&unique);
|
&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 zebra_pbr_env_display *env = (struct zebra_pbr_env_display *)arg;
|
||||||
struct vty *vty = env->vty;
|
struct vty *vty = env->vty;
|
||||||
struct zebra_ns *zns = env->zns;
|
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,
|
vty_out(vty, "IPtable %s action %s (%u)\n", iptable->ipset_name,
|
||||||
iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
|
iptable->action == ZEBRA_IPTABLES_DROP ? "drop" : "redirect",
|
||||||
iptable->unique);
|
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) {
|
if (iptable->action != ZEBRA_IPTABLES_DROP) {
|
||||||
struct pbr_rule_fwmark_lookup prfl;
|
struct pbr_rule_fwmark_lookup prfl;
|
||||||
|
|
||||||
|
@ -226,4 +226,26 @@ extern void zebra_pbr_show_iptable(struct vty *vty);
|
|||||||
extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
|
extern void zebra_pbr_iptable_update_interfacelist(struct stream *s,
|
||||||
struct zebra_pbr_iptable *zpi);
|
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 */
|
#endif /* _ZEBRA_PBR_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user