summaryrefslogtreecommitdiff
path: root/zebra/zapi_msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zapi_msg.c')
-rw-r--r--zebra/zapi_msg.c336
1 files changed, 179 insertions, 157 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index b93911bee7..9b91289dec 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -42,6 +42,7 @@
#include "lib/libfrr.h"
#include "lib/sockopt.h"
+#include "zebra/zebra_router.h"
#include "zebra/rib.h"
#include "zebra/zebra_memory.h"
#include "zebra/zebra_ns.h"
@@ -63,6 +64,7 @@
#include "zebra/table_manager.h"
#include "zebra/zapi_msg.h"
#include "zebra/zebra_errors.h"
+#include "zebra/zebra_mlag.h"
/* Encoding helpers -------------------------------------------------------- */
@@ -207,12 +209,6 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- /* Check this client need interface information. */
- if (!client->ifinfo) {
- stream_free(s);
- return 0;
- }
-
if (!ifp->link_params) {
stream_free(s);
return 0;
@@ -364,7 +360,7 @@ static void zebra_interface_nbr_address_add_update(struct interface *ifp,
p->prefixlen, ifc->ifp->name);
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
client, ifp, ifc);
}
@@ -388,7 +384,7 @@ static void zebra_interface_nbr_address_delete_update(struct interface *ifp,
p->prefixlen, ifc->ifp->name);
}
- for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client))
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client))
zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
client, ifp, ifc);
}
@@ -432,8 +428,8 @@ int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
- /* Fill in the ifIndex of the interface and its new VRF (id) */
- stream_putl(s, ifp->ifindex);
+ /* Fill in the name of the interface and its new VRF (id) */
+ stream_put(s, ifp->name, INTERFACE_NAMSIZ);
stream_putl(s, vrf_id);
/* Write packet size. */
@@ -529,6 +525,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client,
memset(&api, 0, sizeof(api));
api.vrf_id = re->vrf_id;
api.type = re->type;
+ api.safi = SAFI_UNICAST;
api.instance = re->instance;
api.flags = re->flags;
@@ -766,7 +763,7 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
rule->rule.unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (rule->sock == client->sock)
break;
}
@@ -802,7 +799,7 @@ void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset,
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
ipset->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (ipset->sock == client->sock)
break;
}
@@ -832,7 +829,7 @@ void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset,
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
ipset->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (ipset->sock == client->sock)
break;
}
@@ -862,7 +859,7 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable,
zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__,
iptable->unique);
- for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) {
+ for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
if (iptable->sock == client->sock)
break;
}
@@ -1107,7 +1104,8 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
/* Anything not AF_INET/INET6 has been filtered out above */
if (!exist)
- zebra_evaluate_rnh(zvrf, p.family, 1, type, &p);
+ zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
+ &p);
}
stream_failure:
@@ -1187,6 +1185,7 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
unsigned short l = 0;
struct prefix p;
uint16_t flags;
+ uint32_t label = MPLS_INVALID_LABEL;
uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
s = msg;
@@ -1229,12 +1228,15 @@ static void zread_fec_register(ZAPI_HANDLER_ARGS)
l += 5;
STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
l += PSIZE(p.prefixlen);
- if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
+ if (flags & ZEBRA_FEC_REGISTER_LABEL) {
+ STREAM_GETL(s, label);
+ l += 4;
+ } else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
STREAM_GETL(s, label_index);
l += 4;
- } else
- label_index = MPLS_INVALID_LABEL_INDEX;
- zebra_mpls_fec_register(zvrf, &p, label_index, client);
+ }
+
+ zebra_mpls_fec_register(zvrf, &p, label, label_index, client);
}
stream_failure:
@@ -1309,9 +1311,6 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS)
struct vrf *vrf;
struct interface *ifp;
- /* Interface information is needed. */
- vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf));
-
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
FOR_ALL_INTERFACES (vrf, ifp) {
/* Skip pseudo interface. */
@@ -1319,6 +1318,7 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS)
continue;
zsend_interface_add(client, ifp);
+ zsend_interface_link_params(client, ifp);
zsend_interface_addresses(client, ifp);
}
}
@@ -1327,7 +1327,6 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS)
/* Unregister zebra server interface information. */
static void zread_interface_delete(ZAPI_HANDLER_ARGS)
{
- vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf));
}
void zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
@@ -1389,147 +1388,153 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
else
re->table = zvrf->table_id;
+ if (!CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)
+ || api.nexthop_num == 0) {
+ char buf_prefix[PREFIX_STRLEN];
+
+ prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
+ flog_warn(EC_ZEBRA_RX_ROUTE_NO_NEXTHOPS,
+ "%s: received a route without nexthops for prefix %s",
+ __func__, buf_prefix);
+ XFREE(MTYPE_RE, re);
+ return;
+ }
+
/*
* TBD should _all_ of the nexthop add operations use
* api_nh->vrf_id instead of re->vrf_id ? I only changed
* for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
*/
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP))
- for (i = 0; i < api.nexthop_num; i++) {
- api_nh = &api.nexthops[i];
- ifindex_t ifindex = 0;
-
- if (IS_ZEBRA_DEBUG_RECV)
- zlog_debug("nh type %d", api_nh->type);
-
- switch (api_nh->type) {
- case NEXTHOP_TYPE_IFINDEX:
- nexthop = route_entry_nexthop_ifindex_add(
- re, api_nh->ifindex, api_nh->vrf_id);
- break;
- case NEXTHOP_TYPE_IPV4:
- if (IS_ZEBRA_DEBUG_RECV) {
- char nhbuf[INET6_ADDRSTRLEN] = {0};
-
- inet_ntop(AF_INET, &api_nh->gate.ipv4,
- nhbuf, INET6_ADDRSTRLEN);
- zlog_debug("%s: nh=%s, vrf_id=%d",
- __func__, nhbuf,
- api_nh->vrf_id);
- }
- nexthop = route_entry_nexthop_ipv4_add(
- re, &api_nh->gate.ipv4, NULL,
- api_nh->vrf_id);
- break;
- case NEXTHOP_TYPE_IPV4_IFINDEX:
-
- memset(&vtep_ip, 0, sizeof(struct ipaddr));
- if (CHECK_FLAG(api.flags,
- ZEBRA_FLAG_EVPN_ROUTE)) {
- ifindex = get_l3vni_svi_ifindex(vrf_id);
- } else {
- ifindex = api_nh->ifindex;
- }
-
- if (IS_ZEBRA_DEBUG_RECV) {
- char nhbuf[INET6_ADDRSTRLEN] = {0};
-
- inet_ntop(AF_INET, &api_nh->gate.ipv4,
- nhbuf, INET6_ADDRSTRLEN);
- zlog_debug(
- "%s: nh=%s, vrf_id=%d (re->vrf_id=%d), ifindex=%d",
- __func__, nhbuf, api_nh->vrf_id,
- re->vrf_id, ifindex);
- }
- nexthop = route_entry_nexthop_ipv4_ifindex_add(
- re, &api_nh->gate.ipv4, NULL, ifindex,
- api_nh->vrf_id);
-
- /* if this an EVPN route entry,
- * program the nh as neigh
- */
- if (CHECK_FLAG(api.flags,
- ZEBRA_FLAG_EVPN_ROUTE)) {
- SET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_EVPN_RVTEP);
- vtep_ip.ipa_type = IPADDR_V4;
- memcpy(&(vtep_ip.ipaddr_v4),
- &(api_nh->gate.ipv4),
- sizeof(struct in_addr));
- zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api_nh->rmac, &vtep_ip,
- &api.prefix);
- }
- break;
- case NEXTHOP_TYPE_IPV6:
- nexthop = route_entry_nexthop_ipv6_add(
- re, &api_nh->gate.ipv6, api_nh->vrf_id);
- break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- memset(&vtep_ip, 0, sizeof(struct ipaddr));
- if (CHECK_FLAG(api.flags,
- ZEBRA_FLAG_EVPN_ROUTE)) {
- ifindex = get_l3vni_svi_ifindex(vrf_id);
- } else {
- ifindex = api_nh->ifindex;
- }
-
- nexthop = route_entry_nexthop_ipv6_ifindex_add(
- re, &api_nh->gate.ipv6, ifindex,
- api_nh->vrf_id);
-
- /* if this an EVPN route entry,
- * program the nh as neigh
- */
- if (CHECK_FLAG(api.flags,
- ZEBRA_FLAG_EVPN_ROUTE)) {
- SET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_EVPN_RVTEP);
- vtep_ip.ipa_type = IPADDR_V6;
- memcpy(&vtep_ip.ipaddr_v6,
- &(api_nh->gate.ipv6),
- sizeof(struct in6_addr));
- zebra_vxlan_evpn_vrf_route_add(
- vrf_id, &api_nh->rmac, &vtep_ip,
- &api.prefix);
- }
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- nexthop = route_entry_nexthop_blackhole_add(
- re, api_nh->bh_type);
- break;
+ for (i = 0; i < api.nexthop_num; i++) {
+ api_nh = &api.nexthops[i];
+ ifindex_t ifindex = 0;
+
+ if (IS_ZEBRA_DEBUG_RECV)
+ zlog_debug("nh type %d", api_nh->type);
+
+ switch (api_nh->type) {
+ case NEXTHOP_TYPE_IFINDEX:
+ nexthop = route_entry_nexthop_ifindex_add(
+ re, api_nh->ifindex, api_nh->vrf_id);
+ break;
+ case NEXTHOP_TYPE_IPV4:
+ if (IS_ZEBRA_DEBUG_RECV) {
+ char nhbuf[INET6_ADDRSTRLEN] = {0};
+
+ inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
+ INET6_ADDRSTRLEN);
+ zlog_debug("%s: nh=%s, vrf_id=%d", __func__,
+ nhbuf, api_nh->vrf_id);
}
+ nexthop = route_entry_nexthop_ipv4_add(
+ re, &api_nh->gate.ipv4, NULL, api_nh->vrf_id);
+ break;
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (!nexthop) {
- flog_warn(
- EC_ZEBRA_NEXTHOP_CREATION_FAILED,
- "%s: Nexthops Specified: %d but we failed to properly create one",
- __PRETTY_FUNCTION__, api.nexthop_num);
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
- return;
+ memset(&vtep_ip, 0, sizeof(struct ipaddr));
+ if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ ifindex = get_l3vni_svi_ifindex(vrf_id);
+ } else {
+ ifindex = api_nh->ifindex;
}
- /* MPLS labels for BGP-LU or Segment Routing */
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
- && api_nh->type != NEXTHOP_TYPE_IFINDEX
- && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
- enum lsp_types_t label_type;
-
- label_type =
- lsp_type_from_re_type(client->proto);
-
- if (IS_ZEBRA_DEBUG_RECV) {
- zlog_debug(
- "%s: adding %d labels of type %d (1st=%u)",
- __func__, api_nh->label_num,
- label_type, api_nh->labels[0]);
- }
-
- nexthop_add_labels(nexthop, label_type,
- api_nh->label_num,
- &api_nh->labels[0]);
+
+ if (IS_ZEBRA_DEBUG_RECV) {
+ char nhbuf[INET6_ADDRSTRLEN] = {0};
+
+ inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
+ INET6_ADDRSTRLEN);
+ zlog_debug(
+ "%s: nh=%s, vrf_id=%d (re->vrf_id=%d), ifindex=%d",
+ __func__, nhbuf, api_nh->vrf_id,
+ re->vrf_id, ifindex);
+ }
+ nexthop = route_entry_nexthop_ipv4_ifindex_add(
+ re, &api_nh->gate.ipv4, NULL, ifindex,
+ api_nh->vrf_id);
+
+ /* if this an EVPN route entry,
+ * program the nh as neigh
+ */
+ if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ SET_FLAG(nexthop->flags,
+ NEXTHOP_FLAG_EVPN_RVTEP);
+ vtep_ip.ipa_type = IPADDR_V4;
+ memcpy(&(vtep_ip.ipaddr_v4),
+ &(api_nh->gate.ipv4),
+ sizeof(struct in_addr));
+ zebra_vxlan_evpn_vrf_route_add(
+ vrf_id, &api_nh->rmac, &vtep_ip,
+ &api.prefix);
+ }
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ nexthop = route_entry_nexthop_ipv6_add(
+ re, &api_nh->gate.ipv6, api_nh->vrf_id);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ memset(&vtep_ip, 0, sizeof(struct ipaddr));
+ if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ ifindex = get_l3vni_svi_ifindex(vrf_id);
+ } else {
+ ifindex = api_nh->ifindex;
+ }
+
+ nexthop = route_entry_nexthop_ipv6_ifindex_add(
+ re, &api_nh->gate.ipv6, ifindex,
+ api_nh->vrf_id);
+
+ /* if this an EVPN route entry,
+ * program the nh as neigh
+ */
+ if (CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
+ SET_FLAG(nexthop->flags,
+ NEXTHOP_FLAG_EVPN_RVTEP);
+ vtep_ip.ipa_type = IPADDR_V6;
+ memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6),
+ sizeof(struct in6_addr));
+ zebra_vxlan_evpn_vrf_route_add(
+ vrf_id, &api_nh->rmac, &vtep_ip,
+ &api.prefix);
+ }
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ nexthop = route_entry_nexthop_blackhole_add(
+ re, api_nh->bh_type);
+ break;
+ }
+
+ if (!nexthop) {
+ flog_warn(
+ EC_ZEBRA_NEXTHOP_CREATION_FAILED,
+ "%s: Nexthops Specified: %d but we failed to properly create one",
+ __PRETTY_FUNCTION__, api.nexthop_num);
+ nexthops_free(re->ng.nexthop);
+ XFREE(MTYPE_RE, re);
+ return;
+ }
+ if (api_nh->onlink)
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
+
+ /* MPLS labels for BGP-LU or Segment Routing */
+ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
+ && api_nh->type != NEXTHOP_TYPE_IFINDEX
+ && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
+ enum lsp_types_t label_type;
+
+ label_type = lsp_type_from_re_type(client->proto);
+
+ if (IS_ZEBRA_DEBUG_RECV) {
+ zlog_debug(
+ "%s: adding %d labels of type %d (1st=%u)",
+ __func__, api_nh->label_num, label_type,
+ api_nh->labels[0]);
}
+
+ nexthop_add_labels(nexthop, label_type,
+ api_nh->label_num,
+ &api_nh->labels[0]);
}
+ }
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE))
re->distance = api.distance;
@@ -1651,13 +1656,27 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
+ stream_putl(s, vrf_get_backend());
stream_putc(s, mpls_enabled);
stream_putl(s, multipath_num);
+ stream_putc(s, zebra_mlag_get_role());
stream_putw_at(s, 0, stream_get_endp(s));
zserv_send_message(client, s);
}
+void zsend_capabilities_all_clients(void)
+{
+ struct listnode *node, *nnode;
+ struct zebra_vrf *zvrf;
+ struct zserv *client;
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
+ zsend_capabilities(client, zvrf);
+ }
+}
+
/* Tie up route-type and client->sock */
static void zread_hello(ZAPI_HANDLER_ARGS)
{
@@ -1686,6 +1705,7 @@ static void zread_hello(ZAPI_HANDLER_ARGS)
}
zsend_capabilities(client, zvrf);
+ zebra_vrf_update_all(client);
stream_failure:
return;
}
@@ -1696,11 +1716,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->ifinfo, zvrf_id(zvrf));
+ vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
+ }
vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf));
}
@@ -2437,12 +2457,14 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_FEC_REGISTER] = zread_fec_register,
[ZEBRA_FEC_UNREGISTER] = zread_fec_unregister,
[ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
+ [ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip,
[ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
[ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
[ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
[ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
[ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
[ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
+ [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
[ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
[ZEBRA_PW_ADD] = zread_pseudowire,
[ZEBRA_PW_DELETE] = zread_pseudowire,