Coverage Report

Created: 2026-04-09 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/zebra/zapi_msg.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Zebra API message creation & consumption.
4
 * Portions:
5
 *   Copyright (C) 1997-1999  Kunihiro Ishiguro
6
 *   Copyright (C) 2015-2018  Cumulus Networks, Inc.
7
 *   et al.
8
 */
9
10
#include <zebra.h>
11
#include <libgen.h>
12
13
#include "lib/prefix.h"
14
#include "lib/stream.h"
15
#include "lib/memory.h"
16
#include "lib/table.h"
17
#include "lib/network.h"
18
#include "lib/log.h"
19
#include "lib/zclient.h"
20
#include "lib/privs.h"
21
#include "lib/nexthop.h"
22
#include "lib/vrf.h"
23
#include "lib/libfrr.h"
24
#include "lib/lib_errors.h"
25
26
#include "zebra/zebra_router.h"
27
#include "zebra/rib.h"
28
#include "zebra/zebra_ns.h"
29
#include "zebra/zebra_vrf.h"
30
#include "zebra/router-id.h"
31
#include "zebra/redistribute.h"
32
#include "zebra/debug.h"
33
#include "zebra/zebra_rnh.h"
34
#include "zebra/interface.h"
35
#include "zebra/zebra_ptm.h"
36
#include "zebra/rtadv.h"
37
#include "zebra/zebra_mpls.h"
38
#include "zebra/zebra_mroute.h"
39
#include "zebra/zebra_vxlan.h"
40
#include "zebra/zebra_evpn_mh.h"
41
#include "zebra/rt.h"
42
#include "zebra/zebra_pbr.h"
43
#include "zebra/zebra_tc.h"
44
#include "zebra/table_manager.h"
45
#include "zebra/zapi_msg.h"
46
#include "zebra/zebra_errors.h"
47
#include "zebra/zebra_mlag.h"
48
#include "zebra/connected.h"
49
#include "zebra/zebra_opaque.h"
50
#include "zebra/zebra_srte.h"
51
#include "zebra/zebra_srv6.h"
52
53
2
DEFINE_MTYPE_STATIC(ZEBRA, RE_OPAQUE, "Route Opaque Data");
54
2
55
2
static int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
56
2
57
2
/* Encoding helpers -------------------------------------------------------- */
58
2
59
2
static void zserv_encode_interface(struct stream *s, struct interface *ifp)
60
2
{
61
  /* Interface information. */
62
0
  struct zebra_if *zif = ifp->info;
63
64
0
  stream_put(s, ifp->name, INTERFACE_NAMSIZ);
65
0
  stream_putl(s, ifp->ifindex);
66
0
  stream_putc(s, ifp->status);
67
0
  stream_putq(s, ifp->flags);
68
0
  stream_putc(s, ifp->ptm_enable);
69
0
  stream_putc(s, ifp->ptm_status);
70
0
  stream_putl(s, ifp->metric);
71
0
  stream_putl(s, ifp->speed);
72
0
  stream_putl(s, ifp->mtu);
73
0
  stream_putl(s, ifp->mtu6);
74
0
  stream_putl(s, ifp->bandwidth);
75
0
  stream_putl(s, zif->link_ifindex);
76
0
  stream_putl(s, ifp->ll_type);
77
0
  stream_putl(s, ifp->hw_addr_len);
78
0
  if (ifp->hw_addr_len)
79
0
    stream_put(s, ifp->hw_addr, ifp->hw_addr_len);
80
81
  /* Then, Traffic Engineering parameters if any */
82
0
  if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) {
83
0
    stream_putc(s, 1);
84
0
    zebra_interface_link_params_write(s, ifp);
85
0
  } else
86
0
    stream_putc(s, 0);
87
88
  /* Write packet size. */
89
0
  stream_putw_at(s, 0, stream_get_endp(s));
90
0
}
91
92
static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf)
93
0
{
94
0
  struct vrf_data data;
95
0
  const char *netns_name = zvrf_ns_name(zvrf);
96
97
0
  memset(&data, 0, sizeof(data));
98
0
  data.l.table_id = zvrf->table_id;
99
100
0
  if (netns_name)
101
0
    strlcpy(data.l.netns_name, basename((char *)netns_name),
102
0
      NS_NAMSIZ);
103
0
  else
104
0
    memset(data.l.netns_name, 0, NS_NAMSIZ);
105
  /* Pass the tableid and the netns NAME */
106
0
  stream_put(s, &data, sizeof(struct vrf_data));
107
  /* Interface information. */
108
0
  stream_put(s, zvrf_name(zvrf), VRF_NAMSIZ);
109
  /* Write packet size. */
110
0
  stream_putw_at(s, 0, stream_get_endp(s));
111
0
}
112
113
static int zserv_encode_nexthop(struct stream *s, struct nexthop *nexthop)
114
0
{
115
0
  stream_putl(s, nexthop->vrf_id);
116
0
  stream_putc(s, nexthop->type);
117
0
  switch (nexthop->type) {
118
0
  case NEXTHOP_TYPE_IPV4:
119
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
120
0
    stream_put_in_addr(s, &nexthop->gate.ipv4);
121
0
    stream_putl(s, nexthop->ifindex);
122
0
    break;
123
0
  case NEXTHOP_TYPE_IPV6:
124
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
125
0
    stream_put(s, &nexthop->gate.ipv6, 16);
126
0
    stream_putl(s, nexthop->ifindex);
127
0
    break;
128
0
  case NEXTHOP_TYPE_IFINDEX:
129
0
    stream_putl(s, nexthop->ifindex);
130
0
    break;
131
0
  case NEXTHOP_TYPE_BLACKHOLE:
132
    /* do nothing */
133
0
    break;
134
0
  }
135
0
  return 1;
136
0
}
137
138
/*
139
 * Zebra error addition adds error type.
140
 *
141
 *
142
 *  0                   1
143
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
144
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145
 * |      enum zebra_error_types   |
146
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147
 *
148
 */
149
static void zserv_encode_error(struct stream *s, enum zebra_error_types error)
150
0
{
151
0
  stream_put(s, &error, sizeof(error));
152
153
  /* Write packet size. */
154
0
  stream_putw_at(s, 0, stream_get_endp(s));
155
0
}
156
157
/* Send handlers ----------------------------------------------------------- */
158
159
/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
160
/*
161
 * This function is called in the following situations:
162
 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
163
 *   from the client.
164
 * - at startup, when zebra figures out the available interfaces
165
 * - when an interface is added (where support for
166
 *   RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
167
 *   an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
168
 *   received)
169
 */
170
int zsend_interface_add(struct zserv *client, struct interface *ifp)
171
0
{
172
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
173
174
0
  zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf->vrf_id);
175
0
  zserv_encode_interface(s, ifp);
176
177
0
  client->ifadd_cnt++;
178
0
  return zserv_send_message(client, s);
179
0
}
180
181
/* Interface deletion from zebra daemon. */
182
int zsend_interface_delete(struct zserv *client, struct interface *ifp)
183
0
{
184
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
185
186
0
  zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf->vrf_id);
187
0
  zserv_encode_interface(s, ifp);
188
189
0
  client->ifdel_cnt++;
190
0
  return zserv_send_message(client, s);
191
0
}
192
193
int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
194
0
{
195
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
196
197
0
  zclient_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf));
198
0
  zserv_encode_vrf(s, zvrf);
199
200
0
  client->vrfadd_cnt++;
201
0
  return zserv_send_message(client, s);
202
0
}
203
204
/* VRF deletion from zebra daemon. */
205
int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)
206
207
0
{
208
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
209
210
0
  zclient_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf));
211
0
  zserv_encode_vrf(s, zvrf);
212
213
0
  client->vrfdel_cnt++;
214
0
  return zserv_send_message(client, s);
215
0
}
216
217
int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
218
0
{
219
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
220
221
0
  zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf->vrf_id);
222
223
  /* Add Interface Index */
224
0
  stream_putl(s, ifp->ifindex);
225
226
  /* Then TE Link Parameters */
227
0
  if (zebra_interface_link_params_write(s, ifp) == 0) {
228
0
    stream_free(s);
229
0
    return 0;
230
0
  }
231
232
  /* Write packet size. */
233
0
  stream_putw_at(s, 0, stream_get_endp(s));
234
235
0
  return zserv_send_message(client, s);
236
0
}
237
238
/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
239
 * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
240
 *
241
 * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:
242
 * - in response to a 3-byte ZEBRA_INTERFACE_ADD request
243
 *   from the client, after the ZEBRA_INTERFACE_ADD has been
244
 *   sent from zebra to the client
245
 * - redistribute new address info to all clients in the following situations
246
 *    - at startup, when zebra figures out the available interfaces
247
 *    - when an interface is added (where support for
248
 *      RTM_IFANNOUNCE or AF_NETLINK sockets is available), or when
249
 *      an interface is marked IFF_UP (i.e., an RTM_IFINFO message is
250
 *      received)
251
 *    - for the vty commands "ip address A.B.C.D/M [<label LINE>]"
252
 *      and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"
253
 *    - when an RTM_NEWADDR message is received from the kernel,
254
 *
255
 * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:
256
 *
257
 *                   zsend_interface_address(DELETE)
258
 *                           ^
259
 *                           |
260
 *          zebra_interface_address_delete_update
261
 *             ^                        ^      ^
262
 *             |                        |      if_delete_update
263
 *             |                        |
264
 *         ip_address_uninstall        connected_delete_ipv4
265
 *         [ipv6_addresss_uninstall]   [connected_delete_ipv6]
266
 *             ^                        ^
267
 *             |                        |
268
 *             |                  RTM_NEWADDR on routing/netlink socket
269
 *             |
270
 *         vty commands:
271
 *     "no ip address A.B.C.D/M [label LINE]"
272
 *     "no ip address A.B.C.D/M"
273
 *     ["no ipv6 address X:X::X:X/M"]
274
 *
275
 */
276
int zsend_interface_address(int cmd, struct zserv *client,
277
          struct interface *ifp, struct connected *ifc)
278
0
{
279
0
  int blen;
280
0
  struct prefix *p;
281
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
282
283
0
  zclient_create_header(s, cmd, ifp->vrf->vrf_id);
284
0
  stream_putl(s, ifp->ifindex);
285
286
  /* Interface address flag. */
287
0
  stream_putc(s, ifc->flags);
288
289
  /* Prefix information. */
290
0
  p = ifc->address;
291
0
  stream_putc(s, p->family);
292
0
  blen = prefix_blen(p);
293
0
  stream_put(s, &p->u.prefix, blen);
294
295
  /*
296
   * XXX gnu version does not send prefixlen for
297
   * ZEBRA_INTERFACE_ADDRESS_DELETE
298
   * but zebra_interface_address_delete_read() in the gnu version
299
   * expects to find it
300
   */
301
0
  stream_putc(s, p->prefixlen);
302
303
  /* Destination. */
304
0
  p = ifc->destination;
305
0
  if (p)
306
0
    stream_put(s, &p->u.prefix, blen);
307
0
  else
308
0
    stream_put(s, NULL, blen);
309
310
  /* Write packet size. */
311
0
  stream_putw_at(s, 0, stream_get_endp(s));
312
313
0
  client->connected_rt_add_cnt++;
314
0
  return zserv_send_message(client, s);
315
0
}
316
317
static int zsend_interface_nbr_address(int cmd, struct zserv *client,
318
               struct interface *ifp,
319
               struct nbr_connected *ifc)
320
0
{
321
0
  int blen;
322
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
323
0
  struct prefix *p;
324
325
0
  zclient_create_header(s, cmd, ifp->vrf->vrf_id);
326
0
  stream_putl(s, ifp->ifindex);
327
328
  /* Prefix information. */
329
0
  p = ifc->address;
330
0
  stream_putc(s, p->family);
331
0
  blen = prefix_blen(p);
332
0
  stream_put(s, &p->u.prefix, blen);
333
334
  /*
335
   * XXX gnu version does not send prefixlen for
336
   * ZEBRA_INTERFACE_ADDRESS_DELETE
337
   * but zebra_interface_address_delete_read() in the gnu version
338
   * expects to find it
339
   */
340
0
  stream_putc(s, p->prefixlen);
341
342
  /* Write packet size. */
343
0
  stream_putw_at(s, 0, stream_get_endp(s));
344
345
0
  return zserv_send_message(client, s);
346
0
}
347
348
/* Interface address addition. */
349
static void zebra_interface_nbr_address_add_update(struct interface *ifp,
350
               struct nbr_connected *ifc)
351
0
{
352
0
  struct listnode *node, *nnode;
353
0
  struct zserv *client;
354
0
  struct prefix *p;
355
356
0
  if (IS_ZEBRA_DEBUG_EVENT) {
357
0
    char buf[INET6_ADDRSTRLEN];
358
359
0
    p = ifc->address;
360
0
    zlog_debug(
361
0
      "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s",
362
0
      inet_ntop(p->family, &p->u.prefix, buf,
363
0
          INET6_ADDRSTRLEN),
364
0
      p->prefixlen, ifc->ifp->name);
365
0
  }
366
367
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
368
    /* Do not send unsolicited messages to synchronous clients. */
369
0
    if (client->synchronous)
370
0
      continue;
371
372
0
    zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
373
0
              client, ifp, ifc);
374
0
  }
375
0
}
376
377
/* Interface address deletion. */
378
static void zebra_interface_nbr_address_delete_update(struct interface *ifp,
379
                  struct nbr_connected *ifc)
380
0
{
381
0
  struct listnode *node, *nnode;
382
0
  struct zserv *client;
383
0
  struct prefix *p;
384
385
0
  if (IS_ZEBRA_DEBUG_EVENT) {
386
0
    char buf[INET6_ADDRSTRLEN];
387
388
0
    p = ifc->address;
389
0
    zlog_debug(
390
0
      "MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s",
391
0
      inet_ntop(p->family, &p->u.prefix, buf,
392
0
          INET6_ADDRSTRLEN),
393
0
      p->prefixlen, ifc->ifp->name);
394
0
  }
395
396
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
397
    /* Do not send unsolicited messages to synchronous clients. */
398
0
    if (client->synchronous)
399
0
      continue;
400
401
0
    zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE,
402
0
              client, ifp, ifc);
403
0
  }
404
0
}
405
406
/* Send addresses on interface to client */
407
int zsend_interface_addresses(struct zserv *client, struct interface *ifp)
408
0
{
409
0
  struct listnode *cnode, *cnnode;
410
0
  struct connected *c;
411
0
  struct nbr_connected *nc;
412
413
  /* Send interface addresses. */
414
0
  for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
415
0
    if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL))
416
0
      continue;
417
418
0
    if (zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, client,
419
0
              ifp, c)
420
0
        < 0)
421
0
      return -1;
422
0
  }
423
424
  /* Send interface neighbors. */
425
0
  for (ALL_LIST_ELEMENTS(ifp->nbr_connected, cnode, cnnode, nc)) {
426
0
    if (zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
427
0
            client, ifp, nc)
428
0
        < 0)
429
0
      return -1;
430
0
  }
431
432
0
  return 0;
433
0
}
434
435
/* Notify client about interface moving from one VRF to another.
436
 * Whether client is interested in old and new VRF is checked by caller.
437
 */
438
int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp,
439
             vrf_id_t vrf_id)
440
0
{
441
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
442
443
0
  zclient_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf->vrf_id);
444
445
  /* Fill in the name of the interface and its new VRF (id) */
446
0
  stream_put(s, ifp->name, INTERFACE_NAMSIZ);
447
0
  stream_putl(s, vrf_id);
448
449
  /* Write packet size. */
450
0
  stream_putw_at(s, 0, stream_get_endp(s));
451
452
0
  client->if_vrfchg_cnt++;
453
0
  return zserv_send_message(client, s);
454
0
}
455
456
/* Add new nbr connected IPv6 address */
457
void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address)
458
0
{
459
0
  struct nbr_connected *ifc;
460
0
  struct prefix p;
461
462
0
  p.family = AF_INET6;
463
0
  IPV6_ADDR_COPY(&p.u.prefix6, address);
464
0
  p.prefixlen = IPV6_MAX_BITLEN;
465
466
0
  ifc = listnode_head(ifp->nbr_connected);
467
0
  if (!ifc) {
468
    /* new addition */
469
0
    ifc = nbr_connected_new();
470
0
    ifc->address = prefix_new();
471
0
    ifc->ifp = ifp;
472
0
    listnode_add(ifp->nbr_connected, ifc);
473
0
  }
474
475
0
  prefix_copy(ifc->address, &p);
476
477
0
  zebra_interface_nbr_address_add_update(ifp, ifc);
478
479
0
  if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 1);
480
0
}
481
482
void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address)
483
0
{
484
0
  struct nbr_connected *ifc;
485
0
  struct prefix p;
486
487
0
  p.family = AF_INET6;
488
0
  IPV6_ADDR_COPY(&p.u.prefix6, address);
489
0
  p.prefixlen = IPV6_MAX_BITLEN;
490
491
0
  ifc = nbr_connected_check(ifp, &p);
492
0
  if (!ifc)
493
0
    return;
494
495
0
  listnode_delete(ifp->nbr_connected, ifc);
496
497
0
  zebra_interface_nbr_address_delete_update(ifp, ifc);
498
499
0
  if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 0);
500
501
0
  nbr_connected_free(ifc);
502
0
}
503
504
/*
505
 * The cmd passed to zsend_interface_update  may be ZEBRA_INTERFACE_UP or
506
 * ZEBRA_INTERFACE_DOWN.
507
 *
508
 * The ZEBRA_INTERFACE_UP message is sent from the zebra server to
509
 * the clients in one of 2 situations:
510
 *   - an if_up is detected e.g., as a result of an RTM_IFINFO message
511
 *   - a vty command modifying the bandwidth of an interface is received.
512
 * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.
513
 */
514
int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)
515
0
{
516
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
517
518
0
  zclient_create_header(s, cmd, ifp->vrf->vrf_id);
519
0
  zserv_encode_interface(s, ifp);
520
521
0
  if (cmd == ZEBRA_INTERFACE_UP)
522
0
    client->ifup_cnt++;
523
0
  else
524
0
    client->ifdown_cnt++;
525
526
0
  return zserv_send_message(client, s);
527
0
}
528
529
int zsend_redistribute_route(int cmd, struct zserv *client,
530
           const struct route_node *rn,
531
           const struct route_entry *re)
532
0
{
533
0
  struct zapi_route api;
534
0
  struct zapi_nexthop *api_nh;
535
0
  struct nexthop *nexthop;
536
0
  const struct prefix *p, *src_p;
537
0
  uint8_t count = 0;
538
0
  afi_t afi;
539
0
  size_t stream_size =
540
0
    MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
541
542
0
  srcdest_rnode_prefixes(rn, &p, &src_p);
543
0
  memset(&api, 0, sizeof(api));
544
0
  api.vrf_id = re->vrf_id;
545
0
  api.type = re->type;
546
0
  api.safi = SAFI_UNICAST;
547
0
  api.instance = re->instance;
548
0
  api.flags = re->flags;
549
550
0
  afi = family2afi(p->family);
551
0
  switch (afi) {
552
0
  case AFI_IP:
553
0
    if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
554
0
      client->redist_v4_add_cnt++;
555
0
    else
556
0
      client->redist_v4_del_cnt++;
557
0
    break;
558
0
  case AFI_IP6:
559
0
    if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
560
0
      client->redist_v6_add_cnt++;
561
0
    else
562
0
      client->redist_v6_del_cnt++;
563
0
    break;
564
0
  case AFI_L2VPN:
565
0
  case AFI_MAX:
566
0
  case AFI_UNSPEC:
567
0
    break;
568
0
  }
569
570
  /* Prefix. */
571
0
  api.prefix = *p;
572
0
  if (src_p) {
573
0
    SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
574
0
    memcpy(&api.src_prefix, src_p, sizeof(api.src_prefix));
575
0
  }
576
577
0
  for (nexthop = re->nhe->nhg.nexthop;
578
0
       nexthop; nexthop = nexthop->next) {
579
0
    if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
580
0
      continue;
581
582
0
    api_nh = &api.nexthops[count];
583
0
    api_nh->vrf_id = nexthop->vrf_id;
584
0
    api_nh->type = nexthop->type;
585
0
    api_nh->weight = nexthop->weight;
586
0
    switch (nexthop->type) {
587
0
    case NEXTHOP_TYPE_BLACKHOLE:
588
0
      api_nh->bh_type = nexthop->bh_type;
589
0
      break;
590
0
    case NEXTHOP_TYPE_IPV4:
591
0
    case NEXTHOP_TYPE_IPV4_IFINDEX:
592
0
      api_nh->gate.ipv4 = nexthop->gate.ipv4;
593
0
      api_nh->ifindex = nexthop->ifindex;
594
0
      break;
595
0
    case NEXTHOP_TYPE_IFINDEX:
596
0
      api_nh->ifindex = nexthop->ifindex;
597
0
      break;
598
0
    case NEXTHOP_TYPE_IPV6:
599
0
    case NEXTHOP_TYPE_IPV6_IFINDEX:
600
0
      api_nh->gate.ipv6 = nexthop->gate.ipv6;
601
0
      api_nh->ifindex = nexthop->ifindex;
602
0
    }
603
0
    count++;
604
0
  }
605
606
  /* Nexthops. */
607
0
  if (count) {
608
0
    SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
609
0
    api.nexthop_num = count;
610
0
  }
611
612
  /* Attributes. */
613
0
  SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
614
0
  api.distance = re->distance;
615
0
  SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
616
0
  api.metric = re->metric;
617
0
  if (re->tag) {
618
0
    SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
619
0
    api.tag = re->tag;
620
0
  }
621
0
  SET_FLAG(api.message, ZAPI_MESSAGE_MTU);
622
0
  api.mtu = re->mtu;
623
624
0
  struct stream *s = stream_new(stream_size);
625
626
  /* Encode route and send. */
627
0
  if (zapi_route_encode(cmd, s, &api) < 0) {
628
0
    stream_free(s);
629
0
    return -1;
630
0
  }
631
632
0
  if (IS_ZEBRA_DEBUG_SEND)
633
0
    zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %pFX",
634
0
         __func__, zserv_command_string(cmd),
635
0
         zebra_route_string(client->proto),
636
0
         zebra_route_string(api.type), api.vrf_id,
637
0
         &api.prefix);
