mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 11:24:42 +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,8 +85,9 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
|
||||
addattr32(&req.n, sizeof(req), FRA_PRIORITY, rule->priority);
|
||||
|
||||
/* interface on which applied */
|
||||
addattr_l(&req.n, sizeof(req), FRA_IFNAME, ifp->name,
|
||||
strlen(ifp->name)+1);
|
||||
if (ifp)
|
||||
addattr_l(&req.n, sizeof(req), FRA_IFNAME, ifp->name,
|
||||
strlen(ifp->name) + 1);
|
||||
|
||||
/* source IP, if specified */
|
||||
if (IS_RULE_FILTERING_ON_SRC_IP(rule)) {
|
||||
@ -114,7 +115,8 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule,
|
||||
zlog_debug(
|
||||
"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),
|
||||
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.dst_ip, buf2, sizeof(buf2)),
|
||||
rule->action.table);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "debug.h"
|
||||
#include "zebra_netns_notify.h"
|
||||
#include "zebra_netns_id.h"
|
||||
#include "zebra_pbr.h"
|
||||
|
||||
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 *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)) {
|
||||
znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables);
|
||||
|
||||
RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst);
|
||||
zebra_ns_free_table(znst);
|
||||
}
|
||||
|
||||
route_table_finish(zns->if_table);
|
||||
zebra_vxlan_ns_disable(zns);
|
||||
#if defined(HAVE_RTADV)
|
||||
@ -257,6 +261,9 @@ int zebra_ns_init(void)
|
||||
/* Default NS is activated */
|
||||
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()) {
|
||||
ns_add_hook(NS_NEW_HOOK, zebra_ns_new);
|
||||
ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled);
|
||||
|
@ -71,6 +71,8 @@ struct zebra_ns {
|
||||
|
||||
struct zebra_ns_table_head ns_tables;
|
||||
|
||||
struct hash *rules_hash;
|
||||
|
||||
/* Back pointer */
|
||||
struct ns *ns;
|
||||
};
|
||||
|
@ -21,6 +21,9 @@
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include <jhash.h>
|
||||
#include <hash.h>
|
||||
|
||||
#include "zebra/zebra_pbr.h"
|
||||
#include "zebra/rt.h"
|
||||
|
||||
@ -31,14 +34,93 @@
|
||||
/* Private 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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,8 +90,10 @@ struct zebra_pbr_rule {
|
||||
struct zebra_pbr_action action;
|
||||
};
|
||||
|
||||
void zebra_pbr_add_rule(struct zebra_pbr_rule *rule, struct interface *ifp);
|
||||
void zebra_pbr_del_rule(struct zebra_pbr_rule *rule, struct interface *ifp);
|
||||
void zebra_pbr_add_rule(struct zebra_ns *zns, 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);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
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 */
|
||||
|
@ -2636,7 +2636,7 @@ static inline void zread_rule(uint16_t command, struct zserv *client,
|
||||
if (zpr.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:
|
||||
|
Loading…
Reference in New Issue
Block a user