diff options
Diffstat (limited to 'zebra/zapi_msg.c')
| -rw-r--r-- | zebra/zapi_msg.c | 179 |
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, |