638
0
  return zserv_send_message(client, s);
639
0
}
640
641
/*
642
 * Modified version of zsend_ipv4_nexthop_lookup(): Query unicast rib if
643
 * nexthop is not found on mrib. Returns both route metric and protocol
644
 * distance.
645
 *
646
 * *XXX* this ZAPI call is slated to be removed at some point in the future
647
 * since MRIB support in PIM is hopelessly broken in its interactions with NHT.
648
 * The plan is to make pimd use NHT to receive URIB and MRIB in parallel and
649
 * make the decision there, which will obsolete this ZAPI op.
650
 * (Otherwise we would need to implement sending NHT updates for the result of
651
 * this "URIB-MRIB-combined" table, but we only decide that here on the fly,
652
 * so it'd be rather complex to do NHT for.)
653
 */
654
static int zsend_nexthop_lookup_mrib(struct zserv *client, struct ipaddr *addr,
655
             struct route_entry *re,
656
             struct zebra_vrf *zvrf)
657
3
{
658
3
  struct stream *s;
659
3
  unsigned long nump;
660
3
  uint8_t num;
661
3
  struct nexthop *nexthop;
662
663
  /* Get output stream. */
664
3
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
665
3
  stream_reset(s);
666
667
  /* Fill in result. */
668
3
  zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf));
669
3
  stream_put_ipaddr(s, addr);
670
671
3
  if (re) {
672
0
    struct nexthop_group *nhg;
673
674
0
    stream_putc(s, re->distance);
675
0
    stream_putl(s, re->metric);
676
0
    num = 0;
677
    /* remember position for nexthop_num */
678
0
    nump = stream_get_endp(s);
679
    /* reserve room for nexthop_num */
680
0
    stream_putc(s, 0);
681
0
    nhg = rib_get_fib_nhg(re);
682
0
    for (ALL_NEXTHOPS_PTR(nhg, nexthop)) {
683
0
      if (rnh_nexthop_valid(re, nexthop))
684
0
        num += zserv_encode_nexthop(s, nexthop);
685
0
    }
686
687
    /* store nexthop_num */
688
0
    stream_putc_at(s, nump, num);
689
3
  } else {
690
3
    stream_putc(s, 0); /* distance */
691
3
    stream_putl(s, 0); /* metric */
692
3
    stream_putc(s, 0); /* nexthop_num */
693
3
  }
694
695
3
  stream_putw_at(s, 0, stream_get_endp(s));
696
697
3
  return zserv_send_message(client, s);
698
3
}
699
700
int zsend_nhg_notify(uint16_t type, uint16_t instance, uint32_t session_id,
701
         uint32_t id, enum zapi_nhg_notify_owner note)
702
0
{
703
0
  struct zserv *client;
704
0
  struct stream *s;
705
706
0
  client = zserv_find_client_session(type, instance, session_id);
707
0
  if (!client) {
708
0
    if (IS_ZEBRA_DEBUG_PACKET) {
709
0
      zlog_debug("Not Notifying Owner: %u(%u) about %u(%d)",
710
0
           type, instance, id, note);
711
0
    }
712
0
    return 0;
713
0
  }
714
715
0
  if (IS_ZEBRA_DEBUG_SEND)
716
0
    zlog_debug("%s: type %d, id %d, note %s",
717
0
         __func__, type, id, zapi_nhg_notify_owner2str(note));
718
719
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
720
0
  stream_reset(s);
721
722
0
  zclient_create_header(s, ZEBRA_NHG_NOTIFY_OWNER, VRF_DEFAULT);
723
724
0
  stream_put(s, &note, sizeof(note));
725
0
  stream_putl(s, id);
726
727
0
  stream_putw_at(s, 0, stream_get_endp(s));
728
729
0
  return zserv_send_message(client, s);
730
0
}
731
732
/*
733
 * Common utility send route notification, called from a path using a
734
 * route_entry and from a path using a dataplane context.
735
 */
736
static int route_notify_internal(const struct route_node *rn, int type,
737
         uint16_t instance, vrf_id_t vrf_id,
738
         uint32_t table_id,
739
         enum zapi_route_notify_owner note, afi_t afi,
740
         safi_t safi)
741
0
{
742
0
  struct zserv *client;
743
0
  struct stream *s;
744
0
  uint8_t blen;
745
746
0
  client = zserv_find_client(type, instance);
747
0
  if (!client || !client->notify_owner) {
748
0
    if (IS_ZEBRA_DEBUG_PACKET)
749
0
      zlog_debug(
750
0
        "Not Notifying Owner: %s about prefix %pRN(%u) %d vrf: %u",
751
0
        zebra_route_string(type), rn, table_id, note,
752
0
        vrf_id);
753
0
    return 0;
754
0
  }
755
756
0
  if (IS_ZEBRA_DEBUG_PACKET)
757
0
    zlog_debug(
758
0
      "Notifying Owner: %s about prefix %pRN(%u) %d vrf: %u",
759
0
      zebra_route_string(type), rn, table_id, note, vrf_id);
760
761
  /* We're just allocating a small-ish buffer here, since we only
762
   * encode a small amount of data.
763
   */
764
0
  s = stream_new(ZEBRA_SMALL_PACKET_SIZE);
765
766
0
  stream_reset(s);
767
768
0
  zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
769
770
0
  stream_put(s, &note, sizeof(note));
771
772
0
  stream_putc(s, rn->p.family);
773
774
0
  blen = prefix_blen(&rn->p);
775
0
  stream_putc(s, rn->p.prefixlen);
776
0
  stream_put(s, &rn->p.u.prefix, blen);
777
778
0
  stream_putl(s, table_id);
779
780
  /* Encode AFI, SAFI in the message */
781
0
  stream_putc(s, afi);
782
0
  stream_putc(s, safi);
783
784
0
  stream_putw_at(s, 0, stream_get_endp(s));
785
786
0
  return zserv_send_message(client, s);
787
0
}
788
789
int zsend_route_notify_owner(const struct route_node *rn,
790
           struct route_entry *re,
791
           enum zapi_route_notify_owner note, afi_t afi,
792
           safi_t safi)
793
0
{
794
0
  return (route_notify_internal(rn, re->type, re->instance, re->vrf_id,
795
0
              re->table, note, afi, safi));
796
0
}
797
798
/*
799
 * Route-owner notification using info from dataplane update context.
800
 */
801
int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx,
802
         enum zapi_route_notify_owner note)
803
0
{
804
0
  int result;
805
0
  struct route_node *rn = rib_find_rn_from_ctx(ctx);
806
807
0
  result = route_notify_internal(
808
0
    rn, dplane_ctx_get_type(ctx), dplane_ctx_get_instance(ctx),
809
0
    dplane_ctx_get_vrf(ctx), dplane_ctx_get_table(ctx), note,
810
0
    dplane_ctx_get_afi(ctx), dplane_ctx_get_safi(ctx));
811
812
0
  route_unlock_node(rn);
813
814
0
  return result;
815
0
}
816
817
static void zread_route_notify_request(ZAPI_HANDLER_ARGS)
818
0
{
819
0
  uint8_t notify;
820
821
0
  STREAM_GETC(msg, notify);
822
0
  client->notify_owner = notify;
823
0
stream_failure:
824
0
  return;
825
0
}
826
827
void zsend_rule_notify_owner(const struct zebra_dplane_ctx *ctx,
828
           enum zapi_rule_notify_owner note)
829
0
{
830
0
  struct listnode *node;
831
0
  struct zserv *client;
832
0
  struct stream *s;
833
834
0
  if (IS_ZEBRA_DEBUG_PACKET)
835
0
    zlog_debug("%s: Notifying %u", __func__,
836
0
         dplane_ctx_rule_get_unique(ctx));
837
838
0
  for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
839
0
    if (dplane_ctx_rule_get_sock(ctx) == client->sock)
840
0
      break;
841
0
  }
842
843
0
  if (!client)
844
0
    return;
845
846
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
847
848
0
  zclient_create_header(s, ZEBRA_RULE_NOTIFY_OWNER, VRF_DEFAULT);
849
0
  stream_put(s, &note, sizeof(note));
850
0
  stream_putl(s, dplane_ctx_rule_get_seq(ctx));
851
0
  stream_putl(s, dplane_ctx_rule_get_priority(ctx));
852
0
  stream_putl(s, dplane_ctx_rule_get_unique(ctx));
853
0
  stream_put(s, dplane_ctx_rule_get_ifname(ctx), INTERFACE_NAMSIZ);
854
855
0
  stream_putw_at(s, 0, stream_get_endp(s));
856
857
0
  zserv_send_message(client, s);
858
0
}
859
860
void zsend_iptable_notify_owner(const struct zebra_dplane_ctx *ctx,
861
        enum zapi_iptable_notify_owner note)
862
0
{
863
0
  struct listnode *node;
864
0
  struct zserv *client;
865
0
  struct stream *s;
866
0
  struct zebra_pbr_iptable ipt;
867
0
  uint16_t cmd = ZEBRA_IPTABLE_NOTIFY_OWNER;
868
0
  struct zebra_pbr_iptable *ipt_hash;
869
0
  enum dplane_op_e op = dplane_ctx_get_op(ctx);
870
871
0
  dplane_ctx_get_pbr_iptable(ctx, &ipt);
872
873
0
  ipt_hash = hash_lookup(zrouter.iptable_hash, &ipt);
874
0
  if (ipt_hash) {
875
0
    if (op == DPLANE_OP_IPTABLE_ADD &&
876
0
        CHECK_FLAG(ipt_hash->internal_flags,
877
0
             IPTABLE_INSTALL_QUEUED))
878
0
      UNSET_FLAG(ipt_hash->internal_flags,
879
0
           IPTABLE_INSTALL_QUEUED);
880
0
    else if (op == DPLANE_OP_IPTABLE_DELETE &&
881
0
       CHECK_FLAG(ipt_hash->internal_flags,
882
0
            IPTABLE_UNINSTALL_QUEUED))
883
0
      UNSET_FLAG(ipt_hash->internal_flags,
884
0
           IPTABLE_UNINSTALL_QUEUED);
885
0
  }
886
0
  if (IS_ZEBRA_DEBUG_PACKET)
887
0
    zlog_debug("%s: Notifying %s id %u note %u", __func__,
888
0
         zserv_command_string(cmd), ipt.unique, note);
889
890
0
  for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
891
0
    if (ipt.sock == client->sock)
892
0
      break;
893
0
  }
894
895
0
  if (!client)
896
0
    return;
897
898
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
899
900
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
901
0
  stream_putw(s, note);
902
0
  stream_putl(s, ipt.unique);
903
0
  stream_put(s, ipt.ipset_name, ZEBRA_IPSET_NAME_SIZE);
904
0
  stream_putw_at(s, 0, stream_get_endp(s));
905
906
0
  zserv_send_message(client, s);
907
0
}
908
909
void zsend_ipset_notify_owner(const struct zebra_dplane_ctx *ctx,
910
            enum zapi_ipset_notify_owner note)
911
0
{
912
0
  struct listnode *node;
913
0
  struct zserv *client;
914
0
  struct stream *s;
915
0
  struct zebra_pbr_ipset ipset;
916
0
  uint16_t cmd = ZEBRA_IPSET_NOTIFY_OWNER;
917
918
0
  dplane_ctx_get_pbr_ipset(ctx, &ipset);
919
920
0
  if (IS_ZEBRA_DEBUG_PACKET)
921
0
    zlog_debug("%s: Notifying %s id %u note %u", __func__,
922
0
         zserv_command_string(cmd), ipset.unique, note);
923
924
0
  for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
925
0
    if (ipset.sock == client->sock)
926
0
      break;
927
0
  }
928
929
0
  if (!client)
930
0
    return;
931
932
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
933
934
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
935
0
  stream_putw(s, note);
936
0
  stream_putl(s, ipset.unique);
937
0
  stream_put(s, ipset.ipset_name, ZEBRA_IPSET_NAME_SIZE);
938
0
  stream_putw_at(s, 0, stream_get_endp(s));
939
940
0
  zserv_send_message(client, s);
941
0
}
942
943
void zsend_ipset_entry_notify_owner(const struct zebra_dplane_ctx *ctx,
944
            enum zapi_ipset_entry_notify_owner note)
945
0
{
946
0
  struct listnode *node;
947
0
  struct zserv *client;
948
0
  struct stream *s;
949
0
  struct zebra_pbr_ipset_entry ipent;
950
0
  struct zebra_pbr_ipset ipset;
951
0
  uint16_t cmd = ZEBRA_IPSET_ENTRY_NOTIFY_OWNER;
952
953
0
  dplane_ctx_get_pbr_ipset_entry(ctx, &ipent);
954
0
  dplane_ctx_get_pbr_ipset(ctx, &ipset);
955
956
0
  if (IS_ZEBRA_DEBUG_PACKET)
957
0
    zlog_debug("%s: Notifying %s id %u note %u", __func__,
958
0
         zserv_command_string(cmd), ipent.unique, note);
959
960
0
  for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) {
961
0
    if (ipent.sock == client->sock)
962
0
      break;
963
0
  }
964
965
0
  if (!client)
966
0
    return;
967
968
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
969
970
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
971
0
  stream_putw(s, note);
972
0
  stream_putl(s, ipent.unique);
973
0
  stream_put(s, ipset.ipset_name, ZEBRA_IPSET_NAME_SIZE);
974
0
  stream_putw_at(s, 0, stream_get_endp(s));
975
976
0
  zserv_send_message(client, s);
977
0
}
978
979
void zsend_nhrp_neighbor_notify(int cmd, struct interface *ifp,
980
        struct ipaddr *ipaddr, int ndm_state,
981
        union sockunion *link_layer_ipv4)
982
0
{
983
0
  struct stream *s;
984
0
  struct listnode *node, *nnode;
985
0
  struct zserv *client;
986
0
  afi_t afi;
987
0
  union sockunion ip;
988
989
0
  if (IS_ZEBRA_DEBUG_PACKET)
990
0
    zlog_debug("%s: Notifying Neighbor entry (%u)", __func__, cmd);
991
992
0
  sockunion_family(&ip) = ipaddr_family(ipaddr);
993
0
  afi = family2afi(sockunion_family(&ip));
994
0
  memcpy((char *)sockunion_get_addr(&ip), &ipaddr->ip.addr,
995
0
         family2addrsize(sockunion_family(&ip)));
996
997
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
998
0
    if (!vrf_bitmap_check(client->nhrp_neighinfo[afi],
999
0
              ifp->vrf->vrf_id))
1000
0
      continue;
1001
1002
0
    s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1003
0
    zclient_neigh_ip_encode(s, cmd, &ip, link_layer_ipv4, ifp,
1004
0
          ndm_state);
1005
0
    stream_putw_at(s, 0, stream_get_endp(s));
1006
0
    zserv_send_message(client, s);
1007
0
  }
1008
0
}
1009
1010
1011
/* Router-id is updated. Send ZEBRA_ROUTER_ID_UPDATE to client. */
1012
int zsend_router_id_update(struct zserv *client, afi_t afi, struct prefix *p,
1013
         vrf_id_t vrf_id)
1014
0
{
1015
0
  int blen;
1016
0
  struct stream *s;
1017
1018
  /* Check this client need interface information. */
1019
0
  if (!vrf_bitmap_check(client->ridinfo[afi], vrf_id))
1020
0
    return 0;
1021
1022
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1023
1024
  /* Message type. */
1025
0
  zclient_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id);
1026
1027
  /* Prefix information. */
1028
0
  stream_putc(s, p->family);
1029
0
  blen = prefix_blen(p);
1030
0
  stream_put(s, &p->u.prefix, blen);
1031
0
  stream_putc(s, p->prefixlen);
1032
1033
  /* Write packet size. */
1034
0
  stream_putw_at(s, 0, stream_get_endp(s));
1035
1036
0
  return zserv_send_message(client, s);
1037
0
}
1038
1039
/*
1040
 * Function used by Zebra to send a PW status update to LDP daemon
1041
 */
1042
int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)
1043
0
{
1044
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1045
1046
0
  zclient_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id);
1047
0
  stream_write(s, pw->ifname, INTERFACE_NAMSIZ);
1048
0
  stream_putl(s, pw->ifindex);
1049
0
  stream_putl(s, pw->status);
1050
1051
  /* Put length at the first point of the stream. */
1052
0
  stream_putw_at(s, 0, stream_get_endp(s));
1053
1054
0
  return zserv_send_message(client, s);
1055
0
}
1056
1057
/* Send response to a get label chunk request to client */
1058
int zsend_assign_label_chunk_response(struct zserv *client, vrf_id_t vrf_id,
1059
              struct label_manager_chunk *lmc)
1060
0
{
1061
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1062
1063
0
  zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id);
1064
  /* proto */
1065
0
  stream_putc(s, client->proto);
1066
  /* instance */
1067
0
  stream_putw(s, client->instance);
1068
1069
0
  if (lmc) {
1070
    /* keep */
1071
0
    stream_putc(s, lmc->keep);
1072
    /* start and end labels */
1073
0
    stream_putl(s, lmc->start);
1074
0
    stream_putl(s, lmc->end);
1075
0
  }
1076
1077
  /* Write packet size. */
1078
0
  stream_putw_at(s, 0, stream_get_endp(s));
1079
1080
0
  return zserv_send_message(client, s);
1081
0
}
1082
1083
/* Send response to a label manager connect request to client */
1084
int zsend_label_manager_connect_response(struct zserv *client, vrf_id_t vrf_id,
1085
           unsigned short result)
1086
0
{
1087
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1088
1089
0
  zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id);
1090
1091
  /* proto */
1092
0
  stream_putc(s, client->proto);
1093
1094
  /* instance */
1095
0
  stream_putw(s, client->instance);
1096
1097
  /* result */
1098
0
  stream_putc(s, result);
1099
1100
  /* Write packet size. */
1101
0
  stream_putw_at(s, 0, stream_get_endp(s));
1102
1103
0
  return zserv_send_message(client, s);
1104
0
}
1105
1106
/* Send response to a get table chunk request to client */
1107
static int zsend_assign_table_chunk_response(struct zserv *client,
1108
               vrf_id_t vrf_id,
1109
               struct table_manager_chunk *tmc)
1110
0
{
1111
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1112
1113
0
  zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, vrf_id);
1114
1115
0
  if (tmc) {
1116
    /* start and end labels */
1117
0
    stream_putl(s, tmc->start);
1118
0
    stream_putl(s, tmc->end);
1119
0
  }
1120
1121
  /* Write packet size. */
1122
0
  stream_putw_at(s, 0, stream_get_endp(s));
1123
1124
0
  return zserv_send_message(client, s);
1125
0
}
1126
1127
static int zsend_table_manager_connect_response(struct zserv *client,
1128
            vrf_id_t vrf_id,
1129
            uint16_t result)
1130
0
{
1131
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1132
1133
0
  zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, vrf_id);
1134
1135
  /* result */
1136
0
  stream_putc(s, result);
1137
1138
0
  stream_putw_at(s, 0, stream_get_endp(s));
1139
1140
0
  return zserv_send_message(client, s);
