From: Renato Westphal Date: Fri, 11 Jan 2019 21:20:13 +0000 (-0200) Subject: lib, zebra: add AFI parameter to the ZEBRA_REDISTRIBUTE_DEFAULT_* messages X-Git-Tag: frr-7.0~10^2~15 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=fcca30daba3721da7dde995527bfe0d29adb5bf5;p=matthieu%2Ffrr.git lib, zebra: add AFI parameter to the ZEBRA_REDISTRIBUTE_DEFAULT_* messages 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 --- diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 29bd23b514..a810e01468 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -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)); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 101bd57cc9..958f8c2281 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -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); diff --git a/lib/zclient.c b/lib/zclient.c index d2a6c75548..e85720e7d5 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -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) diff --git a/lib/zclient.h b/lib/zclient.h index 8fe711f310..ad34dcb82b 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -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. */ diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 5db9b529ef..54f1735e7a 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -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)) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 714c47b4e6..6d1e44996e 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -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], diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index c7bde55cd9..79ddb192c1 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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; diff --git a/zebra/redistribute.c b/zebra/redistribute.c index f48fc6addb..b9c1f0aefd 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -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. */ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 32614f408e..9b20e366fc 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -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)); } diff --git a/zebra/zserv.c b/zebra/zserv.c index a48505a514..502186d226 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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(); diff --git a/zebra/zserv.h b/zebra/zserv.h index f0b8934ae1..041485cdc2 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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;