#include "zebra/zebra_pbr.h"
#include "zebra/table_manager.h"
#include "zebra/zapi_msg.h"
+#include "zebra/zebra_errors.h"
/* Encoding helpers -------------------------------------------------------- */
unsigned short l = 0;
uint8_t flags = 0;
uint16_t type = cmd2type[hdr->command];
+ bool exist;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug(
l += 4;
if (p.family == AF_INET) {
if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is too large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) {
if (p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN;
} else {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_UNKNOWN_FAMILY,
"rnh_register: Received unknown family type %d\n",
p.family);
return;
}
- rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type);
+ rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
+ if (!rnh)
+ return;
+
if (type == RNH_NEXTHOP_TYPE) {
if (flags
&& !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
/* Anything not AF_INET/INET6 has been filtered out above */
- zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p);
+ if (!exist)
+ zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type,
+ &p);
}
stream_failure:
l += 4;
if (p.family == AF_INET) {
if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v4 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
l += IPV4_MAX_BYTELEN;
} else if (p.family == AF_INET6) {
if (p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length %d is to large for a v6 address",
__PRETTY_FUNCTION__, p.prefixlen);
return;
STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
l += IPV6_MAX_BYTELEN;
} else {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_UNKNOWN_FAMILY,
"rnh_register: Received unknown family type %d\n",
p.family);
return;
* registration
*/
if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_IRDP_LEN_MISMATCH,
"fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
hdr->length);
return;
memset(&p, 0, sizeof(p));
STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_UNKNOWN_FAMILY,
"fec_register: Received unknown family type %d\n",
p.family);
return;
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
|| (p.family == AF_INET6
&& p.prefixlen > IPV6_MAX_BITLEN)) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix hdr->length: %d is to long for %d",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return;
* fec unregistration
*/
if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_IRDP_LEN_MISMATCH,
"fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
hdr->length);
return;
memset(&p, 0, sizeof(p));
STREAM_GETW(s, p.family);
if (p.family != AF_INET && p.family != AF_INET6) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_UNKNOWN_FAMILY,
"fec_unregister: Received unknown family type %d\n",
p.family);
return;
if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
|| (p.family == AF_INET6
&& p.prefixlen > IPV6_MAX_BITLEN)) {
- zlog_warn(
+ zlog_debug(
"%s: Received prefix hdr->length %d which is greater than %d can support",
__PRETTY_FUNCTION__, p.prefixlen, p.family);
return;
char buff[PREFIX2STR_BUFFER];
prefix2str(p, buff, sizeof(buff));
- zlog_warn(
+ flog_warn(
+ EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
"%s: Prefix %s has %d nexthops, but we can only use the first %d",
caller, buff, nexthop_num, multipath_num);
}
}
if (!nexthop) {
- zlog_warn(
+ 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);
afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- zlog_warn("%s: Received SRC Prefix but afi is not v6",
+ flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ "%s: Received SRC Prefix but afi is not v6",
__PRETTY_FUNCTION__);
nexthops_free(re->ng.nexthop);
XFREE(MTYPE_RE, re);
afi = family2afi(api.prefix.family);
if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- zlog_warn("%s: Received a src prefix while afi is not v6",
+ flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
+ "%s: Received a src prefix while afi is not v6",
__PRETTY_FUNCTION__);
return;
}
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
- false);
+ api.distance, false);
/* Stats */
switch (api.prefix.family) {
}
}
-/* This function support multiple nexthop. */
-/*
- * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update re and
- * add kernel route.
- */
-static void zread_ipv4_add(ZAPI_HANDLER_ARGS)
-{
- int i;
- struct route_entry *re;
- struct prefix p;
- uint8_t message;
- struct in_addr nhop_addr;
- uint8_t nexthop_num;
- uint8_t nexthop_type;
- struct stream *s;
- ifindex_t ifindex;
- safi_t safi;
- int ret;
- enum lsp_types_t label_type = ZEBRA_LSP_NONE;
- mpls_label_t label;
- struct nexthop *nexthop;
- enum blackhole_type bh_type = BLACKHOLE_NULL;
-
- /* Get input stream. */
- s = msg;
-
- /* Allocate new re. */
- re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
- /* Type, flags, message. */
- STREAM_GETC(s, re->type);
- if (re->type > ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified route type %d is not a legal value\n",
- __PRETTY_FUNCTION__, re->type);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GETW(s, re->instance);
- STREAM_GETL(s, re->flags);
- STREAM_GETC(s, message);
- STREAM_GETW(s, safi);
- re->uptime = time(NULL);
-
- /* IPv4 prefix. */
- memset(&p, 0, sizeof(struct prefix_ipv4));
- p.family = AF_INET;
- STREAM_GETC(s, p.prefixlen);
- if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
- "%s: Specified prefix length %d is greater than what v4 can be",
- __PRETTY_FUNCTION__, p.prefixlen);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
- /* VRF ID */
- re->vrf_id = zvrf_id(zvrf);
-
- /* Nexthop parse. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
- STREAM_GETC(s, nexthop_num);
- zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
- nexthop_num);
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
- label_type = lsp_type_from_re_type(client->proto);
-
- for (i = 0; i < nexthop_num; i++) {
- STREAM_GETC(s, nexthop_type);
-
- switch (nexthop_type) {
- case NEXTHOP_TYPE_IFINDEX:
- STREAM_GETL(s, ifindex);
- route_entry_nexthop_ifindex_add(re, ifindex,
- re->vrf_id);
- break;
- case NEXTHOP_TYPE_IPV4:
- STREAM_GET(&nhop_addr.s_addr, s,
- IPV4_MAX_BYTELEN);
- nexthop = route_entry_nexthop_ipv4_add(
- re, &nhop_addr, NULL, re->vrf_id);
- /*
- * For labeled-unicast, each nexthop is followed
- * by the label.
- */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) {
- STREAM_GETL(s, label);
- nexthop_add_labels(nexthop, label_type,
- 1, &label);
- }
- break;
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- STREAM_GET(&nhop_addr.s_addr, s,
- IPV4_MAX_BYTELEN);
- STREAM_GETL(s, ifindex);
- route_entry_nexthop_ipv4_ifindex_add(
- re, &nhop_addr, NULL, ifindex,
- re->vrf_id);
- break;
- case NEXTHOP_TYPE_IPV6:
- zlog_warn(
- "%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops",
- __PRETTY_FUNCTION__);
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
- return;
- case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re, bh_type);
- break;
- default:
- zlog_warn(
- "%s: Specified nexthop type: %d does not exist",
- __PRETTY_FUNCTION__, nexthop_type);
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
- return;
- }
- }
- }
-
- /* Distance. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
- STREAM_GETC(s, re->distance);
-
- /* Metric. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
- STREAM_GETL(s, re->metric);
-
- /* Tag */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
- STREAM_GETL(s, re->tag);
- else
- re->tag = 0;
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
- STREAM_GETL(s, re->mtu);
- else
- re->mtu = 0;
-
- /* Table */
- re->table = zvrf->table_id;
-
- ret = rib_add_multipath(AFI_IP, safi, &p, NULL, re);
-
- /* Stats */
- if (ret > 0)
- client->v4_route_add_cnt++;
- else if (ret < 0)
- client->v4_route_upd8_cnt++;
-
- return;
-
-stream_failure:
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
-}
-
-/* Zebra server IPv4 prefix delete function. */
-static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
-{
- struct stream *s;
- struct zapi_ipv4 api;
- struct prefix p;
- uint32_t table_id;
-
- s = msg;
-
- /* Type, flags, message. */
- STREAM_GETC(s, api.type);
- STREAM_GETW(s, api.instance);
- STREAM_GETL(s, api.flags);
- STREAM_GETC(s, api.message);
- STREAM_GETW(s, api.safi);
-
- /* IPv4 prefix. */
- memset(&p, 0, sizeof(struct prefix));
- p.family = AF_INET;
- STREAM_GETC(s, p.prefixlen);
- if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn("%s: Passed in prefixlen %d is impossible",
- __PRETTY_FUNCTION__, p.prefixlen);
- return;
- }
- STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
- table_id = zvrf->table_id;
-
- rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, NULL, NULL, table_id, 0, false);
- client->v4_route_del_cnt++;
-
-stream_failure:
- return;
-}
-
/* MRIB Nexthop lookup for IPv4. */
static void zread_ipv4_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
{
return;
}
-/* Zebra server IPv6 prefix add function. */
-static void zread_ipv4_route_ipv6_nexthop_add(ZAPI_HANDLER_ARGS)
-{
- unsigned int i;
- struct stream *s;
- struct in6_addr nhop_addr;
- struct route_entry *re;
- uint8_t message;
- uint8_t nexthop_num;
- uint8_t nexthop_type;
- struct prefix p;
- safi_t safi;
- static struct in6_addr nexthops[MULTIPATH_NUM];
- static unsigned int ifindices[MULTIPATH_NUM];
- int ret;
- static mpls_label_t labels[MULTIPATH_NUM];
- enum lsp_types_t label_type = ZEBRA_LSP_NONE;
- mpls_label_t label;
- struct nexthop *nexthop;
- enum blackhole_type bh_type = BLACKHOLE_NULL;
-
- /* Get input stream. */
- s = msg;
-
- memset(&nhop_addr, 0, sizeof(struct in6_addr));
-
- /* Allocate new re. */
- re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
- /* Type, flags, message. */
- STREAM_GETC(s, re->type);
- if (re->type > ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified route type: %d is not a legal value\n",
- __PRETTY_FUNCTION__, re->type);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GETW(s, re->instance);
- STREAM_GETL(s, re->flags);
- STREAM_GETC(s, message);
- STREAM_GETW(s, safi);
- re->uptime = time(NULL);
-
- /* IPv4 prefix. */
- memset(&p, 0, sizeof(struct prefix_ipv4));
- p.family = AF_INET;
- STREAM_GETC(s, p.prefixlen);
- if (p.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
- "%s: Prefix Length %d is greater than what a v4 address can use",
- __PRETTY_FUNCTION__, p.prefixlen);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GET(&p.u.prefix4, s, PSIZE(p.prefixlen));
-
- /* VRF ID */
- re->vrf_id = zvrf_id(zvrf);
-
- /*
- * We need to give nh-addr, nh-ifindex with the same next-hop object
- * to the re to ensure that IPv6 multipathing works; need to coalesce
- * these. Clients should send the same number of paired set of
- * next-hop-addr/next-hop-ifindices.
- */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
- unsigned int nh_count = 0;
- unsigned int if_count = 0;
- unsigned int max_nh_if = 0;
-
- STREAM_GETC(s, nexthop_num);
- zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
- nexthop_num);
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
- label_type = lsp_type_from_re_type(client->proto);
-
- for (i = 0; i < nexthop_num; i++) {
- STREAM_GETC(s, nexthop_type);
-
- switch (nexthop_type) {
- case NEXTHOP_TYPE_IPV6:
- STREAM_GET(&nhop_addr, s, 16);
- if (nh_count < MULTIPATH_NUM) {
- /*
- * For labeled-unicast, each nexthop is
- * followed by the label.
- */
- if (CHECK_FLAG(message,
- ZAPI_MESSAGE_LABEL)) {
- STREAM_GETL(s, label);
- labels[nh_count] = label;
- }
- nexthops[nh_count] = nhop_addr;
- nh_count++;
- }
- break;
- case NEXTHOP_TYPE_IFINDEX:
- if (if_count < multipath_num)
- STREAM_GETL(s, ifindices[if_count++]);
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re, bh_type);
- break;
- default:
- zlog_warn(
- "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
- __PRETTY_FUNCTION__);
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
- return;
- }
- }
-
- max_nh_if = (nh_count > if_count) ? nh_count : if_count;
- for (i = 0; i < max_nh_if; i++) {
- if ((i < nh_count)
- && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) {
- if ((i < if_count) && ifindices[i])
- nexthop =
- route_entry_nexthop_ipv6_ifindex_add(
- re, &nexthops[i],
- ifindices[i],
- re->vrf_id);
- else
- nexthop = route_entry_nexthop_ipv6_add(
- re, &nexthops[i], re->vrf_id);
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
- nexthop_add_labels(nexthop, label_type,
- 1, &labels[i]);
- } else {
- if ((i < if_count) && ifindices[i])
- route_entry_nexthop_ifindex_add(
- re, ifindices[i], re->vrf_id);
- }
- }
- }
-
- /* Distance. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
- STREAM_GETC(s, re->distance);
-
- /* Metric. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
- STREAM_GETL(s, re->metric);
-
- /* Tag */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
- STREAM_GETL(s, re->tag);
- else
- re->tag = 0;
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
- STREAM_GETL(s, re->mtu);
- else
- re->mtu = 0;
-
- /* Table */
- re->table = zvrf->table_id;
-
- ret = rib_add_multipath(AFI_IP6, safi, &p, NULL, re);
- /* Stats */
- if (ret > 0)
- client->v4_route_add_cnt++;
- else if (ret < 0)
- client->v4_route_upd8_cnt++;
-
- return;
-
-stream_failure:
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
-}
-
-static void zread_ipv6_add(ZAPI_HANDLER_ARGS)
-{
- unsigned int i;
- struct stream *s;
- struct in6_addr nhop_addr;
- ifindex_t ifindex;
- struct route_entry *re;
- uint8_t message;
- uint8_t nexthop_num;
- uint8_t nexthop_type;
- struct prefix p;
- struct prefix_ipv6 src_p, *src_pp;
- safi_t safi;
- static struct in6_addr nexthops[MULTIPATH_NUM];
- static unsigned int ifindices[MULTIPATH_NUM];
- int ret;
- static mpls_label_t labels[MULTIPATH_NUM];
- enum lsp_types_t label_type = ZEBRA_LSP_NONE;
- mpls_label_t label;
- struct nexthop *nexthop;
- enum blackhole_type bh_type = BLACKHOLE_NULL;
-
- /* Get input stream. */
- s = msg;
-
- memset(&nhop_addr, 0, sizeof(struct in6_addr));
-
- /* Allocate new re. */
- re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
-
- /* Type, flags, message. */
- STREAM_GETC(s, re->type);
- if (re->type > ZEBRA_ROUTE_MAX) {
- zlog_warn("%s: Specified route type: %d is not a legal value\n",
- __PRETTY_FUNCTION__, re->type);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GETW(s, re->instance);
- STREAM_GETL(s, re->flags);
- STREAM_GETC(s, message);
- STREAM_GETW(s, safi);
- re->uptime = time(NULL);
-
- /* IPv6 prefix. */
- memset(&p, 0, sizeof(p));
- p.family = AF_INET6;
- STREAM_GETC(s, p.prefixlen);
- if (p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
- "%s: Specified prefix length %d is to large for v6 prefix",
- __PRETTY_FUNCTION__, p.prefixlen);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) {
- memset(&src_p, 0, sizeof(src_p));
- src_p.family = AF_INET6;
- STREAM_GETC(s, src_p.prefixlen);
- if (src_p.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
- "%s: Specified src prefix length %d is to large for v6 prefix",
- __PRETTY_FUNCTION__, src_p.prefixlen);
- XFREE(MTYPE_RE, re);
- return;
- }
- STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
- src_pp = &src_p;
- } else
- src_pp = NULL;
-
- /* VRF ID */
- re->vrf_id = zvrf_id(zvrf);
-
- /*
- * We need to give nh-addr, nh-ifindex with the same next-hop object
- * to the re to ensure that IPv6 multipathing works; need to coalesce
- * these. Clients should send the same number of paired set of
- * next-hop-addr/next-hop-ifindices.
- */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) {
- unsigned int nh_count = 0;
- unsigned int if_count = 0;
- unsigned int max_nh_if = 0;
-
- STREAM_GETC(s, nexthop_num);
- zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
- nexthop_num);
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
- label_type = lsp_type_from_re_type(client->proto);
-
- for (i = 0; i < nexthop_num; i++) {
- STREAM_GETC(s, nexthop_type);
-
- switch (nexthop_type) {
- case NEXTHOP_TYPE_IPV6:
- STREAM_GET(&nhop_addr, s, 16);
- if (nh_count < MULTIPATH_NUM) {
- /*
- * For labeled-unicast, each nexthop is
- * followed by label.
- */
- if (CHECK_FLAG(message,
- ZAPI_MESSAGE_LABEL)) {
- STREAM_GETL(s, label);
- labels[nh_count] = label;
- }
- nexthops[nh_count++] = nhop_addr;
- }
- break;
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- STREAM_GET(&nhop_addr, s, 16);
- STREAM_GETL(s, ifindex);
- route_entry_nexthop_ipv6_ifindex_add(
- re, &nhop_addr, ifindex, re->vrf_id);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- if (if_count < multipath_num)
- STREAM_GETL(s, ifindices[if_count++]);
- break;
- case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re, bh_type);
- break;
- default:
- zlog_warn(
- "%s: Please use ZEBRA_ROUTE_ADD if you want to pass non v6 nexthops",
- __PRETTY_FUNCTION__);
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
- return;
- }
- }
-
- max_nh_if = (nh_count > if_count) ? nh_count : if_count;
- for (i = 0; i < max_nh_if; i++) {
- if ((i < nh_count)
- && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) {
- if ((i < if_count) && ifindices[i])
- nexthop =
- route_entry_nexthop_ipv6_ifindex_add(
- re, &nexthops[i],
- ifindices[i],
- re->vrf_id);
- else
- nexthop = route_entry_nexthop_ipv6_add(
- re, &nexthops[i], re->vrf_id);
- if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
- nexthop_add_labels(nexthop, label_type,
- 1, &labels[i]);
- } else {
- if ((i < if_count) && ifindices[i])
- route_entry_nexthop_ifindex_add(
- re, ifindices[i], re->vrf_id);
- }
- }
- }
-
- /* Distance. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE))
- STREAM_GETC(s, re->distance);
-
- /* Metric. */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC))
- STREAM_GETL(s, re->metric);
-
- /* Tag */
- if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG))
- STREAM_GETL(s, re->tag);
- else
- re->tag = 0;
-
- if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU))
- STREAM_GETL(s, re->mtu);
- else
- re->mtu = 0;
-
- re->table = zvrf->table_id;
-
- ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re);
- /* Stats */
- if (ret > 0)
- client->v6_route_add_cnt++;
- else if (ret < 0)
- client->v6_route_upd8_cnt++;
-
- return;
-
-stream_failure:
- nexthops_free(re->ng.nexthop);
- XFREE(MTYPE_RE, re);
-}
-
-/* Zebra server IPv6 prefix delete function. */
-static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
-{
- struct stream *s;
- struct zapi_ipv6 api;
- struct prefix p;
- struct prefix_ipv6 src_p, *src_pp;
-
- s = msg;
-
- /* Type, flags, message. */
- STREAM_GETC(s, api.type);
- STREAM_GETW(s, api.instance);
- STREAM_GETL(s, api.flags);
- STREAM_GETC(s, api.message);
- STREAM_GETW(s, api.safi);
-
- /* IPv4 prefix. */
- memset(&p, 0, sizeof(struct prefix));
- p.family = AF_INET6;
- STREAM_GETC(s, p.prefixlen);
- STREAM_GET(&p.u.prefix6, s, PSIZE(p.prefixlen));
-
- if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
- memset(&src_p, 0, sizeof(struct prefix_ipv6));
- src_p.family = AF_INET6;
- STREAM_GETC(s, src_p.prefixlen);
- STREAM_GET(&src_p.prefix, s, PSIZE(src_p.prefixlen));
- src_pp = &src_p;
- } else
- src_pp = NULL;
-
- rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
-
- client->v6_route_del_cnt++;
-
-stream_failure:
- return;
-}
-
/* Register zebra server router-id information. Send current router-id */
static void zread_router_id_add(ZAPI_HANDLER_ARGS)
{
client->notify_owner = true;
/* accept only dynamic routing protocols */
- if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) {
+ if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) {
zlog_notice(
"client %d says hello and bids fair to announce only %s routes vrf=%u",
client->sock, zebra_route_string(proto),
STREAM_GET(&prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
STREAM_GETC(s, prefix.prefixlen);
if (prefix.prefixlen > IPV4_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix length %d is greater than a v4 address can support",
__PRETTY_FUNCTION__, prefix.prefixlen);
return;
STREAM_GET(&prefix.u.prefix6, s, 16);
STREAM_GETC(s, prefix.prefixlen);
if (prefix.prefixlen > IPV6_MAX_BITLEN) {
- zlog_warn(
+ zlog_debug(
"%s: Specified prefix length %d is greater than a v6 address can support",
__PRETTY_FUNCTION__, prefix.prefixlen);
return;
STREAM_GET(&gate.ipv6, s, 16);
break;
default:
- zlog_warn("%s: Specified AF %d is not supported for this call",
- __PRETTY_FUNCTION__, prefix.family);
+ zlog_debug("%s: Specified AF %d is not supported for this call",
+ __PRETTY_FUNCTION__, prefix.family);
return;
}
STREAM_GETL(s, ifindex);
/* accept only dynamic routing protocols */
if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
- zlog_err("client %d has wrong protocol %s", client->sock,
+ flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+ "client %d has wrong protocol %s", client->sock,
zebra_route_string(proto));
zsend_table_manager_connect_response(client, vrf_id, 1);
return;
/* accept only dynamic routing protocols */
if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
- zlog_err("client %d has wrong protocol %s", client->sock,
+ flog_err(EC_ZEBRA_TM_WRONG_PROTO,
+ "client %d has wrong protocol %s", client->sock,
zebra_route_string(proto));
zsend_label_manager_connect_response(client, vrf_id, 1);
return;
uint8_t proto, unsigned int instance)
{
if (proto != client->proto) {
- zlog_err("%s: msg vs client proto mismatch, client=%u msg=%u",
+ flog_err(EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
+ "%s: msg vs client proto mismatch, client=%u msg=%u",
op, client->proto, proto);
/* TODO: fail when BGP sets proto and instance */
/* return 1; */
}
if (instance != client->instance) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_PROTO_OR_INSTANCE_MISMATCH,
"%s: msg vs client instance mismatch, client=%u msg=%u",
op, client->instance, instance);
/* TODO: fail when BGP sets proto and instance */
lmc = assign_label_chunk(client->proto, client->instance, keep, size);
if (!lmc)
- zlog_err(
+ flog_err(
+ EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK,
"Unable to assign Label Chunk of size %u to %s instance %u",
size, zebra_route_string(client->proto),
client->instance);
else {
/* Sanity: don't allow 'unidentified' requests */
if (!client->proto) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_LM_ALIENS,
"Got label request from an unidentified client");
return;
}
tmc = assign_table_chunk(client->proto, client->instance, size);
if (!tmc)
- zlog_err("%s: Unable to assign Table Chunk of size %u",
+ flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
+ "%s: Unable to assign Table Chunk of size %u",
__func__, size);
else
zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
else {
/* Sanity: don't allow 'unidentified' requests */
if (!client->proto) {
- zlog_err(
+ flog_err(
+ EC_ZEBRA_TM_ALIENS,
"Got table request from an unidentified client");
return;
}
switch (hdr->command) {
case ZEBRA_PW_ADD:
if (pw) {
- zlog_warn("%s: pseudowire %s already exists [%s]",
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
+ "%s: pseudowire %s already exists [%s]",
__func__, ifname,
zserv_command_string(hdr->command));
return;
break;
case ZEBRA_PW_DELETE:
if (!pw) {
- zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ "%s: pseudowire %s not found [%s]", __func__,
ifname, zserv_command_string(hdr->command));
return;
}
case ZEBRA_PW_SET:
case ZEBRA_PW_UNSET:
if (!pw) {
- zlog_warn("%s: pseudowire %s not found [%s]", __func__,
+ flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
+ "%s: pseudowire %s not found [%s]", __func__,
ifname, zserv_command_string(hdr->command));
return;
}
[ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
[ZEBRA_ROUTE_ADD] = zread_route_add,
[ZEBRA_ROUTE_DELETE] = zread_route_del,
- [ZEBRA_IPV4_ROUTE_ADD] = zread_ipv4_add,
- [ZEBRA_IPV4_ROUTE_DELETE] = zread_ipv4_delete,
- [ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD] = zread_ipv4_route_ipv6_nexthop_add,
- [ZEBRA_IPV6_ROUTE_ADD] = zread_ipv6_add,
- [ZEBRA_IPV6_ROUTE_DELETE] = zread_ipv6_delete,
[ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
[ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
[ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
[ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
[ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
[ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
+#if HAVE_BFDD > 0
+ [ZEBRA_BFD_DEST_REPLAY] = zebra_ptm_bfd_dst_replay,
+#endif /* HAVE_BFDD */
[ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
[ZEBRA_VRF_LABEL] = zread_vrf_label,
[ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
copy = stream_dup(orig);
stream_set_getp(copy, 0);
- zserv_privs.change(ZPRIVS_RAISE);
snprintf(fname, MAXPATHLEN, "%s/%u", DAEMON_VTY_DIR, command);
- fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+
+ frr_elevate_privs(&zserv_privs) {
+ fd = open(fname, O_CREAT | O_WRONLY | O_EXCL, 0644);
+ }
stream_flush(copy, fd);
close(fd);
- zserv_privs.change(ZPRIVS_LOWER);
stream_free(copy);
}
#endif
zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
if (!zvrf) {
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
- zlog_warn("ZAPI message specifies unknown VRF: %d",
- hdr.vrf_id);
+ zlog_debug("ZAPI message specifies unknown VRF: %d",
+ hdr.vrf_id);
return;
}