1141
0
}
1142
1143
/* SRv6 locator add notification from zebra daemon. */
1144
int zsend_zebra_srv6_locator_add(struct zserv *client, struct srv6_locator *loc)
1145
0
{
1146
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1147
1148
0
  zclient_create_header(s, ZEBRA_SRV6_LOCATOR_ADD, VRF_DEFAULT);
1149
0
  zapi_srv6_locator_encode(s, loc);
1150
0
  stream_putw_at(s, 0, stream_get_endp(s));
1151
1152
0
  return zserv_send_message(client, s);
1153
0
}
1154
1155
/* SRv6 locator delete notification from zebra daemon. */
1156
int zsend_zebra_srv6_locator_delete(struct zserv *client,
1157
            struct srv6_locator *loc)
1158
0
{
1159
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
1160
1161
0
  zclient_create_header(s, ZEBRA_SRV6_LOCATOR_DELETE, VRF_DEFAULT);
1162
0
  zapi_srv6_locator_encode(s, loc);
1163
0
  stream_putw_at(s, 0, stream_get_endp(s));
1164
1165
0
  return zserv_send_message(client, s);
1166
0
}
1167
1168
/* Inbound message handling ------------------------------------------------ */
1169
1170
/* Nexthop register */
1171
static void zread_rnh_register(ZAPI_HANDLER_ARGS)
1172
19
{
1173
19
  struct rnh *rnh;
1174
19
  struct stream *s;
1175
19
  struct prefix p;
1176
19
  unsigned short l = 0;
1177
19
  uint8_t connected = 0;
1178
19
  uint8_t resolve_via_default;
1179
19
  bool exist;
1180
19
  bool flag_changed = false;
1181
19
  uint8_t orig_flags;
1182
19
  safi_t safi;
1183
1184
19
  if (IS_ZEBRA_DEBUG_NHT)
1185
0
    zlog_debug(
1186
19
      "rnh_register msg from client %s: hdr->length=%d vrf=%u",
1187
19
      zebra_route_string(client->proto), hdr->length,
1188
19
      zvrf->vrf->vrf_id);
1189
1190
19
  s = msg;
1191
1192
19
  if (!client->nh_reg_time)
1193
19
    client->nh_reg_time = monotime(NULL);
1194
1195
1.04k
  while (l < hdr->length) {
1196
1.04k
    STREAM_GETC(s, connected);
1197
1.04k
    STREAM_GETC(s, resolve_via_default);
1198
1.04k
    STREAM_GETW(s, safi);
1199
1.04k
    STREAM_GETW(s, p.family);
1200
1.04k
    STREAM_GETC(s, p.prefixlen);
1201
1.04k
    l += 7;
1202
1.04k
    if (p.family == AF_INET) {
1203
858
      client->v4_nh_watch_add_cnt++;
1204
858
      if (p.prefixlen > IPV4_MAX_BITLEN) {
1205
0
        zlog_debug(
1206
0
          "%s: Specified prefix hdr->length %d is too large for a v4 address",
1207
0
          __func__, p.prefixlen);
1208
0
        return;
1209
0
      }
1210
858
      STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1211
858
      l += IPV4_MAX_BYTELEN;
1212
858
    } else if (p.family == AF_INET6) {
1213
175
      client->v6_nh_watch_add_cnt++;
1214
175
      if (p.prefixlen > IPV6_MAX_BITLEN) {
1215
0
        zlog_debug(
1216
0
          "%s: Specified prefix hdr->length %d is to large for a v6 address",
1217
0
          __func__, p.prefixlen);
1218
0
        return;
1219
0
      }
1220
175
      STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
1221
175
      l += IPV6_MAX_BYTELEN;
1222
175
    } else {
1223
12
      flog_err(
1224
12
        EC_ZEBRA_UNKNOWN_FAMILY,
1225
12
        "rnh_register: Received unknown family type %d",
1226
12
        p.family);
1227
12
      return;
1228
12
    }
1229
1.03k
    rnh = zebra_add_rnh(&p, zvrf_id(zvrf), safi, &exist);
1230
1.03k
    if (!rnh)
1231
6
      return;
1232
1233
1.02k
    orig_flags = rnh->flags;
1234
1.02k
    if (connected && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
1235
668
      SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
1236
359
    else if (!connected
1237
152
       && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
1238
17
      UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
1239
1240
1.02k
    if (resolve_via_default)
1241
688
      SET_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT);
1242
1243
1.02k
    if (orig_flags != rnh->flags)
1244
777
      flag_changed = true;
1245
1246
    /* Anything not AF_INET/INET6 has been filtered out above */
1247
1.02k
    if (!exist || flag_changed)
1248
1.02k
      zebra_evaluate_rnh(zvrf, family2afi(p.family), 1, &p,
1249
1.02k
             safi);
1250
1251
1.02k
    zebra_add_rnh_client(rnh, client, zvrf_id(zvrf));
1252
1.02k
  }
1253
1254
1
stream_failure:
1255
1
  return;
1256
19
}
1257
1258
/* Nexthop register */
1259
static void zread_rnh_unregister(ZAPI_HANDLER_ARGS)
1260
1
{
1261
1
  struct rnh *rnh;
1262
1
  struct stream *s;
1263
1
  struct prefix p;
1264
1
  unsigned short l = 0;
1265
1
  safi_t safi;
1266
1267
1
  if (IS_ZEBRA_DEBUG_NHT)
1268
0
    zlog_debug(
1269
1
      "rnh_unregister msg from client %s: hdr->length=%d vrf: %u",
1270
1
      zebra_route_string(client->proto), hdr->length,
1271
1
      zvrf->vrf->vrf_id);
1272
1273
1
  s = msg;
1274
1275
1
  while (l < hdr->length) {
1276
1
    uint8_t ignore;
1277
1278
1
    STREAM_GETC(s, ignore);
1279
1
    if (ignore != 0)
1280
1
      goto stream_failure;
1281
0
    STREAM_GETC(s, ignore);
1282
0
    if (ignore != 0)
1283
0
      goto stream_failure;
1284
1285
0
    STREAM_GETW(s, safi);
1286
0
    STREAM_GETW(s, p.family);
1287
0
    STREAM_GETC(s, p.prefixlen);
1288
0
    l += 7;
1289
0
    if (p.family == AF_INET) {
1290
0
      client->v4_nh_watch_rem_cnt++;
1291
0
      if (p.prefixlen > IPV4_MAX_BITLEN) {
1292
0
        zlog_debug(
1293
0
          "%s: Specified prefix hdr->length %d is to large for a v4 address",
1294
0
          __func__, p.prefixlen);
1295
0
        return;
1296
0
      }
1297
0
      STREAM_GET(&p.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1298
0
      l += IPV4_MAX_BYTELEN;
1299
0
    } else if (p.family == AF_INET6) {
1300
0
      client->v6_nh_watch_rem_cnt++;
1301
0
      if (p.prefixlen > IPV6_MAX_BITLEN) {
1302
0
        zlog_debug(
1303
0
          "%s: Specified prefix hdr->length %d is to large for a v6 address",
1304
0
          __func__, p.prefixlen);
1305
0
        return;
1306
0
      }
1307
0
      STREAM_GET(&p.u.prefix6, s, IPV6_MAX_BYTELEN);
1308
0
      l += IPV6_MAX_BYTELEN;
1309
0
    } else {
1310
0
      flog_err(
1311
0
        EC_ZEBRA_UNKNOWN_FAMILY,
1312
0
        "rnh_register: Received unknown family type %d",
1313
0
        p.family);
1314
0
      return;
1315
0
    }
1316
0
    rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), safi);
1317
0
    if (rnh) {
1318
0
      client->nh_dereg_time = monotime(NULL);
1319
0
      zebra_remove_rnh_client(rnh, client);
1320
0
    }
1321
0
  }
1322
1
stream_failure:
1323
1
  return;
1324
1
}
1325
1326
28
#define ZEBRA_MIN_FEC_LENGTH 5
1327
1328
/* FEC register */
1329
static void zread_fec_register(ZAPI_HANDLER_ARGS)
1330
28
{
1331
28
  struct stream *s;
1332
28
  unsigned short l = 0;
1333
28
  struct prefix p;
1334
28
  uint16_t flags;
1335
28
  uint32_t label = MPLS_INVALID_LABEL;
1336
28
  uint32_t label_index = MPLS_INVALID_LABEL_INDEX;
1337
1338
28
  s = msg;
1339
28
  zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1340
28
  if (!zvrf)
1341
0
    return;
1342
1343
  /*
1344
   * The minimum amount of data that can be sent for one fec
1345
   * registration
1346
   */
1347
28
  if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
1348
0
    flog_err(
1349
0
      EC_ZEBRA_IRDP_LEN_MISMATCH,
1350
0
      "fec_register: Received a fec register of hdr->length %d, it is of insufficient size to properly decode",
1351
0
      hdr->length);
1352
0
    return;
1353
0
  }
1354
1355
3.42k
  while (l < hdr->length) {
1356
3.42k
    STREAM_GETW(s, flags);
1357
3.42k
    memset(&p, 0, sizeof(p));
1358
3.42k
    STREAM_GETW(s, p.family);
1359
3.41k
    if (p.family != AF_INET && p.family != AF_INET6) {
1360
22
      flog_err(
1361
22
        EC_ZEBRA_UNKNOWN_FAMILY,
1362
22
        "fec_register: Received unknown family type %d",
1363
22
        p.family);
1364
22
      return;
1365
22
    }
1366
3.39k
    STREAM_GETC(s, p.prefixlen);
1367
3.39k
    if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1368
3.39k
        || (p.family == AF_INET6
1369
1.44k
      && p.prefixlen > IPV6_MAX_BITLEN)) {
1370
3
      zlog_debug(
1371
3
        "%s: Specified prefix hdr->length: %d is to long for %d",
1372
3
        __func__, p.prefixlen, p.family);
1373
3
      return;
1374
3
    }
1375
3.39k
    l += 5;
1376
3.39k
    STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1377
3.39k
    l += PSIZE(p.prefixlen);
1378
3.39k
    if (flags & ZEBRA_FEC_REGISTER_LABEL) {
1379
356
      STREAM_GETL(s, label);
1380
356
      l += 4;
1381
3.03k
    } else if (flags & ZEBRA_FEC_REGISTER_LABEL_INDEX) {
1382
15
      STREAM_GETL(s, label_index);
1383
15
      l += 4;
1384
15
    }
1385
1386
3.39k
    zebra_mpls_fec_register(zvrf, &p, label, label_index, client);
1387
3.39k
  }
1388
1389
3
stream_failure:
1390
3
  return;
1391
28
}
1392
1393
/* FEC unregister */
1394
static void zread_fec_unregister(ZAPI_HANDLER_ARGS)
1395
0
{
1396
0
  struct stream *s;
1397
0
  unsigned short l = 0;
1398
0
  struct prefix p;
1399
0
  uint16_t flags;
1400
1401
0
  s = msg;
1402
0
  zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
1403
0
  if (!zvrf)
1404
0
    return;
1405
1406
  /*
1407
   * The minimum amount of data that can be sent for one
1408
   * fec unregistration
1409
   */
1410
0
  if (hdr->length < ZEBRA_MIN_FEC_LENGTH) {
1411
0
    flog_err(
1412
0
      EC_ZEBRA_IRDP_LEN_MISMATCH,
1413
0
      "fec_unregister: Received a fec unregister of hdr->length %d, it is of insufficient size to properly decode",
1414
0
      hdr->length);
1415
0
    return;
1416
0
  }
1417
1418
0
  while (l < hdr->length) {
1419
0
    STREAM_GETW(s, flags);
1420
0
    if (flags != 0)
1421
0
      goto stream_failure;
1422
1423
0
    memset(&p, 0, sizeof(p));
1424
0
    STREAM_GETW(s, p.family);
1425
0
    if (p.family != AF_INET && p.family != AF_INET6) {
1426
0
      flog_err(
1427
0
        EC_ZEBRA_UNKNOWN_FAMILY,
1428
0
        "fec_unregister: Received unknown family type %d",
1429
0
        p.family);
1430
0
      return;
1431
0
    }
1432
0
    STREAM_GETC(s, p.prefixlen);
1433
0
    if ((p.family == AF_INET && p.prefixlen > IPV4_MAX_BITLEN)
1434
0
        || (p.family == AF_INET6
1435
0
      && p.prefixlen > IPV6_MAX_BITLEN)) {
1436
0
      zlog_debug(
1437
0
        "%s: Received prefix hdr->length %d which is greater than %d can support",
1438
0
        __func__, p.prefixlen, p.family);
1439
0
      return;
1440
0
    }
1441
0
    l += 5;
1442
0
    STREAM_GET(&p.u.prefix, s, PSIZE(p.prefixlen));
1443
0
    l += PSIZE(p.prefixlen);
1444
0
    zebra_mpls_fec_unregister(zvrf, &p, client);
1445
0
  }
1446
1447
0
stream_failure:
1448
0
  return;
1449
0
}
1450
1451
1452
/*
1453
 * Register zebra server interface information.
1454
 * Send current all interface and address information.
1455
 */
1456
static void zread_interface_add(ZAPI_HANDLER_ARGS)
1457
0
{
1458
0
  struct vrf *vrf;
1459
0
  struct interface *ifp;
1460
1461
0
  vrf_id_t vrf_id = zvrf_id(zvrf);
1462
0
  if (vrf_id != VRF_DEFAULT && vrf_id != VRF_UNKNOWN) {
1463
0
    FOR_ALL_INTERFACES (zvrf->vrf, ifp) {
1464
      /* Skip pseudo interface. */
1465
0
      if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
1466
0
        continue;
1467
1468
0
      zsend_interface_add(client, ifp);
1469
0
      zsend_interface_link_params(client, ifp);
1470
0
      zsend_interface_addresses(client, ifp);
1471
0
    }
1472
0
    return;
1473
0
  }
1474
1475
0
  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
1476
0
    FOR_ALL_INTERFACES (vrf, ifp) {
1477
      /* Skip pseudo interface. */
1478
0
      if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE))
1479
0
        continue;
1480
1481
0
      zsend_interface_add(client, ifp);
1482
0
      zsend_interface_link_params(client, ifp);
1483
0
      zsend_interface_addresses(client, ifp);
1484
0
    }
1485
0
  }
1486
0
}
1487
1488
/* Unregister zebra server interface information. */
1489
static void zread_interface_delete(ZAPI_HANDLER_ARGS)
1490
0
{
1491
0
}
1492
1493
/*
1494
 * Handle message requesting interface be set up or down.
1495
 */
1496
static void zread_interface_set_protodown(ZAPI_HANDLER_ARGS)
1497
0
{
1498
0
  ifindex_t ifindex;
1499
0
  struct interface *ifp;
1500
0
  char down;
1501
0
  enum protodown_reasons reason;
1502
1503
0
  STREAM_GETL(msg, ifindex);
1504
0
  STREAM_GETC(msg, down);
1505
1506
  /* set ifdown */
1507
0
  ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex);
1508
1509
0
  if (!ifp) {
1510
0
    zlog_warn(
1511
0
      "Cannot set protodown %s for interface %u; does not exist",
1512
0
      down ? "on" : "off", ifindex);
1513
1514
0
    return;
1515
0
  }
1516
1517
0
  switch (client->proto) {
1518
0
  case ZEBRA_ROUTE_VRRP:
1519
0
    reason = ZEBRA_PROTODOWN_VRRP;
1520
0
    break;
1521
0
  case ZEBRA_ROUTE_SHARP:
1522
0
    reason = ZEBRA_PROTODOWN_SHARP;
1523
0
    break;
1524
0
  default:
1525
0
    reason = 0;
1526
0
    break;
1527
0
  }
1528
1529
0
  zebra_if_set_protodown(ifp, down, reason);
1530
1531
0
stream_failure:
1532
0
  return;
1533
0
}
1534
1535
bool zserv_nexthop_num_warn(const char *caller, const struct prefix *p,
1536
          const unsigned int nexthop_num)
1537
0
{
1538
0
  if (nexthop_num > zrouter.multipath_num) {
1539
0
    char buff[PREFIX2STR_BUFFER];
1540
1541
0
    if (p)
1542
0
      prefix2str(p, buff, sizeof(buff));
1543
1544
0
    flog_warn(
1545
0
      EC_ZEBRA_MORE_NH_THAN_MULTIPATH,
1546
0
      "%s: Prefix %s has %d nexthops, but we can only use the first %d",
1547
0
      caller, (p ? buff : "(NULL)"), nexthop_num,
1548
0
      zrouter.multipath_num);
1549
0
    return true;
1550
0
  }
1551
1552
0
  return false;
1553
0
}
1554
1555
/*
1556
 * Create a new nexthop based on a zapi nexthop.
1557
 */
1558
static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh,
1559
           uint32_t flags, struct prefix *p,
1560
           uint16_t backup_nexthop_num)
1561
0
{
1562
0
  struct nexthop *nexthop = NULL;
1563
0
  struct interface *ifp;
1564
0
  int i;
1565
0
  char nhbuf[INET6_ADDRSTRLEN] = "";
1566
1567
0
  switch (api_nh->type) {
1568
0
  case NEXTHOP_TYPE_IFINDEX:
1569
0
    nexthop = nexthop_from_ifindex(api_nh->ifindex, api_nh->vrf_id);
1570
0
    break;
1571
0
  case NEXTHOP_TYPE_IPV4:
1572
0
    if (IS_ZEBRA_DEBUG_RECV) {
1573
0
      inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1574
0
          sizeof(nhbuf));
1575
0
      zlog_debug("%s: nh=%s, vrf_id=%d", __func__,
1576
0
           nhbuf, api_nh->vrf_id);
1577
0
    }
1578
0
    nexthop = nexthop_from_ipv4(&api_nh->gate.ipv4, NULL,
1579
0
              api_nh->vrf_id);
1580
0
    break;
1581
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
1582
0
    if (IS_ZEBRA_DEBUG_RECV) {
1583
0
      inet_ntop(AF_INET, &api_nh->gate.ipv4, nhbuf,
1584
0
          sizeof(nhbuf));
1585
0
      zlog_debug("%s: nh=%s, vrf_id=%d, ifindex=%d",
1586
0
           __func__, nhbuf, api_nh->vrf_id,
1587
0
           api_nh->ifindex);
1588
0
    }
1589
1590
0
    nexthop = nexthop_from_ipv4_ifindex(
1591
0
      &api_nh->gate.ipv4, NULL, api_nh->ifindex,
1592
0
      api_nh->vrf_id);
1593
1594
    /* Special handling for IPv4 routes sourced from EVPN:
1595
     * the nexthop and associated MAC need to be installed.
1596
     */
1597
0
    if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
1598
0
      SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN);
1599
0
      nexthop->rmac = api_nh->rmac;
1600
0
    }
1601
0
    break;
1602
0
  case NEXTHOP_TYPE_IPV6:
1603
0
    if (IS_ZEBRA_DEBUG_RECV) {
1604
0
      inet_ntop(AF_INET6, &api_nh->gate.ipv6, nhbuf,
1605
0
          sizeof(nhbuf));
1606
0
      zlog_debug("%s: nh=%s, vrf_id=%d", __func__,
1607
0
           nhbuf, api_nh->vrf_id);
1608
0
    }
1609
0
    nexthop = nexthop_from_ipv6(&api_nh->gate.ipv6, api_nh->vrf_id);
1610
0
    break;
1611
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
1612
0
    if (IS_ZEBRA_DEBUG_RECV) {
1613
0
      inet_ntop(AF_INET6, &api_nh->gate.ipv6, nhbuf,
1614
0
          sizeof(nhbuf));
1615
0
      zlog_debug("%s: nh=%s, vrf_id=%d, ifindex=%d",
1616
0
           __func__, nhbuf, api_nh->vrf_id,
1617
0
           api_nh->ifindex);
1618
0
    }
1619
0
    nexthop = nexthop_from_ipv6_ifindex(&api_nh->gate.ipv6,
1620
0
                api_nh->ifindex,
1621
0
                api_nh->vrf_id);
1622
1623
    /* Special handling for IPv6 routes sourced from EVPN:
1624
     * the nexthop and associated MAC need to be installed.
1625
     */
1626
0
    if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) {
1627
0
      SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN);
1628
0
      nexthop->rmac = api_nh->rmac;
1629
0
    }
1630
0
    break;
1631
0
  case NEXTHOP_TYPE_BLACKHOLE:
1632
0
    if (IS_ZEBRA_DEBUG_RECV)
1633
0
      zlog_debug("%s: nh blackhole %d",
1634
0
           __func__, api_nh->bh_type);
1635
1636
0
    nexthop =
1637
0
      nexthop_from_blackhole(api_nh->bh_type, api_nh->vrf_id);
1638
0
    break;
1639
0
  }
1640
1641
  /* Return early if we couldn't process the zapi nexthop */
