]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, zebra: add AFI parameter to the ZEBRA_REDISTRIBUTE_DEFAULT_* messages
authorRenato Westphal <renato@opensourcerouting.org>
Fri, 11 Jan 2019 21:20:13 +0000 (19:20 -0200)
committerRenato Westphal <renato@opensourcerouting.org>
Tue, 19 Feb 2019 12:40:29 +0000 (09:40 -0300)
Some daemons like ospfd and isisd have the ability to advertise a
default route to their peers only if one exists in the RIB. This
is what the "default-information originate" commands do when used
without the "always" parameter.

For that to work, these daemons use the ZEBRA_REDISTRIBUTE_DEFAULT_ADD
message to request default route information to zebra. The problem
is that this message didn't have an AFI parameter, so a default route
from any address-family would satisfy the requests from both daemons
(e.g. ::/0 would trigger ospfd to advertise a default route to its
peers, and 0.0.0.0/0 would trigger isisd to advertise a default route
to its IPv6 peers).

Fix this by adding an AFI parameter to the
ZEBRA_REDISTRIBUTE_DEFAULT_{ADD,DELETE} messages and making the
corresponding code changes.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
eigrpd/eigrp_zebra.c
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
ospf6d/ospf6_zebra.c
ospfd/ospf_flood.c
ospfd/ospf_zebra.c
zebra/redistribute.c
zebra/zapi_msg.c
zebra/zserv.c
zebra/zserv.h

index 29bd23b5141dc4212e7587fe63c3f793e814ea57..a810e0146851090d6b0cbb9c53ef01919496b694 100644 (file)
@@ -425,7 +425,7 @@ void eigrp_zebra_route_delete(struct prefix *p)
 int eigrp_is_type_redistributed(int type)
 {
        return ((DEFAULT_ROUTE_TYPE(type))
-                       ? vrf_bitmap_check(zclient->default_information,
+                       ? vrf_bitmap_check(zclient->default_information[AFI_IP],
                                           VRF_DEFAULT)
                        : vrf_bitmap_check(zclient->redist[AFI_IP][type],
                                           VRF_DEFAULT));
index 101bd57cc932f0049b7b462141d56510a57e1cc6..958f8c2281a4a90e4af4fd44ab3d46dc77055710 100644 (file)
@@ -390,7 +390,7 @@ void isis_zebra_redistribute_set(afi_t afi, int type)
 {
        if (type == DEFAULT_ROUTE)
                zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
-                                            zclient, VRF_DEFAULT);
+                                            zclient, afi, VRF_DEFAULT);
        else
                zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
                                     0, VRF_DEFAULT);
@@ -400,7 +400,7 @@ void isis_zebra_redistribute_unset(afi_t afi, int type)
 {
        if (type == DEFAULT_ROUTE)
                zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
-                                            zclient, VRF_DEFAULT);
+                                            zclient, afi, VRF_DEFAULT);
        else
                zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
                                     type, 0, VRF_DEFAULT);
index d2a6c75548f41698834c1ec3efacc1f6eff85e9a..e85720e7d52a0d4db8a75c4399cef49e0440790b 100644 (file)
@@ -173,10 +173,10 @@ void zclient_stop(struct zclient *zclient)
                redist_del_instance(
                        &zclient->mi_redist[afi][zclient->redist_default],
                        zclient->instance);
-       }
 
-       vrf_bitmap_free(zclient->default_information);
-       zclient->default_information = VRF_BITMAP_NULL;
+               vrf_bitmap_free(zclient->default_information[afi]);
+               zclient->default_information[afi] = VRF_BITMAP_NULL;
+       }
 }
 
 void zclient_reset(struct zclient *zclient)
@@ -447,7 +447,7 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
        }
 
        /* Resend all redistribute request. */
