]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd, lib, pbrd, zebra: Pass by ifname
authorDonald Sharp <sharpd@nvidia.com>
Thu, 10 Sep 2020 15:31:39 +0000 (11:31 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Sat, 12 Sep 2020 00:04:45 +0000 (20:04 -0400)
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>
12 files changed:
bgpd/bgp_zebra.c
lib/pbr.h
lib/zclient.c
lib/zclient.h
pbrd/pbr_map.c
pbrd/pbr_map.h
pbrd/pbr_zebra.c
zebra/rule_netlink.c
zebra/zapi_msg.c
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_pbr.c

index 15bd6d33b82efcbd0018554fe2501cdca07d446a..a1312b97b6443549ceb80862cb4fceb9253d1c7d 100644 (file)
@@ -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, &note))
+                                    ifname, &note))
                return -1;
 
        bgp_pbra = bgp_pbr_action_rule_lookup(vrf_id, unique);
index 53a63122cc9ee16329407c89b4bdc818cda77399..e365888662e193dde6e8d14d3c349a447bb965b4 100644 (file)
--- 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
index b842e7c31b020653262554e9b7ef8711447cb2bd..c5016d22e2c9c922c99da49b8a16830659d158e4 100644 (file)
@@ -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;
 
index b8444e8a86fb4d798b5fa2b25a0d9335c56e7dcb..f99b3ad7432aa3cc8e617345a26d0187af864ab2 100644 (file)
@@ -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,
index 058881cbfc770bb0d7399066cc90f43a1c3a52ee..d6500af881c6375127c410c1b9fae2903213c001 100644 (file)
@@ -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)
index 43266f21e96da4a62e90585ec96ce0af93f54d56..ad2db146b7e6309da5aa20b05e3d2af9d9caee7c 100644 (file)
@@ -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);
index a7420974a9115971ff869fa90093e374f4b7c43b..269bd6da8d6f6cffce339e470826900c86feb6f2 100644 (file)
@@ -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, &note))
+                                    ifname, &note))
                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,
index 3a3baab4ca34a651c6f3133ec0b684a3583025be..d6a34327a6ae20ed454a3afb3d684391241c37de 100644 (file)
@@ -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,
index 66f535177f4f544e24f7ea00aacfcbe532e7302f..e436e5a288a0bdd86ff4ce0c0acc3fdd8bbcdd55 100644 (file)
@@ -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;
index 97712357179ba0779c2c52161f6f1395b2d8e8e2..abd0adb64e3b50a55b3e8a65dee9d1c47215a0dc 100644 (file)
@@ -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;
index 5dd789a85128b987ecfdc1acb254fbaf87593982..1d852b1bac2d1668b0e8b42cd24dc7d588e8cd49 100644 (file)
@@ -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);
index 95d241c59fbc2d09bdd346e8813f3b3f57ecfb4e..c244d2a955786275893b52fb1c831f79b3d2c692 100644 (file)
@@ -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);