1642
0
  if (nexthop == NULL) {
1643
0
    goto done;
1644
0
  }
1645
1646
  /* Mark nexthop as onlink either if client has explicitly told us
1647
   * to or if the nexthop is on an 'unnumbered' interface.
1648
   */
1649
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK))
1650
0
    SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
1651
0
  else if (api_nh->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
1652
0
    ifp = if_lookup_by_index(api_nh->ifindex, api_nh->vrf_id);
1653
0
    if (ifp && connected_is_unnumbered(ifp))
1654
0
      SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
1655
0
  }
1656
1657
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1658
0
    nexthop->weight = api_nh->weight;
1659
1660
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1661
    /* Validate count */
1662
0
    if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS) {
1663
0
      if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_EVENT)
1664
0
        zlog_debug("%s: invalid backup nh count %d",
1665
0
             __func__, api_nh->backup_num);
1666
0
      nexthop_free(nexthop);
1667
0
      nexthop = NULL;
1668
0
      goto done;
1669
0
    }
1670
1671
    /* Copy backup info */
1672
0
    SET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP);
1673
0
    nexthop->backup_num = api_nh->backup_num;
1674
1675
0
    for (i = 0; i < api_nh->backup_num; i++) {
1676
      /* Validate backup index */
1677
0
      if (api_nh->backup_idx[i] < backup_nexthop_num) {
1678
0
        nexthop->backup_idx[i] = api_nh->backup_idx[i];
1679
0
      } else {
1680
0
        if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_EVENT)
1681
0
          zlog_debug("%s: invalid backup nh idx %d",
1682
0
               __func__,
1683
0
               api_nh->backup_idx[i]);
1684
0
        nexthop_free(nexthop);
1685
0
        nexthop = NULL;
1686
0
        goto done;
1687
0
      }
1688
0
    }
1689
0
  }
1690
1691
0
done:
1692
0
  return nexthop;
1693
0
}
1694
1695
static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
1696
             struct zapi_nexthop *nhops, uint32_t flags,
1697
             uint32_t message, uint16_t nexthop_num,
1698
             uint16_t backup_nh_num,
1699
             struct nexthop_group **png,
1700
             struct nhg_backup_info **pbnhg)
1701
0
{
1702
0
  struct nexthop_group *ng = NULL;
1703
0
  struct nhg_backup_info *bnhg = NULL;
1704
0
  uint16_t i;
1705
0
  struct nexthop *last_nh = NULL;
1706
1707
0
  assert(!(png && pbnhg));
1708
1709
0
  if (png)
1710
0
    ng = nexthop_group_new();
1711
1712
0
  if (pbnhg && backup_nh_num > 0) {
1713
0
    if (IS_ZEBRA_DEBUG_RECV)
1714
0
      zlog_debug("%s: adding %d backup nexthops", __func__,
1715
0
           backup_nh_num);
1716
1717
0
    bnhg = zebra_nhg_backup_alloc();
1718
0
  }
1719
1720
  /*
1721
   * TBD should _all_ of the nexthop add operations use
1722
   * api_nh->vrf_id instead of re->vrf_id ? I only changed
1723
   * for cases NEXTHOP_TYPE_IPV4 and NEXTHOP_TYPE_IPV6.
1724
   */
1725
0
  for (i = 0; i < nexthop_num; i++) {
1726
0
    struct nexthop *nexthop;
1727
0
    enum lsp_types_t label_type;
1728
0
    char nhbuf[NEXTHOP_STRLEN];
1729
0
    char labelbuf[MPLS_LABEL_STRLEN];
1730
0
    struct zapi_nexthop *api_nh = &nhops[i];
1731
1732
    /* Convert zapi nexthop */
1733
0
    nexthop = nexthop_from_zapi(api_nh, flags, p, backup_nh_num);
1734
0
    if (!nexthop) {
1735
0
      flog_warn(
1736
0
        EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1737
0
        "%s: Nexthops Specified: %u(%u) but we failed to properly create one",
1738
0
        __func__, nexthop_num, i);
1739
0
      if (ng)
1740
0
        nexthop_group_delete(&ng);
1741
0
      if (bnhg)
1742
0
        zebra_nhg_backup_free(&bnhg);
1743
0
      return false;
1744
0
    }
1745
1746
0
    if (bnhg
1747
0
        && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
1748
0
      if (IS_ZEBRA_DEBUG_RECV) {
1749
0
        nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
1750
0
        zlog_debug("%s: backup nh %s with BACKUP flag!",
1751
0
             __func__, nhbuf);
1752
0
      }
1753
0
      UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP);
1754
0
      nexthop->backup_num = 0;
1755
0
    }
1756
1757
0
    if (CHECK_FLAG(message, ZAPI_MESSAGE_SRTE)) {
1758
0
      SET_FLAG(nexthop->flags, NEXTHOP_FLAG_SRTE);
1759
0
      nexthop->srte_color = api_nh->srte_color;
1760
0
    }
1761
1762
    /* Labels for MPLS BGP-LU or Segment Routing or EVPN */
1763
0
    if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)
1764
0
        && api_nh->type != NEXTHOP_TYPE_IFINDEX
1765
0
        && api_nh->type != NEXTHOP_TYPE_BLACKHOLE
1766
0
        && api_nh->label_num > 0) {
1767
1768
      /* If label type was passed, use it */
1769
0
      if (api_nh->label_type)
1770
0
        label_type = api_nh->label_type;
1771
0
      else
1772
0
        label_type =
1773
0
          lsp_type_from_re_type(client->proto);
1774
1775
0
      nexthop_add_labels(nexthop, label_type,
1776
0
             api_nh->label_num,
1777
0
             &api_nh->labels[0]);
1778
0
    }
1779
1780
0
    if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6LOCAL)
1781
0
        && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
1782
0
      if (IS_ZEBRA_DEBUG_RECV)
1783
0
        zlog_debug("%s: adding seg6local action %s",
1784
0
             __func__,
1785
0
             seg6local_action2str(
1786
0
               api_nh->seg6local_action));
1787
1788
0
      nexthop_add_srv6_seg6local(nexthop,
1789
0
               api_nh->seg6local_action,
1790
0
               &api_nh->seg6local_ctx);
1791
0
    }
1792
1793
0
    if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6)
1794
0
        && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
1795
0
      if (IS_ZEBRA_DEBUG_RECV)
1796
0
        zlog_debug("%s: adding seg6", __func__);
1797
1798
0
      nexthop_add_srv6_seg6(nexthop, &api_nh->seg6_segs);
1799
0
    }
1800
1801
0
    if (IS_ZEBRA_DEBUG_RECV) {
1802
0
      labelbuf[0] = '\0';
1803
0
      nhbuf[0] = '\0';
1804
1805
0
      nexthop2str(nexthop, nhbuf, sizeof(nhbuf));
1806
1807
0
      if (nexthop->nh_label &&
1808
0
          nexthop->nh_label->num_labels > 0) {
1809
0
        mpls_label2str(nexthop->nh_label->num_labels,
1810
0
                 nexthop->nh_label->label,
1811
0
                 labelbuf, sizeof(labelbuf),
1812
0
                 nexthop->nh_label_type, false);
1813
0
      }
1814
1815
0
      zlog_debug("%s: nh=%s, vrf_id=%d %s",
1816
0
           __func__, nhbuf, api_nh->vrf_id, labelbuf);
1817
0
    }
1818
1819
0
    if (ng) {
1820
      /* Add new nexthop to temporary list. This list is
1821
       * canonicalized - sorted - so that it can be hashed
1822
       * later in route processing. We expect that the sender
1823
       * has sent the list sorted, and the zapi client api
1824
       * attempts to enforce that, so this should be
1825
       * inexpensive - but it is necessary to support shared
1826
       * nexthop-groups.
1827
       */
1828
0
      nexthop_group_add_sorted(ng, nexthop);
1829
0
    }
1830
0
    if (bnhg) {
1831
      /* Note that the order of the backup nexthops is
1832
       * significant, so we don't sort this list as we do the
1833
       * primary nexthops, we just append.
1834
       */
1835
0
      if (last_nh)
1836
0
        NEXTHOP_APPEND(last_nh, nexthop);
1837
0
      else
1838
0
        bnhg->nhe->nhg.nexthop = nexthop;
1839
1840
0
      last_nh = nexthop;
1841
0
    }
1842
0
  }
1843
1844
1845
  /* succesfully read, set caller pointers now */
1846
0
  if (png)
1847
0
    *png = ng;
1848
1849
0
  if (pbnhg)
1850
0
    *pbnhg = bnhg;
1851
1852
0
  return true;
1853
0
}
1854
1855
static int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
1856
0
{
1857
0
  uint16_t i;
1858
0
  struct zapi_nexthop *znh;
1859
1860
0
  STREAM_GETW(s, api_nhg->proto);
1861
0
  STREAM_GETL(s, api_nhg->id);
1862
1863
0
  if (cmd == ZEBRA_NHG_DEL)
1864
0
    goto done;
1865
1866
0
  STREAM_GETW(s, api_nhg->resilience.buckets);
1867
0
  STREAM_GETL(s, api_nhg->resilience.idle_timer);
1868
0
  STREAM_GETL(s, api_nhg->resilience.unbalanced_timer);
1869
1870
  /* Nexthops */
1871
0
  STREAM_GETW(s, api_nhg->nexthop_num);
1872
1873
0
  if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->nexthop_num))
1874
0
    return -1;
1875
1876
0
  if (api_nhg->nexthop_num <= 0) {
1877
0
    flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1878
0
        "%s: No nexthops sent", __func__);
1879
0
    return -1;
1880
0
  }
1881
1882
0
  for (i = 0; i < api_nhg->nexthop_num; i++) {
1883
0
    znh = &((api_nhg->nexthops)[i]);
1884
1885
0
    if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
1886
0
      flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1887
0
          "%s: Nexthop creation failed", __func__);
1888
0
      return -1;
1889
0
    }
1890
0
  }
1891
1892
  /* Backup Nexthops */
1893
0
  STREAM_GETW(s, api_nhg->backup_nexthop_num);
1894
1895
0
  if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->backup_nexthop_num))
1896
0
    return -1;
1897
1898
0
  for (i = 0; i < api_nhg->backup_nexthop_num; i++) {
1899
0
    znh = &((api_nhg->backup_nexthops)[i]);
1900
1901
0
    if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
1902
0
      flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1903
0
          "%s: Backup Nexthop creation failed",
1904
0
          __func__);
1905
0
      return -1;
1906
0
    }
1907
0
  }
1908
1909
0
done:
1910
0
  return 0;
1911
1912
0
stream_failure:
1913
0
  flog_warn(
1914
0
    EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1915
0
    "%s: Nexthop Group decode failed with some sort of stream read failure",
1916
0
    __func__);
1917
0
  return -1;
1918
0
}
1919
1920
static void zread_nhg_del(ZAPI_HANDLER_ARGS)
1921
0
{
1922
0
  struct stream *s;
1923
0
  struct zapi_nhg api_nhg = {};
1924
0
  struct nhg_hash_entry *nhe;
1925
1926
0
  s = msg;
1927
0
  if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
1928
0
    if (IS_ZEBRA_DEBUG_RECV)
1929
0
      zlog_debug("%s: Unable to decode zapi_nhg sent",
1930
0
           __func__);
1931
0
    return;
1932
0
  }
1933
1934
  /*
1935
   * Delete the received nhg id
1936
   */
1937
0
  nhe = zebra_nhg_proto_del(api_nhg.id, api_nhg.proto);
1938
1939
0
  if (nhe) {
1940
0
    zebra_nhg_decrement_ref(nhe);
1941
0
    zsend_nhg_notify(api_nhg.proto, client->instance,
1942
0
         client->session_id, api_nhg.id,
1943
0
         ZAPI_NHG_REMOVED);
1944
0
  } else
1945
0
    zsend_nhg_notify(api_nhg.proto, client->instance,
1946
0
         client->session_id, api_nhg.id,
1947
0
         ZAPI_NHG_REMOVE_FAIL);
1948
0
}
1949
1950
static void zread_nhg_add(ZAPI_HANDLER_ARGS)
1951
0
{
1952
0
  struct stream *s;
1953
0
  struct zapi_nhg api_nhg = {};
1954
0
  struct nexthop_group *nhg = NULL;
1955
0
  struct nhg_backup_info *bnhg = NULL;
1956
0
  struct nhg_hash_entry *nhe;
1957
1958
0
  s = msg;
1959
0
  if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
1960
0
    if (IS_ZEBRA_DEBUG_RECV)
1961
0
      zlog_debug("%s: Unable to decode zapi_nhg sent",
1962
0
           __func__);
1963
0
    return;
1964
0
  }
1965
1966
0
  if ((!zapi_read_nexthops(client, NULL, api_nhg.nexthops, 0, 0,
1967
0
         api_nhg.nexthop_num,
1968
0
         api_nhg.backup_nexthop_num, &nhg, NULL))
1969
0
      || (!zapi_read_nexthops(client, NULL, api_nhg.backup_nexthops, 0, 0,
1970
0
            api_nhg.backup_nexthop_num,
1971
0
            api_nhg.backup_nexthop_num, NULL, &bnhg))) {
1972
1973
0
    flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
1974
0
        "%s: Nexthop Group Creation failed", __func__);
1975
1976
    /* Free any local allocations */
1977
0
    nexthop_group_delete(&nhg);
1978
0
    zebra_nhg_backup_free(&bnhg);
1979
1980
0
    return;
1981
0
  }
1982
1983
  /* Create a temporary nhe */
1984
0
  nhe = zebra_nhg_alloc();
1985
0
  nhe->id = api_nhg.id;
1986
0
  nhe->type = api_nhg.proto;
1987
0
  nhe->zapi_instance = client->instance;
1988
0
  nhe->zapi_session = client->session_id;
1989
1990
  /* Take over the list(s) of nexthops */
1991
0
  nhe->nhg.nexthop = nhg->nexthop;
1992
0
  nhg->nexthop = NULL;
1993
1994
0
  nhe->nhg.nhgr = api_nhg.resilience;
1995
1996
0
  if (bnhg) {
1997
0
    nhe->backup_info = bnhg;
1998
0
    bnhg = NULL;
1999
0
  }
2000
2001
  /*
2002
   * TODO:
2003
   * Assume fully resolved for now and install.
2004
   * Resolution is going to need some more work.
2005
   */
2006
2007
  /* Enqueue to workqueue for processing */
2008
0
  rib_queue_nhe_add(nhe);
2009
2010
  /* Free any local allocations */
2011
0
  nexthop_group_delete(&nhg);
2012
0
  zebra_nhg_backup_free(&bnhg);
2013
2014
0
}
2015
2016
static void zread_route_add(ZAPI_HANDLER_ARGS)
2017
0
{
2018
0
  struct stream *s;
2019
0
  struct zapi_route api;
2020
0
  afi_t afi;
2021
0
  struct prefix_ipv6 *src_p = NULL;
2022
0
  struct route_entry *re;
2023
0
  struct nexthop_group *ng = NULL;
2024
0
  struct nhg_backup_info *bnhg = NULL;
2025
0
  int ret;
2026
0
  vrf_id_t vrf_id;
2027
0
  struct nhg_hash_entry nhe, *n = NULL;
2028
2029
0
  s = msg;
2030
0
  if (zapi_route_decode(s, &api) < 0) {
2031
0
    if (IS_ZEBRA_DEBUG_RECV)
2032
0
      zlog_debug("%s: Unable to decode zapi_route sent",
2033
0
           __func__);
2034
0
    return;
2035
0
  }
2036
2037
0
  vrf_id = zvrf_id(zvrf);
2038
2039
0
  if (IS_ZEBRA_DEBUG_RECV)
2040
0
    zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x",
2041
0
         __func__, vrf_id, api.tableid, &api.prefix,
2042
0
         (int)api.message, api.flags);
2043
2044
  /* Allocate new route. */
2045
0
  re = zebra_rib_route_entry_new(
2046
0
    vrf_id, api.type, api.instance, api.flags, api.nhgid,
2047
0
    api.tableid ? api.tableid : zvrf->table_id, api.metric, api.mtu,
2048
0
    api.distance, api.tag);
2049
2050
0
  if (!CHECK_FLAG(api.message, ZAPI_MESSAGE_NHG)
2051
0
      && (!CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)
2052
0
    || api.nexthop_num == 0)) {
2053
0
    flog_warn(
2054
0
      EC_ZEBRA_RX_ROUTE_NO_NEXTHOPS,
2055
0
      "%s: received a route without nexthops for prefix %pFX from client %s",
2056
0
      __func__, &api.prefix,
2057
0
      zebra_route_string(client->proto));
2058
2059
0
    XFREE(MTYPE_RE, re);
2060
0
    return;
2061
0
  }
2062
2063
  /* Report misuse of the backup flag */
2064
0
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)
2065
0
      && api.backup_nexthop_num == 0) {
2066
0
    if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_EVENT)
2067
0
      zlog_debug(
2068
0
        "%s: client %s: BACKUP flag set but no backup nexthops, prefix %pFX",
2069
0
        __func__, zebra_route_string(client->proto),
2070
0
        &api.prefix);
2071
0
  }
2072
2073
0
  if (!re->nhe_id
2074
0
      && (!zapi_read_nexthops(client, &api.prefix, api.nexthops,
2075
0
            api.flags, api.message, api.nexthop_num,
2076
0
            api.backup_nexthop_num, &ng, NULL)
2077
0
    || !zapi_read_nexthops(client, &api.prefix, api.backup_nexthops,
2078
0
               api.flags, api.message,
2079
0
               api.backup_nexthop_num,
2080
0
               api.backup_nexthop_num, NULL, &bnhg))) {
2081
2082
0
    nexthop_group_delete(&ng);
2083
0
    zebra_nhg_backup_free(&bnhg);
2084
0
    XFREE(MTYPE_RE, re);
2085
0
    return;
2086
0
  }
2087
2088
0
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_OPAQUE)) {
2089
0
    re->opaque =
2090
0
      XMALLOC(MTYPE_RE_OPAQUE,
2091
0
        sizeof(struct re_opaque) + api.opaque.length);
2092
0
    re->opaque->length = api.opaque.length;
2093
0
    memcpy(re->opaque->data, api.opaque.data, re->opaque->length);
2094
0
  }
2095
2096
0
  afi = family2afi(api.prefix.family);
2097
0
  if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
2098
0
    flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
2099
0
        "%s: Received SRC Prefix but afi is not v6",
2100
0
        __func__);
2101
0
    nexthop_group_delete(&ng);
2102
0
    zebra_nhg_backup_free(&bnhg);
2103
0
    XFREE(MTYPE_RE_OPAQUE, re->opaque);
2104
0
    XFREE(MTYPE_RE, re);
2105
0
    return;
2106
0
  }
2107
0
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
2108
0
    src_p = &api.src_prefix;
2109
2110
0
  if (api.safi != SAFI_UNICAST && api.safi != SAFI_MULTICAST) {
2111
0
    flog_warn(EC_LIB_ZAPI_MISSMATCH,
2112
0
        "%s: Received safi: %d but we can only accept UNICAST or MULTICAST",
2113
0
        __func__, api.safi);
2114
0
    nexthop_group_delete(&ng);
2115
0
    zebra_nhg_backup_free(&bnhg);
2116
0
    XFREE(MTYPE_RE_OPAQUE, re->opaque);
2117
0
    XFREE(MTYPE_RE, re);
2118
0
    return;
2119
0
  }
2120
2121
  /*
2122
   * If we have an ID, this proto owns the NHG it sent along with the
2123
   * route, so we just send the ID into rib code with it.
2124
   *
2125
   * Havent figured out how to handle backup NHs with this yet, so lets
2126
   * keep that separate.
2127
   * Include backup info with the route. We use a temporary nhe here;
2128
   * if this is a new/unknown nhe, a new copy will be allocated
2129
   * and stored.
2130
   */
2131
0
  if (!re->nhe_id) {
2132
0
    zebra_nhe_init(&nhe, afi, ng->nexthop);
2133
0
    nhe.nhg.nexthop = ng->nexthop;
2134
0
    nhe.backup_info = bnhg;
2135
0
    n = zebra_nhe_copy(&nhe, 0);
2136
0
  }
2137
0
  ret = rib_add_multipath_nhe(afi, api.safi, &api.prefix, src_p, re, n,
2138
0
            false);
2139
2140
  /*
2141
   * rib_add_multipath_nhe only fails in a couple spots
2142
   * and in those spots we have not freed memory
2143
   */
2144
0
  if (ret == -1) {
2145
0
    client->error_cnt++;
2146
0
    XFREE(MTYPE_RE_OPAQUE, re->opaque);
2147
0
    XFREE(MTYPE_RE, re);
2148
0
  }