-       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        if (i != zclient->redist_default
                            && vrf_bitmap_check(zclient->redist[afi][i],
@@ -456,10 +456,13 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
                                                        zclient, afi, i, 0,
                                                        vrf_id);
 
-       /* If default information is needed. */
-       if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
-               zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
-                                  vrf_id);
+               /* If default information is needed. */
+               if (vrf_bitmap_check(zclient->default_information[afi],
+                                    VRF_DEFAULT))
+                       zebra_redistribute_default_send(
+                               ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
+                               vrf_id);
+       }
 }
 
 /* Send unregister requests to zebra daemon for the information in a VRF. */
@@ -512,7 +515,7 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
        }
 
        /* Flush all redistribute request. */
-       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        if (i != zclient->redist_default
                            && vrf_bitmap_check(zclient->redist[afi][i],
@@ -521,10 +524,13 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
                                        ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
                                        i, 0, vrf_id);
 
-       /* If default information is needed. */
-       if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
-               zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
-                                  vrf_id);
+               /* If default information is needed. */
+               if (vrf_bitmap_check(zclient->default_information[afi],
+                                    VRF_DEFAULT))
+                       zebra_redistribute_default_send(
+                               ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
+                               vrf_id);
+       }
 }
 
 /* Send request to zebra daemon to start or stop RA. */
@@ -620,12 +626,13 @@ void zclient_init(struct zclient *zclient, int redist_default,
        zclient->redist_default = redist_default;
        zclient->instance = instance;
        /* Pending: make afi(s) an arg. */
-       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                redist_add_instance(&zclient->mi_redist[afi][redist_default],
                                    instance);
 
-       /* Set default-information redistribute to zero. */
-       zclient->default_information = vrf_bitmap_init();
+               /* Set default-information redistribute to zero. */
+               zclient->default_information[afi] = vrf_bitmap_init();
+       }
 
        if (zclient_debug)
                zlog_debug("zclient_start is called");
@@ -1280,6 +1287,22 @@ int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
        return zclient_send_message(zclient);
 }
 
+int zebra_redistribute_default_send(int command, struct zclient *zclient,
+                                   afi_t afi, vrf_id_t vrf_id)
+{
+       struct stream *s;
+
+       s = zclient->obuf;
+       stream_reset(s);
+
+       zclient_create_header(s, command, vrf_id);
+       stream_putc(s, afi);
+
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       return zclient_send_message(zclient);
+}
+
 /* Get prefix in ZServ format; family should be filled in on prefix */
 static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
 {
@@ -2708,21 +2731,22 @@ void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
 
 
 void zclient_redistribute_default(int command, struct zclient *zclient,
-                                 vrf_id_t vrf_id)
+                                 afi_t afi, vrf_id_t vrf_id)
 {
 
        if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
-               if (vrf_bitmap_check(zclient->default_information, vrf_id))
+               if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
                        return;
-               vrf_bitmap_set(zclient->default_information, vrf_id);
+               vrf_bitmap_set(zclient->default_information[afi], vrf_id);
        } else {
-               if (!vrf_bitmap_check(zclient->default_information, vrf_id))
+               if (!vrf_bitmap_check(zclient->default_information[afi],
+                                     vrf_id))
                        return;
-               vrf_bitmap_unset(zclient->default_information, vrf_id);
+               vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
        }
 
        if (zclient->sock > 0)
-               zebra_message_send(zclient, command, vrf_id);
+               zebra_redistribute_default_send(command, zclient, afi, vrf_id);
 }
 
 static void zclient_event(enum event event, struct zclient *zclient)
index 8fe711f31044f24fe8126b247c143056031709c5..ad34dcb82befd61100250f5837108f6f45b090cc 100644 (file)
@@ -213,7 +213,7 @@ struct zclient {
        vrf_bitmap_t redist[AFI_MAX][ZEBRA_ROUTE_MAX];
 
        /* Redistribute defauilt. */
-       vrf_bitmap_t default_information;
+       vrf_bitmap_t default_information[AFI_MAX];
 
        /* Pointer to the callback functions. */
        void (*zebra_connected)(struct zclient *);
@@ -476,13 +476,16 @@ extern int zebra_redistribute_send(int command, struct zclient *, afi_t,
                                   int type, unsigned short instance,
                                   vrf_id_t vrf_id);
 
+extern int zebra_redistribute_default_send(int command, struct zclient *zclient,
+                                          afi_t afi, vrf_id_t vrf_id);
+
 /* If state has changed, update state and call zebra_redistribute_send. */
 extern void zclient_redistribute(int command, struct zclient *, afi_t, int type,
                                 unsigned short instance, vrf_id_t vrf_id);
 
 /* If state has changed, update state and send the command to zebra. */
 extern void zclient_redistribute_default(int command, struct zclient *,
-                                        vrf_id_t vrf_id);
+                                        afi_t, vrf_id_t vrf_id);
 
 /* Send the message in zclient->obuf to the zebra daemon (or enqueue it).
    Returns 0 for success or -1 on an I/O error. */
