summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2020-09-10 17:31:39 +0200
committerDonald Sharp <sharpd@nvidia.com>2020-09-12 02:04:45 +0200
commit58a1d249249840694e04f7b31a45c35ef6d067c8 (patch)
tree663ac92256f90326dabc7d099d5eb3b8ba4124c9 /zebra
parentMerge pull request #6974 from liron-ze/high-cpu-usage (diff)
downloadfrr-58a1d249249840694e04f7b31a45c35ef6d067c8.tar.xz
frr-58a1d249249840694e04f7b31a45c35ef6d067c8.zip
bgpd, lib, pbrd, zebra: Pass by ifname
When installing rules pass by the interface name across zapi. This is being changed because we have a situation where if you quickly create/destroy ephermeal interfaces under linux the upper level protocol may be trying to add a rule for a interface that does not quite exist at the moment. Since ip rules actually want the interface name ( to handle just this sort of situation ) convert over to passing the interface name and storing it and using it in zebra. Ticket: CM-31042 Signed-off-by: Stephen Worley <sworley@nvidia.com> Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/rule_netlink.c14
-rw-r--r--zebra/zapi_msg.c20
-rw-r--r--zebra/zebra_dplane.c15
-rw-r--r--zebra/zebra_dplane.h1
-rw-r--r--zebra/zebra_pbr.c15
5 files changed, 32 insertions, 33 deletions
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index 3a3baab4c..d6a34327a 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -74,7 +74,7 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
char buf[];
} *req = buf;
- const char *ifname = dplane_ctx_get_ifname(ctx);
+ const char *ifname = dplane_ctx_rule_get_ifname(ctx);
char buf1[PREFIX_STRLEN];
char buf2[PREFIX_STRLEN];
@@ -141,9 +141,9 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "Tx %s family %s IF %s(%u) Pref %u Fwmark %u Src %s Dst %s Table %u",
+ "Tx %s family %s IF %s Pref %u Fwmark %u Src %s Dst %s Table %u",
nl_msg_type_to_str(cmd), nl_family_to_str(family),
- ifname, dplane_ctx_get_ifindex(ctx), priority, fwmark,
+ ifname, priority, fwmark,
prefix2str(src_ip, buf1, sizeof(buf1)),
prefix2str(dst_ip, buf2, sizeof(buf2)), table);
@@ -324,13 +324,13 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ret = dplane_pbr_rule_delete(&rule);
zlog_debug(
- "%s: %s leftover rule: family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
+ "%s: %s leftover rule: family %s IF %s Pref %u Src %s Dst %s Table %u",
__func__,
((ret == ZEBRA_DPLANE_REQUEST_FAILURE)
? "Failed to remove"
: "Removed"),
nl_family_to_str(frh->family), rule.ifname,
- rule.rule.ifindex, rule.rule.priority,
+ rule.rule.priority,
prefix2str(&rule.rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&rule.rule.filter.dst_ip, buf2,
@@ -350,10 +350,10 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "Rx %s family %s IF %s(%u) Pref %u Src %s Dst %s Table %u",
+ "Rx %s family %s IF %s Pref %u Src %s Dst %s Table %u",
nl_msg_type_to_str(h->nlmsg_type),
nl_family_to_str(frh->family), rule.ifname,
- rule.rule.ifindex, rule.rule.priority,
+ rule.rule.priority,
prefix2str(&rule.rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&rule.rule.filter.dst_ip, buf2,
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 66f535177..e436e5a28 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -815,7 +815,7 @@ void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
stream_putl(s, dplane_ctx_rule_get_seq(ctx));
stream_putl(s, dplane_ctx_rule_get_priority(ctx));
stream_putl(s, dplane_ctx_rule_get_unique(ctx));
- stream_putl(s, dplane_ctx_get_ifindex(ctx));
+ stream_put(s, dplane_ctx_rule_get_ifname(ctx), INTERFACE_NAMSIZ);
stream_putw_at(s, 0, stream_get_endp(s));
@@ -2751,6 +2751,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
struct zebra_pbr_rule zpr;
struct stream *s;
uint32_t total, i;
+ char ifname[INTERFACE_NAMSIZ + 1] = {};
s = msg;
STREAM_GETL(s, total);
@@ -2776,21 +2777,10 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
STREAM_GETC(s, zpr.rule.filter.dsfield);
STREAM_GETL(s, zpr.rule.filter.fwmark);
STREAM_GETL(s, zpr.rule.action.table);
- STREAM_GETL(s, zpr.rule.ifindex);
+ STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
- if (zpr.rule.ifindex) {
- struct interface *ifp;
-
- ifp = if_lookup_by_index_per_ns(zvrf->zns,
- zpr.rule.ifindex);
- if (!ifp) {
- zlog_debug("Failed to lookup ifindex: %u",
- zpr.rule.ifindex);
- return;
- }
-
- strlcpy(zpr.ifname, ifp->name, sizeof(zpr.ifname));
- }
+ strlcpy(zpr.ifname, ifname, sizeof(zpr.ifname));
+ strlcpy(zpr.rule.ifname, ifname, sizeof(zpr.rule.ifname));
if (!is_default_prefix(&zpr.rule.filter.src_ip))
zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_IP;
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 977123571..abd0adb64 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -210,6 +210,7 @@ struct dplane_ctx_rule {
uint8_t dsfield;
struct prefix src_ip;
struct prefix dst_ip;
+ char ifname[INTERFACE_NAMSIZ + 1];
};
struct dplane_rule_info {
@@ -1632,6 +1633,13 @@ int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx)
return ctx->u.rule.sock;
}
+const char *dplane_ctx_rule_get_ifname(const struct zebra_dplane_ctx *ctx)
+{
+ DPLANE_CTX_VALID(ctx);
+
+ return ctx->u.rule.new.ifname;
+}
+
int dplane_ctx_rule_get_unique(const struct zebra_dplane_ctx *ctx)
{
DPLANE_CTX_VALID(ctx);
@@ -2191,6 +2199,7 @@ static void dplane_ctx_rule_init_single(struct dplane_ctx_rule *dplane_rule,
dplane_rule->dsfield = rule->rule.filter.dsfield;
prefix_copy(&(dplane_rule->dst_ip), &rule->rule.filter.dst_ip);
prefix_copy(&(dplane_rule->src_ip), &rule->rule.filter.src_ip);
+ strlcpy(dplane_rule->ifname, rule->ifname, INTERFACE_NAMSIZ);
}
/**
@@ -2212,10 +2221,9 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
char buf2[PREFIX_STRLEN];
zlog_debug(
- "init dplane ctx %s: IF %s(%u) Prio %u Fwmark %u Src %s Dst %s Table %u",
+ "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %s Dst %s Table %u",
dplane_op2str(op), new_rule->ifname,
- new_rule->rule.ifindex, new_rule->rule.priority,
- new_rule->rule.filter.fwmark,
+ new_rule->rule.priority, new_rule->rule.filter.fwmark,
prefix2str(&new_rule->rule.filter.src_ip, buf1,
sizeof(buf1)),
prefix2str(&new_rule->rule.filter.dst_ip, buf2,
@@ -2232,7 +2240,6 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
ctx->zd_vrf_id = new_rule->vrf_id;
memcpy(ctx->zd_ifname, new_rule->ifname, sizeof(new_rule->ifname));
- ctx->zd_ifindex = new_rule->rule.ifindex;
ctx->u.rule.sock = new_rule->sock;
ctx->u.rule.unique = new_rule->rule.unique;
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 5dd789a85..1d852b1ba 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -423,6 +423,7 @@ uint32_t dplane_ctx_neigh_get_update_flags(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_sock(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_unique(const struct zebra_dplane_ctx *ctx);
int dplane_ctx_rule_get_seq(const struct zebra_dplane_ctx *ctx);
+const char *dplane_ctx_rule_get_ifname(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_priority(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_old_priority(const struct zebra_dplane_ctx *ctx);
uint32_t dplane_ctx_rule_get_table(const struct zebra_dplane_ctx *ctx);
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 95d241c59..c244d2a95 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -167,10 +167,11 @@ uint32_t zebra_pbr_rules_hash_key(const void *arg)
prefix_hash_key(&rule->rule.filter.src_ip));
if (rule->rule.filter.fwmark)
- key = jhash_3words(rule->rule.filter.fwmark, rule->vrf_id,
- rule->rule.ifindex, key);
+ key = jhash_2words(rule->rule.filter.fwmark, rule->vrf_id, key);
else
- key = jhash_2words(rule->vrf_id, rule->rule.ifindex, key);
+ key = jhash_1word(rule->vrf_id, key);
+
+ key = jhash(rule->ifname, strlen(rule->ifname), key);
return jhash_3words(rule->rule.filter.src_port,
rule->rule.filter.dst_port,
@@ -212,7 +213,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (!prefix_same(&r1->rule.filter.dst_ip, &r2->rule.filter.dst_ip))
return false;
- if (r1->rule.ifindex != r2->rule.ifindex)
+ if (strcmp(r1->rule.ifname, r2->rule.ifname) != 0)
return false;
if (r1->vrf_id != r2->vrf_id)
@@ -224,7 +225,7 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
struct pbr_rule_unique_lookup {
struct zebra_pbr_rule *rule;
uint32_t unique;
- ifindex_t ifindex;
+ char ifname[INTERFACE_NAMSIZ + 1];
vrf_id_t vrf_id;
};
@@ -234,7 +235,7 @@ static int pbr_rule_lookup_unique_walker(struct hash_bucket *b, void *data)
struct zebra_pbr_rule *rule = b->data;
if (pul->unique == rule->rule.unique
- && pul->ifindex == rule->rule.ifindex
+ && strncmp(pul->ifname, rule->rule.ifname, INTERFACE_NAMSIZ) == 0
&& pul->vrf_id == rule->vrf_id) {
pul->rule = rule;
return HASHWALK_ABORT;
@@ -249,7 +250,7 @@ pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule)
struct pbr_rule_unique_lookup pul;
pul.unique = zrule->rule.unique;
- pul.ifindex = zrule->rule.ifindex;
+ strlcpy(pul.ifname, zrule->rule.ifname, INTERFACE_NAMSIZ);
pul.rule = NULL;
pul.vrf_id = zrule->vrf_id;
hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul);