From: Donald Sharp Date: Thu, 10 Sep 2020 15:31:39 +0000 (-0400) Subject: bgpd, lib, pbrd, zebra: Pass by ifname X-Git-Tag: base_7.6~563^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=58a1d249249840694e04f7b31a45c35ef6d067c8;p=mirror%2Ffrr.git 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 Signed-off-by: Donald Sharp --- diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 15bd6d33b8..a1312b97b6 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2153,10 +2153,10 @@ static int rule_notify_owner(ZAPI_CALLBACK_ARGS) enum zapi_rule_notify_owner note; struct bgp_pbr_action *bgp_pbra; struct bgp_pbr_rule *bgp_pbr = NULL; - ifindex_t ifi; + char ifname[INTERFACE_NAMSIZ + 1]; if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique, - &ifi, ¬e)) + ifname, ¬e)) return -1; bgp_pbra = bgp_pbr_action_rule_lookup(vrf_id, unique); diff --git a/lib/pbr.h b/lib/pbr.h index 53a63122cc..e365888662 100644 --- a/lib/pbr.h +++ b/lib/pbr.h @@ -97,7 +97,8 @@ struct pbr_rule { uint32_t unique; struct pbr_filter filter; struct pbr_action action; - ifindex_t ifindex; + + char ifname[INTERFACE_NAMSIZ + 1]; }; /* TCP flags value shared diff --git a/lib/zclient.c b/lib/zclient.c index b842e7c31b..c5016d22e2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1424,7 +1424,7 @@ int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule) stream_putw(s, zrule->filter.fwmark); /* fwmark */ stream_putl(s, zrule->action.table); - stream_putl(s, zrule->ifindex); + stream_put(s, zrule->ifname, INTERFACE_NAMSIZ); /* Put length at the first point of the stream. */ stream_putw_at(s, 0, stream_get_endp(s)); @@ -1454,26 +1454,23 @@ stream_failure: } bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno, - uint32_t *priority, uint32_t *unique, - ifindex_t *ifindex, + uint32_t *priority, uint32_t *unique, char *ifname, enum zapi_rule_notify_owner *note) { uint32_t prio, seq, uni; - ifindex_t ifi; STREAM_GET(note, s, sizeof(*note)); STREAM_GETL(s, seq); STREAM_GETL(s, prio); STREAM_GETL(s, uni); - STREAM_GETL(s, ifi); + STREAM_GET(ifname, s, INTERFACE_NAMSIZ); if (zclient_debug) - zlog_debug("%s: %u %u %u %u", __func__, seq, prio, uni, ifi); + zlog_debug("%s: %u %u %u %s", __func__, seq, prio, uni, ifname); *seqno = seq; *priority = prio; *unique = uni; - *ifindex = ifi; return true; diff --git a/lib/zclient.h b/lib/zclient.h index b8444e8a86..f99b3ad743 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -844,8 +844,7 @@ bool zapi_route_notify_decode(struct stream *s, struct prefix *p, uint32_t *tableid, enum zapi_route_notify_owner *note); bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno, - uint32_t *priority, uint32_t *unique, - ifindex_t *ifindex, + uint32_t *priority, uint32_t *unique, char *ifname, enum zapi_rule_notify_owner *note); bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique, diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c index 058881cbfc..d6500af881 100644 --- a/pbrd/pbr_map.c +++ b/pbrd/pbr_map.c @@ -398,7 +398,7 @@ void pbr_map_delete_vrf(struct pbr_map_sequence *pbrms) pbr_map_delete_common(pbrms); } -struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex, +struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, char *ifname, struct pbr_map_interface **ppmi) { struct pbr_map_sequence *pbrms; @@ -408,7 +408,8 @@ struct pbr_map_sequence *pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex, RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) { for (ALL_LIST_ELEMENTS_RO(pbrm->incoming, inode, pmi)) { - if (pmi->ifp->ifindex != ifindex) + if (strncmp(pmi->ifp->name, ifname, INTERFACE_NAMSIZ) + != 0) continue; if (ppmi) diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h index 43266f21e9..ad2db146b7 100644 --- a/pbrd/pbr_map.h +++ b/pbrd/pbr_map.h @@ -158,7 +158,7 @@ extern struct pbr_map_entry_head pbr_maps; extern struct pbr_map_sequence *pbrms_get(const char *name, uint32_t seqno); extern struct pbr_map_sequence * -pbrms_lookup_unique(uint32_t unique, ifindex_t ifindex, +pbrms_lookup_unique(uint32_t unique, char *ifname, struct pbr_map_interface **ppmi); extern struct pbr_map *pbrm_find(const char *name); diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index a7420974a9..269bd6da8d 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -208,15 +208,15 @@ static int rule_notify_owner(ZAPI_CALLBACK_ARGS) enum zapi_rule_notify_owner note; struct pbr_map_sequence *pbrms; struct pbr_map_interface *pmi; - ifindex_t ifi; + char ifname[INTERFACE_NAMSIZ + 1]; uint64_t installed; if (!zapi_rule_notify_decode(zclient->ibuf, &seqno, &priority, &unique, - &ifi, ¬e)) + ifname, ¬e)) return -1; pmi = NULL; - pbrms = pbrms_lookup_unique(unique, ifi, &pmi); + pbrms = pbrms_lookup_unique(unique, ifname, &pmi); if (!pbrms) { DEBUGD(&pbr_dbg_zebra, "%s: Failure to lookup pbrms based upon %u", __func__, @@ -546,7 +546,7 @@ static void pbr_encode_pbr_map_sequence(struct stream *s, stream_putl(s, pbr_nht_get_table(pbrms->nhgrp_name)); else if (pbrms->nhg) stream_putl(s, pbr_nht_get_table(pbrms->internal_nhg_name)); - stream_putl(s, ifp->ifindex); + stream_put(s, ifp->name, INTERFACE_NAMSIZ); } void pbr_send_pbr_map(struct pbr_map_sequence *pbrms, diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c index 3a3baab4ca..d6a34327a6 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 66f535177f..e436e5a288 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 9771235717..abd0adb64e 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 5dd789a851..1d852b1bac 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 95d241c59f..c244d2a955 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);