index 5db9b529efe3cdbb73427c0679fa2c50110d2c39..54f1735e7acc6652ba747695a0e96af0a8b8aab4 100644 (file)
@@ -269,7 +269,8 @@ DEFUN (show_zebra,
        vty_out(vty, "Zebra Infomation\n");
        vty_out(vty, "  fail: %d\n", zclient->fail);
        vty_out(vty, "  redistribute default: %d\n",
-               vrf_bitmap_check(zclient->default_information, VRF_DEFAULT));
+               vrf_bitmap_check(zclient->default_information[AFI_IP6],
+                                VRF_DEFAULT));
        vty_out(vty, "  redistribute:");
        for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
                if (vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
index 714c47b4e67c5d7ac511f4ea4242e40df1433710..6d1e44996e4ea0c89f3398a8c619f7b9489bcc06 100644 (file)
@@ -96,8 +96,9 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
 
                redist_on =
                        is_prefix_default(&p)
-                               ? vrf_bitmap_check(zclient->default_information,
-                                                  ospf->vrf_id)
+                               ? vrf_bitmap_check(
+                                         zclient->default_information[AFI_IP],
+                                         ospf->vrf_id)
                                : (zclient->mi_redist[AFI_IP][type].enabled
                                   || vrf_bitmap_check(
                                              zclient->redist[AFI_IP][type],
index c7bde55cd9d12c10ebd0e87a8586ec5c916cb386..79ddb192c17b8ba0b45686c0c887b77a399c3bab 100644 (file)
@@ -655,7 +655,7 @@ int ospf_is_type_redistributed(struct ospf *ospf, int type,
                               unsigned short instance)
 {
        return (DEFAULT_ROUTE_TYPE(type)
-                       ? vrf_bitmap_check(zclient->default_information,
+                       ? vrf_bitmap_check(zclient->default_information[AFI_IP],
                                           ospf->vrf_id)
                        : ((instance
                            && redist_check_instance(
@@ -793,8 +793,8 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
                         * existance.
                         */
                        zclient_redistribute_default(
-                                       ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
-                                        zclient, ospf->vrf_id);
+                               ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, AFI_IP,
+                               ospf->vrf_id);
                }
 
                ospf_asbr_status_update(ospf, ++ospf->redistribute);
@@ -820,7 +820,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
 
                        zclient_redistribute_default(
                                        ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
-                                       zclient, ospf->vrf_id);
+                                       zclient, AFI_IP, ospf->vrf_id);
                        /* here , ex-info should be added since ex-info might
                         * have not updated earlier if def route is not exist.
                         * If ex-iinfo ex-info already exist , it will return
@@ -845,7 +845,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
 
                        zclient_redistribute_default(
                                        ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
-                                       zclient, ospf->vrf_id);
+                                       zclient, AFI_IP, ospf->vrf_id);
                }
        }
 
@@ -857,7 +857,7 @@ int ospf_redistribute_default_unset(struct ospf *ospf)
                if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0))
                        return CMD_SUCCESS;
                zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
-                                zclient, ospf->vrf_id);
+                                zclient, AFI_IP, ospf->vrf_id);
        }
 
        ospf->default_originate = DEFAULT_ORIGINATE_NONE;
index f48fc6addb6069b05a5199ee29c7e1ef76e5d807..b9c1f0aefd42e5bfdf9faacfe7fb2ecc2d27ebd3 100644 (file)
@@ -177,7 +177,8 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
                send_redistribute = 0;
 
                if (is_default_prefix(p)
-                   && vrf_bitmap_check(client->redist_default, re->vrf_id))
+                   && vrf_bitmap_check(client->redist_default[afi],
+                                       re->vrf_id))
                        send_redistribute = 1;
                else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
                                          re->vrf_id))
@@ -246,7 +247,8 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
 
        for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) {
                if ((is_default_prefix(p)
-                    && vrf_bitmap_check(client->redist_default, re->vrf_id))
+                    && vrf_bitmap_check(client->redist_default[afi],
+                                        re->vrf_id))
                    || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL],
                                        re->vrf_id)
                    || (re->instance
@@ -354,13 +356,41 @@ stream_failure:
 
 void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS)
 {
-       vrf_bitmap_set(client->redist_default, zvrf_id(zvrf));
+       afi_t afi = 0;
+
+       STREAM_GETC(msg, afi);
+
+       if (afi == 0 || afi >= AFI_MAX) {
+               flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+                         "%s: Specified afi %u does not exist",
+                         __PRETTY_FUNCTION__, afi);
+               return;
+       }
+
+       vrf_bitmap_set(client->redist_default[afi], zvrf_id(zvrf));
        zebra_redistribute_default(client, zvrf_id(zvrf));
+
+stream_failure:
+       return;
 }
 
 void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS)
 {
-       vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
+       afi_t afi = 0;
+
+       STREAM_GETC(msg, afi);
+
+       if (afi == 0 || afi >= AFI_MAX) {
+               flog_warn(EC_ZEBRA_REDISTRIBUTE_UNKNOWN_AF,
+                         "%s: Specified afi %u does not exist",
+                         __PRETTY_FUNCTION__, afi);
+               return;
+       }
+
+       vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
+
+stream_failure:
+       return;
 }
 
 /* Interface up information. */
index 32614f408e6085384db76d641f2ac550b33b8686..9b20e366fc46a9fae3979c606316cb8c97064f0e 100644 (file)
@@ -1700,10 +1700,11 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
        int i;
        afi_t afi;
 
-       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf));
-       vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf));
+               vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
+       }
        vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf));
        vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
 }
