mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 22:03:51 +00:00
zebra: Keep track of rules written
Keep track of rules written into the kernel. This will allow us to delete them on shutdown if we are not cleaned up properly. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
1fbfe5a572
commit
43fe6a2a73
@ -85,6 +85,7 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
|
|||||||
addattr32(&req.n, sizeof(req), FRA_PRIORITY, rule->priority);
|
addattr32(&req.n, sizeof(req), FRA_PRIORITY, rule->priority);
|
||||||
|
|
||||||
/* interface on which applied */
|
/* interface on which applied */
|
||||||
|
if (ifp)
|
||||||
addattr_l(&req.n, sizeof(req), FRA_IFNAME, ifp->name,
|
addattr_l(&req.n, sizeof(req), FRA_IFNAME, ifp->name,
|
||||||
strlen(ifp->name) + 1);
|
strlen(ifp->name) + 1);
|
||||||
|
|
||||||
@ -114,7 +115,8 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"Tx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
|
"Tx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
|
||||||
nl_msg_type_to_str(cmd), nl_family_to_str(family),
|
nl_msg_type_to_str(cmd), nl_family_to_str(family),
|
||||||
ifp->name, ifp->ifindex, rule->priority,
|
ifp ? ifp->name : "Unknown", ifp ? ifp->ifindex : 0,
|
||||||
|
rule->priority,
|
||||||
prefix2str(&rule->filter.src_ip, buf1, sizeof(buf1)),
|
prefix2str(&rule->filter.src_ip, buf1, sizeof(buf1)),
|
||||||
prefix2str(&rule->filter.dst_ip, buf2, sizeof(buf2)),
|
prefix2str(&rule->filter.dst_ip, buf2, sizeof(buf2)),
|
||||||
rule->action.table);
|
rule->action.table);
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "zebra_netns_notify.h"
|
#include "zebra_netns_notify.h"
|
||||||
#include "zebra_netns_id.h"
|
#include "zebra_netns_id.h"
|
||||||
|
#include "zebra_pbr.h"
|
||||||
|
|
||||||
extern struct zebra_privs_t zserv_privs;
|
extern struct zebra_privs_t zserv_privs;
|
||||||
|
|
||||||
@ -211,12 +212,15 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
|
|||||||
struct zebra_ns_table *znst;
|
struct zebra_ns_table *znst;
|
||||||
struct zebra_ns *zns = (struct zebra_ns *)(*info);
|
struct zebra_ns *zns = (struct zebra_ns *)(*info);
|
||||||
|
|
||||||
|
hash_clean(zns->rules_hash, zebra_pbr_rules_free);
|
||||||
|
hash_free(zns->rules_hash);
|
||||||
while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) {
|
while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) {
|
||||||
znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables);
|
znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables);
|
||||||
|
|
||||||
RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst);
|
RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst);
|
||||||
zebra_ns_free_table(znst);
|
zebra_ns_free_table(znst);
|
||||||
}
|
}
|
||||||
|
|
||||||
route_table_finish(zns->if_table);
|
route_table_finish(zns->if_table);
|
||||||
zebra_vxlan_ns_disable(zns);
|
zebra_vxlan_ns_disable(zns);
|
||||||
#if defined(HAVE_RTADV)
|
#if defined(HAVE_RTADV)
|
||||||
@ -257,6 +261,9 @@ int zebra_ns_init(void)
|
|||||||
/* Default NS is activated */
|
/* Default NS is activated */
|
||||||
zebra_ns_enable(ns_id, (void **)&dzns);
|
zebra_ns_enable(ns_id, (void **)&dzns);
|
||||||
|
|
||||||
|
dzns->rules_hash =
|
||||||
|
hash_create_size(8, zebra_pbr_rules_hash_key,
|
||||||
|
zebra_pbr_rules_hash_equal, "Rules Hash");
|
||||||
if (vrf_is_backend_netns()) {
|
if (vrf_is_backend_netns()) {
|
||||||
ns_add_hook(NS_NEW_HOOK, zebra_ns_new);
|
ns_add_hook(NS_NEW_HOOK, zebra_ns_new);
|
||||||
ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled);
|
ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled);
|
||||||
|
@ -71,6 +71,8 @@ struct zebra_ns {
|
|||||||
|
|
||||||
struct zebra_ns_table_head ns_tables;
|
struct zebra_ns_table_head ns_tables;
|
||||||
|
|
||||||
|
struct hash *rules_hash;
|
||||||
|
|
||||||
/* Back pointer */
|
/* Back pointer */
|
||||||
struct ns *ns;
|
struct ns *ns;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include <jhash.h>
|
||||||
|
#include <hash.h>
|
||||||
|
|
||||||
#include "zebra/zebra_pbr.h"
|
#include "zebra/zebra_pbr.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
|
|
||||||
@ -31,14 +34,93 @@
|
|||||||
/* Private functions */
|
/* Private functions */
|
||||||
|
|
||||||
/* Public functions */
|
/* Public functions */
|
||||||
void zebra_pbr_add_rule(struct zebra_pbr_rule *rule, struct interface *ifp)
|
void zebra_pbr_rules_free(void *arg)
|
||||||
{
|
{
|
||||||
|
struct zebra_pbr_rule *rule;
|
||||||
|
|
||||||
|
rule = (struct zebra_pbr_rule *)arg;
|
||||||
|
|
||||||
|
kernel_del_pbr_rule(rule, NULL);
|
||||||
|
XFREE(MTYPE_TMP, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t zebra_pbr_rules_hash_key(void *arg)
|
||||||
|
{
|
||||||
|
struct zebra_pbr_rule *rule;
|
||||||
|
uint32_t key;
|
||||||
|
|
||||||
|
rule = (struct zebra_pbr_rule *)arg;
|
||||||
|
key = jhash_3words(rule->seq, rule->priority, rule->action.table,
|
||||||
|
prefix_hash_key(&rule->filter.src_ip));
|
||||||
|
return jhash_3words(rule->filter.src_port, rule->filter.dst_port,
|
||||||
|
prefix_hash_key(&rule->filter.dst_ip), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
|
||||||
|
{
|
||||||
|
const struct zebra_pbr_rule *r1, *r2;
|
||||||
|
|
||||||
|
r1 = (const struct zebra_pbr_rule *)arg1;
|
||||||
|
r2 = (const struct zebra_pbr_rule *)arg2;
|
||||||
|
|
||||||
|
if (r1->seq != r2->seq)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (r1->priority != r2->priority)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (r1->action.table != r2->action.table)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (r1->filter.src_port != r2->filter.src_port)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (r1->filter.dst_port != r2->filter.dst_port)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!prefix_same(&r1->filter.src_ip, &r2->filter.src_ip))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!prefix_same(&r1->filter.dst_ip, &r2->filter.dst_ip))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *pbr_rule_alloc_intern(void *arg)
|
||||||
|
{
|
||||||
|
struct zebra_pbr_rule *zpr;
|
||||||
|
struct zebra_pbr_rule *new;
|
||||||
|
|
||||||
|
zpr = (struct zebra_pbr_rule *)arg;
|
||||||
|
|
||||||
|
new = XCALLOC(MTYPE_TMP, sizeof(*new));
|
||||||
|
|
||||||
|
memcpy(new, zpr, sizeof(*zpr));
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
|
||||||
|
struct interface *ifp)
|
||||||
|
{
|
||||||
|
(void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
|
||||||
kernel_add_pbr_rule(rule, ifp);
|
kernel_add_pbr_rule(rule, ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zebra_pbr_del_rule(struct zebra_pbr_rule *rule, struct interface *ifp)
|
void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
|
||||||
|
struct interface *ifp)
|
||||||
{
|
{
|
||||||
|
struct zebra_pbr_rule *lookup;
|
||||||
|
|
||||||
|
lookup = hash_lookup(zns->rules_hash, rule);
|
||||||
kernel_del_pbr_rule(rule, ifp);
|
kernel_del_pbr_rule(rule, ifp);
|
||||||
|
|
||||||
|
if (lookup)
|
||||||
|
XFREE(MTYPE_TMP, lookup);
|
||||||
|
else
|
||||||
|
zlog_warn("%s: Rule being deleted we know nothing about",
|
||||||
|
__PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -57,5 +139,3 @@ int kernel_pbr_rule_del(struct zebra_pbr_rule *rule, struct interface *ifp)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,8 +90,10 @@ struct zebra_pbr_rule {
|
|||||||
struct zebra_pbr_action action;
|
struct zebra_pbr_action action;
|
||||||
};
|
};
|
||||||
|
|
||||||
void zebra_pbr_add_rule(struct zebra_pbr_rule *rule, struct interface *ifp);
|
void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
|
||||||
void zebra_pbr_del_rule(struct zebra_pbr_rule *rule, struct interface *ifp);
|
struct interface *ifp);
|
||||||
|
void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule,
|
||||||
|
struct interface *ifp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Install specified rule for a specific interface.
|
* Install specified rule for a specific interface.
|
||||||
@ -126,4 +128,7 @@ extern void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
|
|||||||
extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule,
|
extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule,
|
||||||
struct interface *ifp);
|
struct interface *ifp);
|
||||||
|
|
||||||
|
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);
|
||||||
#endif /* _ZEBRA_PBR_H */
|
#endif /* _ZEBRA_PBR_H */
|
||||||
|
@ -2636,7 +2636,7 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
|
|||||||
if (zpr.filter.dst_port)
|
if (zpr.filter.dst_port)
|
||||||
zpr.filter.filter_bm |= PBR_FILTER_DST_PORT;
|
zpr.filter.filter_bm |= PBR_FILTER_DST_PORT;
|
||||||
|
|
||||||
zebra_pbr_add_rule(&zpr, ifp);
|
zebra_pbr_add_rule(zvrf->zns, &zpr, ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_failure:
|
stream_failure:
|
||||||
|
Loading…
Reference in New Issue
Block a user