2149
2150
  /* At this point, these allocations are not needed: 're' has been
2151
   * retained or freed, and if 're' still exists, it is using
2152
   * a reference to a shared group object.
2153
   */
2154
0
  nexthop_group_delete(&ng);
2155
0
  if (bnhg)
2156
0
    zebra_nhg_backup_free(&bnhg);
2157
2158
  /* Stats */
2159
0
  switch (api.prefix.family) {
2160
0
  case AF_INET:
2161
0
    if (ret == 0)
2162
0
      client->v4_route_add_cnt++;
2163
0
    else if (ret == 1)
2164
0
      client->v4_route_upd8_cnt++;
2165
0
    break;
2166
0
  case AF_INET6:
2167
0
    if (ret == 0)
2168
0
      client->v6_route_add_cnt++;
2169
0
    else if (ret == 1)
2170
0
      client->v6_route_upd8_cnt++;
2171
0
    break;
2172
0
  }
2173
0
}
2174
2175
void zapi_re_opaque_free(struct re_opaque *opaque)
2176
0
{
2177
0
  XFREE(MTYPE_RE_OPAQUE, opaque);
2178
0
}
2179
2180
static void zread_route_del(ZAPI_HANDLER_ARGS)
2181
0
{
2182
0
  struct stream *s;
2183
0
  struct zapi_route api;
2184
0
  afi_t afi;
2185
0
  struct prefix_ipv6 *src_p = NULL;
2186
0
  uint32_t table_id;
2187
2188
0
  s = msg;
2189
0
  if (zapi_route_decode(s, &api) < 0)
2190
0
    return;
2191
2192
0
  afi = family2afi(api.prefix.family);
2193
0
  if (afi != AFI_IP6 && CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) {
2194
0
    flog_warn(EC_ZEBRA_RX_SRCDEST_WRONG_AFI,
2195
0
        "%s: Received a src prefix while afi is not v6",
2196
0
        __func__);
2197
0
    return;
2198
0
  }
2199
0
  if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
2200
0
    src_p = &api.src_prefix;
2201
2202
0
  if (api.tableid)
2203
0
    table_id = api.tableid;
2204
0
  else
2205
0
    table_id = zvrf->table_id;
2206
2207
0
  if (IS_ZEBRA_DEBUG_RECV)
2208
0
    zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x",
2209
0
         __func__, zvrf_id(zvrf), table_id, &api.prefix,
2210
0
         (int)api.message, api.flags);
2211
2212
0
  rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
2213
0
       api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric,
2214
0
       api.distance, false);
2215
2216
  /* Stats */
2217
0
  switch (api.prefix.family) {
2218
0
  case AF_INET:
2219
0
    client->v4_route_del_cnt++;
2220
0
    break;
2221
0
  case AF_INET6:
2222
0
    client->v6_route_del_cnt++;
2223
0
    break;
2224
0
  }
2225
0
}
2226
2227
/* MRIB Nexthop lookup for IPv4. */
2228
static void zread_nexthop_lookup_mrib(ZAPI_HANDLER_ARGS)
2229
3
{
2230
3
  struct ipaddr addr;
2231
3
  struct route_entry *re = NULL;
2232
3
  union g_addr gaddr;
2233
2234
3
  STREAM_GET_IPADDR(msg, &addr);
2235
2236
3
  switch (addr.ipa_type) {
2237
0
  case IPADDR_V4:
2238
0
    gaddr.ipv4 = addr.ipaddr_v4;
2239
0
    re = rib_match_multicast(AFI_IP, zvrf_id(zvrf), &gaddr, NULL);
2240
0
    break;
2241
0
  case IPADDR_V6:
2242
0
    gaddr.ipv6 = addr.ipaddr_v6;
2243
0
    re = rib_match_multicast(AFI_IP6, zvrf_id(zvrf), &gaddr, NULL);
2244
0
    break;
2245
0
  case IPADDR_NONE:
2246
    /* ??? */
2247
0
    goto stream_failure;
2248
3
  }
2249
2250
3
  zsend_nexthop_lookup_mrib(client, &addr, re, zvrf);
2251
2252
3
stream_failure:
2253
3
  return;
2254
3
}
2255
2256
/* Register zebra server router-id information.  Send current router-id */
2257
static void zread_router_id_add(ZAPI_HANDLER_ARGS)
2258
0
{
2259
0
  afi_t afi;
2260
0
  struct prefix p;
2261
0
  struct prefix zero;
2262
2263
0
  STREAM_GETW(msg, afi);
2264
2265
0
  if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
2266
0
    zlog_warn(
2267
0
      "Invalid AFI %u while registering for router ID notifications",
2268
0
      afi);
2269
0
    goto stream_failure;
2270
0
  }
2271
2272
  /* Router-id information is needed. */
2273
0
  vrf_bitmap_set(client->ridinfo[afi], zvrf_id(zvrf));
2274
2275
0
  router_id_get(afi, &p, zvrf);
2276
2277
  /*
2278
   * If we have not officially setup a router-id let's not
2279
   * tell the upper level protocol about it yet.
2280
   */
2281
0
  memset(&zero, 0, sizeof(zero));
2282
0
  if ((p.family == AF_INET && p.u.prefix4.s_addr == INADDR_ANY)
2283
0
      || (p.family == AF_INET6
2284
0
    && memcmp(&p.u.prefix6, &zero.u.prefix6,
2285
0
        sizeof(struct in6_addr))
2286
0
         == 0))
2287
0
    return;
2288
2289
0
  zsend_router_id_update(client, afi, &p, zvrf_id(zvrf));
2290
2291
0
stream_failure:
2292
0
  return;
2293
0
}
2294
2295
/* Unregister zebra server router-id information. */
2296
static void zread_router_id_delete(ZAPI_HANDLER_ARGS)
2297
0
{
2298
0
  afi_t afi;
2299
2300
0
  STREAM_GETW(msg, afi);
2301
2302
0
  if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
2303
0
    zlog_warn(
2304
0
      "Invalid AFI %u while unregistering from router ID notifications",
2305
0
      afi);
2306
0
    goto stream_failure;
2307
0
  }
2308
2309
0
  vrf_bitmap_unset(client->ridinfo[afi], zvrf_id(zvrf));
2310
2311
0
stream_failure:
2312
0
  return;
2313
0
}
2314
2315
static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf)
2316
0
{
2317
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2318
2319
0
  zclient_create_header(s, ZEBRA_CAPABILITIES, zvrf->vrf->vrf_id);
2320
0
  stream_putl(s, vrf_get_backend());
2321
0
  stream_putc(s, mpls_enabled);
2322
0
  stream_putl(s, zrouter.multipath_num);
2323
0
  stream_putc(s, zebra_mlag_get_role());
2324
2325
0
  stream_putw_at(s, 0, stream_get_endp(s));
2326
0
  zserv_send_message(client, s);
2327
0
}
2328
2329
void zsend_capabilities_all_clients(void)
2330
0
{
2331
0
  struct listnode *node, *nnode;
2332
0
  struct zebra_vrf *zvrf;
2333
0
  struct zserv *client;
2334
2335
0
  zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
2336
0
  for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) {
2337
    /* Do not send unsolicited messages to synchronous clients. */
2338
0
    if (client->synchronous)
2339
0
      continue;
2340
2341
0
    zsend_capabilities(client, zvrf);
2342
0
  }
2343
0
}
2344
2345
/* Tie up route-type and client->sock */
2346
static void zread_hello(ZAPI_HANDLER_ARGS)
2347
0
{
2348
  /* type of protocol (lib/zebra.h) */
2349
0
  uint8_t proto;
2350
0
  unsigned short instance;
2351
0
  uint8_t notify;
2352
0
  uint8_t synchronous;
2353
0
  uint32_t session_id;
2354
2355
0
  STREAM_GETC(msg, proto);
2356
0
  STREAM_GETW(msg, instance);
2357
0
  STREAM_GETL(msg, session_id);
2358
0
  STREAM_GETC(msg, notify);
2359
0
  STREAM_GETC(msg, synchronous);
2360
0
  if (notify)
2361
0
    client->notify_owner = true;
2362
2363
0
  if (synchronous)
2364
0
    client->synchronous = true;
2365
2366
  /* accept only dynamic routing protocols */
2367
0
  if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) {
2368
0
    zlog_notice(
2369
0
      "client %d says hello and bids fair to announce only %s routes vrf=%u",
2370
0
      client->sock, zebra_route_string(proto),
2371
0
      zvrf->vrf->vrf_id);
2372
0
    if (instance)
2373
0
      zlog_notice("client protocol instance %d", instance);
2374
2375
0
    client->proto = proto;
2376
0
    client->instance = instance;
2377
0
    client->session_id = session_id;
2378
2379
    /* Graceful restart processing for client connect */
2380
0
    zebra_gr_client_reconnect(client);
2381
0
  }
2382
2383
0
  if (!client->synchronous) {
2384
0
    zsend_capabilities(client, zvrf);
2385
0
    zebra_vrf_update_all(client);
2386
0
  }
2387
0
stream_failure:
2388
0
  return;
2389
0
}
2390
2391
/* Unregister all information in a VRF. */
2392
static void zread_vrf_unregister(ZAPI_HANDLER_ARGS)
2393
0
{
2394
0
  int i;
2395
0
  afi_t afi;
2396
2397
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2398
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2399
0
      vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf));
2400
0
    vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf));
2401
0
    vrf_bitmap_unset(client->ridinfo[afi], zvrf_id(zvrf));
2402
0
    vrf_bitmap_unset(client->nhrp_neighinfo[afi], zvrf_id(zvrf));
2403
0
  }
2404
0
}
2405
2406
/*
2407
 * Validate incoming zapi mpls lsp / labels message
2408
 */
2409
static int zapi_labels_validate(const struct zapi_labels *zl)
2410
0
{
2411
0
  int ret = -1;
2412
0
  int i, j, idx;
2413
0
  uint32_t bits[8];
2414
0
  uint32_t ival;
2415
0
  const struct zapi_nexthop *znh;
2416
2417
  /* Validate backup info: no duplicates for a single primary */
2418
0
  if (zl->backup_nexthop_num == 0) {
2419
0
    ret = 0;
2420
0
    goto done;
2421
0
  }
2422
2423
0
  for (j = 0; j < zl->nexthop_num; j++) {
2424
0
    znh = &zl->nexthops[j];
2425
2426
0
    memset(bits, 0, sizeof(bits));
2427
2428
0
    for (i = 0; i < znh->backup_num; i++) {
2429
0
      idx = znh->backup_idx[i] / 32;
2430
2431
0
      ival = 1 << znh->backup_idx[i] % 32;
2432
2433
      /* Check whether value is already used */
2434
0
      if (ival & bits[idx]) {
2435
        /* Fail */
2436
2437
0
        if (IS_ZEBRA_DEBUG_RECV)
2438
0
          zlog_debug("%s: invalid zapi mpls message: duplicate backup nexthop index %d",
2439
0
               __func__,
2440
0
               znh->backup_idx[i]);
2441
0
        goto done;
2442
0
      }
2443
2444
      /* Mark index value */
2445
0
      bits[idx] |= ival;
2446
0
    }
2447
0
  }
2448
2449
0
  ret = 0;
2450
2451
0
done:
2452
2453
0
  return ret;
2454
0
}
2455
2456
/*
2457
 * Handle request to create an MPLS LSP.
2458
 *
2459
 * A single message can fully specify an LSP with multiple nexthops.
2460
 *
2461
 * When the optional ZAPI_LABELS_FTN flag is set, the specified FEC (route) is
2462
 * updated to use the received label(s).
2463
 */
2464
static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
2465
0
{
2466
0
  struct stream *s;
2467
0
  struct zapi_labels zl;
2468
2469
  /* Get input stream.  */
2470
0
  s = msg;
2471
0
  if (zapi_labels_decode(s, &zl) < 0) {
2472
0
    if (IS_ZEBRA_DEBUG_RECV)
2473
0
      zlog_debug("%s: Unable to decode zapi_labels sent",
2474
0
           __func__);
2475
0
    return;
2476
0
  }
2477
2478
0
  if (!mpls_enabled)
2479
0
    return;
2480
2481
  /* Validate; will debug on failure */
2482
0
  if (zapi_labels_validate(&zl) < 0)
2483
0
    return;
2484
2485
0
  mpls_zapi_labels_process(true, zvrf, &zl);
2486
0
}
2487
2488
/*
2489
 * Handle request to delete an MPLS LSP.
2490
 *
2491
 * An LSP is identified by its type and local label. When the received message
2492
 * doesn't contain any nexthop, the whole LSP is deleted. Otherwise, only the
2493
 * listed LSP nexthops (aka NHLFEs) are deleted.
2494
 *
2495
 * When the optional ZAPI_LABELS_FTN flag is set, the labels of the specified
2496
 * FEC (route) nexthops are deleted.
2497
 */
2498
static void zread_mpls_labels_delete(ZAPI_HANDLER_ARGS)
2499
1
{
2500
1
  struct stream *s;
2501
1
  struct zapi_labels zl;
2502
2503
  /* Get input stream.  */
2504
1
  s = msg;
2505
1
  if (zapi_labels_decode(s, &zl) < 0) {
2506
1
    if (IS_ZEBRA_DEBUG_RECV)
2507
0
      zlog_debug("%s: Unable to decode zapi_labels sent",
2508
1
           __func__);
2509
1
    return;
2510
1
  }
2511
2512
0
  if (!mpls_enabled)
2513
0
    return;
2514
2515
0
  if (zl.nexthop_num > 0) {
2516
0
    mpls_zapi_labels_process(false /*delete*/, zvrf, &zl);
2517
0
  } else {
2518
0
    mpls_lsp_uninstall_all_vrf(zvrf, zl.type, zl.local_label);
2519
2520
0
    if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN))
2521
0
      mpls_ftn_uninstall(zvrf, zl.type, &zl.route.prefix,
2522
0
             zl.route.type, zl.route.instance);
2523
0
  }
2524
0
}
2525
2526
/*
2527
 * Handle request to add an MPLS LSP or change an existing one.
2528
 *
2529
 * A single message can fully specify an LSP with multiple nexthops.
2530
 *
2531
 * When the optional ZAPI_LABELS_FTN flag is set, the specified FEC (route) is
2532
 * updated to use the received label(s).
2533
 *
2534
 * NOTE: zebra will use route replace semantics (make-before-break) to update
2535
 * the LSP in the forwarding plane if that's supported by the underlying
2536
 * platform.
2537
 */
2538
static void zread_mpls_labels_replace(ZAPI_HANDLER_ARGS)
2539
0
{
2540
0
  struct stream *s;
2541
0
  struct zapi_labels zl;
2542
2543
  /* Get input stream.  */
2544
0
  s = msg;
2545
0
  if (zapi_labels_decode(s, &zl) < 0) {
2546
0
    if (IS_ZEBRA_DEBUG_RECV)
2547
0
      zlog_debug("%s: Unable to decode zapi_labels sent",
2548
0
           __func__);
2549
0
    return;
2550
0
  }
2551
2552
0
  if (!mpls_enabled)
2553
0
    return;
2554
2555
  /* Validate; will debug on failure */
2556
0
  if (zapi_labels_validate(&zl) < 0)
2557
0
    return;
2558
2559
  /* This removes everything, then re-adds from the client's
2560
   * zapi message. Since the LSP will be processed later, on this
2561
   * this same pthread, all of the changes will 'appear' at once.
2562
   */
2563
0
  mpls_lsp_uninstall_all_vrf(zvrf, zl.type, zl.local_label);
2564
0
  if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN))
2565
0
    mpls_ftn_uninstall(zvrf, zl.type, &zl.route.prefix,
2566
0
           zl.route.type, zl.route.instance);
2567
2568
0
  mpls_zapi_labels_process(true, zvrf, &zl);
2569
0
}
2570
2571
static void zread_sr_policy_set(ZAPI_HANDLER_ARGS)
2572
5
{
2573
5
  struct stream *s;
2574
5
  struct zapi_sr_policy zp;
2575
5
  struct zapi_srte_tunnel *zt;
2576
5
  struct zebra_sr_policy *policy;
2577
2578
  /* Get input stream.  */
2579
5
  s = msg;
2580
5
  if (zapi_sr_policy_decode(s, &zp) < 0) {
2581
2
    if (IS_ZEBRA_DEBUG_RECV)
2582
0
      zlog_debug("%s: Unable to decode zapi_sr_policy sent",
2583
2
           __func__);
2584
2
    return;
2585
2
  }
2586
3
  zt = &zp.segment_list;
2587
3
  if (zt->label_num < 1) {
2588
2
    if (IS_ZEBRA_DEBUG_RECV)
2589
0
      zlog_debug(
2590
2
        "%s: SR-TE tunnel must contain at least one label",
2591
2
        __func__);
2592
2
    return;
2593
2
  }
2594
2595
1
  if (!mpls_enabled)
2596
1
    return;
2597
2598
0
  policy = zebra_sr_policy_find(zp.color, &zp.endpoint);
2599
0
  if (!policy) {
2600
0
    policy = zebra_sr_policy_add(zp.color, &zp.endpoint, zp.name);
2601
0
    policy->sock = client->sock;
2602
0
  }
2603
  /* TODO: per-VRF list of SR-TE policies. */
2604
0
  policy->zvrf = zvrf;
2605
2606
0
  zebra_sr_policy_validate(policy, &zp.segment_list);
2607
0
}
2608
2609
static void zread_sr_policy_delete(ZAPI_HANDLER_ARGS)
2610
2
{
2611
2
  struct stream *s;
2612
2
  struct zapi_sr_policy zp;
2613
2
  struct zebra_sr_policy *policy;
2614
2615
  /* Get input stream.  */
2616
2
  s = msg;
2617
2
  if (zapi_sr_policy_decode(s, &zp) < 0) {
2618
0
    if (IS_ZEBRA_DEBUG_RECV)
2619
0
      zlog_debug("%s: Unable to decode zapi_sr_policy sent",
2620
0
           __func__);
2621
0
    return;
2622
0
  }
2623
2624
2
  if (!mpls_enabled)
2625
2
    return;
2626
2627
0
  policy = zebra_sr_policy_find(zp.color, &zp.endpoint);
2628
0
  if (!policy) {
2629
0
    if (IS_ZEBRA_DEBUG_RECV)
2630
0
      zlog_debug("%s: Unable to find SR-TE policy", __func__);
2631
0
    return;
2632
0
  }
2633
2634
0
  zebra_sr_policy_del(policy);
2635
0
}
2636
2637
int zsend_sr_policy_notify_status(uint32_t color, struct ipaddr *endpoint,
2638
          char *name, int status)
2639
0
{
2640
0
  struct zserv *client;
2641
0
  struct stream *s;
2642
2643
0
  client = zserv_find_client(ZEBRA_ROUTE_SRTE, 0);
2644
0
  if (!client) {
2645
0
    if (IS_ZEBRA_DEBUG_PACKET)
2646
0
      zlog_debug(
2647
0
        "Not notifying pathd about policy %s"
2648
0
        " status change to %d",
2649
0
        name, status);
2650
0
    return 0;
2651
0
  }
2652
2653
0
  if (IS_ZEBRA_DEBUG_PACKET)
2654
0
    zlog_debug(
2655
0
      "Notifying pathd about policy %s status change"
2656
0
      " to %d",
2657
0
      name, status);
2658
2659
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2660
0
  stream_reset(s);
2661
2662
0
  zclient_create_header(s, ZEBRA_SR_POLICY_NOTIFY_STATUS, VRF_DEFAULT);
2663
0
  stream_putl(s, color);
2664
0
  stream_put_ipaddr(s, endpoint);
2665
0
  stream_write(s, name, SRTE_POLICY_NAME_MAX_LENGTH);
2666
0
  stream_putl(s, status);
2667
2668
0
  stream_putw_at(s, 0, stream_get_endp(s));
2669
2670
0
  return zserv_send_message(client, s);
2671
0
}
2672
2673
/* Send client close notify to client */
2674
int zsend_client_close_notify(struct zserv *client, struct zserv *closed_client)
2675
0
{
2676
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2677
2678
0
  zclient_create_header(s, ZEBRA_CLIENT_CLOSE_NOTIFY, VRF_DEFAULT);
2679
2680
0
  stream_putc(s, closed_client->proto);
2681
0
  stream_putw(s, closed_client->instance);
2682
0
  stream_putl(s, closed_client->session_id);
2683
2684
0
  stream_putw_at(s, 0, stream_get_endp(s));
2685
2686
0
  return zserv_send_message(client, s);
2687
0
}
2688
2689
int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client,
2690
              vrf_id_t vrf_id,
2691
              struct srv6_locator *loc)