index a48505a5141074094f6cad73aa3779dd58e49aaa..502186d226a2e4742d5164818b2ea9b2fdc3eccd 100644 (file)
@@ -616,11 +616,12 @@ static void zserv_client_free(struct zserv *client)
        pthread_mutex_destroy(&client->ibuf_mtx);
 
        /* Free bitmaps. */
-       for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (int i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        vrf_bitmap_free(client->redist[afi][i]);
 
-       vrf_bitmap_free(client->redist_default);
+               vrf_bitmap_free(client->redist_default[afi]);
+       }
        vrf_bitmap_free(client->ifinfo);
        vrf_bitmap_free(client->ridinfo);
 
@@ -700,10 +701,11 @@ static struct zserv *zserv_client_create(int sock)
                              memory_order_relaxed);
 
        /* Initialize flags */
-       for (afi = AFI_IP; afi < AFI_MAX; afi++)
+       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                        client->redist[afi][i] = vrf_bitmap_init();
-       client->redist_default = vrf_bitmap_init();
+               client->redist_default[afi] = vrf_bitmap_init();
+       }
        client->ifinfo = vrf_bitmap_init();
        client->ridinfo = vrf_bitmap_init();
 
index f0b8934ae13053cfc2a0e988f6c812f3e99b15dc..041485cdc252e27f44a059df09accfb017d86390 100644 (file)
@@ -87,7 +87,7 @@ struct zserv {
        vrf_bitmap_t redist[AFI_MAX][ZEBRA_ROUTE_MAX];
 
        /* Redistribute default route flag. */
-       vrf_bitmap_t redist_default;
+       vrf_bitmap_t redist_default[AFI_MAX];
 
        /* Interface information. */
        vrf_bitmap_t ifinfo;