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.c179
1 files changed, 118 insertions, 61 deletions
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 4ef4bc6722..61bd1417d1 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -867,7 +867,7 @@ void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
}
void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx,
- uint16_t note)
+ enum zapi_iptable_notify_owner note)
{
struct listnode *node;
struct zserv *client;
@@ -901,7 +901,8 @@ void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx,
zserv_send_message(client, s);
}
-void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx, uint16_t note)
+void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx,
+ enum zapi_ipset_notify_owner note)
{
struct listnode *node;
struct zserv *client;
@@ -936,7 +937,7 @@ void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx, uint16_t note)
}
void zsend_ipset_entry_notify_owner(const struct zebra_dplane_ctx *ctx,
- uint16_t note)
+ enum zapi_ipset_entry_notify_owner note)
{
struct listnode *node;
struct zserv *client;
@@ -996,7 +997,8 @@ void zsend_nhrp_neighbor_notify(int cmd, struct interface *ifp,
continue;
s = stream_new(ZEBRA_MAX_PACKET_SIZ);
- zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp);
+ zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp,
+ ndm_state);
stream_putw_at(s, 0, stream_get_endp(s));
zserv_send_message(client, s);
}
@@ -1135,14 +1137,32 @@ static int zsend_table_manager_connect_response(struct zserv *client,
return zserv_send_message(client, s);
}
-/* Inbound message handling ------------------------------------------------ */
+/* SRv6 locator add notification from zebra daemon. */
+int zsend_zebra_srv6_locator_add(struct zserv *client, struct srv6_locator *loc)
+{
+ struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
-const int cmd2type[] = {
- [ZEBRA_NEXTHOP_REGISTER] = RNH_NEXTHOP_TYPE,
- [ZEBRA_NEXTHOP_UNREGISTER] = RNH_NEXTHOP_TYPE,
- [ZEBRA_IMPORT_ROUTE_REGISTER] = RNH_IMPORT_CHECK_TYPE,
- [ZEBRA_IMPORT_ROUTE_UNREGISTER] = RNH_IMPORT_CHECK_TYPE,
-};
+ zclient_create_header(s, ZEBRA_SRV6_LOCATOR_ADD, VRF_DEFAULT);
+ zapi_srv6_locator_encode(s, loc);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zserv_send_message(client, s);
+}
+
+/* SRv6 locator delete notification from zebra daemon. */
+int zsend_zebra_srv6_locator_delete(struct zserv *client,
+ struct srv6_locator *loc)
+{
+ struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
+
+ zclient_create_header(s, ZEBRA_SRV6_LOCATOR_DELETE, VRF_DEFAULT);
+ zapi_srv6_locator_encode(s, loc);
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return zserv_send_message(client, s);
+}
+
+/* Inbound message handling ------------------------------------------------ */
/* Nexthop register */
static void zread_rnh_register(ZAPI_HANDLER_ARGS)
@@ -1151,17 +1171,17 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
struct stream *s;
struct prefix p;
unsigned short l = 0;
- uint8_t flags = 0;
- uint16_t type = cmd2type[hdr->command];
+ uint8_t connected = 0;
+ uint8_t resolve_via_default;
bool exist;
bool flag_changed = false;
uint8_t orig_flags;
+ safi_t safi;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug(
- "rnh_register msg from client %s: hdr->length=%d, type=%s vrf=%u",
+ "rnh_register msg from client %s: hdr->length=%d vrf=%u",
zebra_route_string(client->proto), hdr->length,
- (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route",
zvrf->vrf->vrf_id);
s = msg;
@@ -1170,10 +1190,12 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
client->nh_reg_time = monotime(NULL);
while (l < hdr->length) {
- STREAM_GETC(s, flags);
+ STREAM_GETC(s, connected);
+ STREAM_GETC(s, resolve_via_default);
+ STREAM_GETW(s, safi);
STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
- l += 4;
+ l += 7;
if (p.family == AF_INET) {
client->v4_nh_watch_add_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
@@ -1201,37 +1223,29 @@ static void zread_rnh_register(ZAPI_HANDLER_ARGS)
p.family);
return;
}
- rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type, &exist);
+ rnh = zebra_add_rnh(&p, zvrf_id(zvrf), &exist);
if (!rnh)
return;
orig_flags = rnh->flags;
- if (type == RNH_NEXTHOP_TYPE) {
- if (flags
- && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
- SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
- else if (!flags
- && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
- UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
- } else if (type == RNH_IMPORT_CHECK_TYPE) {
- if (flags
- && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH))
- SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
- else if (!flags
- && CHECK_FLAG(rnh->flags,
- ZEBRA_NHT_EXACT_MATCH))
- UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
- }
+ if (connected && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
+ SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
+ else if (!connected
+ && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
+ UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
+
+ if (resolve_via_default)
+ SET_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT);
if (orig_flags != rnh->flags)
flag_changed = true;
/* Anything not AF_INET/INET6 has been filtered out above */
if (!exist || flag_changed)
- zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, type,
- &p);
+ zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, &p,
+ safi);
- zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf));
+ zebra_add_rnh_client(rnh, client, zvrf_id(zvrf));
}
stream_failure:
@@ -1245,7 +1259,7 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
struct stream *s;
struct prefix p;
unsigned short l = 0;
- uint16_t type = cmd2type[hdr->command];
+ safi_t safi;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug(
@@ -1256,15 +1270,19 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
s = msg;
while (l < hdr->length) {
- uint8_t flags;
+ uint8_t ignore;
- STREAM_GETC(s, flags);
- if (flags != 0)
+ STREAM_GETC(s, ignore);
+ if (ignore != 0)
+ goto stream_failure;
+ STREAM_GETC(s, ignore);
+ if (ignore != 0)
goto stream_failure;
+ STREAM_GETW(s, safi);
STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
- l += 4;
+ l += 7;
if (p.family == AF_INET) {
client->v4_nh_watch_rem_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
@@ -1292,10 +1310,10 @@ static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
p.family);
return;
}
- rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type);
+ rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), safi);
if (rnh) {
client->nh_dereg_time = monotime(NULL);
- zebra_remove_rnh_client(rnh, client, type);
+ zebra_remove_rnh_client(rnh, client);
}
}
stream_failure:
@@ -1609,7 +1627,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh,
zlog_debug("%s: nh blackhole %d",
__func__, api_nh->bh_type);
- nexthop = nexthop_from_blackhole(api_nh->bh_type);
+ nexthop =
+ nexthop_from_blackhole(api_nh->bh_type, api_nh->vrf_id);
break;
}
@@ -1937,6 +1956,11 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS)
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
"%s: Nexthop Group Creation failed", __func__);
+
+ /* Free any local allocations */
+ nexthop_group_delete(&nhg);
+ zebra_nhg_backup_free(&bnhg);
+
return;
}
@@ -2110,6 +2134,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
ret = rib_add_multipath_nhe(afi, api.safi, &api.prefix, src_p,
re, &nhe);
+ /*
+ * rib_add_multipath_nhe only fails in a couple spots
+ * and in those spots we have not freed memory
+ */
+ if (ret == -1) {
+ client->error_cnt++;
+ XFREE(MTYPE_RE, re);
+ }
+
/* At this point, these allocations are not needed: 're' has been
* retained or freed, and if 're' still exists, it is using
* a reference to a shared group object.
@@ -2121,15 +2154,15 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
/* Stats */
switch (api.prefix.family) {
case AF_INET:
- if (ret > 0)
+ if (ret == 0)
client->v4_route_add_cnt++;
- else if (ret < 0)
+ else if (ret == 1)
client->v4_route_upd8_cnt++;
break;
case AF_INET6:
- if (ret > 0)
+ if (ret == 0)
client->v6_route_add_cnt++;
- else if (ret < 0)
+ else if (ret == 1)
client->v6_route_upd8_cnt++;
break;
}
@@ -2205,8 +2238,8 @@ stream_failure:
static void zread_router_id_add(ZAPI_HANDLER_ARGS)
{
afi_t afi;
-
struct prefix p;
+ struct prefix zero;
STREAM_GETW(msg, afi);
@@ -2222,6 +2255,18 @@ static void zread_router_id_add(ZAPI_HANDLER_ARGS)
router_id_get(afi, &p, zvrf);
+ /*
+ * If we have not officially setup a router-id let's not
+ * tell the upper level protocol about it yet.
+ */
+ memset(&zero, 0, sizeof(zero));
+ if ((p.family == AF_INET && p.u.prefix4.s_addr == INADDR_ANY)
+ || (p.family == AF_INET6
+ && memcmp(&p.u.prefix6, &zero.u.prefix6,
+ sizeof(struct in6_addr))
+ == 0))
+ return;
+
zsend_router_id_update(client, afi, &p, zvrf_id(zvrf));
stream_failure:
@@ -2799,7 +2844,7 @@ static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
}
static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
- vrf_id_t vrf_id)
+ struct zebra_vrf *zvrf)
{
struct stream *s;
uint32_t size;
@@ -2811,7 +2856,7 @@ static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
/* Get data. */
STREAM_GETL(s, size);
- tmc = assign_table_chunk(client->proto, client->instance, size);
+ tmc = assign_table_chunk(client->proto, client->instance, size, zvrf);
if (!tmc)
flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
"%s: Unable to assign Table Chunk of size %u",
@@ -2820,13 +2865,14 @@ static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
tmc->end);
/* send response back */
- zsend_assign_table_chunk_response(client, vrf_id, tmc);
+ zsend_assign_table_chunk_response(client, zvrf_id(zvrf), tmc);
stream_failure:
return;
}
-static void zread_release_table_chunk(struct zserv *client, struct stream *msg)
+static void zread_release_table_chunk(struct zserv *client, struct stream *msg,
+ struct zebra_vrf *zvrf)
{
struct stream *s;
uint32_t start, end;
@@ -2838,7 +2884,7 @@ static void zread_release_table_chunk(struct zserv *client, struct stream *msg)
STREAM_GETL(s, start);
STREAM_GETL(s, end);
- release_table_chunk(client->proto, client->instance, start, end);
+ release_table_chunk(client->proto, client->instance, start, end, zvrf);
stream_failure:
return;
@@ -2858,9 +2904,9 @@ static void zread_table_manager_request(ZAPI_HANDLER_ARGS)
return;
}
if (hdr->command == ZEBRA_GET_TABLE_CHUNK)
- zread_get_table_chunk(client, msg, zvrf_id(zvrf));
+ zread_get_table_chunk(client, msg, zvrf);
else if (hdr->command == ZEBRA_RELEASE_TABLE_CHUNK)
- zread_release_table_chunk(client, msg);
+ zread_release_table_chunk(client, msg, zvrf);
}
}
@@ -3107,6 +3153,8 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS)
}
zvrf->label[afi] = nlabel;
+ zvrf->label_proto[afi] = client->proto;
+
stream_failure:
return;
}
@@ -3129,6 +3177,7 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
STREAM_GETL(s, zpr.rule.seq);
STREAM_GETL(s, zpr.rule.priority);
STREAM_GETL(s, zpr.rule.unique);
+ STREAM_GETC(s, zpr.rule.filter.ip_proto);
STREAM_GETC(s, zpr.rule.filter.src_ip.family);
STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
@@ -3141,6 +3190,12 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
STREAM_GETW(s, zpr.rule.filter.dst_port);
STREAM_GETC(s, zpr.rule.filter.dsfield);
STREAM_GETL(s, zpr.rule.filter.fwmark);
+
+ STREAM_GETL(s, zpr.rule.action.queue_id);
+ STREAM_GETW(s, zpr.rule.action.vlan_id);
+ STREAM_GETW(s, zpr.rule.action.vlan_flags);
+ STREAM_GETW(s, zpr.rule.action.pcp);
+
STREAM_GETL(s, zpr.rule.action.table);
STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
@@ -3162,6 +3217,9 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
if (zpr.rule.filter.dsfield)
zpr.rule.filter.filter_bm |= PBR_FILTER_DSFIELD;
+ if (zpr.rule.filter.ip_proto)
+ zpr.rule.filter.filter_bm |= PBR_FILTER_IP_PROTOCOL;
+
if (zpr.rule.filter.fwmark)
zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
@@ -3382,6 +3440,7 @@ static inline void zebra_gre_get(ZAPI_HANDLER_ARGS)
stream_putl(s, IFINDEX_INTERNAL);
stream_putl(s, VRF_UNKNOWN);
stream_putl(s, 0);
+ stream_putl(s, 0);
}
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
@@ -3622,8 +3681,6 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_HELLO] = zread_hello,
[ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
[ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,
- [ZEBRA_IMPORT_ROUTE_REGISTER] = zread_rnh_register,
- [ZEBRA_IMPORT_ROUTE_UNREGISTER] = zread_rnh_unregister,
[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,
@@ -3653,8 +3710,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
[ZEBRA_REMOTE_ES_VTEP_ADD] = zebra_evpn_proc_remote_es,
[ZEBRA_REMOTE_ES_VTEP_DEL] = zebra_evpn_proc_remote_es,
- [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add,
- [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del,
+ [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add_zapi,
+ [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del_zapi,
[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,