2692
0
{
2693
0
  struct srv6_locator_chunk chunk = {};
2694
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
2695
2696
0
  strlcpy(chunk.locator_name, loc->name, sizeof(chunk.locator_name));
2697
0
  chunk.prefix = loc->prefix;
2698
0
  chunk.block_bits_length = loc->block_bits_length;
2699
0
  chunk.node_bits_length = loc->node_bits_length;
2700
0
  chunk.function_bits_length = loc->function_bits_length;
2701
0
  chunk.argument_bits_length = loc->argument_bits_length;
2702
0
  chunk.keep = 0;
2703
0
  chunk.proto = client->proto;
2704
0
  chunk.instance = client->instance;
2705
0
  chunk.flags = loc->flags;
2706
2707
0
  zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, vrf_id);
2708
0
  zapi_srv6_locator_chunk_encode(s, &chunk);
2709
0
  stream_putw_at(s, 0, stream_get_endp(s));
2710
0
  return zserv_send_message(client, s);
2711
0
}
2712
2713
/* Send response to a table manager connect request to client */
2714
static void zread_table_manager_connect(struct zserv *client,
2715
          struct stream *msg, vrf_id_t vrf_id)
2716
0
{
2717
0
  struct stream *s;
2718
0
  uint8_t proto;
2719
0
  uint16_t instance;
2720
0
  struct vrf *vrf = vrf_lookup_by_id(vrf_id);
2721
2722
0
  s = msg;
2723
2724
  /* Get data. */
2725
0
  STREAM_GETC(s, proto);
2726
0
  STREAM_GETW(s, instance);
2727
2728
  /* accept only dynamic routing protocols */
2729
0
  if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
2730
0
    flog_err(EC_ZEBRA_TM_WRONG_PROTO,
2731
0
       "client %d has wrong protocol %s", client->sock,
2732
0
       zebra_route_string(proto));
2733
0
    zsend_table_manager_connect_response(client, vrf_id, 1);
2734
0
    return;
2735
0
  }
2736
0
  zlog_notice("client %d with vrf %s(%u) instance %u connected as %s",
2737
0
        client->sock, VRF_LOGNAME(vrf), vrf_id, instance,
2738
0
        zebra_route_string(proto));
2739
0
  client->proto = proto;
2740
0
  client->instance = instance;
2741
2742
  /*
2743
   * Release previous labels of same protocol and instance.
2744
   * This is done in case it restarted from an unexpected shutdown.
2745
   */
2746
0
  release_daemon_table_chunks(client);
2747
2748
0
  zsend_table_manager_connect_response(client, vrf_id, 0);
2749
2750
0
stream_failure:
2751
0
  return;
2752
0
}
2753
2754
static void zread_label_manager_connect(struct zserv *client,
2755
          struct stream *msg, vrf_id_t vrf_id)
2756
0
{
2757
0
  struct stream *s;
2758
  /* type of protocol (lib/zebra.h) */
2759
0
  uint8_t proto;
2760
0
  unsigned short instance;
2761
2762
  /* Get input stream.  */
2763
0
  s = msg;
2764
2765
  /* Get data. */
2766
0
  STREAM_GETC(s, proto);
2767
0
  STREAM_GETW(s, instance);
2768
2769
  /* accept only dynamic routing protocols */
2770
0
  if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) {
2771
0
    flog_err(EC_ZEBRA_TM_WRONG_PROTO,
2772
0
       "client %d has wrong protocol %s", client->sock,
2773
0
       zebra_route_string(proto));
2774
0
    zsend_label_manager_connect_response(client, vrf_id, 1);
2775
0
    return;
2776
0
  }
2777
2778
  /* recall proto and instance in this socket */
2779
0
  client->proto = proto;
2780
0
  client->instance = instance;
2781
2782
  /* call hook for connection using wrapper */
2783
0
  lm_client_connect_call(client, vrf_id);
2784
2785
0
stream_failure:
2786
0
  return;
2787
0
}
2788
2789
static void zread_get_label_chunk(struct zserv *client, struct stream *msg,
2790
          vrf_id_t vrf_id)
2791
0
{
2792
0
  struct stream *s;
2793
0
  uint8_t keep;
2794
0
  uint32_t size, base;
2795
0
  struct label_manager_chunk *lmc = NULL;
2796
0
  uint8_t proto;
2797
0
  unsigned short instance;
2798
2799
  /* Get input stream.  */
2800
0
  s = msg;
2801
2802
  /* Get data. */
2803
0
  STREAM_GETC(s, proto);
2804
0
  STREAM_GETW(s, instance);
2805
0
  STREAM_GETC(s, keep);
2806
0
  STREAM_GETL(s, size);
2807
0
  STREAM_GETL(s, base);
2808
2809
#ifndef FUZZING
2810
  assert(proto == client->proto && instance == client->instance);
2811
#endif
2812
2813
  /* call hook to get a chunk using wrapper */
2814
0
  lm_get_chunk_call(&lmc, client, keep, size, base, vrf_id);
2815
2816
0
stream_failure:
2817
0
  return;
2818
0
}
2819
2820
static void zread_release_label_chunk(struct zserv *client, struct stream *msg)
2821
0
{
2822
0
  struct stream *s;
2823
0
  uint32_t start, end;
2824
0
  uint8_t proto;
2825
0
  unsigned short instance;
2826
2827
  /* Get input stream.  */
2828
0
  s = msg;
2829
2830
  /* Get data. */
2831
0
  STREAM_GETC(s, proto);
2832
0
  STREAM_GETW(s, instance);
2833
0
  STREAM_GETL(s, start);
2834
0
  STREAM_GETL(s, end);
2835
2836
#ifndef FUZZING
2837
  assert(proto == client->proto && instance == client->instance);
2838
#endif
2839
  /* call hook to release a chunk using wrapper */
2840
0
  lm_release_chunk_call(client, start, end);
2841
2842
0
stream_failure:
2843
0
  return;
2844
0
}
2845
2846
static void zread_label_manager_request(ZAPI_HANDLER_ARGS)
2847
0
{
2848
0
  if (hdr->command == ZEBRA_LABEL_MANAGER_CONNECT
2849
0
      || hdr->command == ZEBRA_LABEL_MANAGER_CONNECT_ASYNC)
2850
0
    zread_label_manager_connect(client, msg, zvrf_id(zvrf));
2851
0
  else {
2852
0
    if (hdr->command == ZEBRA_GET_LABEL_CHUNK)
2853
0
      zread_get_label_chunk(client, msg, zvrf_id(zvrf));
2854
0
    else if (hdr->command == ZEBRA_RELEASE_LABEL_CHUNK)
2855
0
      zread_release_label_chunk(client, msg);
2856
0
  }
2857
0
}
2858
2859
static void zread_get_table_chunk(struct zserv *client, struct stream *msg,
2860
          struct zebra_vrf *zvrf)
2861
0
{
2862
0
  struct stream *s;
2863
0
  uint32_t size;
2864
0
  struct table_manager_chunk *tmc;
2865
2866
  /* Get input stream.  */
2867
0
  s = msg;
2868
2869
  /* Get data. */
2870
0
  STREAM_GETL(s, size);
2871
2872
0
  tmc = assign_table_chunk(client->proto, client->instance, size, zvrf);
2873
0
  if (!tmc)
2874
0
    flog_err(EC_ZEBRA_TM_CANNOT_ASSIGN_CHUNK,
2875
0
       "%s: Unable to assign Table Chunk of size %u",
2876
0
       __func__, size);
2877
0
  else
2878
0
    zlog_debug("Assigned Table Chunk %u - %u", tmc->start,
2879
0
         tmc->end);
2880
  /* send response back */
2881
0
  zsend_assign_table_chunk_response(client, zvrf_id(zvrf), tmc);
2882
2883
0
stream_failure:
2884
0
  return;
2885
0
}
2886
2887
static void zread_release_table_chunk(struct zserv *client, struct stream *msg,
2888
              struct zebra_vrf *zvrf)
2889
0
{
2890
0
  struct stream *s;
2891
0
  uint32_t start, end;
2892
2893
  /* Get input stream.  */
2894
0
  s = msg;
2895
2896
  /* Get data. */
2897
0
  STREAM_GETL(s, start);
2898
0
  STREAM_GETL(s, end);
2899
2900
0
  release_table_chunk(client->proto, client->instance, start, end, zvrf);
2901
2902
0
stream_failure:
2903
0
  return;
2904
0
}
2905
2906
static void zread_table_manager_request(ZAPI_HANDLER_ARGS)
2907
0
{
2908
  /* to avoid sending other messages like ZEBRA_INTERFACE_UP */
2909
0
  if (hdr->command == ZEBRA_TABLE_MANAGER_CONNECT)
2910
0
    zread_table_manager_connect(client, msg, zvrf_id(zvrf));
2911
0
  else {
2912
    /* Sanity: don't allow 'unidentified' requests */
2913
0
    if (!client->proto) {
2914
0
      flog_err(
2915
0
        EC_ZEBRA_TM_ALIENS,
2916
0
        "Got SRv6 request from an unidentified client");
2917
0
      return;
2918
0
    }
2919
0
    if (hdr->command == ZEBRA_GET_TABLE_CHUNK)
2920
0
      zread_get_table_chunk(client, msg, zvrf);
2921
0
    else if (hdr->command == ZEBRA_RELEASE_TABLE_CHUNK)
2922
0
      zread_release_table_chunk(client, msg, zvrf);
2923
0
  }
2924
0
}
2925
2926
static void zread_srv6_manager_get_locator_chunk(struct zserv *client,
2927
             struct stream *msg,
2928
             vrf_id_t vrf_id)
2929
0
{
2930
0
  struct stream *s = msg;
2931
0
  uint16_t len;
2932
0
  char locator_name[SRV6_LOCNAME_SIZE] = {0};
2933
2934
  /* Get data. */
2935
0
  STREAM_GETW(s, len);
2936
0
  STREAM_GET(locator_name, s, len);
2937
2938
  /* call hook to get a chunk using wrapper */
2939
0
  struct srv6_locator *loc = NULL;
2940
0
  srv6_manager_get_locator_chunk_call(&loc, client, locator_name, vrf_id);
2941
2942
0
stream_failure:
2943
0
  return;
2944
0
}
2945
2946
static void zread_srv6_manager_release_locator_chunk(struct zserv *client,
2947
                 struct stream *msg,
2948
                 vrf_id_t vrf_id)
2949
0
{
2950
0
  struct stream *s = msg;
2951
0
  uint16_t len;
2952
0
  char locator_name[SRV6_LOCNAME_SIZE] = {0};
2953
2954
  /* Get data. */
2955
0
  STREAM_GETW(s, len);
2956
0
  STREAM_GET(locator_name, s, len);
2957
2958
  /* call hook to release a chunk using wrapper */
2959
0
  srv6_manager_release_locator_chunk_call(client, locator_name, vrf_id);
2960
2961
0
stream_failure:
2962
0
  return;
2963
0
}
2964
2965
static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS)
2966
0
{
2967
0
  switch (hdr->command) {
2968
0
  case ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK:
2969
0
    zread_srv6_manager_get_locator_chunk(client, msg,
2970
0
                 zvrf_id(zvrf));
2971
0
    break;
2972
0
  case ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK:
2973
0
    zread_srv6_manager_release_locator_chunk(client, msg,
2974
0
               zvrf_id(zvrf));
2975
0
    break;
2976
0
  default:
2977
0
    zlog_err("%s: unknown SRv6 Manager command", __func__);
2978
0
    break;
2979
0
  }
2980
0
}
2981
2982
static void zread_pseudowire(ZAPI_HANDLER_ARGS)
2983
0
{
2984
0
  struct stream *s;
2985
0
  char ifname[INTERFACE_NAMSIZ];
2986
0
  ifindex_t ifindex;
2987
0
  int type;
2988
0
  int af;
2989
0
  union g_addr nexthop;
2990
0
  uint32_t local_label;
2991
0
  uint32_t remote_label;
2992
0
  uint8_t flags;
2993
0
  union pw_protocol_fields data;
2994
0
  uint8_t protocol;
2995
0
  struct zebra_pw *pw;
2996
2997
  /* Get input stream.  */
2998
0
  s = msg;
2999
3000
  /* Get data. */
3001
0
  STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
3002
0
  ifname[INTERFACE_NAMSIZ - 1] = '\0';
3003
0
  STREAM_GETL(s, ifindex);
3004
0
  STREAM_GETL(s, type);
3005
0
  STREAM_GETL(s, af);
3006
0
  switch (af) {
3007
0
  case AF_INET:
3008
0
    STREAM_GET(&nexthop.ipv4.s_addr, s, IPV4_MAX_BYTELEN);
3009
0
    break;
3010
0
  case AF_INET6:
3011
0
    STREAM_GET(&nexthop.ipv6, s, 16);
3012
0
    break;
3013
0
  default:
3014
0
    return;
3015
0
  }
3016
0
  STREAM_GETL(s, local_label);
3017
0
  STREAM_GETL(s, remote_label);
3018
0
  STREAM_GETC(s, flags);
3019
0
  STREAM_GET(&data, s, sizeof(data));
3020
0
  protocol = client->proto;
3021
3022
0
  pw = zebra_pw_find(zvrf, ifname);
3023
0
  switch (hdr->command) {
3024
0
  case ZEBRA_PW_ADD:
3025
0
    if (pw) {
3026
0
      flog_warn(EC_ZEBRA_PSEUDOWIRE_EXISTS,
3027
0
          "%s: pseudowire %s already exists [%s]",
3028
0
          __func__, ifname,
3029
0
          zserv_command_string(hdr->command));
3030
0
      return;
3031
0
    }
3032
3033
0
    zebra_pw_add(zvrf, ifname, protocol, client);
3034
0
    break;
3035
0
  case ZEBRA_PW_DELETE:
3036
0
    if (!pw) {
3037
0
      flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
3038
0
          "%s: pseudowire %s not found [%s]", __func__,
3039
0
          ifname, zserv_command_string(hdr->command));
3040
0
      return;
3041
0
    }
3042
3043
0
    zebra_pw_del(zvrf, pw);
3044
0
    break;
3045
0
  case ZEBRA_PW_SET:
3046
0
  case ZEBRA_PW_UNSET:
3047
0
    if (!pw) {
3048
0
      flog_warn(EC_ZEBRA_PSEUDOWIRE_NONEXISTENT,
3049
0
          "%s: pseudowire %s not found [%s]", __func__,
3050
0
          ifname, zserv_command_string(hdr->command));
3051
0
      return;
3052
0
    }
3053
3054
0
    switch (hdr->command) {
3055
0
    case ZEBRA_PW_SET:
3056
0
      pw->enabled = 1;
3057
0
      break;
3058
0
    case ZEBRA_PW_UNSET:
3059
0
      pw->enabled = 0;
3060
0
      break;
3061
0
    }
3062
3063
0
    zebra_pw_change(pw, ifindex, type, af, &nexthop, local_label,
3064
0
        remote_label, flags, &data);
3065
0
    break;
3066
0
  }
3067
3068
0
stream_failure:
3069
0
  return;
3070
0
}
3071
3072
static void zread_interface_set_master(ZAPI_HANDLER_ARGS)
3073
0
{
3074
0
  struct interface *master;
3075
0
  struct interface *slave;
3076
0
  struct stream *s = msg;
3077
0
  int ifindex;
3078
0
  vrf_id_t vrf_id;
3079
3080
0
  STREAM_GETL(s, vrf_id);
3081
0
  STREAM_GETL(s, ifindex);
3082
0
  master = if_lookup_by_index(ifindex, vrf_id);
3083
3084
0
  STREAM_GETL(s, vrf_id);
3085
0
  STREAM_GETL(s, ifindex);
3086
0
  slave = if_lookup_by_index(ifindex, vrf_id);
3087
3088
0
  if (!master || !slave)
3089
0
    return;
3090
3091
0
  kernel_interface_set_master(master, slave);
3092
3093
0
stream_failure:
3094
0
  return;
3095
0
}
3096
3097
3098
static void zread_vrf_label(ZAPI_HANDLER_ARGS)
3099
0
{
3100
0
  struct interface *ifp;
3101
0
  mpls_label_t nlabel;
3102
0
  afi_t afi;
3103
0
  struct stream *s;
3104
0
  struct zebra_vrf *def_zvrf;
3105
0
  enum lsp_types_t ltype;
3106
3107
0
  s = msg;
3108
0
  STREAM_GETL(s, nlabel);
3109
0
  STREAM_GETC(s, afi);
3110
3111
0
  if (!(IS_VALID_AFI(afi))) {
3112
0
    zlog_warn("Invalid AFI for VRF label: %u", afi);
3113
0
    return;
3114
0
  }
3115
3116
0
  if (nlabel == zvrf->label[afi]) {
3117
    /*
3118
     * Nothing to do here move along
3119
     */
3120
0
    return;
3121
0
  }
3122
3123
0
  STREAM_GETC(s, ltype);
3124
3125
0
  if (zvrf->vrf->vrf_id != VRF_DEFAULT)
3126
0
    ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id);
3127
0
  else
3128
0
    ifp = if_lookup_by_name("lo", VRF_DEFAULT);
3129
3130
0
  if (!ifp) {
3131
0
    zlog_debug("Unable to find specified Interface for %s",
3132
0
         zvrf->vrf->name);
3133
0
    return;
3134
0
  }
3135
3136
0
  def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
3137
3138
0
  if (zvrf->label[afi] != MPLS_LABEL_NONE) {
3139
0
    afi_t scrubber;
3140
0
    bool really_remove;
3141
3142
0
    really_remove = true;
3143
0
    for (scrubber = AFI_IP; scrubber < AFI_MAX; scrubber++) {
3144
0
      if (scrubber == afi)
3145
0
        continue;
3146
3147
0
      if (zvrf->label[scrubber] == MPLS_LABEL_NONE)
3148
0
        continue;
3149
3150
0
      if (zvrf->label[afi] == zvrf->label[scrubber]) {
3151
0
        really_remove = false;
3152
0
        break;
3153
0
      }
3154
0
    }
3155
3156
0
    if (really_remove)
3157
0
      mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi],
3158
0
             NEXTHOP_TYPE_IFINDEX, NULL,
3159
0
             ifp->ifindex, false /*backup*/);
3160
0
  }
3161
3162
0
  if (nlabel != MPLS_LABEL_NONE) {
3163
0
    mpls_label_t out_label = MPLS_LABEL_IMPLICIT_NULL;
3164
0
    mpls_lsp_install(def_zvrf, ltype, nlabel, 1, &out_label,
3165
0
         NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex);
3166
0
  }
3167
3168
0
  zvrf->label[afi] = nlabel;
3169
0
  zvrf->label_proto[afi] = client->proto;
3170
3171
0
stream_failure:
3172
0
  return;
3173
0
}
3174
3175
static inline void zread_rule(ZAPI_HANDLER_ARGS)
3176
58
{
3177
58
  struct zebra_pbr_rule zpr;
3178
58
  struct stream *s;
3179
58
  uint32_t total, i;
3180
58
  char ifname[INTERFACE_NAMSIZ + 1] = {};
3181
3182
58
  s = msg;
3183
58
  STREAM_GETL(s, total);
3184
3185
1.98k
  for (i = 0; i < total; i++) {
3186
1.98k
    memset(&zpr, 0, sizeof(zpr));
3187
3188
1.98k
    zpr.sock = client->sock;
3189
1.98k
    zpr.rule.vrf_id = hdr->vrf_id;
3190
1.98k
    STREAM_GETL(s, zpr.rule.seq);
3191
1.98k
    STREAM_GETL(s, zpr.rule.priority);
3192
1.98k
    STREAM_GETL(s, zpr.rule.unique);
3193
1.97k
    STREAM_GETC(s, zpr.rule.filter.ip_proto);
3194
1.97k
    STREAM_GETC(s, zpr.rule.filter.src_ip.family);
3195
1.97k
    STREAM_GETC(s, zpr.rule.filter.src_ip.prefixlen);
3196
1.97k
    STREAM_GET(&zpr.rule.filter.src_ip.u.prefix, s,
3197
1.97k
         prefix_blen(&zpr.rule.filter.src_ip));
3198
1.97k
    STREAM_GETW(s, zpr.rule.filter.src_port);
3199
1.97k
    STREAM_GETC(s, zpr.rule.filter.dst_ip.family);
3200
1.97k
    STREAM_GETC(s, zpr.rule.filter.dst_ip.prefixlen);
3201
1.97k
    STREAM_GET(&zpr.rule.filter.dst_ip.u.prefix, s,
3202
1.97k
         prefix_blen(&zpr.rule.filter.dst_ip));
3203
1.97k
    STREAM_GETW(s, zpr.rule.filter.dst_port);
3204
1.97k
    STREAM_GETC(s, zpr.rule.filter.dsfield);
3205
1.97k
    STREAM_GETL(s, zpr.rule.filter.fwmark);
3206
3207
1.97k
    STREAM_GETL(s, zpr.rule.action.queue_id);
3208
1.97k
    STREAM_GETW(s, zpr.rule.action.vlan_id);
3209
1.97k
    STREAM_GETW(s, zpr.rule.action.vlan_flags);
3210
1.97k
    STREAM_GETW(s, zpr.rule.action.pcp);
3211
3212
1.97k
    STREAM_GETL(s, zpr.rule.action.table);
3213
1.97k
    STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
3214
3215
1.96k
    strlcpy(zpr.ifname, ifname, sizeof(zpr.ifname));
3216
1.96k
    strlcpy(zpr.rule.ifname, ifname, sizeof(zpr.rule.ifname));
3217
3218
1.96k
    if (!is_default_prefix(&zpr.rule.filter.src_ip))
3219
1.95k
      zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_IP;
3220
3221
1.96k
    if (!is_default_prefix(&zpr.rule.filter.dst_ip))
3222
1.94k
      zpr.rule.filter.filter_bm |= PBR_FILTER_DST_IP;
3223
3224
1.96k
    if (zpr.rule.filter.src_port)
3225
1.85k
      zpr.rule.filter.filter_bm |= PBR_FILTER_SRC_PORT;
3226
3227
1.96k
    if (zpr.rule.filter.dst_port)
3228
1.57k
      zpr.rule.filter.filter_bm |= PBR_FILTER_DST_PORT;
3229
3230
1.96k
    if (zpr.rule.filter.dsfield)
3231
1.47k
      zpr.rule.filter.filter_bm |= PBR_FILTER_DSFIELD;
3232
3233
1.96k
    if (zpr.rule.filter.ip_proto)
3234
1.86k
      zpr.rule.filter.filter_bm |= PBR_FILTER_IP_PROTOCOL;
3235
3236
1.96k
    if (zpr.rule.filter.fwmark)
3237
1.81k
      zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
3238
3239
1.96k
    if (!(zpr.rule.filter.src_ip.family == AF_INET
3240
1.03k
          || zpr.rule.filter.src_ip.family == AF_INET6)) {
3241
26
      zlog_warn(
3242
26
        "Unsupported PBR source IP family: %s (%hhu)",
3243
26
        family2str(zpr.rule.filter.src_ip.family),
3244
26
        zpr.rule.filter.src_ip.family);
3245
26
      return;
3246
26
    }
3247
1.93k
    if (!(zpr.rule.filter.dst_ip.family == AF_INET
3248
927
          || zpr.rule.filter.dst_ip.family == AF_INET6)) {
3249
16
      zlog_warn(
3250
16
        "Unsupported PBR destination IP family: %s (%hhu)",
3251
16
        family2str(zpr.rule.filter.dst_ip.family),
3252
16
        zpr.rule.filter.dst_ip.family);
3253
16
      return;
3254
16
    }
3255
3256
3257
1.92k
    zpr.vrf_id = zvrf->vrf->vrf_id;
3258
1.92k
    if (hdr->command == ZEBRA_RULE_ADD)
3259
1.87k
      zebra_pbr_add_rule(&zpr);
3260
49
    else
3261
49
      zebra_pbr_del_rule(&zpr);
3262
1.92k
  }
3263
3264
16
stream_failure:
3265
16
  return;
3266
58
}
3267
3268
static inline void zread_tc_qdisc(ZAPI_HANDLER_ARGS)
3269
13
{
3270
13
  struct zebra_tc_qdisc qdisc;
3271
13
  struct stream *s;
3272
13
  uint32_t total, i;
3273
3274
13
  s = msg;
3275
13
  STREAM_GETL(s, total);
3276
3277
2.75k
  for (i = 0; i < total; i++) {
3278
2.75k
    memset(&qdisc, 0, sizeof(qdisc));
3279
3280
2.75k
    qdisc.sock = client->sock;
3281
2.75k
    STREAM_GETL(s, qdisc.qdisc.ifindex);
3282
2.74k
    STREAM_GETL(s, qdisc.qdisc.kind);
3283
3284
2.74k
    if (hdr->command == ZEBRA_TC_QDISC_INSTALL)
3285
1.85k
      zebra_tc_qdisc_install(&qdisc);
3286
894
    else
3287
894
      zebra_tc_qdisc_uninstall(&qdisc);
3288
2.74k
  }
3289
3290
13
stream_failure:
3291
13
  return;
3292
13
}
3293
3294
static inline void zread_tc_class(ZAPI_HANDLER_ARGS)
3295
28
{
3296
28
  struct zebra_tc_class class;
3297
28
  struct stream *s;
3298
28
  uint32_t total, i;
3299
3300
28
  s = msg;
3301
28
  STREAM_GETL(s, total);
3302
3303
5.41k
  for (i = 0; i < total; i++) {
3304
5.41k
    memset(&class, 0, sizeof(class));
3305
3306
5.41k
    class.sock = client->sock;
3307
5.41k
    STREAM_GETL(s, class.class.ifindex);
3308
5.39k
    STREAM_GETL(s, class.class.handle);
3309
5.39k
    STREAM_GETL(s, class.class.kind);
3310
5.39k
    STREAM_GETQ(s, class.class.u.htb.rate);
3311
5.39k
    STREAM_GETQ(s, class.class.u.htb.ceil);
3312
3313
5.38k
    if (hdr->command == ZEBRA_TC_CLASS_ADD)
3314
2.54k
      zebra_tc_class_add(&class);
3315
2.83k
    else
3316
2.83k
      zebra_tc_class_delete(&class);
3317
5.38k
  }
3318
3319
28
stream_failure:
3320
28
  return;
3321
28
}
3322
3323
static inline void zread_tc_filter(ZAPI_HANDLER_ARGS)
3324
58
{
3325
58
  struct zebra_tc_filter filter;
3326
58
  struct stream *s;
3327
58
  uint32_t total, i;
3328
3329
58
  s = msg;
3330
58
  STREAM_GETL(s, total);
3331
3332
13.8k
  for (i = 0; i < total; i++) {
3333
13.8k
    memset(&filter, 0, sizeof(filter));
3334
3335
13.8k
    filter.sock = client->sock;
3336
13.8k
    STREAM_GETL(s, filter.filter.ifindex);
3337
13.8k
    STREAM_GETL(s, filter.filter.handle);
3338
13.8k
    STREAM_GETL(s, filter.filter.priority);
3339
13.8k
    STREAM_GETL(s, filter.filter.protocol);
3340
13.8k
    STREAM_GETL(s, filter.filter.kind);
3341
13.8k
    switch (filter.filter.kind) {
3342
607
    case TC_FILTER_FLOWER: {
3343
607
      STREAM_GETL(s, filter.filter.u.flower.filter_bm);
3344
607
      uint32_t filter_bm = filter.filter.u.flower.filter_bm;
3345
3346
607
      if (filter_bm & TC_FLOWER_IP_PROTOCOL)
3347
325
        STREAM_GETC(s, filter.filter.u.flower.ip_proto);
3348
607
      if (filter_bm & TC_FLOWER_SRC_IP) {
3349
293
        STREAM_GETC(
3350
293
          s,
3351
293
          filter.filter.u.flower.src_ip.family);
3352
293
        STREAM_GETC(s, filter.filter.u.flower.src_ip
3353
293
                   .prefixlen);
3354
293
        STREAM_GET(
3355
293
          &filter.filter.u.flower.src_ip.u.prefix,
3356
293
          s,
3357
293
          prefix_blen(&filter.filter.u.flower
3358
293
                   .src_ip));
3359
3360
293
        if (!(filter.filter.u.flower.src_ip.family ==
3361
293
                AF_INET ||
3362
140
              filter.filter.u.flower.src_ip.family ==
3363
140
                AF_INET6)) {
3364
5
          zlog_warn(
3365
5
            "Unsupported TC source IP family: %s (%hhu)",
3366
5
            family2str(
3367
5
              filter.filter.u.flower
3368
5
                .src_ip.family),
3369
5
            filter.filter.u.flower.src_ip
3370
5
              .family);
3371
5
          return;
3372
5
        }
3373
293
      }
3374
602
      if (filter_bm & TC_FLOWER_SRC_PORT) {
3375
361
        STREAM_GETW(
3376
361
          s, filter.filter.u.flower.src_port_min);
3377
360
        STREAM_GETW(
3378
360
          s, filter.filter.u.flower.src_port_max);
3379
360
      }
3380
601
      if (filter_bm & TC_FLOWER_DST_IP) {
3381
161
        STREAM_GETC(
3382
161
          s,
3383
161
          filter.filter.u.flower.dst_ip.family);
3384
161
        STREAM_GETC(s, filter.filter.u.flower.dst_ip
3385
161
                   .prefixlen);
3386
161
        STREAM_GET(
3387
161
          &filter.filter.u.flower.dst_ip.u.prefix,
3388
161
          s,
3389
161
          prefix_blen(&filter.filter.u.flower
3390
161
                   .dst_ip));
3391
161
        if (!(filter.filter.u.flower.dst_ip.family ==
3392
161
                AF_INET ||
3393
89
              filter.filter.u.flower.dst_ip.family ==
3394
89
                AF_INET6)) {
3395
1
          zlog_warn(
3396
1
            "Unsupported TC destination IP family: %s (%hhu)",
3397
1
            family2str(
3398
1
              filter.filter.u.flower
3399
1
                .dst_ip.family),
3400
1
            filter.filter.u.flower.dst_ip
3401
1
              .family);
3402
1
          return;
3403
1
        }
3404
161
      }
3405
600
      if (filter_bm & TC_FLOWER_DST_PORT) {
3406
166
        STREAM_GETW(
3407
166
          s, filter.filter.u.flower.dst_port_min);
3408
166
        STREAM_GETW(
3409
166
          s, filter.filter.u.flower.dst_port_max);
3410
166
      }
3411
600
      if (filter_bm & TC_FLOWER_DSFIELD) {
3412
256
        STREAM_GETC(s, filter.filter.u.flower.dsfield);
3413
256
        STREAM_GETC(
3414
256
          s, filter.filter.u.flower.dsfield_mask);
3415
256
      }
3416
600
      STREAM_GETL(s, filter.filter.u.flower.classid);
3417
600
      break;
3418
600
    }
3419
600
    case TC_FILTER_BPF:
3420
57
    case TC_FILTER_FLOW:
3421
63
    case TC_FILTER_U32:
3422
581
    case TC_FILTER_UNSPEC:
3423
581
      break;
3424
13.8k
    }
3425
3426
13.8k
    if (hdr->command == ZEBRA_TC_FILTER_ADD)
3427
6.57k
      zebra_tc_filter_add(&filter);
3428
7.24k
    else
3429
7.24k
      zebra_tc_filter_delete(&filter);
3430
13.8k
  }
3431
3432
52
stream_failure:
3433
52
  return;
3434
58
}
3435
3436
static inline void zread_ipset(ZAPI_HANDLER_ARGS)
3437
29
{
3438
29
  struct zebra_pbr_ipset zpi;
3439
29
  struct stream *s;
3440
29
  uint32_t total, i;
3441
3442
29
  s = msg;
3443
29
  STREAM_GETL(s, total);
3444
3445
4.03k
  for (i = 0; i < total; i++) {
3446
4.03k
    memset(&zpi, 0, sizeof(zpi));
3447
3448
4.03k
    zpi.sock = client->sock;
3449
4.03k
    zpi.vrf_id = zvrf->vrf->vrf_id;
3450
4.03k
    STREAM_GETL(s, zpi.unique);
3451
4.03k
    STREAM_GETL(s, zpi.type);
3452
4.03k
    STREAM_GETC(s, zpi.family);
3453
4.03k
    STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
3454
3455
4.00k
    if (hdr->command == ZEBRA_IPSET_CREATE)
3456
3.75k
      zebra_pbr_create_ipset(&zpi);
3457
254
    else
3458
254
      zebra_pbr_destroy_ipset(&zpi);
3459
4.00k
  }
3460
3461
29
stream_failure:
3462
29
  return;
3463
29
}
3464
3465
static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS)
3466
0
{
3467
0
  struct zebra_pbr_ipset_entry zpi;
3468
0
  struct zebra_pbr_ipset ipset;
3469
0
  struct stream *s;
3470
0
  uint32_t total, i;
3471
3472
0
  s = msg;
3473
0
  STREAM_GETL(s, total);
3474
3475
0
  for (i = 0; i < total; i++) {
3476
0
    memset(&zpi, 0, sizeof(zpi));
3477
0
    memset(&ipset, 0, sizeof(ipset));
3478
3479
0
    zpi.sock = client->sock;
3480
0
    STREAM_GETL(s, zpi.unique);
3481
0
    STREAM_GET(&ipset.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
3482
0
    ipset.ipset_name[ZEBRA_IPSET_NAME_SIZE - 1] = '\0';
3483
0
    STREAM_GETC(s, zpi.src.family);
3484
0
    STREAM_GETC(s, zpi.src.prefixlen);
3485
0
    STREAM_GET(&zpi.src.u.prefix, s, prefix_blen(&zpi.src));
3486
0
    STREAM_GETC(s, zpi.dst.family);
3487
0
    STREAM_GETC(s, zpi.dst.prefixlen);
3488
0
    STREAM_GET(&zpi.dst.u.prefix, s, prefix_blen(&zpi.dst));
3489
3490
0
    STREAM_GETW(s, zpi.src_port_min);
3491
0
    STREAM_GETW(s, zpi.src_port_max);
3492
0
    STREAM_GETW(s, zpi.dst_port_min);
3493
0
    STREAM_GETW(s, zpi.dst_port_max);
3494
0
    STREAM_GETC(s, zpi.proto);
3495
0
    if (!is_default_prefix(&zpi.src))
3496
0
      zpi.filter_bm |= PBR_FILTER_SRC_IP;
3497
3498
0
    if (!is_default_prefix(&zpi.dst))
3499
0
      zpi.filter_bm |= PBR_FILTER_DST_IP;
3500
0
    if (zpi.dst_port_min != 0 || zpi.proto == IPPROTO_ICMP)
3501
0
      zpi.filter_bm |= PBR_FILTER_DST_PORT;
3502
0
    if (zpi.src_port_min != 0 || zpi.proto == IPPROTO_ICMP)
3503
0
      zpi.filter_bm |= PBR_FILTER_SRC_PORT;
3504
0
    if (zpi.dst_port_max != 0)
3505
0
      zpi.filter_bm |= PBR_FILTER_DST_PORT_RANGE;
3506
0
    if (zpi.src_port_max != 0)
3507
0
      zpi.filter_bm |= PBR_FILTER_SRC_PORT_RANGE;
3508
0
    if (zpi.proto != 0)
3509
0
      zpi.filter_bm |= PBR_FILTER_PROTO;
3510
3511
0
    if (!(zpi.dst.family == AF_INET
3512
0
          || zpi.dst.family == AF_INET6)) {
3513
0
      zlog_warn(
3514
0
        "Unsupported PBR destination IP family: %s (%hhu)",
3515
0
        family2str(zpi.dst.family), zpi.dst.family);
3516
0
      goto stream_failure;
3517
0
    }
3518
0
    if (!(zpi.src.family == AF_INET
3519
0
          || zpi.src.family == AF_INET6)) {
3520
0
      zlog_warn(
3521
0
        "Unsupported PBR source IP family: %s (%hhu)",
3522
0
        family2str(zpi.src.family), zpi.src.family);
3523
0
      goto stream_failure;
3524
0
    }
3525
3526
    /* calculate backpointer */
3527
0
    zpi.backpointer =
3528
0
      zebra_pbr_lookup_ipset_pername(ipset.ipset_name);
3529
3530
0
    if (!zpi.backpointer) {
3531
0
      zlog_warn("ipset name specified: %s does not exist",
3532
0
          ipset.ipset_name);
3533
0
      goto stream_failure;
3534
0
    }
3535
3536
0
    if (hdr->command == ZEBRA_IPSET_ENTRY_ADD)
3537
0
      zebra_pbr_add_ipset_entry(&zpi);
3538
0
    else
3539
0
      zebra_pbr_del_ipset_entry(&zpi);
3540
0
  }
3541
3542
0
stream_failure:
3543
0
  return;
3544
0
}
3545
3546
3547
static inline void zebra_neigh_register(ZAPI_HANDLER_ARGS)
3548
0
{
3549
0
  afi_t afi;
3550
3551
0
  STREAM_GETW(msg, afi);
3552
0
  if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
3553
0
    zlog_warn(
3554
0
      "Invalid AFI %u while registering for neighbors notifications",
3555
0
      afi);
3556
0
    goto stream_failure;
3557
0
  }
3558
0
  vrf_bitmap_set(client->nhrp_neighinfo[afi], zvrf_id(zvrf));
3559
0
stream_failure:
3560
0
  return;
3561
0
}
3562
3563
static inline void zebra_neigh_unregister(ZAPI_HANDLER_ARGS)
3564
0
{
3565
0
  afi_t afi;
3566
3567
0
  STREAM_GETW(msg, afi);
3568
0
  if (afi <= AFI_UNSPEC || afi >= AFI_MAX) {
3569
0
    zlog_warn(
3570
0
      "Invalid AFI %u while unregistering from neighbor notifications",
3571
0
      afi);
3572
0
    goto stream_failure;
3573
0
  }
3574
0
  vrf_bitmap_unset(client->nhrp_neighinfo[afi], zvrf_id(zvrf));
3575
0
stream_failure:
3576
0
  return;
3577
0
}
3578
3579
static inline void zebra_gre_get(ZAPI_HANDLER_ARGS)
3580
0
{
3581
0
  struct stream *s;
3582
0
  ifindex_t idx;
3583
0
  struct interface *ifp;
3584
0
  struct zebra_if *zebra_if = NULL;
3585
0
  struct zebra_l2info_gre *gre_info;
3586
0
  struct interface *ifp_link = NULL;
3587
0
  vrf_id_t vrf_id_link = VRF_UNKNOWN;
3588
0
  vrf_id_t vrf_id = zvrf->vrf->vrf_id;
3589
3590
0
  s = msg;
3591
0
  STREAM_GETL(s, idx);
3592
0
  ifp  = if_lookup_by_index(idx, vrf_id);
3593
3594
0
  if (ifp)
3595
0
    zebra_if = ifp->info;
3596
3597
0
  s = stream_new(ZEBRA_MAX_PACKET_SIZ);
3598
3599
0
  zclient_create_header(s, ZEBRA_GRE_UPDATE, vrf_id);
3600
3601
0
  if (ifp  && IS_ZEBRA_IF_GRE(ifp) && zebra_if) {
3602
0
    gre_info = &zebra_if->l2info.gre;
3603
3604
0
    stream_putl(s, idx);
3605
0
    stream_putl(s, gre_info->ikey);
3606
0
    stream_putl(s, gre_info->ikey);
3607
0
    stream_putl(s, gre_info->ifindex_link);
3608
3609
0
    ifp_link = if_lookup_by_index_per_ns(
3610
0
          zebra_ns_lookup(gre_info->link_nsid),
3611
0
          gre_info->ifindex_link);
3612
0
    if (ifp_link)
3613
0
      vrf_id_link = ifp_link->vrf->vrf_id;
3614
0
    stream_putl(s, vrf_id_link);
3615
0
    stream_putl(s, gre_info->vtep_ip.s_addr);
3616
0
    stream_putl(s, gre_info->vtep_ip_remote.s_addr);
3617
0
  } else {
3618
0
    stream_putl(s, idx);
3619
0
    stream_putl(s, 0);
3620
0
    stream_putl(s, 0);
3621
0
    stream_putl(s, IFINDEX_INTERNAL);
3622
0
    stream_putl(s, VRF_UNKNOWN);
3623
0
    stream_putl(s, 0);
3624
0
    stream_putl(s, 0);
3625
0
  }
3626
  /* Write packet size. */
3627
0
  stream_putw_at(s, 0, stream_get_endp(s));
3628
0
  zserv_send_message(client, s);
3629
3630
0
  return;
3631
0
 stream_failure:
3632
0
  return;
3633
0
}
3634
3635
static inline void zebra_configure_arp(ZAPI_HANDLER_ARGS)
3636
0
{
3637
0
  struct stream *s;
3638
0
  uint8_t fam;
3639
0
  ifindex_t idx;
3640
0
  struct interface *ifp;
3641
3642
0
  s = msg;
3643
0
  STREAM_GETC(s, fam);
3644
0
  if (fam != AF_INET && fam != AF_INET6)
3645
0
    return;
3646
0
  STREAM_GETL(s, idx);
3647
0
  ifp = if_lookup_by_index_per_ns(zvrf->zns, idx);
3648
0
  if (!ifp)
3649
0
    return;
3650
0
  dplane_neigh_table_update(ifp, fam, 1, 0, 0);
3651
0
stream_failure:
3652
0
  return;
3653
0
}
3654
3655
static inline void zebra_neigh_ip_add(ZAPI_HANDLER_ARGS)
3656
0
{
3657
0
  struct stream *s;
3658
0
  struct zapi_neigh_ip api = {};
3659
0
  int ret;
3660
0
  const struct interface *ifp;
3661
3662
0
  s = msg;
3663
0
  ret = zclient_neigh_ip_decode(s, &api);
3664
0
  if (ret < 0)
3665
0
    return;
3666
0
  ifp = if_lookup_by_index(api.index, zvrf_id(zvrf));
3667
0
  if (!ifp)
3668
0
    return;
3669
0
  dplane_neigh_ip_update(DPLANE_OP_NEIGH_IP_INSTALL, ifp, &api.ip_out,
3670
0
             &api.ip_in, api.ndm_state, client->proto);
3671
0
}
3672
3673
3674
static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS)
3675
0
{
3676
0
  struct stream *s;
3677
0
  struct zapi_neigh_ip api = {};
3678
0
  int ret;
3679
0
  struct interface *ifp;
3680
3681
0
  s = msg;
3682
0
  ret = zclient_neigh_ip_decode(s, &api);
3683
0
  if (ret < 0)
3684
0
    return;
3685
0
  ifp = if_lookup_by_index(api.index, zvrf_id(zvrf));
3686
0
  if (!ifp)
3687
0
    return;
3688
0
  dplane_neigh_ip_update(DPLANE_OP_NEIGH_IP_DELETE, ifp, &api.ip_out,
3689
0
             &api.ip_in, api.ndm_state, client->proto);
3690
0
}
3691
3692
3693
static inline void zread_iptable(ZAPI_HANDLER_ARGS)
3694
5
{
3695
5
  struct zebra_pbr_iptable *zpi =
3696
5
    XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable));
3697
5
  struct stream *s;
3698
3699
5
  s = msg;
3700
3701
5
  zpi->interface_name_list = list_new();
3702
5
  zpi->sock = client->sock;
3703
5
  zpi->vrf_id = zvrf->vrf->vrf_id;
3704
5
  STREAM_GETL(s, zpi->unique);
3705
5
  STREAM_GETL(s, zpi->type);
3706
5
  STREAM_GETL(s, zpi->filter_bm);
3707
5
  STREAM_GETL(s, zpi->action);
3708
5
  STREAM_GETL(s, zpi->fwmark);
3709
5
  STREAM_GET(&zpi->ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
3710
5
  STREAM_GETC(s, zpi->family);
3711
5
  STREAM_GETW(s, zpi->pkt_len_min);
3712
5
  STREAM_GETW(s, zpi->pkt_len_max);
3713
5
  STREAM_GETW(s, zpi->tcp_flags);
3714
5
  STREAM_GETW(s, zpi->tcp_mask_flags);
3715
5
  STREAM_GETC(s, zpi->dscp_value);
3716
5
  STREAM_GETC(s, zpi->fragment);
3717
5
  STREAM_GETC(s, zpi->protocol);
3718
5
  STREAM_GETW(s, zpi->flow_label);
3719
5
  STREAM_GETL(s, zpi->nb_interface);
3720
5
  zebra_pbr_iptable_update_interfacelist(s, zpi);
3721
3722
5
  if (hdr->command == ZEBRA_IPTABLE_ADD)
3723
5
    zebra_pbr_add_iptable(zpi);
3724
0
  else
3725
0
    zebra_pbr_del_iptable(zpi);
3726
3727
5
stream_failure:
3728
5
  zebra_pbr_iptable_free(zpi);
3729
5
  zpi = NULL;
3730
5
  return;
3731
5
}
3732
3733
static inline void zread_neigh_discover(ZAPI_HANDLER_ARGS)
3734
0
{
3735
0
  struct stream *s;
3736
0
  ifindex_t ifindex;
3737
0
  struct interface *ifp;
3738
0
  struct prefix p;
3739
0
  struct ipaddr ip;
3740
3741
0
  s = msg;
3742
3743
0
  STREAM_GETL(s, ifindex);
3744
3745
0
  ifp = if_lookup_by_index_per_ns(zvrf->zns, ifindex);
3746
0
  if (!ifp) {
3747
0
    zlog_debug("Failed to lookup ifindex: %u", ifindex);
3748
0
    return;
3749
0
  }
3750
3751
0
  STREAM_GETC(s, p.family);
3752
0
  STREAM_GETC(s, p.prefixlen);
3753
0
  STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
3754
3755
0
  if (p.family == AF_INET)
3756
0
    SET_IPADDR_V4(&ip);
3757
0
  else
3758
0
    SET_IPADDR_V6(&ip);
3759
3760
0
  memcpy(&ip.ip.addr, &p.u.prefix, prefix_blen(&p));
3761
3762
0
  dplane_neigh_discover(ifp, &ip);
3763
3764
0
stream_failure:
3765
0
  return;
3766
0
}
3767
3768
static inline void zebra_gre_source_set(ZAPI_HANDLER_ARGS)
3769
0
{
3770
0
  struct stream *s;
3771
0
  ifindex_t idx, link_idx;
3772
0
  vrf_id_t link_vrf_id;
3773
0
  struct interface *ifp;
3774
0
  struct interface *ifp_link;
3775
0
  vrf_id_t vrf_id = zvrf->vrf->vrf_id;
3776
0
  struct zebra_if *zif, *gre_zif;
3777
0
  struct zebra_l2info_gre *gre_info;
3778
0
  unsigned int mtu;
3779
3780
0
  s = msg;
3781
0
  STREAM_GETL(s, idx);
3782
0
  ifp  = if_lookup_by_index(idx, vrf_id);
3783
0
  STREAM_GETL(s, link_idx);
3784
0
  STREAM_GETL(s, link_vrf_id);
3785
0
  STREAM_GETL(s, mtu);
3786
3787
0
  ifp_link  = if_lookup_by_index(link_idx, link_vrf_id);
3788
0
  if (!ifp_link || !ifp) {
3789
0
    zlog_warn("GRE (index %u, VRF %u) or GRE link interface (index %u, VRF %u) not found, when setting GRE params",
3790
0
        idx, vrf_id, link_idx, link_vrf_id);
3791
0
    return;
3792
0
  }
3793
3794
0
  if (!IS_ZEBRA_IF_GRE(ifp))
3795
0
    return;
3796
3797
0
  gre_zif = (struct zebra_if *)ifp->info;
3798
0
  zif = (struct zebra_if *)ifp_link->info;
3799
0
  if (!zif || !gre_zif)
3800
0
    return;
3801
3802
0
  gre_info = &zif->l2info.gre;
3803
0
  if (!gre_info)
3804
0
    return;
3805
3806
0
  if (!mtu)
3807
0
    mtu = ifp->mtu;
3808
3809
  /* if gre link already set or mtu did not change, do not set it */
3810
0
  if (gre_zif->link && gre_zif->link == ifp_link && mtu == ifp->mtu)
3811
0
    return;
3812
3813
0
  dplane_gre_set(ifp, ifp_link, mtu, gre_info);
3814
3815
0
 stream_failure:
3816
0
  return;
3817
0
}
3818
3819
static void zsend_error_msg(struct zserv *client, enum zebra_error_types error,
3820
          struct zmsghdr *bad_hdr)
3821
0
{
3822
3823
0
  struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
3824
3825
0
  zclient_create_header(s, ZEBRA_ERROR, bad_hdr->vrf_id);
3826
3827
0
  zserv_encode_error(s, error);
3828
3829
0
  client->error_cnt++;
3830
0
  zserv_send_message(client, s);
3831
0
}
3832
3833
static void zserv_error_no_vrf(ZAPI_HANDLER_ARGS)
3834
0
{
3835
0
  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
3836
0
    zlog_debug("ZAPI message specifies unknown VRF: %d",
3837
0
         hdr->vrf_id);
3838
3839
0
  zsend_error_msg(client, ZEBRA_NO_VRF, hdr);
3840
0
}
3841
3842
static void zserv_error_invalid_msg_type(ZAPI_HANDLER_ARGS)
3843
0
{
3844
0
  zlog_info("Zebra received unknown command %d", hdr->command);
3845
3846
0
  zsend_error_msg(client, ZEBRA_INVALID_MSG_TYPE, hdr);
3847
0
}
3848
3849
void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
3850
  [ZEBRA_ROUTER_ID_ADD] = zread_router_id_add,
3851
  [ZEBRA_ROUTER_ID_DELETE] = zread_router_id_delete,
3852
  [ZEBRA_INTERFACE_ADD] = zread_interface_add,
3853
  [ZEBRA_INTERFACE_DELETE] = zread_interface_delete,
3854
  [ZEBRA_INTERFACE_SET_PROTODOWN] = zread_interface_set_protodown,
3855
  [ZEBRA_ROUTE_ADD] = zread_route_add,
3856
  [ZEBRA_ROUTE_DELETE] = zread_route_del,
3857
  [ZEBRA_REDISTRIBUTE_ADD] = zebra_redistribute_add,
3858
  [ZEBRA_REDISTRIBUTE_DELETE] = zebra_redistribute_delete,
3859
  [ZEBRA_REDISTRIBUTE_DEFAULT_ADD] = zebra_redistribute_default_add,
3860
  [ZEBRA_REDISTRIBUTE_DEFAULT_DELETE] = zebra_redistribute_default_delete,
3861
  [ZEBRA_NEXTHOP_LOOKUP_MRIB] = zread_nexthop_lookup_mrib,
3862
  [ZEBRA_HELLO] = zread_hello,
3863
  [ZEBRA_NEXTHOP_REGISTER] = zread_rnh_register,
3864
  [ZEBRA_NEXTHOP_UNREGISTER] = zread_rnh_unregister,
3865
  [ZEBRA_BFD_DEST_UPDATE] = zebra_ptm_bfd_dst_register,
3866
  [ZEBRA_BFD_DEST_REGISTER] = zebra_ptm_bfd_dst_register,
3867
  [ZEBRA_BFD_DEST_DEREGISTER] = zebra_ptm_bfd_dst_deregister,
3868
#if HAVE_BFDD > 0
3869
  [ZEBRA_BFD_DEST_REPLAY] = zebra_ptm_bfd_dst_replay,
3870
#endif /* HAVE_BFDD */
3871
  [ZEBRA_VRF_UNREGISTER] = zread_vrf_unregister,
3872
  [ZEBRA_VRF_LABEL] = zread_vrf_label,
3873
  [ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
3874
  [ZEBRA_INTERFACE_ENABLE_RADV] = zebra_interface_radv_enable,
3875
  [ZEBRA_INTERFACE_DISABLE_RADV] = zebra_interface_radv_disable,
3876
  [ZEBRA_SR_POLICY_SET] = zread_sr_policy_set,
3877
  [ZEBRA_SR_POLICY_DELETE] = zread_sr_policy_delete,
3878
  [ZEBRA_MPLS_LABELS_ADD] = zread_mpls_labels_add,
3879
  [ZEBRA_MPLS_LABELS_DELETE] = zread_mpls_labels_delete,
3880
  [ZEBRA_MPLS_LABELS_REPLACE] = zread_mpls_labels_replace,
3881
  [ZEBRA_IPMR_ROUTE_STATS] = zebra_ipmr_route_stats,
3882
  [ZEBRA_LABEL_MANAGER_CONNECT] = zread_label_manager_request,
3883
  [ZEBRA_LABEL_MANAGER_CONNECT_ASYNC] = zread_label_manager_request,
3884
  [ZEBRA_GET_LABEL_CHUNK] = zread_label_manager_request,
3885
  [ZEBRA_RELEASE_LABEL_CHUNK] = zread_label_manager_request,
3886
  [ZEBRA_FEC_REGISTER] = zread_fec_register,
3887
  [ZEBRA_FEC_UNREGISTER] = zread_fec_unregister,
3888
  [ZEBRA_ADVERTISE_DEFAULT_GW] = zebra_vxlan_advertise_gw_macip,
3889
  [ZEBRA_ADVERTISE_SVI_MACIP] = zebra_vxlan_advertise_svi_macip,
3890
  [ZEBRA_ADVERTISE_SUBNET] = zebra_vxlan_advertise_subnet,
3891
  [ZEBRA_ADVERTISE_ALL_VNI] = zebra_vxlan_advertise_all_vni,
3892
  [ZEBRA_REMOTE_ES_VTEP_ADD] = zebra_evpn_proc_remote_es,
3893
  [ZEBRA_REMOTE_ES_VTEP_DEL] = zebra_evpn_proc_remote_es,
3894
  [ZEBRA_REMOTE_VTEP_ADD] = zebra_vxlan_remote_vtep_add_zapi,
3895
  [ZEBRA_REMOTE_VTEP_DEL] = zebra_vxlan_remote_vtep_del_zapi,
3896
  [ZEBRA_REMOTE_MACIP_ADD] = zebra_vxlan_remote_macip_add,
3897
  [ZEBRA_REMOTE_MACIP_DEL] = zebra_vxlan_remote_macip_del,
3898
  [ZEBRA_DUPLICATE_ADDR_DETECTION] = zebra_vxlan_dup_addr_detection,
3899
  [ZEBRA_INTERFACE_SET_MASTER] = zread_interface_set_master,
3900
  [ZEBRA_PW_ADD] = zread_pseudowire,
3901
  [ZEBRA_PW_DELETE] = zread_pseudowire,
3902
  [ZEBRA_PW_SET] = zread_pseudowire,
3903
  [ZEBRA_PW_UNSET] = zread_pseudowire,
3904
  [ZEBRA_RULE_ADD] = zread_rule,
3905
  [ZEBRA_RULE_DELETE] = zread_rule,
3906
  [ZEBRA_TABLE_MANAGER_CONNECT] = zread_table_manager_request,
3907
  [ZEBRA_GET_TABLE_CHUNK] = zread_table_manager_request,
3908
  [ZEBRA_RELEASE_TABLE_CHUNK] = zread_table_manager_request,
3909
  [ZEBRA_IPSET_CREATE] = zread_ipset,
3910
  [ZEBRA_IPSET_DESTROY] = zread_ipset,
3911
  [ZEBRA_IPSET_ENTRY_ADD] = zread_ipset_entry,
3912
  [ZEBRA_IPSET_ENTRY_DELETE] = zread_ipset_entry,
3913
  [ZEBRA_IPTABLE_ADD] = zread_iptable,
3914
  [ZEBRA_IPTABLE_DELETE] = zread_iptable,
3915
  [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
3916
  [ZEBRA_VXLAN_SG_REPLAY] = zebra_vxlan_sg_replay,
3917
  [ZEBRA_MLAG_CLIENT_REGISTER] = zebra_mlag_client_register,
3918
  [ZEBRA_MLAG_CLIENT_UNREGISTER] = zebra_mlag_client_unregister,
3919
  [ZEBRA_MLAG_FORWARD_MSG] = zebra_mlag_forward_client_msg,
3920
  [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = zread_srv6_manager_request,
3921
  [ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK] = zread_srv6_manager_request,
3922
  [ZEBRA_CLIENT_CAPABILITIES] = zread_client_capabilities,
3923
  [ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover,
3924
  [ZEBRA_NHG_ADD] = zread_nhg_add,
3925
  [ZEBRA_NHG_DEL] = zread_nhg_del,
3926
  [ZEBRA_ROUTE_NOTIFY_REQUEST] = zread_route_notify_request,
3927
  [ZEBRA_EVPN_REMOTE_NH_ADD] = zebra_evpn_proc_remote_nh,
3928
  [ZEBRA_EVPN_REMOTE_NH_DEL] = zebra_evpn_proc_remote_nh,
3929
  [ZEBRA_NEIGH_IP_ADD] = zebra_neigh_ip_add,
3930
  [ZEBRA_NEIGH_IP_DEL] = zebra_neigh_ip_del,
3931
  [ZEBRA_NHRP_NEIGH_REGISTER] = zebra_neigh_register,
3932
  [ZEBRA_NHRP_NEIGH_UNREGISTER] = zebra_neigh_unregister,
3933
  [ZEBRA_CONFIGURE_ARP] = zebra_configure_arp,
3934
  [ZEBRA_GRE_GET] = zebra_gre_get,
3935
  [ZEBRA_GRE_SOURCE_SET] = zebra_gre_source_set,
3936
  [ZEBRA_TC_QDISC_INSTALL] = zread_tc_qdisc,
3937
  [ZEBRA_TC_QDISC_UNINSTALL] = zread_tc_qdisc,
3938
  [ZEBRA_TC_CLASS_ADD] = zread_tc_class,
3939
  [ZEBRA_TC_CLASS_DELETE] = zread_tc_class,
3940
  [ZEBRA_TC_FILTER_ADD] = zread_tc_filter,
3941
  [ZEBRA_TC_FILTER_DELETE] = zread_tc_filter,
3942
};
3943
3944
/*
3945
 * Process a batch of zapi messages.
3946
 */
3947
void zserv_handle_commands(struct zserv *client, struct stream_fifo *fifo)
3948
319
{
3949
319
  struct zmsghdr hdr;
3950
319
  struct zebra_vrf *zvrf;
3951
319
  struct stream *msg;
3952
319
  struct stream_fifo temp_fifo;
3953
3954
319
  stream_fifo_init(&temp_fifo);
3955
3956
638
  while (stream_fifo_head(fifo)) {
3957
319
    msg = stream_fifo_pop(fifo);
3958
3959
319
    if (STREAM_READABLE(msg) > ZEBRA_MAX_PACKET_SIZ) {
3960
25
      if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
3961
0
        zlog_debug(
3962
25
          "ZAPI message is %zu bytes long but the maximum packet size is %u; dropping",
3963
25
          STREAM_READABLE(msg),
3964
25
          ZEBRA_MAX_PACKET_SIZ);
3965
25
      goto continue_loop;
3966
25
    }
3967
294
#ifdef FUZZING
3968
    /*
3969
     * The stream read over in zserv_read
3970
     * already guarantees this conditional
3971
     * when we read actual packets from clients
3972
     * but since we are cheating there is no
3973
     * point in allowing a crash in the fuzzing
3974
     * here.  So let's prevent it.
3975
     */
3976
294
    if (STREAM_READABLE(msg) < ZEBRA_HEADER_SIZE)
3977
0
      goto continue_loop;
3978
294
#endif
3979
294
    zapi_parse_header(msg, &hdr);
3980
294
#ifdef FUZZING
3981
    /*
3982
     * The stream read over in zserv_read
3983
     * already guarantees the sizing of the packet
3984
     * before it can even be enqueued but FUZZING
3985
     * is cheating and calling this function directly
3986
     * Let's cut to the chase and prevent a crash
3987
     * because we have a funny header size -vs-
3988
     * what we can read.
3989
     */
3990
294
    if (STREAM_SIZE(msg) != hdr.length)
3991
31
      goto continue_loop;
3992
263
#endif
3993
3994
3995
263
    if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV
3996
0
        && IS_ZEBRA_DEBUG_DETAIL)
3997
0
      zserv_log_message(NULL, msg, &hdr);
3998
3999
263
    hdr.length -= ZEBRA_HEADER_SIZE;
4000
4001
    /* Before checking for a handler function, check for
4002
     * special messages that are handled in another module;
4003
     * we'll treat these as opaque.
4004
     */
4005
263
    if (zebra_opaque_handles_msgid(hdr.command)) {
4006
      /* Reset message buffer */
4007
3
      stream_set_getp(msg, 0);
4008
4009
3
      stream_fifo_push(&temp_fifo, msg);
4010
4011
      /* Continue without freeing the message */
4012
3
      msg = NULL;
4013
3
      goto continue_loop;
4014
3
    }
4015
4016
    /* lookup vrf */
4017
260
    zvrf = zebra_vrf_lookup_by_id(hdr.vrf_id);
4018
260
    if (!zvrf) {
4019
0
      zserv_error_no_vrf(client, &hdr, msg, zvrf);
4020
0
      goto continue_loop;
4021
0
    }
4022
4023
260
    if (hdr.command >= array_size(zserv_handlers)
4024
260
        || zserv_handlers[hdr.command] == NULL) {
4025
0
      zserv_error_invalid_msg_type(client, &hdr, msg, zvrf);
4026
0
      goto continue_loop;
4027
0
    }
4028
4029
260
    zserv_handlers[hdr.command](client, &hdr, msg, zvrf);
4030
4031
319
continue_loop:
4032
319
    stream_free(msg);
4033
319
  }
4034
4035
  /* Dispatch any special messages from the temp fifo */
4036
319
  if (stream_fifo_head(&temp_fifo) != NULL)
4037
3
    zebra_opaque_enqueue_batch(&temp_fifo);
4038
4039
319
  stream_fifo_deinit(&temp_fifo);
4040
319
}