Coverage Report

Created: 2025-11-09 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/zclient.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* Zebra's client library.
3
 * Copyright (C) 1999 Kunihiro Ishiguro
4
 * Copyright (C) 2005 Andrew J. Schorr
5
 */
6
7
#include <zebra.h>
8
9
#include "prefix.h"
10
#include "stream.h"
11
#include "buffer.h"
12
#include "network.h"
13
#include "vrf.h"
14
#include "vrf_int.h"
15
#include "if.h"
16
#include "log.h"
17
#include "frrevent.h"
18
#include "zclient.h"
19
#include "memory.h"
20
#include "table.h"
21
#include "nexthop.h"
22
#include "mpls.h"
23
#include "sockopt.h"
24
#include "pbr.h"
25
#include "tc.h"
26
#include "nexthop_group.h"
27
#include "lib_errors.h"
28
#include "srte.h"
29
#include "printfrr.h"
30
#include "srv6.h"
31
32
8
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient");
33
8
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs");
34
8
35
8
/* Zebra client events. */
36
8
enum zclient_event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
37
8
38
8
/* Prototype for event manager. */
39
8
static void zclient_event(enum zclient_event, struct zclient *);
40
8
41
8
static void zebra_interface_if_set_value(struct stream *s,
42
8
           struct interface *ifp);
43
8
44
8
struct zclient_options zclient_options_default = {.receive_notify = false,
45
8
              .synchronous = false};
46
8
47
8
struct sockaddr_storage zclient_addr;
48
8
socklen_t zclient_addr_len;
49
8
50
8
/* This file local debug flag. */
51
8
static int zclient_debug;
52
8
53
8
/* Allocate zclient structure. */
54
8
struct zclient *zclient_new(struct event_loop *master,
55
8
          struct zclient_options *opt,
56
8
          zclient_handler *const *handlers, size_t n_handlers)
57
8
{
58
5
  struct zclient *zclient;
59
5
  size_t stream_size =
60
5
    MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
61
62
5
  zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
63
64
5
  zclient->ibuf = stream_new(stream_size);
65
5
  zclient->obuf = stream_new(stream_size);
66
5
  zclient->wb = buffer_new(0);
67
5
  zclient->master = master;
68
69
5
  zclient->handlers = handlers;
70
5
  zclient->n_handlers = n_handlers;
71
72
5
  zclient->receive_notify = opt->receive_notify;
73
5
  zclient->synchronous = opt->synchronous;
74
75
5
  return zclient;
76
5
}
77
78
/* This function is only called when exiting, because
79
   many parts of the code do not check for I/O errors, so they could
80
   reference an invalid pointer if the structure was ever freed.
81
82
   Free zclient structure. */
83
void zclient_free(struct zclient *zclient)
84
0
{
85
0
  if (zclient->ibuf)
86
0
    stream_free(zclient->ibuf);
87
0
  if (zclient->obuf)
88
0
    stream_free(zclient->obuf);
89
0
  if (zclient->wb)
90
0
    buffer_free(zclient->wb);
91
92
0
  XFREE(MTYPE_ZCLIENT, zclient);
93
0
}
94
95
unsigned short *redist_check_instance(struct redist_proto *red,
96
              unsigned short instance)
97
0
{
98
0
  struct listnode *node;
99
0
  unsigned short *id;
100
101
0
  if (!red->instances)
102
0
    return NULL;
103
104
0
  for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
105
0
    if (*id == instance)
106
0
      return id;
107
108
0
  return NULL;
109
0
}
110
111
void redist_add_instance(struct redist_proto *red, unsigned short instance)
112
9
{
113
9
  unsigned short *in;
114
115
9
  red->enabled = 1;
116
117
9
  if (!red->instances)
118
9
    red->instances = list_new();
119
120
9
  in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
121
9
  *in = instance;
122
9
  listnode_add(red->instances, in);
123
9
}
124
125
void redist_del_instance(struct redist_proto *red, unsigned short instance)
126
0
{
127
0
  unsigned short *id;
128
129
0
  id = redist_check_instance(red, instance);
130
0
  if (!id)
131
0
    return;
132
133
0
  listnode_delete(red->instances, id);
134
0
  XFREE(MTYPE_REDIST_INST, id);
135
0
  if (!red->instances->count) {
136
0
    red->enabled = 0;
137
0
    list_delete(&red->instances);
138
0
  }
139
0
}
140
141
void redist_del_all_instances(struct redist_proto *red)
142
26.0k
{
143
26.0k
  struct listnode *ln, *nn;
144
26.0k
  unsigned short *id;
145
146
26.0k
  if (!red->instances)
147
26.0k
    return;
148
149
0
  for (ALL_LIST_ELEMENTS(red->instances, ln, nn, id))
150
0
    redist_del_instance(red, *id);
151
0
}
152
153
/* Stop zebra client services. */
154
void zclient_stop(struct zclient *zclient)
155
0
{
156
0
  afi_t afi;
157
0
  int i;
158
159
0
  if (zclient_debug)
160
0
    zlog_debug("zclient %p stopped", zclient);
161
162
  /* Stop threads. */
163
0
  EVENT_OFF(zclient->t_read);
164
0
  EVENT_OFF(zclient->t_connect);
165
0
  EVENT_OFF(zclient->t_write);
166
167
  /* Reset streams. */
168
0
  stream_reset(zclient->ibuf);
169
0
  stream_reset(zclient->obuf);
170
171
  /* Empty the write buffer. */
172
0
  buffer_reset(zclient->wb);
173
174
  /* Close socket. */
175
0
  if (zclient->sock >= 0) {
176
0
    close(zclient->sock);
177
0
    zclient->sock = -1;
178
0
  }
179
0
  zclient->fail = 0;
180
181
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
182
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
183
0
      vrf_bitmap_free(zclient->redist[afi][i]);
184
0
      zclient->redist[afi][i] = VRF_BITMAP_NULL;
185
0
    }
186
0
    redist_del_instance(
187
0
      &zclient->mi_redist[afi][zclient->redist_default],
188
0
      zclient->instance);
189
190
0
    vrf_bitmap_free(zclient->default_information[afi]);
191
0
    zclient->default_information[afi] = VRF_BITMAP_NULL;
192
0
  }
193
0
}
194
195
void zclient_reset(struct zclient *zclient)
196
0
{
197
0
  afi_t afi;
198
199
0
  zclient_stop(zclient);
200
201
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
202
0
    redist_del_instance(
203
0
      &zclient->mi_redist[afi][zclient->redist_default],
204
0
      zclient->instance);
205
206
0
  zclient_init(zclient, zclient->redist_default, zclient->instance,
207
0
         zclient->privs);
208
0
}
209
210
/**
211
 * Connect to zebra daemon.
212
 * @param zclient a pointer to zclient structure
213
 * @return socket fd just to make sure that connection established
214
 * @see zclient_init
215
 * @see zclient_new
216
 */
217
int zclient_socket_connect(struct zclient *zclient)
218
0
{
219
0
  int sock;
220
0
  int ret;
221
222
  /* We should think about IPv6 connection. */
223
0
  sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
224
0
  if (sock < 0)
225
0
    return -1;
226
227
0
  set_cloexec(sock);
228
0
  setsockopt_so_sendbuf(sock, 1048576);
229
230
  /* Connect to zebra. */
231
0
  ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
232
0
  if (ret < 0) {
233
0
    if (zclient_debug)
234
0
      zlog_debug("%s connect failure: %d(%s)", __func__,
235
0
           errno, safe_strerror(errno));
236
0
    close(sock);
237
0
    return -1;
238
0
  }
239
240
0
  zclient->sock = sock;
241
0
  return sock;
242
0
}
243
244
static enum zclient_send_status zclient_failed(struct zclient *zclient)
245
0
{
246
0
  zclient->fail++;
247
0
  zclient_stop(zclient);
248
0
  zclient_event(ZCLIENT_CONNECT, zclient);
249
0
  return ZCLIENT_SEND_FAILURE;
250
0
}
251
252
static void zclient_flush_data(struct event *thread)
253
0
{
254
0
  struct zclient *zclient = EVENT_ARG(thread);
255
0
256
0
  zclient->t_write = NULL;
257
0
  if (zclient->sock < 0)
258
0
    return;
259
0
  switch (buffer_flush_available(zclient->wb, zclient->sock)) {
260
0
  case BUFFER_ERROR:
261
0
    flog_err(
262
0
      EC_LIB_ZAPI_SOCKET,
263
0
      "%s: buffer_flush_available failed on zclient fd %d, closing",
264
0
      __func__, zclient->sock);
265
0
    zclient_failed(zclient);
266
0
    return;
267
0
  case BUFFER_PENDING:
268
0
    zclient->t_write = NULL;
269
0
    event_add_write(zclient->master, zclient_flush_data, zclient,
270
0
        zclient->sock, &zclient->t_write);
271
0
    break;
272
0
  case BUFFER_EMPTY:
273
0
    if (zclient->zebra_buffer_write_ready)
274
0
      (*zclient->zebra_buffer_write_ready)();
275
0
    break;
276
0
  }
277
0
}
278
279
/*
280
 * Returns:
281
 * ZCLIENT_SEND_FAILED   - is a failure
282
 * ZCLIENT_SEND_SUCCESS  - means we sent data to zebra
283
 * ZCLIENT_SEND_BUFFERED - means we are buffering
284
 */
285
enum zclient_send_status zclient_send_message(struct zclient *zclient)
286
47.1k
{
287
47.1k
  if (zclient->sock < 0)
288
47.1k
    return ZCLIENT_SEND_FAILURE;
289
0
  switch (buffer_write(zclient->wb, zclient->sock,
290
0
           STREAM_DATA(zclient->obuf),
291
0
           stream_get_endp(zclient->obuf))) {
292
0
  case BUFFER_ERROR:
293
0
    flog_err(EC_LIB_ZAPI_SOCKET,
294
0
       "%s: buffer_write failed to zclient fd %d, closing",
295
0
       __func__, zclient->sock);
296
0
    return zclient_failed(zclient);
297
0
  case BUFFER_EMPTY:
298
0
    EVENT_OFF(zclient->t_write);
299
0
    return ZCLIENT_SEND_SUCCESS;
300
0
  case BUFFER_PENDING:
301
0
    event_add_write(zclient->master, zclient_flush_data, zclient,
302
0
        zclient->sock, &zclient->t_write);
303
0
    return ZCLIENT_SEND_BUFFERED;
304
0
  }
305
306
  /* should not get here */
307
0
  return ZCLIENT_SEND_SUCCESS;
308
0
}
309
310
/*
311
 * If we add more data to this structure please ensure that
312
 * struct zmsghdr in lib/zclient.h is updated as appropriate.
313
 */
314
void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
315
49.6k
{
316
  /* length placeholder, caller can update */
317
49.6k
  stream_putw(s, ZEBRA_HEADER_SIZE);
318
49.6k
  stream_putc(s, ZEBRA_HEADER_MARKER);
319
49.6k
  stream_putc(s, ZSERV_VERSION);
320
49.6k
  stream_putl(s, vrf_id);
321
49.6k
  stream_putw(s, command);
322
49.6k
}
323
324
int zclient_read_header(struct stream *s, int sock, uint16_t *size,
325
      uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id,
326
      uint16_t *cmd)
327
0
{
328
0
  if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
329
0
    return -1;
330
331
0
  STREAM_GETW(s, *size);
332
0
  *size -= ZEBRA_HEADER_SIZE;
333
0
  STREAM_GETC(s, *marker);
334
0
  STREAM_GETC(s, *version);
335
0
  STREAM_GETL(s, *vrf_id);
336
0
  STREAM_GETW(s, *cmd);
337
338
0
  if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
339
0
    flog_err(
340
0
      EC_LIB_ZAPI_MISSMATCH,
341
0
      "%s: socket %d version mismatch, marker %d, version %d",
342
0
      __func__, sock, *marker, *version);
343
0
    return -1;
344
0
  }
345
346
0
  if (*size && stream_read(s, sock, *size) != *size)
347
0
    return -1;
348
349
0
  return 0;
350
0
stream_failure:
351
0
  return -1;
352
0
}
353
354
bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
355
255
{
356
255
  STREAM_GETW(zmsg, hdr->length);
357
255
  STREAM_GETC(zmsg, hdr->marker);
358
255
  STREAM_GETC(zmsg, hdr->version);
359
255
  STREAM_GETL(zmsg, hdr->vrf_id);
360
255
  STREAM_GETW(zmsg, hdr->command);
361
255
  return true;
362
0
stream_failure:
363
0
  return false;
364
255
}
365
366
/* Send simple Zebra message. */
367
static enum zclient_send_status zebra_message_send(struct zclient *zclient,
368
               int command, vrf_id_t vrf_id)
369
0
{
370
0
  struct stream *s;
371
372
  /* Get zclient output buffer. */
373
0
  s = zclient->obuf;
374
0
  stream_reset(s);
375
376
  /* Send very simple command only Zebra message. */
377
0
  zclient_create_header(s, command, vrf_id);
378
379
0
  return zclient_send_message(zclient);
380
0
}
381
382
enum zclient_send_status zclient_send_hello(struct zclient *zclient)
383
0
{
384
0
  struct stream *s;
385
386
0
  if (zclient->redist_default || zclient->synchronous) {
387
0
    s = zclient->obuf;
388
0
    stream_reset(s);
389
390
    /* The VRF ID in the HELLO message is always 0. */
391
0
    zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
392
0
    stream_putc(s, zclient->redist_default);
393
0
    stream_putw(s, zclient->instance);
394
0
    stream_putl(s, zclient->session_id);
395
0
    if (zclient->receive_notify)
396
0
      stream_putc(s, 1);
397
0
    else
398
0
      stream_putc(s, 0);
399
0
    if (zclient->synchronous)
400
0
      stream_putc(s, 1);
401
0
    else
402
0
      stream_putc(s, 0);
403
404
0
    stream_putw_at(s, 0, stream_get_endp(s));
405
0
    return zclient_send_message(zclient);
406
0
  }
407
408
0
  return ZCLIENT_SEND_SUCCESS;
409
0
}
410
411
enum zclient_send_status zclient_send_vrf_label(struct zclient *zclient,
412
            vrf_id_t vrf_id, afi_t afi,
413
            mpls_label_t label,
414
            enum lsp_types_t ltype)
415
0
{
416
0
  struct stream *s;
417
418
0
  s = zclient->obuf;
419
0
  stream_reset(s);
420
421
0
  zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
422
0
  stream_putl(s, label);
423
0
  stream_putc(s, afi);
424
0
  stream_putc(s, ltype);
425
0
  stream_putw_at(s, 0, stream_get_endp(s));
426
0
  return zclient_send_message(zclient);
427
0
}
428
429
enum zclient_send_status zclient_send_localsid(struct zclient *zclient,
430
    const struct in6_addr *sid, vrf_id_t vrf_id,
431
    enum seg6local_action_t action,
432
    const struct seg6local_context *context)
433
0
{
434
0
  struct prefix_ipv6 p = {};
435
0
  struct zapi_route api = {};
436
0
  struct zapi_nexthop *znh;
437
0
  struct interface *ifp;
438
439
0
  ifp = if_get_vrf_loopback(vrf_id);
440
0
  if (ifp == NULL)
441
0
    return ZCLIENT_SEND_FAILURE;
442
443
0
  p.family = AF_INET6;
444
0
  p.prefixlen = IPV6_MAX_BITLEN;
445
0
  p.prefix = *sid;
446
447
0
  api.vrf_id = VRF_DEFAULT;
448
0
  api.type = zclient->redist_default;
449
0
  api.instance = 0;
450
0
  api.safi = SAFI_UNICAST;
451
0
  memcpy(&api.prefix, &p, sizeof(p));
452
453
0
  if (action == ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
454
0
    return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
455
456
0
  SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
457
0
  SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
458
459
0
  znh = &api.nexthops[0];
460
461
0
  memset(znh, 0, sizeof(*znh));
462
463
0
  znh->type = NEXTHOP_TYPE_IFINDEX;
464
0
  znh->ifindex = ifp->ifindex;
465
0
  SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_SEG6LOCAL);
466
0
  znh->seg6local_action = action;
467
0
  memcpy(&znh->seg6local_ctx, context, sizeof(struct seg6local_context));
468
469
0
  api.nexthop_num = 1;
470
471
0
  return zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
472
0
}
473
474
/* Send register requests to zebra daemon for the information in a VRF. */
475
void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
476
0
{
477
0
  int i;
478
0
  afi_t afi;
479
480
  /* If not connected to the zebra yet. */
481
0
  if (zclient->sock < 0)
482
0
    return;
483
484
0
  if (zclient_debug)
485
0
    zlog_debug("%s: send register messages for VRF %u", __func__,
486
0
         vrf_id);
487
488
  /* We need router-id information. */
489
0
  zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_ADD, AFI_IP,
490
0
              vrf_id);
491
492
  /* We need interface information. */
493
0
  zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
494
495
  /* Set unwanted redistribute route. */
496
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
497
0
    vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
498
0
             vrf_id);
499
500
  /* Flush all redistribute request. */
501
0
  if (vrf_id == VRF_DEFAULT) {
502
0
    for (afi = AFI_IP; afi < AFI_MAX; afi++) {
503
0
      for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
504
0
        if (!zclient->mi_redist[afi][i].enabled)
505
0
          continue;
506
507
0
        struct listnode *node;
508
0
        unsigned short *id;
509
510
0
        for (ALL_LIST_ELEMENTS_RO(
511
0
               zclient->mi_redist[afi][i]
512
0
                 .instances,
513
0
               node, id))
514
0
          if (!(i == zclient->redist_default
515
0
                && *id == zclient->instance))
516
0
            zebra_redistribute_send(
517
0
              ZEBRA_REDISTRIBUTE_ADD,
518
0
              zclient, afi, i, *id,
519
0
              VRF_DEFAULT);
520
0
      }
521
0
    }
522
0
  }
523
524
  /* Resend all redistribute request. */
525
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
526
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
527
0
      if (i != zclient->redist_default
528
0
          && vrf_bitmap_check(zclient->redist[afi][i],
529
0
            vrf_id))
530
0
        zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
531
0
              zclient, afi, i, 0,
532
0
              vrf_id);
533
534
    /* If default information is needed. */
535
0
    if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
536
0
      zebra_redistribute_default_send(
537
0
        ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
538
0
        vrf_id);
539
0
  }
540
0
}
541
542
/* Send unregister requests to zebra daemon for the information in a VRF. */
543
void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
544
0
{
545
0
  int i;
546
0
  afi_t afi;
547
548
  /* If not connected to the zebra yet. */
549
0
  if (zclient->sock < 0)
550
0
    return;
551
552
0
  if (zclient_debug)
553
0
    zlog_debug("%s: send deregister messages for VRF %u", __func__,
554
0
         vrf_id);
555
556
  /* We need router-id information. */
557
0
  zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_DELETE, AFI_IP,
558
0
              vrf_id);
559
560
0
  zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
561
562
  /* Set unwanted redistribute route. */
563
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
564
0
    vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
565
0
         vrf_id);
566
567
  /* Flush all redistribute request. */
568
0
  if (vrf_id == VRF_DEFAULT) {
569
0
    for (afi = AFI_IP; afi < AFI_MAX; afi++) {
570
0
      for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
571
0
        if (!zclient->mi_redist[afi][i].enabled)
572
0
          continue;
573
574
0
        struct listnode *node;
575
0
        unsigned short *id;
576
577
0
        for (ALL_LIST_ELEMENTS_RO(
578
0
               zclient->mi_redist[afi][i]
579
0
                 .instances,
580
0
               node, id))
581
0
          if (!(i == zclient->redist_default
582
0
                && *id == zclient->instance))
583
0
            zebra_redistribute_send(
584
0
              ZEBRA_REDISTRIBUTE_DELETE,
585
0
              zclient, afi, i, *id,
586
0
              VRF_DEFAULT);
587
0
      }
588
0
    }
589
0
  }
590
591
  /* Flush all redistribute request. */
592
0
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
593
0
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
594
0
      if (i != zclient->redist_default
595
0
          && vrf_bitmap_check(zclient->redist[afi][i],
596
0
            vrf_id))
597
0
        zebra_redistribute_send(
598
0
          ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
599
0
          i, 0, vrf_id);
600
601
    /* If default information is needed. */
602
0
    if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
603
0
      zebra_redistribute_default_send(
604
0
        ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
605
0
        vrf_id);
606
0
  }
607
0
}
608
609
enum zclient_send_status
610
zclient_send_router_id_update(struct zclient *zclient,
611
            zebra_message_types_t type, afi_t afi,
612
            vrf_id_t vrf_id)
613
0
{
614
0
  struct stream *s = zclient->obuf;
615
0
  stream_reset(s);
616
0
  zclient_create_header(s, type, vrf_id);
617
0
  stream_putw(s, afi);
618
0
  stream_putw_at(s, 0, stream_get_endp(s));
619
0
  return zclient_send_message(zclient);
620
0
}
621
622
/* Send request to zebra daemon to start or stop RA. */
623
enum zclient_send_status
624
zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
625
        struct interface *ifp, int enable,
626
        uint32_t ra_interval)
627
0
{
628
0
  struct stream *s;
629
630
  /* If not connected to the zebra yet. */
631
0
  if (zclient->sock < 0)
632
0
    return ZCLIENT_SEND_FAILURE;
633
634
  /* Form and send message. */
635
0
  s = zclient->obuf;
636
0
  stream_reset(s);
637
638
0
  if (enable)
639
0
    zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
640
0
  else
641
0
    zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
642
643
0
  stream_putl(s, ifp->ifindex);
644
0
  stream_putl(s, ra_interval);
645
646
0
  stream_putw_at(s, 0, stream_get_endp(s));
647
648
0
  return zclient_send_message(zclient);
649
0
}
650
651
enum zclient_send_status
652
zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
653
         struct interface *ifp, bool down)
654
0
{
655
0
  struct stream *s;
656
657
0
  if (zclient->sock < 0)
658
0
    return ZCLIENT_SEND_FAILURE;
659
660
0
  s = zclient->obuf;
661
0
  stream_reset(s);
662
0
  zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id);
663
0
  stream_putl(s, ifp->ifindex);
664
0
  stream_putc(s, !!down);
665
0
  stream_putw_at(s, 0, stream_get_endp(s));
666
0
  return zclient_send_message(zclient);
667
0
}
668
669
/* Make connection to zebra daemon. */
670
int zclient_start(struct zclient *zclient)
671
0
{
672
0
  if (zclient_debug)
673
0
    zlog_info("zclient_start is called");
674
675
  /* If already connected to the zebra. */
676
0
  if (zclient->sock >= 0)
677
0
    return 0;
678
679
  /* Check connect thread. */
680
0
  if (zclient->t_connect)
681
0
    return 0;
682
683
0
  if (zclient_socket_connect(zclient) < 0) {
684
0
    if (zclient_debug)
685
0
      zlog_debug("zclient connection fail");
686
0
    zclient->fail++;
687
0
    zclient_event(ZCLIENT_CONNECT, zclient);
688
0
    return -1;
689
0
  }
690
691
0
  if (set_nonblocking(zclient->sock) < 0)
692
0
    flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
693
0
       __func__, zclient->sock);
694
695
  /* Clear fail count. */
696
0
  zclient->fail = 0;
697
0
  if (zclient_debug)
698
0
    zlog_debug("zclient connect success with socket [%d]",
699
0
         zclient->sock);
700
701
  /* Create read thread. */
702
0
  zclient_event(ZCLIENT_READ, zclient);
703
704
0
  zclient_send_hello(zclient);
705
706
0
  zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
707
708
  /* Inform the successful connection. */
709
0
  if (zclient->zebra_connected)
710
0
    (*zclient->zebra_connected)(zclient);
711
712
0
  return 0;
713
0
}
714
715
/* Initialize zebra client.  Argument redist_default is unwanted
716
   redistribute route type. */
717
void zclient_init(struct zclient *zclient, int redist_default,
718
      unsigned short instance, struct zebra_privs_t *privs)
719
3
{
720
3
  int afi, i;
721
722
  /* Set -1 to the default socket value. */
723
3
  zclient->sock = -1;
724
3
  zclient->privs = privs;
725
726
  /* Clear redistribution flags. */
727
12
  for (afi = AFI_IP; afi < AFI_MAX; afi++)
728
288
    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
729
279
      zclient->redist[afi][i] = vrf_bitmap_init();
730
731
  /* Set unwanted redistribute route.  bgpd does not need BGP route
732
     redistribution. */
733
3
  zclient->redist_default = redist_default;
734
3
  zclient->instance = instance;
735
  /* Pending: make afi(s) an arg. */
736
12
  for (afi = AFI_IP; afi < AFI_MAX; afi++) {
737
9
    redist_add_instance(&zclient->mi_redist[afi][redist_default],
738
9
            instance);
739
740
    /* Set default-information redistribute to zero. */
741
9
    zclient->default_information[afi] = vrf_bitmap_init();
742
9
  }
743
744
3
  if (zclient_debug)
745
0
    zlog_debug("scheduling zclient connection");
746
747
3
  zclient_event(ZCLIENT_SCHEDULE, zclient);
748
3
}
749
750
/* This function is a wrapper function for calling zclient_start from
751
   timer or event thread. */
752
static void zclient_connect(struct event *t)
753
0
{
754
0
  struct zclient *zclient;
755
0
756
0
  zclient = EVENT_ARG(t);
757
0
  zclient->t_connect = NULL;
758
0
759
0
  if (zclient_debug)
760
0
    zlog_debug("zclient_connect is called");
761
0
762
0
  zclient_start(zclient);
763
0
}
764
765
enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
766
            const struct prefix *p, safi_t safi,
767
            bool connected, bool resolve_via_def,
768
            vrf_id_t vrf_id)
769
47.1k
{
770
47.1k
  struct stream *s;
771
772
47.1k
  s = zclient->obuf;
773
47.1k
  stream_reset(s);
774
47.1k
  zclient_create_header(s, command, vrf_id);
775
47.1k
  stream_putc(s, (connected) ? 1 : 0);
776
47.1k
  stream_putc(s, (resolve_via_def) ? 1 : 0);
777
47.1k
  stream_putw(s, safi);
778
47.1k
  stream_putw(s, PREFIX_FAMILY(p));
779
47.1k
  stream_putc(s, p->prefixlen);
780
47.1k
  switch (PREFIX_FAMILY(p)) {
781
47.1k
  case AF_INET:
782
47.1k
    stream_put_in_addr(s, &p->u.prefix4);
783
47.1k
    break;
784
0
  case AF_INET6:
785
0
    stream_put(s, &(p->u.prefix6), 16);
786
0
    break;
787
0
  default:
788
0
    break;
789
47.1k
  }
790
47.1k
  stream_putw_at(s, 0, stream_get_endp(s));
791
792
47.1k
  return zclient_send_message(zclient);
793
47.1k
}
794
795
/*
796
 * "xdr_encode"-like interface that allows daemon (client) to send
797
 * a message to zebra server for a route that needs to be
798
 * added/deleted to the kernel. Info about the route is specified
799
 * by the caller in a struct zapi_route. zapi_route_encode() then writes
800
 * the info down the zclient socket using the stream_* functions.
801
 *
802
 * The corresponding read ("xdr_decode") function on the server
803
 * side is zapi_route_decode().
804
 *
805
 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
806
 * byte value.
807
 *
808
 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as a 4
809
 * byte value.
810
 *
811
 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
812
 *
813
 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
814
 *
815
 * XXX: No attention paid to alignment.
816
 */
817
enum zclient_send_status
818
zclient_route_send(uint8_t cmd, struct zclient *zclient, struct zapi_route *api)
819
0
{
820
0
  if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
821
0
    return ZCLIENT_SEND_FAILURE;
822
0
  return zclient_send_message(zclient);
823
0
}
824
825
static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
826
           const struct zapi_nexthop *next2)
827
0
{
828
0
  if (next1->label_num > next2->label_num)
829
0
    return 1;
830
831
0
  if (next1->label_num < next2->label_num)
832
0
    return -1;
833
834
0
  return memcmp(next1->labels, next2->labels, next1->label_num);
835
0
}
836
837
static int zapi_nexthop_srv6_cmp(const struct zapi_nexthop *next1,
838
         const struct zapi_nexthop *next2)
839
0
{
840
0
  int ret = 0;
841
842
0
  ret = memcmp(&next1->seg6_segs, &next2->seg6_segs,
843
0
         sizeof(struct in6_addr));
844
0
  if (ret != 0)
845
0
    return ret;
846
847
0
  if (next1->seg6local_action > next2->seg6local_action)
848
0
    return 1;
849
850
0
  if (next1->seg6local_action < next2->seg6local_action)
851
0
    return -1;
852
853
0
  return memcmp(&next1->seg6local_ctx, &next2->seg6local_ctx,
854
0
          sizeof(struct seg6local_context));
855
0
}
856
857
static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
858
              const struct zapi_nexthop *next2)
859
0
{
860
0
  int ret = 0;
861
862
0
  if (next1->vrf_id < next2->vrf_id)
863
0
    return -1;
864
865
0
  if (next1->vrf_id > next2->vrf_id)
866
0
    return 1;
867
868
0
  if (next1->type < next2->type)
869
0
    return -1;
870
871
0
  if (next1->type > next2->type)
872
0
    return 1;
873
874
0
  if (next1->weight < next2->weight)
875
0
    return -1;
876
877
0
  if (next1->weight > next2->weight)
878
0
    return 1;
879
880
0
  switch (next1->type) {
881
0
  case NEXTHOP_TYPE_IPV4:
882
0
  case NEXTHOP_TYPE_IPV6:
883
0
    ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
884
0
           &next2->gate);
885
0
    if (ret != 0)
886
0
      return ret;
887
0
    break;
888
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
889
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
890
0
    ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
891
0
           &next2->gate);
892
0
    if (ret != 0)
893
0
      return ret;
894
    /* Intentional Fall-Through */
895
0
  case NEXTHOP_TYPE_IFINDEX:
896
0
    if (next1->ifindex < next2->ifindex)
897
0
      return -1;
898
899
0
    if (next1->ifindex > next2->ifindex)
900
0
      return 1;
901
0
    break;
902
0
  case NEXTHOP_TYPE_BLACKHOLE:
903
0
    if (next1->bh_type < next2->bh_type)
904
0
      return -1;
905
906
0
    if (next1->bh_type > next2->bh_type)
907
0
      return 1;
908
0
    break;
909
0
  }
910
911
0
  if (next1->srte_color < next2->srte_color)
912
0
    return -1;
913
0
  if (next1->srte_color > next2->srte_color)
914
0
    return 1;
915
916
0
  if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) ||
917
0
      CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
918
919
0
    if (!CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
920
0
        CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
921
0
      return -1;
922
923
0
    if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
924
0
        !CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
925
0
      return 1;
926
927
0
    if (next1->backup_num > 0 || next2->backup_num > 0) {
928
929
0
      if (next1->backup_num < next2->backup_num)
930
0
        return -1;
931
932
0
      if (next1->backup_num > next2->backup_num)
933
0
        return 1;
934
935
0
      ret = memcmp(next1->backup_idx,
936
0
             next2->backup_idx, next1->backup_num);
937
0
      if (ret != 0)
938
0
        return ret;
939
0
    }
940
0
  }
941
942
0
  return 0;
943
0
}
944
945
static int zapi_nexthop_cmp(const void *item1, const void *item2)
946
0
{
947
0
  int ret = 0;
948
949
0
  const struct zapi_nexthop *next1 = item1;
950
0
  const struct zapi_nexthop *next2 = item2;
951
952
0
  ret = zapi_nexthop_cmp_no_labels(next1, next2);
953
0
  if (ret != 0)
954
0
    return ret;
955
956
0
  ret = zapi_nexthop_labels_cmp(next1, next2);
957
0
  if (ret != 0)
958
0
    return ret;
959
960
0
  ret = zapi_nexthop_srv6_cmp(next1, next2);
961
962
0
  return ret;
963
0
}
964
965
static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp,
966
            uint16_t nexthop_num)
967
0
{
968
0
  qsort(nh_grp, nexthop_num, sizeof(struct zapi_nexthop),
969
0
        &zapi_nexthop_cmp);
970
0
}
971
972
/*
973
 * Encode a single zapi nexthop
974
 */
975
int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
976
      uint32_t api_flags, uint32_t api_message)
977
0
{
978
0
  int i, ret = 0;
979
0
  int nh_flags = api_nh->flags;
980
981
0
  stream_putl(s, api_nh->vrf_id);
982
0
  stream_putc(s, api_nh->type);
983
984
  /* If needed, set 'labelled nexthop' flag */
985
0
  if (api_nh->label_num > 0) {
986
0
    SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_LABEL);
987
988
    /* Validate label count */
989
0
    if (api_nh->label_num > MPLS_MAX_LABELS) {
990
0
      ret = -1;
991
0
      goto done;
992
0
    }
993
0
  }
994
995
  /* If present, set 'weight' flag before encoding flags */
996
0
  if (api_nh->weight)
997
0
    SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_WEIGHT);
998
999
  /* Note that we're only encoding a single octet */
1000
0
  stream_putc(s, nh_flags);
1001
1002
0
  switch (api_nh->type) {
1003
0
  case NEXTHOP_TYPE_BLACKHOLE:
1004
0
    stream_putc(s, api_nh->bh_type);
1005
0
    break;
1006
0
  case NEXTHOP_TYPE_IPV4:
1007
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
1008
0
    stream_put_in_addr(s, &api_nh->gate.ipv4);
1009
0
    stream_putl(s, api_nh->ifindex);
1010
0
    break;
1011
0
  case NEXTHOP_TYPE_IFINDEX:
1012
0
    stream_putl(s, api_nh->ifindex);
1013
0
    break;
1014
0
  case NEXTHOP_TYPE_IPV6:
1015
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
1016
0
    stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
1017
0
           16);
1018
0
    stream_putl(s, api_nh->ifindex);
1019
0
    break;
1020
0
  }
1021
1022
  /* We only encode labels if we have >0 - we use
1023
   * the per-nexthop flag above to signal that the count
1024
   * is present in the payload.
1025
   */
1026
0
  if (api_nh->label_num > 0) {
1027
0
    stream_putc(s, api_nh->label_num);
1028
0
    stream_putc(s, api_nh->label_type);
1029
0
    stream_put(s, &api_nh->labels[0],
1030
0
         api_nh->label_num * sizeof(mpls_label_t));
1031
0
  }
1032
1033
0
  if (api_nh->weight)
1034
0
    stream_putl(s, api_nh->weight);
1035
1036
  /* Router MAC for EVPN routes. */
1037
0
  if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_EVPN))
1038
0
    stream_put(s, &(api_nh->rmac),
1039
0
         sizeof(struct ethaddr));
1040
1041
  /* Color for Segment Routing TE. */
1042
0
  if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1043
0
    stream_putl(s, api_nh->srte_color);
1044
1045
  /* Index of backup nexthop */
1046
0
  if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1047
    /* Validate backup count */
1048
0
    if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS) {
1049
0
      ret = -1;
1050
0
      goto done;
1051
0
    }
1052
1053
0
    stream_putc(s, api_nh->backup_num);
1054
0
    for (i = 0; i < api_nh->backup_num; i++)
1055
0
      stream_putc(s, api_nh->backup_idx[i]);
1056
0
  }
1057
1058
0
  if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_SEG6LOCAL)) {
1059
0
    stream_putl(s, api_nh->seg6local_action);
1060
0
    stream_write(s, &api_nh->seg6local_ctx,
1061
0
           sizeof(struct seg6local_context));
1062
0
  }
1063
1064
0
  if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_SEG6))
1065
0
    stream_write(s, &api_nh->seg6_segs,
1066
0
           sizeof(struct in6_addr));
1067
1068
0
done:
1069
0
  return ret;
1070
0
}
1071
1072
int zapi_srv6_locator_chunk_encode(struct stream *s,
1073
           const struct srv6_locator_chunk *c)
1074
0
{
1075
0
  stream_putw(s, strlen(c->locator_name));
1076
0
  stream_put(s, c->locator_name, strlen(c->locator_name));
1077
0
  stream_putw(s, c->prefix.prefixlen);
1078
0
  stream_put(s, &c->prefix.prefix, sizeof(c->prefix.prefix));
1079
0
  stream_putc(s, c->block_bits_length);
1080
0
  stream_putc(s, c->node_bits_length);
1081
0
  stream_putc(s, c->function_bits_length);
1082
0
  stream_putc(s, c->argument_bits_length);
1083
0
  stream_putc(s, c->flags);
1084
0
  return 0;
1085
0
}
1086
1087
int zapi_srv6_locator_chunk_decode(struct stream *s,
1088
           struct srv6_locator_chunk *c)
1089
0
{
1090
0
  uint16_t len = 0;
1091
1092
0
  c->prefix.family = AF_INET6;
1093
1094
0
  STREAM_GETW(s, len);
1095
0
  if (len > SRV6_LOCNAME_SIZE)
1096
0
    goto stream_failure;
1097
1098
0
  STREAM_GET(c->locator_name, s, len);
1099
0
  STREAM_GETW(s, c->prefix.prefixlen);
1100
0
  STREAM_GET(&c->prefix.prefix, s, sizeof(c->prefix.prefix));
1101
0
  STREAM_GETC(s, c->block_bits_length);
1102
0
  STREAM_GETC(s, c->node_bits_length);
1103
0
  STREAM_GETC(s, c->function_bits_length);
1104
0
  STREAM_GETC(s, c->argument_bits_length);
1105
0
  STREAM_GETC(s, c->flags);
1106
0
  return 0;
1107
1108
0
stream_failure:
1109
0
  return -1;
1110
0
}
1111
1112
int zapi_srv6_locator_encode(struct stream *s, const struct srv6_locator *l)
1113
0
{
1114
0
  stream_putw(s, strlen(l->name));
1115
0
  stream_put(s, l->name, strlen(l->name));
1116
0
  stream_putw(s, l->prefix.prefixlen);
1117
0
  stream_put(s, &l->prefix.prefix, sizeof(l->prefix.prefix));
1118
0
  return 0;
1119
0
}
1120
1121
int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l)
1122
0
{
1123
0
  uint16_t len = 0;
1124
1125
0
  STREAM_GETW(s, len);
1126
0
  if (len > SRV6_LOCNAME_SIZE)
1127
0
    goto stream_failure;
1128
1129
0
  STREAM_GET(l->name, s, len);
1130
0
  STREAM_GETW(s, l->prefix.prefixlen);
1131
0
  STREAM_GET(&l->prefix.prefix, s, sizeof(l->prefix.prefix));
1132
0
  l->prefix.family = AF_INET6;
1133
0
  return 0;
1134
1135
0
stream_failure:
1136
0
  return -1;
1137
0
}
1138
1139
static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
1140
0
{
1141
0
  int i;
1142
1143
0
  if (cmd != ZEBRA_NHG_DEL && cmd != ZEBRA_NHG_ADD) {
1144
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1145
0
       "%s: Specified zapi NHG command (%d) doesn't exist",
1146
0
       __func__, cmd);
1147
0
    return -1;
1148
0
  }
1149
1150
0
  if (api_nhg->nexthop_num >= MULTIPATH_NUM ||
1151
0
      api_nhg->backup_nexthop_num >= MULTIPATH_NUM) {
1152
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1153
0
       "%s: zapi NHG encode with invalid input", __func__);
1154
0
    return -1;
1155
0
  }
1156
1157
0
  stream_reset(s);
1158
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
1159
1160
0
  stream_putw(s, api_nhg->proto);
1161
0
  stream_putl(s, api_nhg->id);
1162
1163
0
  stream_putw(s, api_nhg->resilience.buckets);
1164
0
  stream_putl(s, api_nhg->resilience.idle_timer);
1165
0
  stream_putl(s, api_nhg->resilience.unbalanced_timer);
1166
1167
0
  if (cmd == ZEBRA_NHG_ADD) {
1168
    /* Nexthops */
1169
0
    zapi_nexthop_group_sort(api_nhg->nexthops,
1170
0
          api_nhg->nexthop_num);
1171
1172
0
    stream_putw(s, api_nhg->nexthop_num);
1173
1174
0
    for (i = 0; i < api_nhg->nexthop_num; i++)
1175
0
      zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
1176
1177
    /* Backup nexthops */
1178
0
    stream_putw(s, api_nhg->backup_nexthop_num);
1179
1180
0
    for (i = 0; i < api_nhg->backup_nexthop_num; i++)
1181
0
      zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
1182
0
              0);
1183
0
  }
1184
1185
0
  stream_putw_at(s, 0, stream_get_endp(s));
1186
1187
0
  return 0;
1188
0
}
1189
1190
enum zclient_send_status zclient_nhg_send(struct zclient *zclient, int cmd,
1191
            struct zapi_nhg *api_nhg)
1192
0
{
1193
0
  api_nhg->proto = zclient->redist_default;
1194
1195
0
  if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
1196
0
    return -1;
1197
1198
0
  return zclient_send_message(zclient);
1199
0
}
1200
1201
int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
1202
0
{
1203
0
  struct zapi_nexthop *api_nh;
1204
0
  int i;
1205
0
  int psize;
1206
1207
0
  stream_reset(s);
1208
0
  zclient_create_header(s, cmd, api->vrf_id);
1209
1210
0
  if (api->type >= ZEBRA_ROUTE_MAX) {
1211
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1212
0
       "%s: Specified route type (%u) is not a legal value",
1213
0
       __func__, api->type);
1214
0
    return -1;
1215
0
  }
1216
0
  stream_putc(s, api->type);
1217
1218
0
  stream_putw(s, api->instance);
1219
0
  stream_putl(s, api->flags);
1220
0
  stream_putl(s, api->message);
1221
1222
0
  if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1223
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1224
0
       "%s: Specified route SAFI (%u) is not a legal value",
1225
0
       __func__, api->safi);
1226
0
    return -1;
1227
0
  }
1228
0
  stream_putc(s, api->safi);
1229
1230
  /* Put prefix information. */
1231
0
  stream_putc(s, api->prefix.family);
1232
0
  psize = PSIZE(api->prefix.prefixlen);
1233
0
  stream_putc(s, api->prefix.prefixlen);
1234
0
  stream_write(s, &api->prefix.u.prefix, psize);
1235
1236
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1237
0
    psize = PSIZE(api->src_prefix.prefixlen);
1238
0
    stream_putc(s, api->src_prefix.prefixlen);
1239
0
    stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
1240
0
  }
1241
1242
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1243
0
    stream_putl(s, api->nhgid);
1244
1245
  /* Nexthops.  */
1246
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1247
    /* limit the number of nexthops if necessary */
1248
0
    if (api->nexthop_num > MULTIPATH_NUM) {
1249
0
      flog_err(
1250
0
        EC_LIB_ZAPI_ENCODE,
1251
0
        "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
1252
0
        __func__, &api->prefix, api->nexthop_num,
1253
0
        MULTIPATH_NUM);
1254
0
      return -1;
1255
0
    }
1256
1257
    /* We canonicalize the nexthops by sorting them; this allows
1258
     * zebra to resolve the list of nexthops to a nexthop-group
1259
     * more efficiently.
1260
     */
1261
0
    zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1262
1263
0
    stream_putw(s, api->nexthop_num);
1264
1265
0
    for (i = 0; i < api->nexthop_num; i++) {
1266
0
      api_nh = &api->nexthops[i];
1267
1268
      /* MPLS labels for BGP-LU or Segment Routing */
1269
0
      if (api_nh->label_num > MPLS_MAX_LABELS) {
1270
0
        flog_err(
1271
0
          EC_LIB_ZAPI_ENCODE,
1272
0
          "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
1273
0
          __func__, &api->prefix,
1274
0
          api_nh->label_num, MPLS_MAX_LABELS);
1275
0
        return -1;
1276
0
      }
1277
1278
0
      if (zapi_nexthop_encode(s, api_nh, api->flags,
1279
0
            api->message)
1280
0
          != 0)
1281
0
        return -1;
1282
0
    }
1283
0
  }
1284
1285
  /* Backup nexthops  */
1286
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1287
    /* limit the number of nexthops if necessary */
1288
0
    if (api->backup_nexthop_num > MULTIPATH_NUM) {
1289
0
      flog_err(
1290
0
        EC_LIB_ZAPI_ENCODE,
1291
0
        "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
1292
0
        __func__, &api->prefix, api->backup_nexthop_num,
1293
0
        MULTIPATH_NUM);
1294
0
      return -1;
1295
0
    }
1296
1297
    /* Note that we do not sort the list of backup nexthops -
1298
     * this list is treated as an array and indexed by each
1299
     * primary nexthop that is associated with a backup.
1300
     */
1301
1302
0
    stream_putw(s, api->backup_nexthop_num);
1303
1304
0
    for (i = 0; i < api->backup_nexthop_num; i++) {
1305
0
      api_nh = &api->backup_nexthops[i];
1306
1307
      /* MPLS labels for BGP-LU or Segment Routing */
1308
0
      if (api_nh->label_num > MPLS_MAX_LABELS) {
1309
0
        flog_err(
1310
0
          EC_LIB_ZAPI_ENCODE,
1311
0
          "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
1312
0
          __func__, &api->prefix,
1313
0
          api_nh->label_num, MPLS_MAX_LABELS);
1314
0
        return -1;
1315
0
      }
1316
1317
0
      if (zapi_nexthop_encode(s, api_nh, api->flags,
1318
0
            api->message)
1319
0
          != 0)
1320
0
        return -1;
1321
0
    }
1322
0
  }
1323
1324
  /* Attributes. */
1325
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1326
0
    stream_putc(s, api->distance);
1327
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1328
0
    stream_putl(s, api->metric);
1329
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1330
0
    stream_putl(s, api->tag);
1331
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1332
0
    stream_putl(s, api->mtu);
1333
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1334
0
    stream_putl(s, api->tableid);
1335
1336
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1337
0
    if (api->opaque.length > ZAPI_MESSAGE_OPAQUE_LENGTH) {
1338
0
      flog_err(
1339
0
        EC_LIB_ZAPI_ENCODE,
1340
0
        "%s: opaque length %u is greater than allowed value",
1341
0
        __func__, api->opaque.length);
1342
0
      return -1;
1343
0
    }
1344
1345
0
    stream_putw(s, api->opaque.length);
1346
0
    stream_write(s, api->opaque.data, api->opaque.length);
1347
0
  }
1348
  /* Put length at the first point of the stream. */
1349
0
  stream_putw_at(s, 0, stream_get_endp(s));
1350
1351
0
  return 0;
1352
0
}
1353
1354
/*
1355
 * Decode a single zapi nexthop object
1356
 */
1357
int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1358
      uint32_t api_flags, uint32_t api_message)
1359
0
{
1360
0
  int i, ret = -1;
1361
1362
0
  STREAM_GETL(s, api_nh->vrf_id);
1363
0
  STREAM_GETC(s, api_nh->type);
1364
1365
  /* Note that we're only using a single octet of flags */
1366
0
  STREAM_GETC(s, api_nh->flags);
1367
1368
0
  switch (api_nh->type) {
1369
0
  case NEXTHOP_TYPE_BLACKHOLE:
1370
0
    STREAM_GETC(s, api_nh->bh_type);
1371
0
    break;
1372
0
  case NEXTHOP_TYPE_IPV4:
1373
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
1374
0
    STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1375
0
         IPV4_MAX_BYTELEN);
1376
0
    STREAM_GETL(s, api_nh->ifindex);
1377
0
    break;
1378
0
  case NEXTHOP_TYPE_IFINDEX:
1379
0
    STREAM_GETL(s, api_nh->ifindex);
1380
0
    break;
1381
0
  case NEXTHOP_TYPE_IPV6:
1382
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
1383
0
    STREAM_GET(&api_nh->gate.ipv6, s, 16);
1384
0
    STREAM_GETL(s, api_nh->ifindex);
1385
0
    break;
1386
0
  }
1387
1388
  /* MPLS labels for BGP-LU or Segment Routing */
1389
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1390
0
    STREAM_GETC(s, api_nh->label_num);
1391
0
    STREAM_GETC(s, api_nh->label_type);
1392
0
    if (api_nh->label_num > MPLS_MAX_LABELS) {
1393
0
      flog_err(
1394
0
        EC_LIB_ZAPI_ENCODE,
1395
0
        "%s: invalid number of MPLS labels (%u)",
1396
0
        __func__, api_nh->label_num);
1397
0
      return -1;
1398
0
    }
1399
1400
0
    STREAM_GET(&api_nh->labels[0], s,
1401
0
         api_nh->label_num * sizeof(mpls_label_t));
1402
0
  }
1403
1404
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1405
0
    STREAM_GETL(s, api_nh->weight);
1406
1407
  /* Router MAC for EVPN routes. */
1408
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN))
1409
0
    STREAM_GET(&(api_nh->rmac), s,
1410
0
         sizeof(struct ethaddr));
1411
1412
  /* Color for Segment Routing TE. */
1413
0
  if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1414
0
    STREAM_GETL(s, api_nh->srte_color);
1415
1416
  /* Backup nexthop index */
1417
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1418
0
    STREAM_GETC(s, api_nh->backup_num);
1419
1420
0
    if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS)
1421
0
      return -1;
1422
1423
0
    for (i = 0; i < api_nh->backup_num; i++)
1424
0
      STREAM_GETC(s, api_nh->backup_idx[i]);
1425
0
  }
1426
1427
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6LOCAL)) {
1428
0
    STREAM_GETL(s, api_nh->seg6local_action);
1429
0
    STREAM_GET(&api_nh->seg6local_ctx, s,
1430
0
         sizeof(struct seg6local_context));
1431
0
  }
1432
1433
0
  if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6))
1434
0
    STREAM_GET(&api_nh->seg6_segs, s,
1435
0
         sizeof(struct in6_addr));
1436
1437
  /* Success */
1438
0
  ret = 0;
1439
1440
0
stream_failure:
1441
1442
0
  return ret;
1443
0
}
1444
1445
int zapi_route_decode(struct stream *s, struct zapi_route *api)
1446
0
{
1447
0
  struct zapi_nexthop *api_nh;
1448
0
  int i;
1449
1450
0
  memset(api, 0, sizeof(*api));
1451
1452
  /* Type, flags, message. */
1453
0
  STREAM_GETC(s, api->type);
1454
0
  if (api->type >= ZEBRA_ROUTE_MAX) {
1455
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1456
0
       "%s: Specified route type: %d is not a legal value",
1457
0
       __func__, api->type);
1458
0
    return -1;
1459
0
  }
1460
1461
0
  STREAM_GETW(s, api->instance);
1462
0
  STREAM_GETL(s, api->flags);
1463
0
  STREAM_GETL(s, api->message);
1464
0
  STREAM_GETC(s, api->safi);
1465
0
  if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1466
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1467
0
       "%s: Specified route SAFI (%u) is not a legal value",
1468
0
       __func__, api->safi);
1469
0
    return -1;
1470
0
  }
1471
1472
  /* Prefix. */
1473
0
  STREAM_GETC(s, api->prefix.family);
1474
0
  STREAM_GETC(s, api->prefix.prefixlen);
1475
0
  switch (api->prefix.family) {
1476
0
  case AF_INET:
1477
0
    if (api->prefix.prefixlen > IPV4_MAX_BITLEN) {
1478
0
      flog_err(
1479
0
        EC_LIB_ZAPI_ENCODE,
1480
0
        "%s: V4 prefixlen is %d which should not be more than 32",
1481
0
        __func__, api->prefix.prefixlen);
1482
0
      return -1;
1483
0
    }
1484
0
    break;
1485
0
  case AF_INET6:
1486
0
    if (api->prefix.prefixlen > IPV6_MAX_BITLEN) {
1487
0
      flog_err(
1488
0
        EC_LIB_ZAPI_ENCODE,
1489
0
        "%s: v6 prefixlen is %d which should not be more than 128",
1490
0
        __func__, api->prefix.prefixlen);
1491
0
      return -1;
1492
0
    }
1493
0
    break;
1494
0
  default:
1495
0
    flog_err(EC_LIB_ZAPI_ENCODE,
1496
0
       "%s: Specified family %d is not v4 or v6", __func__,
1497
0
       api->prefix.family);
1498
0
    return -1;
1499
0
  }
1500
0
  STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1501
1502
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1503
0
    api->src_prefix.family = AF_INET6;
1504
0
    STREAM_GETC(s, api->src_prefix.prefixlen);
1505
0
    if (api->src_prefix.prefixlen > IPV6_MAX_BITLEN) {
1506
0
      flog_err(
1507
0
        EC_LIB_ZAPI_ENCODE,
1508
0
        "%s: SRC Prefix prefixlen received: %d is too large",
1509
0
        __func__, api->src_prefix.prefixlen);
1510
0
      return -1;
1511
0
    }
1512
0
    STREAM_GET(&api->src_prefix.prefix, s,
1513
0
         PSIZE(api->src_prefix.prefixlen));
1514
1515
0
    if (api->prefix.family != AF_INET6
1516
0
        || api->src_prefix.prefixlen == 0) {
1517
0
      flog_err(
1518
0
        EC_LIB_ZAPI_ENCODE,
1519
0
        "%s: SRC prefix specified in some manner that makes no sense",
1520
0
        __func__);
1521
0
      return -1;
1522
0
    }
1523
0
  }
1524
1525
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1526
0
    STREAM_GETL(s, api->nhgid);
1527
1528
  /* Nexthops. */
1529
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1530
0
    STREAM_GETW(s, api->nexthop_num);
1531
0
    if (api->nexthop_num > MULTIPATH_NUM) {
1532
0
      flog_err(EC_LIB_ZAPI_ENCODE,
1533
0
         "%s: invalid number of nexthops (%u)",
1534
0
         __func__, api->nexthop_num);
1535
0
      return -1;
1536
0
    }
1537
1538
0
    for (i = 0; i < api->nexthop_num; i++) {
1539
0
      api_nh = &api->nexthops[i];
1540
1541
0
      if (zapi_nexthop_decode(s, api_nh, api->flags,
1542
0
            api->message)
1543
0
          != 0)
1544
0
        return -1;
1545
0
    }
1546
0
  }
1547
1548
  /* Backup nexthops. */
1549
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1550
0
    STREAM_GETW(s, api->backup_nexthop_num);
1551
0
    if (api->backup_nexthop_num > MULTIPATH_NUM) {
1552
0
      flog_err(EC_LIB_ZAPI_ENCODE,
1553
0
         "%s: invalid number of backup nexthops (%u)",
1554
0
         __func__, api->backup_nexthop_num);
1555
0
      return -1;
1556
0
    }
1557
1558
0
    for (i = 0; i < api->backup_nexthop_num; i++) {
1559
0
      api_nh = &api->backup_nexthops[i];
1560
1561
0
      if (zapi_nexthop_decode(s, api_nh, api->flags,
1562
0
            api->message)
1563
0
          != 0)
1564
0
        return -1;
1565
0
    }
1566
0
  }
1567
1568
  /* Attributes. */
1569
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1570
0
    STREAM_GETC(s, api->distance);
1571
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1572
0
    STREAM_GETL(s, api->metric);
1573
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1574
0
    STREAM_GETL(s, api->tag);
1575
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1576
0
    STREAM_GETL(s, api->mtu);
1577
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1578
0
    STREAM_GETL(s, api->tableid);
1579
1580
0
  if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1581
0
    STREAM_GETW(s, api->opaque.length);
1582
0
    if (api->opaque.length > ZAPI_MESSAGE_OPAQUE_LENGTH) {
1583
0
      flog_err(
1584
0
        EC_LIB_ZAPI_ENCODE,
1585
0
        "%s: opaque length %u is greater than allowed value",
1586
0
        __func__, api->opaque.length);
1587
0
      return -1;
1588
0
    }
1589
1590
0
    STREAM_GET(api->opaque.data, s, api->opaque.length);
1591
0
  }
1592
1593
0
  return 0;
1594
0
stream_failure:
1595
0
  return -1;
1596
0
}
1597
1598
static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1599
             uint8_t family)
1600
0
{
1601
0
  struct prefix any;
1602
1603
0
  if (!p) {
1604
0
    memset(&any, 0, sizeof(any));
1605
0
    any.family = family;
1606
0
    p = &any;
1607
0
  }
1608
1609
0
  stream_putc(s, p->family);
1610
0
  stream_putc(s, p->prefixlen);
1611
0
  stream_put(s, &p->u.prefix, prefix_blen(p));
1612
0
}
1613
1614
int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
1615
0
{
1616
0
  stream_reset(s);
1617
0
  zclient_create_header(s, cmd, zrule->vrf_id);
1618
1619
  /*
1620
   * We are sending one item at a time at the moment
1621
   */
1622
0
  stream_putl(s, 1);
1623
1624
0
  stream_putl(s, zrule->seq);
1625
0
  stream_putl(s, zrule->priority);
1626
0
  stream_putl(s, zrule->unique);
1627
1628
0
  zapi_encode_prefix(s, &(zrule->filter.src_ip),
1629
0
         zrule->filter.src_ip.family);
1630
0
  stream_putw(s, zrule->filter.src_port); /* src port */
1631
0
  zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1632
0
         zrule->filter.src_ip.family);
1633
0
  stream_putw(s, zrule->filter.dst_port); /* dst port */
1634
0
  stream_putw(s, zrule->filter.fwmark);   /* fwmark */
1635
1636
0
  stream_putl(s, zrule->action.table);
1637
0
  stream_put(s, zrule->ifname, INTERFACE_NAMSIZ);
1638
1639
  /* Put length at the first point of the stream. */
1640
0
  stream_putw_at(s, 0, stream_get_endp(s));
1641
1642
0
  return 0;
1643
0
}
1644
1645
int zapi_tc_qdisc_encode(uint8_t cmd, struct stream *s, struct tc_qdisc *qdisc)
1646
0
{
1647
0
  stream_reset(s);
1648
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
1649
1650
1651
0
  stream_putl(s, 1);
1652
1653
0
  stream_putl(s, qdisc->ifindex);
1654
0
  stream_putl(s, qdisc->kind);
1655
1656
0
  stream_putw_at(s, 0, stream_get_endp(s));
1657
1658
0
  return 0;
1659
0
}
1660
1661
int zapi_tc_class_encode(uint8_t cmd, struct stream *s, struct tc_class *class)
1662
0
{
1663
0
  stream_reset(s);
1664
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
1665
1666
0
  stream_putl(s, 1);
1667
1668
0
  stream_putl(s, class->ifindex);
1669
0
  stream_putl(s, class->handle);
1670
0
  stream_putl(s, class->kind);
1671
1672
0
  switch (class->kind) {
1673
0
  case TC_QDISC_HTB:
1674
0
    stream_putq(s, class->u.htb.rate);
1675
0
    stream_putq(s, class->u.htb.ceil);
1676
0
    break;
1677
0
  case TC_QDISC_UNSPEC:
1678
0
  case TC_QDISC_NOQUEUE:
1679
    /* not implemented */
1680
0
    break;
1681
0
  }
1682
0
  stream_putw_at(s, 0, stream_get_endp(s));
1683
1684
0
  return 0;
1685
0
}
1686
1687
int zapi_tc_filter_encode(uint8_t cmd, struct stream *s,
1688
        struct tc_filter *filter)
1689
0
{
1690
0
  stream_reset(s);
1691
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
1692
1693
0
  stream_putl(s, 1);
1694
1695
0
  stream_putl(s, filter->ifindex);
1696
0
  stream_putl(s, filter->handle);
1697
0
  stream_putl(s, filter->priority);
1698
0
  stream_putl(s, filter->protocol);
1699
0
  stream_putl(s, filter->kind);
1700
1701
0
  switch (filter->kind) {
1702
0
  case TC_FILTER_FLOWER:
1703
0
    stream_putl(s, filter->u.flower.filter_bm);
1704
0
    if (filter->u.flower.filter_bm & TC_FLOWER_IP_PROTOCOL)
1705
0
      stream_putc(s, filter->u.flower.ip_proto);
1706
0
    if (filter->u.flower.filter_bm & TC_FLOWER_SRC_IP)
1707
0
      zapi_encode_prefix(s, &filter->u.flower.src_ip,
1708
0
             filter->u.flower.src_ip.family);
1709
0
    if (filter->u.flower.filter_bm & TC_FLOWER_SRC_PORT) {
1710
0
      stream_putw(s, filter->u.flower.src_port_min);
1711
0
      stream_putw(s, filter->u.flower.src_port_max);
1712
0
    }
1713
0
    if (filter->u.flower.filter_bm & TC_FLOWER_DST_IP)
1714
0
      zapi_encode_prefix(s, &filter->u.flower.dst_ip,
1715
0
             filter->u.flower.dst_ip.family);
1716
0
    if (filter->u.flower.filter_bm & TC_FLOWER_DST_PORT) {
1717
0
      stream_putw(s, filter->u.flower.dst_port_min);
1718
0
      stream_putw(s, filter->u.flower.dst_port_max);
1719
0
    }
1720
0
    if (filter->u.flower.filter_bm & TC_FLOWER_DSFIELD) {
1721
0
      stream_putc(s, filter->u.flower.dsfield);
1722
0
      stream_putc(s, filter->u.flower.dsfield_mask);
1723
0
    }
1724
0
    stream_putl(s, filter->u.flower.classid);
1725
0
    break;
1726
0
  case TC_FILTER_UNSPEC:
1727
0
  case TC_FILTER_BPF:
1728
0
  case TC_FILTER_FLOW:
1729
0
  case TC_FILTER_U32:
1730
    /* not implemented */
1731
0
    break;
1732
0
  }
1733
1734
0
  stream_putw_at(s, 0, stream_get_endp(s));
1735
1736
0
  return 0;
1737
0
}
1738
1739
bool zapi_nhg_notify_decode(struct stream *s, uint32_t *id,
1740
          enum zapi_nhg_notify_owner *note)
1741
0
{
1742
0
  uint32_t read_id;
1743
1744
0
  STREAM_GET(note, s, sizeof(*note));
1745
0
  STREAM_GETL(s, read_id);
1746
1747
0
  *id = read_id;
1748
1749
0
  return true;
1750
1751
0
stream_failure:
1752
0
  return false;
1753
0
}
1754
1755
bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1756
            uint32_t *tableid,
1757
            enum zapi_route_notify_owner *note,
1758
            afi_t *afi, safi_t *safi)
1759
0
{
1760
0
  uint32_t t;
1761
0
  afi_t afi_val;
1762
0
  safi_t safi_val;
1763
1764
0
  STREAM_GET(note, s, sizeof(*note));
1765
1766
0
  STREAM_GETC(s, p->family);
1767
0
  STREAM_GETC(s, p->prefixlen);
1768
0
  STREAM_GET(&p->u.prefix, s, prefix_blen(p));
1769
0
  STREAM_GETL(s, t);
1770
0
  STREAM_GETC(s, afi_val);
1771
0
  STREAM_GETC(s, safi_val);
1772
1773
0
  *tableid = t;
1774
1775
0
  if (afi)
1776
0
    *afi = afi_val;
1777
0
  if (safi)
1778
0
    *safi = safi_val;
1779
1780
0
  return true;
1781
1782
0
stream_failure:
1783
0
  return false;
1784
0
}
1785
1786
bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1787
           uint32_t *priority, uint32_t *unique, char *ifname,
1788
           enum zapi_rule_notify_owner *note)
1789
0
{
1790
0
  uint32_t prio, seq, uni;
1791
1792
0
  STREAM_GET(note, s, sizeof(*note));
1793
1794
0
  STREAM_GETL(s, seq);
1795
0
  STREAM_GETL(s, prio);
1796
0
  STREAM_GETL(s, uni);
1797
0
  STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
1798
1799
0
  if (zclient_debug)
1800
0
    zlog_debug("%s: %u %u %u %s", __func__, seq, prio, uni, ifname);
1801
0
  *seqno = seq;
1802
0
  *priority = prio;
1803
0
  *unique = uni;
1804
1805
0
  return true;
1806
1807
0
stream_failure:
1808
0
  return false;
1809
0
}
1810
1811
bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1812
            enum zapi_ipset_notify_owner *note)
1813
0
{
1814
0
  uint32_t uni;
1815
0
  uint16_t notew;
1816
1817
0
  STREAM_GETW(s, notew);
1818
1819
0
  STREAM_GETL(s, uni);
1820
1821
0
  if (zclient_debug)
1822
0
    zlog_debug("%s: %u", __func__, uni);
1823
0
  *unique = uni;
1824
0
  *note = (enum zapi_ipset_notify_owner)notew;
1825
0
  return true;
1826
1827
0
stream_failure:
1828
0
  return false;
1829
0
}
1830
1831
bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1832
            char *ipset_name,
1833
            enum zapi_ipset_entry_notify_owner *note)
1834
0
{
1835
0
  uint32_t uni;
1836
0
  uint16_t notew;
1837
1838
0
  STREAM_GETW(s, notew);
1839
1840
0
  STREAM_GETL(s, uni);
1841
1842
0
  STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
1843
1844
0
  if (zclient_debug)
1845
0
    zlog_debug("%s: %u", __func__, uni);
1846
0
  *unique = uni;
1847
0
  *note = (enum zapi_ipset_entry_notify_owner)notew;
1848
1849
0
  return true;
1850
1851
0
stream_failure:
1852
0
  return false;
1853
0
}
1854
1855
bool zapi_iptable_notify_decode(struct stream *s,
1856
    uint32_t *unique,
1857
    enum zapi_iptable_notify_owner *note)
1858
0
{
1859
0
  uint32_t uni;
1860
0
  uint16_t notew;
1861
1862
0
  STREAM_GETW(s, notew);
1863
1864
0
  STREAM_GETL(s, uni);
1865
1866
0
  if (zclient_debug)
1867
0
    zlog_debug("%s: %u", __func__, uni);
1868
0
  *unique = uni;
1869
0
  *note = (enum zapi_iptable_notify_owner)notew;
1870
1871
0
  return true;
1872
1873
0
stream_failure:
1874
0
  return false;
1875
0
}
1876
1877
struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
1878
0
{
1879
0
  struct nexthop *n = nexthop_new();
1880
1881
0
  n->type = znh->type;
1882
0
  n->vrf_id = znh->vrf_id;
1883
0
  n->ifindex = znh->ifindex;
1884
0
  n->gate = znh->gate;
1885
0
  n->srte_color = znh->srte_color;
1886
1887
  /*
1888
   * This function currently handles labels
1889
   */
1890
0
  if (znh->label_num) {
1891
0
    nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
1892
0
           znh->labels);
1893
0
  }
1894
1895
0
  if (CHECK_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1896
0
    SET_FLAG(n->flags, NEXTHOP_FLAG_HAS_BACKUP);
1897
0
    n->backup_num = znh->backup_num;
1898
0
    memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
1899
0
  }
1900
1901
0
  if (znh->seg6local_action != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC)
1902
0
    nexthop_add_srv6_seg6local(n, znh->seg6local_action,
1903
0
             &znh->seg6local_ctx);
1904
1905
0
  if (!sid_zero(&znh->seg6_segs))
1906
0
    nexthop_add_srv6_seg6(n, &znh->seg6_segs);
1907
1908
0
  return n;
1909
0
}
1910
1911
/*
1912
 * Convert nexthop to zapi nexthop
1913
 */
1914
int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1915
            const struct nexthop *nh)
1916
0
{
1917
0
  int i;
1918
1919
0
  memset(znh, 0, sizeof(*znh));
1920
1921
0
  znh->type = nh->type;
1922
0
  znh->vrf_id = nh->vrf_id;
1923
0
  znh->weight = nh->weight;
1924
0
  znh->ifindex = nh->ifindex;
1925
0
  znh->gate = nh->gate;
1926
1927
0
  if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))
1928
0
    SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1929
1930
0
  if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_EVPN))
1931
0
    SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
1932
1933
0
  if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1934
1935
    /* Validate */
1936
0
    if (nh->nh_label->num_labels > MPLS_MAX_LABELS)
1937
0
      return -1;
1938
1939
0
    for (i = 0; i < nh->nh_label->num_labels; i++)
1940
0
      znh->labels[i] = nh->nh_label->label[i];
1941
1942
0
    znh->label_num = i;
1943
0
    znh->label_type = nh->nh_label_type;
1944
0
    SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1945
0
  }
1946
1947
0
  if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
1948
0
    if (nh->backup_num > NEXTHOP_MAX_BACKUPS)
1949
0
      return -1;
1950
1951
0
    SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1952
0
    znh->backup_num = nh->backup_num;
1953
0
    memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
1954
0
  }
1955
1956
0
  if (nh->nh_srv6) {
1957
0
    if (nh->nh_srv6->seg6local_action !=
1958
0
        ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
1959
0
      SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_SEG6LOCAL);
1960
0
      znh->seg6local_action = nh->nh_srv6->seg6local_action;
1961
0
      memcpy(&znh->seg6local_ctx,
1962
0
             &nh->nh_srv6->seg6local_ctx,
1963
0
             sizeof(struct seg6local_context));
1964
0
    }
1965
1966
0
    if (!sid_zero(&nh->nh_srv6->seg6_segs)) {
1967
0
      SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_SEG6);
1968
0
      memcpy(&znh->seg6_segs, &nh->nh_srv6->seg6_segs,
1969
0
             sizeof(struct in6_addr));
1970
0
    }
1971
0
  }
1972
1973
0
  return 0;
1974
0
}
1975
1976
/*
1977
 * Wrapper that converts backup nexthop
1978
 */
1979
int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
1980
             const struct nexthop *nh)
1981
0
{
1982
0
  int ret;
1983
1984
  /* Ensure that zapi flags are correct: backups don't have backups */
1985
0
  ret = zapi_nexthop_from_nexthop(znh, nh);
1986
0
  if (ret == 0)
1987
0
    UNSET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1988
1989
0
  return ret;
1990
0
}
1991
1992
/*
1993
 * Format some info about a zapi nexthop, for debug or logging.
1994
 */
1995
const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
1996
           int bufsize)
1997
0
{
1998
0
  char tmp[INET6_ADDRSTRLEN];
1999
2000
0
  switch (znh->type) {
2001
0
  case NEXTHOP_TYPE_IFINDEX:
2002
0
    snprintf(buf, bufsize, "if %u", znh->ifindex);
2003
0
    break;
2004
0
  case NEXTHOP_TYPE_IPV4:
2005
0
  case NEXTHOP_TYPE_IPV4_IFINDEX:
2006
0
    inet_ntop(AF_INET, &znh->gate.ipv4, tmp, sizeof(tmp));
2007
0
    snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
2008
0
    break;
2009
0
  case NEXTHOP_TYPE_IPV6:
2010
0
  case NEXTHOP_TYPE_IPV6_IFINDEX:
2011
0
    inet_ntop(AF_INET6, &znh->gate.ipv6, tmp, sizeof(tmp));
2012
0
    snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
2013
0
    break;
2014
0
  case NEXTHOP_TYPE_BLACKHOLE:
2015
0
    snprintf(buf, bufsize, "blackhole");
2016
0
    break;
2017
0
  default:
2018
0
    snprintf(buf, bufsize, "unknown");
2019
0
    break;
2020
0
  }
2021
2022
0
  return buf;
2023
0
}
2024
2025
/*
2026
 * Decode the nexthop-tracking update message
2027
 */
2028
bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
2029
        struct zapi_route *nhr)
2030
0
{
2031
0
  uint32_t i;
2032
2033
0
  memset(nhr, 0, sizeof(*nhr));
2034
2035
0
  STREAM_GETL(s, nhr->message);
2036
0
  STREAM_GETW(s, nhr->safi);
2037
0
  STREAM_GETW(s, match->family);
2038
0
  STREAM_GETC(s, match->prefixlen);
2039
  /*
2040
   * What we got told to match against
2041
   */
2042
0
  switch (match->family) {
2043
0
  case AF_INET:
2044
0
    STREAM_GET(&match->u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
2045
0
    break;
2046
0
  case AF_INET6:
2047
0
    STREAM_GET(&match->u.prefix6, s, IPV6_MAX_BYTELEN);
2048
0
    break;
2049
0
  }
2050
  /*
2051
   * What we matched against
2052
   */
2053
0
  STREAM_GETW(s, nhr->prefix.family);
2054
0
  STREAM_GETC(s, nhr->prefix.prefixlen);
2055
0
  switch (nhr->prefix.family) {
2056
0
  case AF_INET:
2057
0
    STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
2058
0
    break;
2059
0
  case AF_INET6:
2060
0
    STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
2061
0
    break;
2062
0
  default:
2063
0
    break;
2064
0
  }
2065
0
  if (CHECK_FLAG(nhr->message, ZAPI_MESSAGE_SRTE))
2066
0
    STREAM_GETL(s, nhr->srte_color);
2067
2068
0
  STREAM_GETC(s, nhr->type);
2069
0
  STREAM_GETW(s, nhr->instance);
2070
0
  STREAM_GETC(s, nhr->distance);
2071
0
  STREAM_GETL(s, nhr->metric);
2072
0
  STREAM_GETC(s, nhr->nexthop_num);
2073
2074
0
  for (i = 0; i < nhr->nexthop_num; i++) {
2075
0
    if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
2076
0
      return false;
2077
0
  }
2078
2079
0
  return true;
2080
0
stream_failure:
2081
0
  return false;
2082
0
}
2083
2084
bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
2085
0
{
2086
0
  memset(error, 0, sizeof(*error));
2087
2088
0
  STREAM_GET(error, s, sizeof(*error));
2089
2090
0
  if (zclient_debug)
2091
0
    zlog_debug("%s: type: %s", __func__,
2092
0
         zebra_error_type2str(*error));
2093
2094
0
  return true;
2095
0
stream_failure:
2096
0
  return false;
2097
0
}
2098
2099
/*
2100
 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
2101
 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
2102
 * then set/unset redist[type] in the client handle (a struct zserv) for the
2103
 * sending client
2104
 */
2105
enum zclient_send_status
2106
zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
2107
      int type, unsigned short instance, vrf_id_t vrf_id)
2108
0
{
2109
0
  struct stream *s;
2110
2111
0
  s = zclient->obuf;
2112
0
  stream_reset(s);
2113
2114
0
  zclient_create_header(s, command, vrf_id);
2115
0
  stream_putc(s, afi);
2116
0
  stream_putc(s, type);
2117
0
  stream_putw(s, instance);
2118
2119
0
  stream_putw_at(s, 0, stream_get_endp(s));
2120
2121
0
  return zclient_send_message(zclient);
2122
0
}
2123
2124
enum zclient_send_status
2125
zebra_redistribute_default_send(int command, struct zclient *zclient, afi_t afi,
2126
        vrf_id_t vrf_id)
2127
0
{
2128
0
  struct stream *s;
2129
2130
0
  s = zclient->obuf;
2131
0
  stream_reset(s);
2132
2133
0
  zclient_create_header(s, command, vrf_id);
2134
0
  stream_putc(s, afi);
2135
2136
0
  stream_putw_at(s, 0, stream_get_endp(s));
2137
2138
0
  return zclient_send_message(zclient);
2139
0
}
2140
2141
/* Send route notify request to zebra */
2142
int zebra_route_notify_send(int command, struct zclient *zclient, bool set)
2143
0
{
2144
0
  struct stream *s;
2145
2146
0
  s = zclient->obuf;
2147
0
  stream_reset(s);
2148
2149
0
  zclient_create_header(s, command, 0);
2150
0
  stream_putc(s, !!set);
2151
2152
0
  stream_putw_at(s, 0, stream_get_endp(s));
2153
2154
0
  return zclient_send_message(zclient);
2155
0
}
2156
2157
/* Get prefix in ZServ format; family should be filled in on prefix */
2158
static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
2159
0
{
2160
0
  size_t plen = prefix_blen(p);
2161
0
  uint8_t c;
2162
0
  p->prefixlen = 0;
2163
2164
0
  if (plen == 0)
2165
0
    return -1;
2166
2167
0
  STREAM_GET(&p->u.prefix, s, plen);
2168
0
  STREAM_GETC(s, c);
2169
0
  p->prefixlen = MIN(plen * 8, c);
2170
2171
0
  return 0;
2172
0
stream_failure:
2173
0
  return -1;
2174
0
}
2175
2176
/* Router-id update from zebra daemon. */
2177
int zebra_router_id_update_read(struct stream *s, struct prefix *rid)
2178
0
{
2179
  /* Fetch interface address. */
2180
0
  STREAM_GETC(s, rid->family);
2181
2182
0
  return zclient_stream_get_prefix(s, rid);
2183
2184
0
stream_failure:
2185
0
  return -1;
2186
0
}
2187
2188
/* Interface addition from zebra daemon. */
2189
/*
2190
 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
2191
 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
2192
 *     0                   1                   2                   3
2193
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2194
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2195
 * |  ifname                                                       |
2196
 * |                                                               |
2197
 * |                                                               |
2198
 * |                                                               |
2199
 * |                                                               |
2200
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2201
 * |  ifindex                                                      |
2202
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2203
 * |  status       |
2204
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2205
 * |  if_flags                                                     |
2206
 * |                                                               |
2207
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2208
 * |  metric                                                       |
2209
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2210
 * |  speed                                                        |
2211
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2212
 * |  ifmtu                                                        |
2213
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2214
 * |  ifmtu6                                                       |
2215
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2216
 * |  bandwidth                                                    |
2217
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2218
 * |  parent ifindex                                               |
2219
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2220
 * |  Link Layer Type                                              |
2221
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2222
 * |  Harware Address Length                                       |
2223
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2224
 * |  Hardware Address      if HW length different from 0          |
2225
 * |   ...                  max INTERFACE_HWADDR_MAX               |
2226
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2227
 * |  Link_params? |  Whether a link-params follows: 1 or 0.
2228
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2229
 * |  Link_params    0 or 1 INTERFACE_LINK_PARAMS_SIZE sized       |
2230
 * |   ....          (struct if_link_params).                      |
2231
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2232
 */
2233
2234
static int zclient_vrf_add(ZAPI_CALLBACK_ARGS)
2235
0
{
2236
0
  struct vrf *vrf;
2237
0
  char vrfname_tmp[VRF_NAMSIZ + 1] = {};
2238
0
  struct vrf_data data;
2239
2240
0
  STREAM_GET(&data, zclient->ibuf, sizeof(struct vrf_data));
2241
  /* Read interface name. */
2242
0
  STREAM_GET(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
2243
2244
0
  if (strlen(vrfname_tmp) == 0)
2245
0
    goto stream_failure;
2246
2247
  /* Lookup/create vrf by name, then vrf_id. */
2248
0
  vrf = vrf_get(vrf_id, vrfname_tmp);
2249
2250
  /* If there's already a VRF with this name, don't create vrf */
2251
0
  if (!vrf)
2252
0
    return 0;
2253
2254
0
  vrf->data.l.table_id = data.l.table_id;
2255
0
  memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
2256
0
  vrf_enable(vrf);
2257
2258
0
  return 0;
2259
0
stream_failure:
2260
0
  return -1;
2261
0
}
2262
2263
static int zclient_vrf_delete(ZAPI_CALLBACK_ARGS)
2264
0
{
2265
0
  struct vrf *vrf;
2266
2267
  /* Lookup vrf by vrf_id. */
2268
0
  vrf = vrf_lookup_by_id(vrf_id);
2269
2270
  /*
2271
   * If a routing protocol doesn't know about a
2272
   * vrf that is about to be deleted.  There is
2273
   * no point in attempting to delete it.
2274
   */
2275
0
  if (!vrf)
2276
0
    return 0;
2277
2278
0
  vrf_delete(vrf);
2279
0
  return 0;
2280
0
}
2281
2282
static int zclient_interface_add(ZAPI_CALLBACK_ARGS)
2283
0
{
2284
0
  struct interface *ifp;
2285
0
  char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
2286
0
  struct stream *s = zclient->ibuf;
2287
0
  struct vrf *vrf;
2288
2289
  /* Read interface name. */
2290
0
  STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
2291
2292
  /* Lookup/create interface by name. */
2293
0
  vrf = vrf_lookup_by_id(vrf_id);
2294
0
  if (!vrf) {
2295
0
    zlog_debug(
2296
0
      "Rx'd interface add from Zebra, but VRF %u does not exist",
2297
0
      vrf_id);
2298
0
    return -1;
2299
0
  }
2300
2301
0
  ifp = if_get_by_name(ifname_tmp, vrf_id, vrf->name);
2302
2303
0
  zebra_interface_if_set_value(s, ifp);
2304
2305
0
  if_new_via_zapi(ifp);
2306
2307
0
  return 0;
2308
0
stream_failure:
2309
0
  return -1;
2310
0
}
2311
2312
/*
2313
 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
2314
 * from zebra server.  The format of this message is the same as
2315
 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
2316
 * except that no sockaddr_dl is sent at the tail of the message.
2317
 */
2318
struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
2319
0
{
2320
0
  struct interface *ifp;
2321
0
  char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
2322
2323
  /* Read interface name. */
2324
0
  STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
2325
2326
  /* Lookup this by interface index. */
2327
0
  ifp = if_lookup_by_name(ifname_tmp, vrf_id);
2328
0
  if (ifp == NULL) {
2329
0
    flog_err(EC_LIB_ZAPI_ENCODE,
2330
0
       "INTERFACE_STATE: Cannot find IF %s in VRF %d",
2331
0
       ifname_tmp, vrf_id);
2332
0
    return NULL;
2333
0
  }
2334
2335
0
  zebra_interface_if_set_value(s, ifp);
2336
2337
0
  return ifp;
2338
0
stream_failure:
2339
0
  return NULL;
2340
0
}
2341
2342
static int zclient_interface_delete(ZAPI_CALLBACK_ARGS)
2343
0
{
2344
0
  struct interface *ifp;
2345
0
  struct stream *s = zclient->ibuf;
2346
2347
0
  ifp = zebra_interface_state_read(s, vrf_id);
2348
2349
0
  if (ifp == NULL)
2350
0
    return 0;
2351
2352
0
  if_destroy_via_zapi(ifp);
2353
0
  return 0;
2354
0
}
2355
2356
static int zclient_interface_up(ZAPI_CALLBACK_ARGS)
2357
0
{
2358
0
  struct interface *ifp;
2359
0
  struct stream *s = zclient->ibuf;
2360
2361
0
  ifp = zebra_interface_state_read(s, vrf_id);
2362
2363
0
  if (!ifp)
2364
0
    return 0;
2365
2366
0
  if_up_via_zapi(ifp);
2367
0
  return 0;
2368
0
}
2369
2370
static int zclient_interface_down(ZAPI_CALLBACK_ARGS)
2371
0
{
2372
0
  struct interface *ifp;
2373
0
  struct stream *s = zclient->ibuf;
2374
2375
0
  ifp = zebra_interface_state_read(s, vrf_id);
2376
2377
0
  if (!ifp)
2378
0
    return 0;
2379
2380
0
  if_down_via_zapi(ifp);
2381
0
  return 0;
2382
0
}
2383
2384
static int zclient_handle_error(ZAPI_CALLBACK_ARGS)
2385
0
{
2386
0
  enum zebra_error_types error;
2387
0
  struct stream *s = zclient->ibuf;
2388
2389
0
  zapi_error_decode(s, &error);
2390
2391
0
  if (zclient->handle_error)
2392
0
    (*zclient->handle_error)(error);
2393
0
  return 0;
2394
0
}
2395
2396
static int link_params_set_value(struct stream *s, struct interface *ifp)
2397
0
{
2398
0
  uint8_t link_params_enabled, nb_ext_adm_grp;
2399
0
  struct if_link_params *iflp;
2400
0
  uint32_t bwclassnum, bitmap_data;
2401
2402
0
  iflp = if_link_params_get(ifp);
2403
2404
0
  if (iflp == NULL)
2405
0
    iflp = if_link_params_init(ifp);
2406
2407
0
  STREAM_GETC(s, link_params_enabled);
2408
0
  if (!link_params_enabled) {
2409
0
    if_link_params_free(ifp);
2410
0
    return 0;
2411
0
  }
2412
2413
0
  STREAM_GETL(s, iflp->lp_status);
2414
0
  STREAM_GETL(s, iflp->te_metric);
2415
0
  STREAM_GETF(s, iflp->max_bw);
2416
0
  STREAM_GETF(s, iflp->max_rsv_bw);
2417
0
  STREAM_GETL(s, bwclassnum);
2418
0
  {
2419
0
    unsigned int i;
2420
0
    for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
2421
0
      STREAM_GETF(s, iflp->unrsv_bw[i]);
2422
0
    if (i < bwclassnum)
2423
0
      flog_err(
2424
0
        EC_LIB_ZAPI_MISSMATCH,
2425
0
        "%s: received %d > %d (MAX_CLASS_TYPE) bw entries - outdated library?",
2426
0
        __func__, bwclassnum, MAX_CLASS_TYPE);
2427
0
  }
2428
0
  STREAM_GETL(s, iflp->admin_grp);
2429
2430
  /* Extended Administrative Group */
2431
0
  admin_group_clear(&iflp->ext_admin_grp);
2432
0
  STREAM_GETC(s, nb_ext_adm_grp);
2433
0
  for (size_t i = 0; i < nb_ext_adm_grp; i++) {
2434
0
    STREAM_GETL(s, bitmap_data);
2435
0
    admin_group_bulk_set(&iflp->ext_admin_grp, bitmap_data, i);
2436
0
  }
2437
2438
0
  STREAM_GETL(s, iflp->rmt_as);
2439
0
  iflp->rmt_ip.s_addr = stream_get_ipv4(s);
2440
2441
0
  STREAM_GETL(s, iflp->av_delay);
2442
0
  STREAM_GETL(s, iflp->min_delay);
2443
0
  STREAM_GETL(s, iflp->max_delay);
2444
0
  STREAM_GETL(s, iflp->delay_var);
2445
2446
0
  STREAM_GETF(s, iflp->pkt_loss);
2447
0
  STREAM_GETF(s, iflp->res_bw);
2448
0
  STREAM_GETF(s, iflp->ava_bw);
2449
0
  STREAM_GETF(s, iflp->use_bw);
2450
2451
0
  return 0;
2452
0
stream_failure:
2453
0
  return -1;
2454
0
}
2455
2456
struct interface *zebra_interface_link_params_read(struct stream *s,
2457
               vrf_id_t vrf_id,
2458
               bool *changed)
2459
0
{
2460
0
  struct if_link_params *iflp;
2461
0
  struct if_link_params iflp_prev = {0};
2462
0
  ifindex_t ifindex;
2463
0
  bool iflp_prev_set = false;
2464
2465
0
  STREAM_GETL(s, ifindex);
2466
2467
0
  struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
2468
2469
0
  if (ifp == NULL) {
2470
0
    flog_err(EC_LIB_ZAPI_ENCODE,
2471
0
       "%s: unknown ifindex %u, shouldn't happen", __func__,
2472
0
       ifindex);
2473
0
    return NULL;
2474
0
  }
2475
2476
0
  iflp = if_link_params_get(ifp);
2477
2478
0
  if (iflp) {
2479
0
    iflp_prev_set = true;
2480
0
    admin_group_init(&iflp_prev.ext_admin_grp);
2481
0
    if_link_params_copy(&iflp_prev, iflp);
2482
0
  }
2483
2484
  /* read the link_params from stream
2485
   * Free ifp->link_params if the stream has no params
2486
   * to means that link-params are not enabled on links.
2487
   */
2488
0
  if (link_params_set_value(s, ifp) != 0)
2489
0
    goto stream_failure;
2490
2491
0
  if (changed != NULL) {
2492
0
    iflp = if_link_params_get(ifp);
2493
2494
0
    if (iflp_prev_set && iflp) {
2495
0
      if (if_link_params_cmp(&iflp_prev, iflp))
2496
0
        *changed = false;
2497
0
      else
2498
0
        *changed = true;
2499
0
    } else if (!iflp_prev_set && !iflp)
2500
0
      *changed = false;
2501
0
    else
2502
0
      *changed = true;
2503
0
  }
2504
2505
0
  if (iflp_prev_set)
2506
0
    admin_group_term(&iflp_prev.ext_admin_grp);
2507
2508
0
  return ifp;
2509
2510
0
stream_failure:
2511
0
  if (iflp_prev_set)
2512
0
    admin_group_term(&iflp_prev.ext_admin_grp);
2513
0
  return NULL;
2514
0
}
2515
2516
static void zebra_interface_if_set_value(struct stream *s,
2517
           struct interface *ifp)
2518
0
{
2519
0
  uint8_t link_params_status = 0;
2520
0
  ifindex_t old_ifindex, new_ifindex;
2521
2522
0
  old_ifindex = ifp->oldifindex;
2523
  /* Read interface's index. */
2524
0
  STREAM_GETL(s, new_ifindex);
2525
0
  if_set_index(ifp, new_ifindex);
2526
0
  STREAM_GETC(s, ifp->status);
2527
2528
  /* Read interface's value. */
2529
0
  STREAM_GETQ(s, ifp->flags);
2530
0
  STREAM_GETC(s, ifp->ptm_enable);
2531
0
  STREAM_GETC(s, ifp->ptm_status);
2532
0
  STREAM_GETL(s, ifp->metric);
2533
0
  STREAM_GETL(s, ifp->speed);
2534
0
  STREAM_GETL(s, ifp->mtu);
2535
0
  STREAM_GETL(s, ifp->mtu6);
2536
0
  STREAM_GETL(s, ifp->bandwidth);
2537
0
  STREAM_GETL(s, ifp->link_ifindex);
2538
0
  STREAM_GETL(s, ifp->ll_type);
2539
0
  STREAM_GETL(s, ifp->hw_addr_len);
2540
0
  if (ifp->hw_addr_len)
2541
0
    STREAM_GET(ifp->hw_addr, s,
2542
0
         MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
2543
2544
  /* Read Traffic Engineering status */
2545
0
  link_params_status = stream_getc(s);
2546
  /* Then, Traffic Engineering parameters if any */
2547
0
  if (link_params_status)
2548
0
    link_params_set_value(s, ifp);
2549
2550
0
  nexthop_group_interface_state_change(ifp, old_ifindex);
2551
2552
0
  return;
2553
0
stream_failure:
2554
0
  zlog_err("Could not parse interface values; aborting");
2555
0
  assert(!"Failed to parse interface values");
2556
0
}
2557
2558
size_t zebra_interface_link_params_write(struct stream *s,
2559
           struct interface *ifp)
2560
0
{
2561
0
  size_t w, nb_ext_adm_grp;
2562
0
  struct if_link_params *iflp;
2563
0
  int i;
2564
2565
2566
0
  if (s == NULL || ifp == NULL)
2567
0
    return 0;
2568
2569
0
  iflp = ifp->link_params;
2570
0
  w = 0;
2571
2572
  /* encode if link_params is enabled */
2573
0
  if (iflp) {
2574
0
    w += stream_putc(s, true);
2575
0
  } else {
2576
0
    w += stream_putc(s, false);
2577
0
    return w;
2578
0
  }
2579
2580
0
  w += stream_putl(s, iflp->lp_status);
2581
2582
0
  w += stream_putl(s, iflp->te_metric);
2583
0
  w += stream_putf(s, iflp->max_bw);
2584
0
  w += stream_putf(s, iflp->max_rsv_bw);
2585
2586
0
  w += stream_putl(s, MAX_CLASS_TYPE);
2587
0
  for (i = 0; i < MAX_CLASS_TYPE; i++)
2588
0
    w += stream_putf(s, iflp->unrsv_bw[i]);
2589
2590
0
  w += stream_putl(s, iflp->admin_grp);
2591
2592
  /* Extended Administrative Group */
2593
0
  nb_ext_adm_grp = admin_group_nb_words(&iflp->ext_admin_grp);
2594
0
  w += stream_putc(s, nb_ext_adm_grp);
2595
0
  for (size_t i = 0; i < nb_ext_adm_grp; i++)
2596
0
    stream_putl(s, admin_group_get_offset(&iflp->ext_admin_grp, i));
2597
2598
0
  w += stream_putl(s, iflp->rmt_as);
2599
0
  w += stream_put_in_addr(s, &iflp->rmt_ip);
2600
2601
0
  w += stream_putl(s, iflp->av_delay);
2602
0
  w += stream_putl(s, iflp->min_delay);
2603
0
  w += stream_putl(s, iflp->max_delay);
2604
0
  w += stream_putl(s, iflp->delay_var);
2605
2606
0
  w += stream_putf(s, iflp->pkt_loss);
2607
0
  w += stream_putf(s, iflp->res_bw);
2608
0
  w += stream_putf(s, iflp->ava_bw);
2609
0
  w += stream_putf(s, iflp->use_bw);
2610
2611
0
  return w;
2612
0
}
2613
2614
/*
2615
 * format of message for address addition is:
2616
 *    0
2617
 *  0 1 2 3 4 5 6 7
2618
 * +-+-+-+-+-+-+-+-+
2619
 * |   type        |  ZEBRA_INTERFACE_ADDRESS_ADD or
2620
 * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_ADDRES_DELETE
2621
 * |               |
2622
 * +               +
2623
 * |   ifindex     |
2624
 * +               +
2625
 * |               |
2626
 * +               +
2627
 * |               |
2628
 * +-+-+-+-+-+-+-+-+
2629
 * |   ifc_flags   |  flags for connected address
2630
 * +-+-+-+-+-+-+-+-+
2631
 * |  addr_family  |
2632
 * +-+-+-+-+-+-+-+-+
2633
 * |    addr...    |
2634
 * :               :
2635
 * |               |
2636
 * +-+-+-+-+-+-+-+-+
2637
 * |    addr_len   |  len of addr. E.g., addr_len = 4 for ipv4 addrs.
2638
 * +-+-+-+-+-+-+-+-+
2639
 * |     daddr..   |
2640
 * :               :
2641
 * |               |
2642
 * +-+-+-+-+-+-+-+-+
2643
 */
2644
2645
static int memconstant(const void *s, int c, size_t n)
2646
0
{
2647
0
  const uint8_t *p = s;
2648
2649
0
  while (n-- > 0)
2650
0
    if (*p++ != c)
2651
0
      return 0;
2652
0
  return 1;
2653
0
}
2654
2655
2656
struct connected *zebra_interface_address_read(int type, struct stream *s,
2657
                 vrf_id_t vrf_id)
2658
0
{
2659
0
  ifindex_t ifindex;
2660
0
  struct interface *ifp;
2661
0
  struct connected *ifc;
2662
0
  struct prefix p, d, *dp;
2663
0
  int plen;
2664
0
  uint8_t ifc_flags;
2665
2666
0
  memset(&p, 0, sizeof(p));
2667
0
  memset(&d, 0, sizeof(d));
2668
2669
  /* Get interface index. */
2670
0
  STREAM_GETL(s, ifindex);
2671
2672
  /* Lookup index. */
2673
0
  ifp = if_lookup_by_index(ifindex, vrf_id);
2674
0
  if (ifp == NULL) {
2675
0
    flog_err(EC_LIB_ZAPI_ENCODE,
2676
0
       "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
2677
0
       (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
2678
0
       ifindex, vrf_id);
2679
0
    return NULL;
2680
0
  }
2681
2682
  /* Fetch flag. */
2683
0
  STREAM_GETC(s, ifc_flags);
2684
2685
  /* Fetch interface address. */
2686
0
  STREAM_GETC(s, d.family);
2687
0
  p.family = d.family;
2688
0
  plen = prefix_blen(&d);
2689
2690
0
  if (zclient_stream_get_prefix(s, &p) != 0)
2691
0
    goto stream_failure;
2692
2693
  /* Fetch destination address. */
2694
0
  STREAM_GET(&d.u.prefix, s, plen);
2695
2696
  /* N.B. NULL destination pointers are encoded as all zeroes */
2697
0
  dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
2698
2699
0
  if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
2700
0
    ifc = connected_lookup_prefix_exact(ifp, &p);
2701
0
    if (!ifc) {
2702
      /* N.B. NULL destination pointers are encoded as all
2703
       * zeroes */
2704
0
      ifc = connected_add_by_prefix(ifp, &p, dp);
2705
0
    }
2706
0
    if (ifc) {
2707
0
      ifc->flags = ifc_flags;
2708
0
      if (ifc->destination)
2709
0
        ifc->destination->prefixlen =
2710
0
          ifc->address->prefixlen;
2711
0
      else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
2712
        /* carp interfaces on OpenBSD with 0.0.0.0/0 as
2713
         * "peer" */
2714
0
        flog_err(
2715
0
          EC_LIB_ZAPI_ENCODE,
2716
0
          "interface %s address %pFX with peer flag set, but no peer address!",
2717
0
          ifp->name, ifc->address);
2718
0
        UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2719
0
      }
2720
0
    }
2721
0
  } else {
2722
0
    assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
2723
0
    ifc = connected_delete_by_prefix(ifp, &p);
2724
0
  }
2725
2726
0
  return ifc;
2727
2728
0
stream_failure:
2729
0
  return NULL;
2730
0
}
2731
2732
/*
2733
 * format of message for neighbor connected address is:
2734
 *    0
2735
 *  0 1 2 3 4 5 6 7
2736
 * +-+-+-+-+-+-+-+-+
2737
 * |   type        |  ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2738
 * +-+-+-+-+-+-+-+-+  ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2739
 * |               |
2740
 * +               +
2741
 * |   ifindex     |
2742
 * +               +
2743
 * |               |
2744
 * +               +
2745
 * |               |
2746
 * +-+-+-+-+-+-+-+-+
2747
 * |  addr_family  |
2748
 * +-+-+-+-+-+-+-+-+
2749
 * |    addr...    |
2750
 * :               :
2751
 * |               |
2752
 * +-+-+-+-+-+-+-+-+
2753
 * |    addr_len   |  len of addr.
2754
 * +-+-+-+-+-+-+-+-+
2755
 */
2756
struct nbr_connected *
2757
zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
2758
0
{
2759
0
  unsigned int ifindex;
2760
0
  struct interface *ifp;
2761
0
  struct prefix p;
2762
0
  struct nbr_connected *ifc;
2763
2764
  /* Get interface index. */
2765
0
  STREAM_GETL(s, ifindex);
2766
2767
  /* Lookup index. */
2768
0
  ifp = if_lookup_by_index(ifindex, vrf_id);
2769
0
  if (ifp == NULL) {
2770
0
    flog_err(EC_LIB_ZAPI_ENCODE,
2771
0
       "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2772
0
       (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
2773
0
                   : "DELETE",
2774
0
       ifindex, vrf_id);
2775
0
    return NULL;
2776
0
  }
2777
2778
0
  STREAM_GETC(s, p.family);
2779
0
  STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
2780
0
  STREAM_GETC(s, p.prefixlen);
2781
2782
0
  if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2783
    /* Currently only supporting P2P links, so any new RA source
2784
       address is
2785
       considered as the replacement of the previously learnt
2786
       Link-Local address. */
2787
0
    if (!(ifc = listnode_head(ifp->nbr_connected))) {
2788
0
      ifc = nbr_connected_new();
2789
0
      ifc->address = prefix_new();
2790
0
      ifc->ifp = ifp;
2791
0
      listnode_add(ifp->nbr_connected, ifc);
2792
0
    }
2793
2794
0
    prefix_copy(ifc->address, &p);
2795
0
  } else {
2796
0
    assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2797
2798
0
    ifc = nbr_connected_check(ifp, &p);
2799
0
    if (ifc)
2800
0
      listnode_delete(ifp->nbr_connected, ifc);
2801
0
  }
2802
2803
0
  return ifc;
2804
2805
0
stream_failure:
2806
0
  return NULL;
2807
0
}
2808
2809
struct interface *zebra_interface_vrf_update_read(struct stream *s,
2810
              vrf_id_t vrf_id,
2811
              vrf_id_t *new_vrf_id)
2812
0
{
2813
0
  char ifname[INTERFACE_NAMSIZ + 1] = {};
2814
0
  struct interface *ifp;
2815
0
  vrf_id_t new_id;
2816
2817
  /* Read interface name. */
2818
0
  STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
2819
2820
  /* Lookup interface. */
2821
0
  ifp = if_lookup_by_name(ifname, vrf_id);
2822
0
  if (ifp == NULL) {
2823
0
    flog_err(EC_LIB_ZAPI_ENCODE,
2824
0
       "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2825
0
       ifname, vrf_id);
2826
0
    return NULL;
2827
0
  }
2828
2829
  /* Fetch new VRF Id. */
2830
0
  STREAM_GETL(s, new_id);
2831
2832
0
  *new_vrf_id = new_id;
2833
0
  return ifp;
2834
2835
0
stream_failure:
2836
0
  return NULL;
2837
0
}
2838
2839
/* filter unwanted messages until the expected one arrives */
2840
static int zclient_read_sync_response(struct zclient *zclient,
2841
              uint16_t expected_cmd)
2842
0
{
2843
0
  struct stream *s;
2844
0
  uint16_t size = -1;
2845
0
  uint8_t marker;
2846
0
  uint8_t version;
2847
0
  vrf_id_t vrf_id;
2848
0
  uint16_t cmd;
2849
0
  fd_set readfds;
2850
0
  int ret;
2851
2852
0
  ret = 0;
2853
0
  cmd = expected_cmd + 1;
2854
0
  while (ret == 0 && cmd != expected_cmd) {
2855
0
    s = zclient->ibuf;
2856
0
    stream_reset(s);
2857
2858
    /* wait until response arrives */
2859
0
    FD_ZERO(&readfds);
2860
0
    FD_SET(zclient->sock, &readfds);
2861
0
    select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2862
0
    if (!FD_ISSET(zclient->sock, &readfds))
2863
0
      continue;
2864
    /* read response */
2865
0
    ret = zclient_read_header(s, zclient->sock, &size, &marker,
2866
0
            &version, &vrf_id, &cmd);
2867
0
    if (zclient_debug)
2868
0
      zlog_debug("%s: Response (%d bytes) received", __func__,
2869
0
           size);
2870
0
  }
2871
0
  if (ret != 0) {
2872
0
    flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2873
0
       __func__);
2874
0
    return -1;
2875
0
  }
2876
2877
0
  return 0;
2878
0
}
2879
/**
2880
 * Connect to label manager in a synchronous way
2881
 *
2882
 * It first writes the request to zclient output buffer and then
2883
 * immediately reads the answer from the input buffer.
2884
 *
2885
 * @param zclient Zclient used to connect to label manager (zebra)
2886
 * @param async Synchronous (0) or asynchronous (1) operation
2887
 * @result Result of response
2888
 */
2889
int lm_label_manager_connect(struct zclient *zclient, int async)
2890
0
{
2891
0
  int ret;
2892
0
  struct stream *s;
2893
0
  uint8_t result;
2894
0
  uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2895
0
             ZEBRA_LABEL_MANAGER_CONNECT;
2896
2897
0
  if (zclient_debug)
2898
0
    zlog_debug("Connecting to Label Manager (LM)");
2899
2900
0
  if (zclient->sock < 0) {
2901
0
    zlog_debug("%s: invalid zclient socket", __func__);
2902
0
    return -1;
2903
0
  }
2904
2905
  /* send request */
2906
0
  s = zclient->obuf;
2907
0
  stream_reset(s);
2908
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
2909
2910
  /* proto */
2911
0
  stream_putc(s, zclient->redist_default);
2912
  /* instance */
2913
0
  stream_putw(s, zclient->instance);
2914
2915
  /* Put length at the first point of the stream. */
2916
0
  stream_putw_at(s, 0, stream_get_endp(s));
2917
2918
0
  ret = writen(zclient->sock, s->data, stream_get_endp(s));
2919
0
  if (ret < 0) {
2920
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2921
0
    close(zclient->sock);
2922
0
    zclient->sock = -1;
2923
0
    return -1;
2924
0
  }
2925
0
  if (ret == 0) {
2926
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2927
0
    close(zclient->sock);
2928
0
    zclient->sock = -1;
2929
0
    return -1;
2930
0
  }
2931
0
  if (zclient_debug)
2932
0
    zlog_debug("LM connect request sent (%d bytes)", ret);
2933
2934
0
  if (async)
2935
0
    return 0;
2936
2937
  /* read response */
2938
0
  if (zclient_read_sync_response(zclient, cmd)
2939
0
      != 0)
2940
0
    return -1;
2941
2942
0
  s = zclient->ibuf;
2943
2944
  /* read instance and proto */
2945
0
  uint8_t proto;
2946
0
  uint16_t instance;
2947
2948
0
  STREAM_GETC(s, proto);
2949
0
  STREAM_GETW(s, instance);
2950
2951
  /* sanity */
2952
0
  if (proto != zclient->redist_default)
2953
0
    flog_err(
2954
0
      EC_LIB_ZAPI_ENCODE,
2955
0
      "Wrong proto (%u) in LM connect response. Should be %u",
2956
0
      proto, zclient->redist_default);
2957
0
  if (instance != zclient->instance)
2958
0
    flog_err(
2959
0
      EC_LIB_ZAPI_ENCODE,
2960
0
      "Wrong instId (%u) in LM connect response. Should be %u",
2961
0
      instance, zclient->instance);
2962
2963
  /* result code */
2964
0
  STREAM_GETC(s, result);
2965
0
  if (zclient_debug)
2966
0
    zlog_debug("LM connect-response received, result %u", result);
2967
2968
0
  return (int)result;
2969
2970
0
stream_failure:
2971
0
  return -1;
2972
0
}
2973
2974
/**
2975
 * Function to request a srv6-locator chunk in an asynchronous way
2976
 *
2977
 * @param zclient Zclient used to connect to table manager (zebra)
2978
 * @param locator_name Name of SRv6-locator
2979
 * @result 0 on success, -1 otherwise
2980
 */
2981
int srv6_manager_get_locator_chunk(struct zclient *zclient,
2982
           const char *locator_name)
2983
0
{
2984
0
  struct stream *s;
2985
0
  const size_t len = strlen(locator_name);
2986
2987
0
  if (zclient_debug)
2988
0
    zlog_debug("Getting SRv6-Locator Chunk %s", locator_name);
2989
2990
0
  if (zclient->sock < 0)
2991
0
    return -1;
2992
2993
  /* send request */
2994
0
  s = zclient->obuf;
2995
0
  stream_reset(s);
2996
0
  zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK,
2997
0
            VRF_DEFAULT);
2998
2999
  /* locator_name */
3000
0
  stream_putw(s, len);
3001
0
  stream_put(s, locator_name, len);
3002
3003
  /* Put length at the first point of the stream. */
3004
0
  stream_putw_at(s, 0, stream_get_endp(s));
3005
3006
0
  return zclient_send_message(zclient);
3007
0
}
3008
3009
/**
3010
 * Function to release a srv6-locator chunk
3011
 *
3012
 * @param zclient Zclient used to connect to table manager (zebra)
3013
 * @param locator_name Name of SRv6-locator
3014
 * @result 0 on success, -1 otherwise
3015
 */
3016
int srv6_manager_release_locator_chunk(struct zclient *zclient,
3017
               const char *locator_name)
3018
0
{
3019
0
  struct stream *s;
3020
0
  const size_t len = strlen(locator_name);
3021
3022
0
  if (zclient_debug)
3023
0
    zlog_debug("Releasing SRv6-Locator Chunk %s", locator_name);
3024
3025
0
  if (zclient->sock < 0)
3026
0
    return -1;
3027
3028
  /* send request */
3029
0
  s = zclient->obuf;
3030
0
  stream_reset(s);
3031
0
  zclient_create_header(s, ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK,
3032
0
            VRF_DEFAULT);
3033
3034
  /* locator_name */
3035
0
  stream_putw(s, len);
3036
0
  stream_put(s, locator_name, len);
3037
3038
  /* Put length at the first point of the stream. */
3039
0
  stream_putw_at(s, 0, stream_get_endp(s));
3040
3041
0
  return zclient_send_message(zclient);
3042
0
}
3043
3044
/*
3045
 * Asynchronous label chunk request
3046
 *
3047
 * @param zclient Zclient used to connect to label manager (zebra)
3048
 * @param keep Avoid garbage collection
3049
 * @param chunk_size Amount of labels requested
3050
 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
3051
 * @result 0 on success, -1 otherwise
3052
 */
3053
enum zclient_send_status zclient_send_get_label_chunk(struct zclient *zclient,
3054
                  uint8_t keep,
3055
                  uint32_t chunk_size,
3056
                  uint32_t base)
3057
0
{
3058
0
  struct stream *s;
3059
3060
0
  if (zclient_debug)
3061
0
    zlog_debug("Getting Label Chunk");
3062
3063
0
  if (zclient->sock < 0)
3064
0
    return ZCLIENT_SEND_FAILURE;
3065
3066
0
  s = zclient->obuf;
3067
0
  stream_reset(s);
3068
3069
0
  zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
3070
  /* proto */
3071
0
  stream_putc(s, zclient->redist_default);
3072
  /* instance */
3073
0
  stream_putw(s, zclient->instance);
3074
0
  stream_putc(s, keep);
3075
0
  stream_putl(s, chunk_size);
3076
0
  stream_putl(s, base);
3077
3078
  /* Put length at the first point of the stream. */
3079
0
  stream_putw_at(s, 0, stream_get_endp(s));
3080
3081
0
  return zclient_send_message(zclient);
3082
0
}
3083
3084
/**
3085
 * Function to request a label chunk in a synchronous way
3086
 *
3087
 * It first writes the request to zclient output buffer and then
3088
 * immediately reads the answer from the input buffer.
3089
 *
3090
 * @param zclient Zclient used to connect to label manager (zebra)
3091
 * @param keep Avoid garbage collection
3092
 * @param chunk_size Amount of labels requested
3093
 * @param start To write first assigned chunk label to
3094
 * @param end To write last assigned chunk label to
3095
 * @result 0 on success, -1 otherwise
3096
 */
3097
int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
3098
           uint32_t chunk_size, uint32_t *start, uint32_t *end)
3099
0
{
3100
0
  int ret;
3101
0
  struct stream *s;
3102
0
  uint8_t response_keep;
3103
3104
0
  if (zclient_debug)
3105
0
    zlog_debug("Getting Label Chunk");
3106
3107
0
  if (zclient->sock < 0)
3108
0
    return -1;
3109
3110
  /* send request */
3111
0
  s = zclient->obuf;
3112
0
  stream_reset(s);
3113
0
  zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
3114
  /* proto */
3115
0
  stream_putc(s, zclient->redist_default);
3116
  /* instance */
3117
0
  stream_putw(s, zclient->instance);
3118
  /* keep */
3119
0
  stream_putc(s, keep);
3120
  /* chunk size */
3121
0
  stream_putl(s, chunk_size);
3122
  /* requested chunk base */
3123
0
  stream_putl(s, base);
3124
  /* Put length at the first point of the stream. */
3125
0
  stream_putw_at(s, 0, stream_get_endp(s));
3126
3127
0
  ret = writen(zclient->sock, s->data, stream_get_endp(s));
3128
0
  if (ret < 0) {
3129
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
3130
0
    close(zclient->sock);
3131
0
    zclient->sock = -1;
3132
0
    return -1;
3133
0
  }
3134
0
  if (ret == 0) {
3135
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
3136
0
    close(zclient->sock);
3137
0
    zclient->sock = -1;
3138
0
    return -1;
3139
0
  }
3140
0
  if (zclient_debug)
3141
0
    zlog_debug("Label chunk request (%d bytes) sent", ret);
3142
3143
  /* read response */
3144
0
  if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
3145
0
    return -1;
3146
3147
  /* parse response */
3148
0
  s = zclient->ibuf;
3149
3150
  /* read proto and instance */
3151
0
  uint8_t proto;
3152
0
  uint8_t instance;
3153
3154
0
  STREAM_GETC(s, proto);
3155
0
  STREAM_GETW(s, instance);
3156
3157
  /* sanities */
3158
0
  if (proto != zclient->redist_default)
3159
0
    flog_err(EC_LIB_ZAPI_ENCODE,
3160
0
       "Wrong proto (%u) in get chunk response. Should be %u",
3161
0
       proto, zclient->redist_default);
3162
0
  if (instance != zclient->instance)
3163
0
    flog_err(EC_LIB_ZAPI_ENCODE,
3164
0
       "Wrong instId (%u) in get chunk response Should be %u",
3165
0
       instance, zclient->instance);
3166
3167
  /* if we requested a specific chunk and it could not be allocated, the
3168
   * response message will end here
3169
   */
3170
0
  if (!STREAM_READABLE(s)) {
3171
0
    zlog_info("Unable to assign Label Chunk to %s instance %u",
3172
0
        zebra_route_string(proto), instance);
3173
0
    return -1;
3174
0
  }
3175
3176
  /* keep */
3177
0
  STREAM_GETC(s, response_keep);
3178
  /* start and end labels */
3179
0
  STREAM_GETL(s, *start);
3180
0
  STREAM_GETL(s, *end);
3181
3182
  /* not owning this response */
3183
0
  if (keep != response_keep) {
3184
0
    flog_err(
3185
0
      EC_LIB_ZAPI_ENCODE,
3186
0
      "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
3187
0
      *start, *end, keep, response_keep);
3188
0
  }
3189
  /* sanity */
3190
0
  if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
3191
0
      || *end > MPLS_LABEL_UNRESERVED_MAX) {
3192
0
    flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
3193
0
       *start, *end);
3194
0
    return -1;
3195
0
  }
3196
3197
0
  if (zclient_debug)
3198
0
    zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
3199
0
         response_keep);
3200
3201
0
  return 0;
3202
3203
0
stream_failure:
3204
0
  return -1;
3205
0
}
3206
3207
/**
3208
 * Function to release a label chunk
3209
 *
3210
 * @param zclient Zclient used to connect to label manager (zebra)
3211
 * @param start First label of chunk
3212
 * @param end Last label of chunk
3213
 * @result 0 on success, -1 otherwise
3214
 */
3215
int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
3216
         uint32_t end)
3217
0
{
3218
0
  int ret;
3219
0
  struct stream *s;
3220
3221
0
  if (zclient_debug)
3222
0
    zlog_debug("Releasing Label Chunk %u - %u", start, end);
3223
3224
0
  if (zclient->sock < 0)
3225
0
    return -1;
3226
3227
  /* send request */
3228
0
  s = zclient->obuf;
3229
0
  stream_reset(s);
3230
0
  zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
3231
3232
  /* proto */
3233
0
  stream_putc(s, zclient->redist_default);
3234
  /* instance */
3235
0
  stream_putw(s, zclient->instance);
3236
  /* start */
3237
0
  stream_putl(s, start);
3238
  /* end */
3239
0
  stream_putl(s, end);
3240
3241
  /* Put length at the first point of the stream. */
3242
0
  stream_putw_at(s, 0, stream_get_endp(s));
3243
3244
0
  ret = writen(zclient->sock, s->data, stream_get_endp(s));
3245
0
  if (ret < 0) {
3246
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
3247
0
    close(zclient->sock);
3248
0
    zclient->sock = -1;
3249
0
    return -1;
3250
0
  }
3251
0
  if (ret == 0) {
3252
0
    flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
3253
0
    close(zclient->sock);
3254
0
    zclient->sock = -1;
3255
0
    return -1;
3256
0
  }
3257
3258
0
  return 0;
3259
0
}
3260
3261
/**
3262
 * Connect to table manager in a synchronous way
3263
 *
3264
 * It first writes the request to zclient output buffer and then
3265
 * immediately reads the answer from the input buffer.
3266
 *
3267
 * @param zclient Zclient used to connect to table manager (zebra)
3268
 * @result Result of response
3269
 */
3270
int tm_table_manager_connect(struct zclient *zclient)
3271
0
{
3272
0
  int ret;
3273
0
  struct stream *s;
3274
0
  uint8_t result;
3275
3276
0
  if (zclient_debug)
3277
0
    zlog_debug("Connecting to Table Manager");
3278
3279
0
  if (zclient->sock < 0)
3280
0
    return ZCLIENT_SEND_FAILURE;
3281
3282
  /* send request */
3283
0
  s = zclient->obuf;
3284
0
  stream_reset(s);
3285
0
  zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
3286
3287
  /* proto */
3288
0
  stream_putc(s, zclient->redist_default);
3289
  /* instance */
3290
0
  stream_putw(s, zclient->instance);
3291
3292
  /* Put length at the first point of the stream. */
3293
0
  stream_putw_at(s, 0, stream_get_endp(s));
3294
3295
0
  ret = zclient_send_message(zclient);
3296
0
  if (ret == ZCLIENT_SEND_FAILURE)
3297
0
    return -1;
3298
3299
0
  if (zclient_debug)
3300
0
    zlog_debug("%s: Table manager connect request sent", __func__);
3301
3302
  /* read response */
3303
0
  if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
3304
0
      != 0)
3305
0
    return -1;
3306
3307
  /* result */
3308
0
  s = zclient->ibuf;
3309
0
  STREAM_GETC(s, result);
3310
0
  if (zclient_debug)
3311
0
    zlog_debug(
3312
0
      "%s: Table Manager connect response received, result %u",
3313
0
      __func__, result);
3314
3315
0
  return (int)result;
3316
0
stream_failure:
3317
0
  return -1;
3318
0
}
3319
3320
/**
3321
 * Function to request a table chunk in a synchronous way
3322
 *
3323
 * It first writes the request to zclient output buffer and then
3324
 * immediately reads the answer from the input buffer.
3325
 *
3326
 * @param zclient Zclient used to connect to table manager (zebra)
3327
 * @param chunk_size Amount of table requested
3328
 * @param start to write first assigned chunk table RT ID to
3329
 * @param end To write last assigned chunk table RT ID to
3330
 * @result 0 on success, -1 otherwise
3331
 */
3332
int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
3333
           uint32_t *start, uint32_t *end)
3334
0
{
3335
0
  int ret;
3336
0
  struct stream *s;
3337
3338
0
  if (zclient_debug)
3339
0
    zlog_debug("Getting Table Chunk");
3340
3341
0
  if (zclient->sock < 0)
3342
0
    return -1;
3343
3344
  /* send request */
3345
0
  s = zclient->obuf;
3346
0
  stream_reset(s);
3347
0
  zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
3348
  /* chunk size */
3349
0
  stream_putl(s, chunk_size);
3350
  /* Put length at the first point of the stream. */
3351
0
  stream_putw_at(s, 0, stream_get_endp(s));
3352
3353
0
  ret = writen(zclient->sock, s->data, stream_get_endp(s));
3354
0
  if (ret < 0) {
3355
0
    flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
3356
0
       __func__);
3357
0
    close(zclient->sock);
3358
0
    zclient->sock = -1;
3359
0
    return -1;
3360
0
  }
3361
0
  if (ret == 0) {
3362
0
    flog_err(EC_LIB_ZAPI_SOCKET,
3363
0
       "%s: zclient->sock connection closed", __func__);
3364
0
    close(zclient->sock);
3365
0
    zclient->sock = -1;
3366
0
    return -1;
3367
0
  }
3368
0
  if (zclient_debug)
3369
0
    zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
3370
0
         ret);
3371
3372
  /* read response */
3373
0
  if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
3374
0
    return -1;
3375
3376
0
  s = zclient->ibuf;
3377
  /* start and end table IDs */
3378
0
  STREAM_GETL(s, *start);
3379
0
  STREAM_GETL(s, *end);
3380
3381
0
  if (zclient_debug)
3382
0
    zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
3383
3384
0
  return 0;
3385
0
stream_failure:
3386
0
  return -1;
3387
0
}
3388
3389
/**
3390
 * Function to release a table chunk
3391
 *
3392
 * @param zclient Zclient used to connect to table manager (zebra)
3393
 * @param start First label of table
3394
 * @param end Last label of chunk
3395
 * @result 0 on success, -1 otherwise
3396
 */
3397
int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
3398
         uint32_t end)
3399
0
{
3400
0
  struct stream *s;
3401
3402
0
  if (zclient_debug)
3403
0
    zlog_debug("Releasing Table Chunk");
3404
3405
0
  if (zclient->sock < 0)
3406
0
    return -1;
3407
3408
  /* send request */
3409
0
  s = zclient->obuf;
3410
0
  stream_reset(s);
3411
0
  zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
3412
3413
  /* start */
3414
0
  stream_putl(s, start);
3415
  /* end */
3416
0
  stream_putl(s, end);
3417
3418
  /* Put length at the first point of the stream. */
3419
0
  stream_putw_at(s, 0, stream_get_endp(s));
3420
3421
0
  if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
3422
0
    return -1;
3423
3424
0
  return 0;
3425
0
}
3426
3427
enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
3428
                struct zapi_sr_policy *zp)
3429
0
{
3430
0
  if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
3431
0
    return ZCLIENT_SEND_FAILURE;
3432
0
  return zclient_send_message(zclient);
3433
0
}
3434
3435
int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
3436
0
{
3437
0
  struct zapi_srte_tunnel *zt = &zp->segment_list;
3438
3439
0
  stream_reset(s);
3440
3441
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
3442
0
  stream_putl(s, zp->color);
3443
0
  stream_put_ipaddr(s, &zp->endpoint);
3444
0
  stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH);
3445
3446
0
  stream_putc(s, zt->type);
3447
0
  stream_putl(s, zt->local_label);
3448
3449
0
  if (zt->label_num > MPLS_MAX_LABELS) {
3450
0
    flog_err(EC_LIB_ZAPI_ENCODE,
3451
0
       "%s: label %u: can't encode %u labels (maximum is %u)",
3452
0
       __func__, zt->local_label, zt->label_num,
3453
0
       MPLS_MAX_LABELS);
3454
0
    return -1;
3455
0
  }
3456
0
  stream_putw(s, zt->label_num);
3457
3458
0
  for (int i = 0; i < zt->label_num; i++)
3459
0
    stream_putl(s, zt->labels[i]);
3460
3461
  /* Put length at the first point of the stream. */
3462
0
  stream_putw_at(s, 0, stream_get_endp(s));
3463
3464
0
  return 0;
3465
0
}
3466
3467
int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
3468
6
{
3469
6
  memset(zp, 0, sizeof(*zp));
3470
3471
6
  struct zapi_srte_tunnel *zt = &zp->segment_list;
3472
3473
6
  STREAM_GETL(s, zp->color);
3474
6
  STREAM_GET_IPADDR(s, &zp->endpoint);
3475
6
  STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3476
3477
  /* segment list of active candidate path */
3478
6
  STREAM_GETC(s, zt->type);
3479
6
  STREAM_GETL(s, zt->local_label);
3480
6
  STREAM_GETW(s, zt->label_num);
3481
6
  if (zt->label_num > MPLS_MAX_LABELS) {
3482
2
    flog_err(EC_LIB_ZAPI_ENCODE,
3483
2
       "%s: label %u: can't decode %u labels (maximum is %u)",
3484
2
       __func__, zt->local_label, zt->label_num,
3485
2
       MPLS_MAX_LABELS);
3486
2
    return -1;
3487
2
  }
3488
10
  for (int i = 0; i < zt->label_num; i++)
3489
6
    STREAM_GETL(s, zt->labels[i]);
3490
3491
4
  return 0;
3492
3493
0
stream_failure:
3494
0
  return -1;
3495
4
}
3496
3497
int zapi_sr_policy_notify_status_decode(struct stream *s,
3498
          struct zapi_sr_policy *zp)
3499
0
{
3500
0
  memset(zp, 0, sizeof(*zp));
3501
3502
0
  STREAM_GETL(s, zp->color);
3503
0
  STREAM_GET_IPADDR(s, &zp->endpoint);
3504
0
  STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3505
0
  STREAM_GETL(s, zp->status);
3506
3507
0
  return 0;
3508
3509
0
stream_failure:
3510
0
  return -1;
3511
0
}
3512
3513
enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
3514
            int cmd, struct zapi_labels *zl)
3515
0
{
3516
0
  if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
3517
0
    return ZCLIENT_SEND_FAILURE;
3518
0
  return zclient_send_message(zclient);
3519
0
}
3520
3521
int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
3522
0
{
3523
0
  struct zapi_nexthop *znh;
3524
3525
0
  stream_reset(s);
3526
3527
0
  zclient_create_header(s, cmd, VRF_DEFAULT);
3528
0
  stream_putc(s, zl->message);
3529
0
  stream_putc(s, zl->type);
3530
0
  stream_putl(s, zl->local_label);
3531
3532
0
  if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3533
0
    stream_putw(s, zl->route.prefix.family);
3534
0
    stream_put_prefix(s, &zl->route.prefix);
3535
0
    stream_putc(s, zl->route.type);
3536
0
    stream_putw(s, zl->route.instance);
3537
0
  }
3538
3539
0
  if (zl->nexthop_num > MULTIPATH_NUM) {
3540
0
    flog_err(
3541
0
      EC_LIB_ZAPI_ENCODE,
3542
0
      "%s: label %u: can't encode %u nexthops (maximum is %u)",
3543
0
      __func__, zl->local_label, zl->nexthop_num,
3544
0
      MULTIPATH_NUM);
3545
0
    return -1;
3546
0
  }
3547
0
  stream_putw(s, zl->nexthop_num);
3548
3549
0
  for (int i = 0; i < zl->nexthop_num; i++) {
3550
0
    znh = &zl->nexthops[i];
3551
3552
0
    if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3553
0
      return -1;
3554
0
  }
3555
3556
0
  if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3557
3558
0
    if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3559
0
      flog_err(
3560
0
        EC_LIB_ZAPI_ENCODE,
3561
0
        "%s: label %u: can't encode %u nexthops (maximum is %u)",
3562
0
        __func__, zl->local_label, zl->nexthop_num,
3563
0
        MULTIPATH_NUM);
3564
0
      return -1;
3565
0
    }
3566
0
    stream_putw(s, zl->backup_nexthop_num);
3567
3568
0
    for (int i = 0; i < zl->backup_nexthop_num; i++) {
3569
0
      znh = &zl->backup_nexthops[i];
3570
3571
0
      if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3572
0
        return -1;
3573
0
    }
3574
3575
0
  }
3576
3577
  /* Put length at the first point of the stream. */
3578
0
  stream_putw_at(s, 0, stream_get_endp(s));
3579
3580
0
  return 0;
3581
0
}
3582
3583
int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
3584
0
{
3585
0
  struct zapi_nexthop *znh;
3586
3587
0
  memset(zl, 0, sizeof(*zl));
3588
3589
  /* Get data. */
3590
0
  STREAM_GETC(s, zl->message);
3591
0
  STREAM_GETC(s, zl->type);
3592
0
  STREAM_GETL(s, zl->local_label);
3593
3594
0
  if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3595
0
    size_t psize;
3596
3597
0
    STREAM_GETW(s, zl->route.prefix.family);
3598
0
    STREAM_GETC(s, zl->route.prefix.prefixlen);
3599
3600
0
    psize = PSIZE(zl->route.prefix.prefixlen);
3601
0
    switch (zl->route.prefix.family) {
3602
0
    case AF_INET:
3603
0
      if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
3604
0
        zlog_debug(
3605
0
          "%s: Specified prefix length %d is greater than a v4 address can support",
3606
0
          __func__, zl->route.prefix.prefixlen);
3607
0
        return -1;
3608
0
      }
3609
0
      STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
3610
0
           psize);
3611
0
      break;
3612
0
    case AF_INET6:
3613
0
      if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
3614
0
        zlog_debug(
3615
0
          "%s: Specified prefix length %d is greater than a v6 address can support",
3616
0
          __func__, zl->route.prefix.prefixlen);
3617
0
        return -1;
3618
0
      }
3619
0
      STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
3620
0
      break;
3621
0
    default:
3622
0
      flog_err(EC_LIB_ZAPI_ENCODE,
3623
0
         "%s: Specified family %u is not v4 or v6",
3624
0
         __func__, zl->route.prefix.family);
3625
0
      return -1;
3626
0
    }
3627
3628
0
    STREAM_GETC(s, zl->route.type);
3629
0
    STREAM_GETW(s, zl->route.instance);
3630
0
  }
3631
3632
0
  STREAM_GETW(s, zl->nexthop_num);
3633
3634
0
  if (zl->nexthop_num > MULTIPATH_NUM) {
3635
0
    flog_warn(
3636
0
      EC_LIB_ZAPI_ENCODE,
3637
0
      "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
3638
0
      __func__, &zl->route.prefix, zl->nexthop_num,
3639
0
      MULTIPATH_NUM);
3640
0
  }
3641
3642
0
  zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
3643
3644
0
  for (int i = 0; i < zl->nexthop_num; i++) {
3645
0
    znh = &zl->nexthops[i];
3646
3647
0
    if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3648
0
      return -1;
3649
3650
0
    if (znh->type == NEXTHOP_TYPE_BLACKHOLE) {
3651
0
      flog_warn(
3652
0
        EC_LIB_ZAPI_ENCODE,
3653
0
        "%s: Prefix %pFX has a blackhole nexthop which we cannot use for a label",
3654
0
        __func__, &zl->route.prefix);
3655
0
      return -1;
3656
0
    }
3657
0
  }
3658
3659
0
  if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3660
0
    STREAM_GETW(s, zl->backup_nexthop_num);
3661
3662
0
    if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3663
0
      flog_warn(
3664
0
        EC_LIB_ZAPI_ENCODE,
3665
0
        "%s: Prefix %pFX has %d backup nexthops, but we can only use the first %d",
3666
0
        __func__, &zl->route.prefix,
3667
0
        zl->backup_nexthop_num, MULTIPATH_NUM);
3668
0
    }
3669
3670
0
    zl->backup_nexthop_num = MIN(MULTIPATH_NUM,
3671
0
               zl->backup_nexthop_num);
3672
3673
0
    for (int i = 0; i < zl->backup_nexthop_num; i++) {
3674
0
      znh = &zl->backup_nexthops[i];
3675
3676
0
      if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3677
0
        return -1;
3678
3679
0
      if (znh->type == NEXTHOP_TYPE_BLACKHOLE) {
3680
0
        flog_warn(
3681
0
          EC_LIB_ZAPI_ENCODE,
3682
0
          "%s: Prefix %pFX has a backup blackhole nexthop which we cannot use for a label",
3683
0
          __func__, &zl->route.prefix);
3684
0
        return -1;
3685
0
      }
3686
0
    }
3687
0
  }
3688
3689
0
  return 0;
3690
0
stream_failure:
3691
0
  return -1;
3692
0
}
3693
3694
enum zclient_send_status zebra_send_pw(struct zclient *zclient, int command,
3695
               struct zapi_pw *pw)
3696
0
{
3697
0
  struct stream *s;
3698
3699
  /* Reset stream. */
3700
0
  s = zclient->obuf;
3701
0
  stream_reset(s);
3702
3703
0
  zclient_create_header(s, command, VRF_DEFAULT);
3704
0
  stream_write(s, pw->ifname, INTERFACE_NAMSIZ);
3705
0
  stream_putl(s, pw->ifindex);
3706
3707
  /* Put type */
3708
0
  stream_putl(s, pw->type);
3709
3710
  /* Put nexthop */
3711
0
  stream_putl(s, pw->af);
3712
0
  switch (pw->af) {
3713
0
  case AF_INET:
3714
0
    stream_put_in_addr(s, &pw->nexthop.ipv4);
3715
0
    break;
3716
0
  case AF_INET6:
3717
0
    stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
3718
0
    break;
3719
0
  default:
3720
0
    flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
3721
0
    return ZCLIENT_SEND_FAILURE;
3722
0
  }
3723
3724
  /* Put labels */
3725
0
  stream_putl(s, pw->local_label);
3726
0
  stream_putl(s, pw->remote_label);
3727
3728
  /* Put flags */
3729
0
  stream_putc(s, pw->flags);
3730
3731
  /* Protocol specific fields */
3732
0
  stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
3733
3734
  /* Put length at the first point of the stream. */
3735
0
  stream_putw_at(s, 0, stream_get_endp(s));
3736
3737
0
  return zclient_send_message(zclient);
3738
0
}
3739
3740
/*
3741
 * Receive PW status update from Zebra and send it to LDE process.
3742
 */
3743
int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
3744
0
{
3745
0
  struct stream *s;
3746
3747
0
  memset(pw, 0, sizeof(struct zapi_pw_status));
3748
0
  s = zclient->ibuf;
3749
3750
  /* Get data. */
3751
0
  stream_get(pw->ifname, s, INTERFACE_NAMSIZ);
3752
0
  STREAM_GETL(s, pw->ifindex);
3753
0
  STREAM_GETL(s, pw->status);
3754
3755
0
  return 0;
3756
0
stream_failure:
3757
0
  return -1;
3758
0
}
3759
3760
static int zclient_capability_decode(ZAPI_CALLBACK_ARGS)
3761
0
{
3762
0
  struct zclient_capabilities cap;
3763
0
  struct stream *s = zclient->ibuf;
3764
0
  int vrf_backend;
3765
0
  uint8_t mpls_enabled;
3766
3767
0
  STREAM_GETL(s, vrf_backend);
3768
3769
0
  if (vrf_backend < 0 || vrf_configure_backend(vrf_backend)) {
3770
0
    flog_err(EC_LIB_ZAPI_ENCODE,
3771
0
       "%s: Garbage VRF backend type: %d", __func__,
3772
0
       vrf_backend);
3773
0
    goto stream_failure;
3774
0
  }
3775
3776
3777
0
  memset(&cap, 0, sizeof(cap));
3778
0
  STREAM_GETC(s, mpls_enabled);
3779
0
  cap.mpls_enabled = !!mpls_enabled;
3780
0
  STREAM_GETL(s, cap.ecmp);
3781
0
  STREAM_GETC(s, cap.role);
3782
3783
0
  if (zclient->zebra_capabilities)
3784
0
    (*zclient->zebra_capabilities)(&cap);
3785
3786
0
stream_failure:
3787
0
  return 0;
3788
0
}
3789
3790
enum zclient_send_status zclient_send_mlag_register(struct zclient *client,
3791
                uint32_t bit_map)
3792
0
{
3793
0
  struct stream *s;
3794
3795
0
  s = client->obuf;
3796
0
  stream_reset(s);
3797
3798
0
  zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
3799
0
  stream_putl(s, bit_map);
3800
3801
0
  stream_putw_at(s, 0, stream_get_endp(s));
3802
0
  return zclient_send_message(client);
3803
0
}
3804
3805
enum zclient_send_status zclient_send_mlag_deregister(struct zclient *client)
3806
0
{
3807
0
  return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER,
3808
0
          VRF_DEFAULT);
3809
0
}
3810
3811
enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
3812
            struct stream *client_s)
3813
0
{
3814
0
  struct stream *s;
3815
3816
0
  s = client->obuf;
3817
0
  stream_reset(s);
3818
3819
0
  zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
3820
0
  stream_put(s, client_s->data, client_s->endp);
3821
3822
0
  stream_putw_at(s, 0, stream_get_endp(s));
3823
0
  return zclient_send_message(client);
3824
0
}
3825
3826
/*
3827
 * Send an OPAQUE message, contents opaque to zebra. The message header
3828
 * is a message subtype.
3829
 */
3830
enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
3831
               uint32_t type, const uint8_t *data,
3832
               size_t datasize)
3833
0
{
3834
0
  struct stream *s;
3835
0
  uint16_t flags = 0;
3836
3837
  /* Check buffer size */
3838
0
  if (STREAM_SIZE(zclient->obuf) <
3839
0
      (ZEBRA_HEADER_SIZE + sizeof(type) + datasize))
3840
0
    return ZCLIENT_SEND_FAILURE;
3841
3842
0
  s = zclient->obuf;
3843
0
  stream_reset(s);
3844
3845
0
  zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3846
3847
  /* Send sub-type and flags */
3848
0
  stream_putl(s, type);
3849
0
  stream_putw(s, flags);
3850
3851
  /* Send opaque data */
3852
0
  stream_write(s, data, datasize);
3853
3854
  /* Put length into the header at the start of the stream. */
3855
0
  stream_putw_at(s, 0, stream_get_endp(s));
3856
3857
0
  return zclient_send_message(zclient);
3858
0
}
3859
3860
/*
3861
 * Send an OPAQUE message to a specific zclient. The contents are opaque
3862
 * to zebra.
3863
 */
3864
enum zclient_send_status
3865
zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
3866
          uint8_t proto, uint16_t instance,
3867
          uint32_t session_id, const uint8_t *data,
3868
          size_t datasize)
3869
0
{
3870
0
  struct stream *s;
3871
0
  uint16_t flags = 0;
3872
3873
  /* Check buffer size */
3874
0
  if (STREAM_SIZE(zclient->obuf) <
3875
0
      (ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
3876
0
    return ZCLIENT_SEND_FAILURE;
3877
3878
0
  s = zclient->obuf;
3879
0
  stream_reset(s);
3880
3881
0
  zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3882
3883
  /* Send sub-type and flags */
3884
0
  SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
3885
0
  stream_putl(s, type);
3886
0
  stream_putw(s, flags);
3887
3888
  /* Send destination client info */
3889
0
  stream_putc(s, proto);
3890
0
  stream_putw(s, instance);
3891
0
  stream_putl(s, session_id);
3892
3893
  /* Send opaque data */
3894
0
  stream_write(s, data, datasize);
3895
3896
  /* Put length into the header at the start of the stream. */
3897
0
  stream_putw_at(s, 0, stream_get_endp(s));
3898
3899
0
  return zclient_send_message(zclient);
3900
0
}
3901
3902
/*
3903
 * Decode incoming opaque message into info struct
3904
 */
3905
int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
3906
0
{
3907
0
  memset(info, 0, sizeof(*info));
3908
3909
  /* Decode subtype and flags */
3910
0
  STREAM_GETL(s, info->type);
3911
0
  STREAM_GETW(s, info->flags);
3912
3913
  /* Decode unicast client info if present */
3914
0
  if (CHECK_FLAG(info->flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
3915
0
    STREAM_GETC(s, info->proto);
3916
0
    STREAM_GETW(s, info->instance);
3917
0
    STREAM_GETL(s, info->session_id);
3918
0
  }
3919
3920
0
  info->len = STREAM_READABLE(s);
3921
3922
0
  return 0;
3923
3924
0
stream_failure:
3925
3926
0
  return -1;
3927
0
}
3928
3929
/*
3930
 * Send a registration request for opaque messages with a specified subtype.
3931
 */
3932
enum zclient_send_status zclient_register_opaque(struct zclient *zclient,
3933
             uint32_t type)
3934
0
{
3935
0
  struct stream *s;
3936
3937
0
  s = zclient->obuf;
3938
0
  stream_reset(s);
3939
3940
0
  zclient_create_header(s, ZEBRA_OPAQUE_REGISTER, VRF_DEFAULT);
3941
3942
  /* Send sub-type */
3943
0
  stream_putl(s, type);
3944
3945
  /* Add zclient info */
3946
0
  stream_putc(s, zclient->redist_default);
3947
0
  stream_putw(s, zclient->instance);
3948
0
  stream_putl(s, zclient->session_id);
3949
3950
  /* Put length at the first point of the stream. */
3951
0
  stream_putw_at(s, 0, stream_get_endp(s));
3952
3953
0
  return zclient_send_message(zclient);
3954
0
}
3955
3956
/*
3957
 * Send an un-registration request for a specified opaque subtype.
3958
 */
3959
enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
3960
               uint32_t type)
3961
0
{
3962
0
  struct stream *s;
3963
3964
0
  s = zclient->obuf;
3965
0
  stream_reset(s);
3966
3967
0
  zclient_create_header(s, ZEBRA_OPAQUE_UNREGISTER, VRF_DEFAULT);
3968
3969
  /* Send sub-type */
3970
0
  stream_putl(s, type);
3971
3972
  /* Add zclient info */
3973
0
  stream_putc(s, zclient->redist_default);
3974
0
  stream_putw(s, zclient->instance);
3975
0
  stream_putl(s, zclient->session_id);
3976
3977
  /* Put length at the first point of the stream. */
3978
0
  stream_putw_at(s, 0, stream_get_endp(s));
3979
3980
0
  return zclient_send_message(zclient);
3981
0
}
3982
3983
/* Utility to decode opaque registration info */
3984
int zapi_opaque_reg_decode(struct stream *s, struct zapi_opaque_reg_info *info)
3985
0
{
3986
0
  STREAM_GETL(s, info->type);
3987
0
  STREAM_GETC(s, info->proto);
3988
0
  STREAM_GETW(s, info->instance);
3989
0
  STREAM_GETL(s, info->session_id);
3990
3991
0
  return 0;
3992
3993
0
stream_failure:
3994
3995
0
  return -1;
3996
0
}
3997
3998
/* Utility to decode client close notify info */
3999
int zapi_client_close_notify_decode(struct stream *s,
4000
            struct zapi_client_close_info *info)
4001
0
{
4002
0
  memset(info, 0, sizeof(*info));
4003
4004
0
  STREAM_GETC(s, info->proto);
4005
0
  STREAM_GETW(s, info->instance);
4006
0
  STREAM_GETL(s, info->session_id);
4007
4008
0
  return 0;
4009
4010
0
stream_failure:
4011
4012
0
  return -1;
4013
0
}
4014
4015
static zclient_handler *const lib_handlers[] = {
4016
  /* fundamentals */
4017
  [ZEBRA_CAPABILITIES] = zclient_capability_decode,
4018
  [ZEBRA_ERROR] = zclient_handle_error,
4019
4020
  /* VRF & interface code is shared in lib */
4021
  [ZEBRA_VRF_ADD] = zclient_vrf_add,
4022
  [ZEBRA_VRF_DELETE] = zclient_vrf_delete,
4023
  [ZEBRA_INTERFACE_ADD] = zclient_interface_add,
4024
  [ZEBRA_INTERFACE_DELETE] = zclient_interface_delete,
4025
  [ZEBRA_INTERFACE_UP] = zclient_interface_up,
4026
  [ZEBRA_INTERFACE_DOWN] = zclient_interface_down,
4027
4028
  /* BFD */
4029
  [ZEBRA_BFD_DEST_REPLAY] = zclient_bfd_session_replay,
4030
  [ZEBRA_INTERFACE_BFD_DEST_UPDATE] = zclient_bfd_session_update,
4031
};
4032
4033
#ifdef FUZZING
4034
int zclient_read_fuzz(struct zclient *zclient, const uint8_t *data, size_t len)
4035
0
{
4036
0
  uint16_t length, command;
4037
0
  uint8_t marker, version;
4038
0
  vrf_id_t vrf_id;
4039
4040
  /* Length check. */
4041
0
  if (len > STREAM_SIZE(zclient->ibuf)) {
4042
0
    struct stream *ns;
4043
0
    flog_err(
4044
0
      EC_LIB_ZAPI_ENCODE,
4045
0
      "%s: message size %zu exceeds buffer size %lu, expanding...",
4046
0
      __func__, len,
4047
0
      (unsigned long)STREAM_SIZE(zclient->ibuf));
4048
0
    ns = stream_new(len);
4049
0
    stream_free(zclient->ibuf);
4050
0
    zclient->ibuf = ns;
4051
0
  }
4052
4053
0
  if (len < ZEBRA_HEADER_SIZE) {
4054
0
    flog_err(EC_LIB_ZAPI_MISSMATCH,
4055
0
       "%s: socket %d message length %zu is less than %d ",
4056
0
       __func__, zclient->sock, len, ZEBRA_HEADER_SIZE);
4057
0
    return -1;
4058
0
  }
4059
4060
0
  stream_reset(zclient->ibuf);
4061
0
  stream_put(zclient->ibuf, data, len);
4062
4063
0
  length = stream_getw(zclient->ibuf);
4064
0
  marker = stream_getc(zclient->ibuf);
4065
0
  version = stream_getc(zclient->ibuf);
4066
0
  vrf_id = stream_getl(zclient->ibuf);
4067
0
  command = stream_getw(zclient->ibuf);
4068
4069
0
  if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
4070
0
    flog_err(
4071
0
      EC_LIB_ZAPI_MISSMATCH,
4072
0
      "%s: socket %d version mismatch, marker %d, version %d",
4073
0
      __func__, zclient->sock, marker, version);
4074
0
    return -1;
4075
0
  }
4076
4077
0
  length -= ZEBRA_HEADER_SIZE;
4078
4079
0
  if (zclient_debug)
4080
0
    zlog_debug("zclient %p command %s VRF %u", zclient,
4081
0
         zserv_command_string(command), vrf_id);
4082
4083
0
  if (command < array_size(lib_handlers) && lib_handlers[command])
4084
0
    lib_handlers[command](command, zclient, length, vrf_id);
4085
0
  if (command < zclient->n_handlers && zclient->handlers[command])
4086
0
    zclient->handlers[command](command, zclient, length, vrf_id);
4087
4088
0
  if (zclient->sock < 0)
4089
    /* Connection was closed during packet processing. */
4090
0
    return -1;
4091
4092
  /* Register read thread. */
4093
0
  stream_reset(zclient->ibuf);
4094
0
  zclient_event(ZCLIENT_READ, zclient);
4095
4096
0
  return 0;
4097
0
}
4098
#endif
4099
4100
/* Zebra client message read function. */
4101
static void zclient_read(struct event *thread)
4102
0
{
4103
0
  size_t already;
4104
0
  uint16_t length, command;
4105
0
  uint8_t marker, version;
4106
0
  vrf_id_t vrf_id;
4107
0
  struct zclient *zclient;
4108
0
4109
0
  /* Get socket to zebra. */
4110
0
  zclient = EVENT_ARG(thread);
4111
0
  zclient->t_read = NULL;
4112
0
4113
0
  /* Read zebra header (if we don't have it already). */
4114
0
  already = stream_get_endp(zclient->ibuf);
4115
0
  if (already < ZEBRA_HEADER_SIZE) {
4116
0
    ssize_t nbyte;
4117
0
    if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
4118
0
                ZEBRA_HEADER_SIZE - already))
4119
0
         == 0)
4120
0
        || (nbyte == -1)) {
4121
0
      if (zclient_debug)
4122
0
        zlog_debug(
4123
0
          "zclient connection closed socket [%d].",
4124
0
          zclient->sock);
4125
0
      zclient_failed(zclient);
4126
0
      return;
4127
0
    }
4128
0
    if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
4129
0
      zclient_event(ZCLIENT_READ, zclient);
4130
0
      return;
4131
0
    }
4132
0
    already = ZEBRA_HEADER_SIZE;
4133
0
  }
4134
0
4135
0
  /* Reset to read from the beginning of the incoming packet. */
4136
0
  stream_set_getp(zclient->ibuf, 0);
4137
0
4138
0
  /* Fetch header values. */
4139
0
  length = stream_getw(zclient->ibuf);
4140
0
  marker = stream_getc(zclient->ibuf);
4141
0
  version = stream_getc(zclient->ibuf);
4142
0
  vrf_id = stream_getl(zclient->ibuf);
4143
0
  command = stream_getw(zclient->ibuf);
4144
0
4145
0
  if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
4146
0
    flog_err(
4147
0
      EC_LIB_ZAPI_MISSMATCH,
4148
0
      "%s: socket %d version mismatch, marker %d, version %d",
4149
0
      __func__, zclient->sock, marker, version);
4150
0
    zclient_failed(zclient);
4151
0
    return;
4152
0
  }
4153
0
4154
0
  if (length < ZEBRA_HEADER_SIZE) {
4155
0
    flog_err(EC_LIB_ZAPI_MISSMATCH,
4156
0
       "%s: socket %d message length %u is less than %d ",
4157
0
       __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
4158
0
    zclient_failed(zclient);
4159
0
    return;
4160
0
  }
4161
0
4162
0
  /* Length check. */
4163
0
  if (length > STREAM_SIZE(zclient->ibuf)) {
4164
0
    struct stream *ns;
4165
0
    flog_err(
4166
0
      EC_LIB_ZAPI_ENCODE,
4167
0
      "%s: message size %u exceeds buffer size %lu, expanding...",
4168
0
      __func__, length,
4169
0
      (unsigned long)STREAM_SIZE(zclient->ibuf));
4170
0
    ns = stream_new(length);
4171
0
    stream_copy(ns, zclient->ibuf);
4172
0
    stream_free(zclient->ibuf);
4173
0
    zclient->ibuf = ns;
4174
0
  }
4175
0
4176
0
  /* Read rest of zebra packet. */
4177
0
  if (already < length) {
4178
0
    ssize_t nbyte;
4179
0
    if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
4180
0
                length - already))
4181
0
         == 0)
4182
0
        || (nbyte == -1)) {
4183
0
      if (zclient_debug)
4184
0
        zlog_debug(
4185
0
          "zclient connection closed socket [%d].",
4186
0
          zclient->sock);
4187
0
      zclient_failed(zclient);
4188
0
      return;
4189
0
    }
4190
0
    if (nbyte != (ssize_t)(length - already)) {
4191
0
      /* Try again later. */
4192
0
      zclient_event(ZCLIENT_READ, zclient);
4193
0
      return;
4194
0
    }
4195
0
  }
4196
0
4197
0
  length -= ZEBRA_HEADER_SIZE;
4198
0
4199
0
  if (zclient_debug)
4200
0
    zlog_debug("zclient %p command %s VRF %u", zclient,
4201
0
         zserv_command_string(command), vrf_id);
4202
0
4203
0
  if (command < array_size(lib_handlers) && lib_handlers[command])
4204
0
    lib_handlers[command](command, zclient, length, vrf_id);
4205
0
  if (command < zclient->n_handlers && zclient->handlers[command])
4206
0
    zclient->handlers[command](command, zclient, length, vrf_id);
4207
0
4208
0
  if (zclient->sock < 0)
4209
0
    /* Connection was closed during packet processing. */
4210
0
    return;
4211
0
4212
0
  /* Register read thread. */
4213
0
  stream_reset(zclient->ibuf);
4214
0
  zclient_event(ZCLIENT_READ, zclient);
4215
0
}
4216
4217
void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
4218
        int type, unsigned short instance, vrf_id_t vrf_id)
4219
0
{
4220
4221
0
  if (instance) {
4222
0
    if (command == ZEBRA_REDISTRIBUTE_ADD) {
4223
0
      if (redist_check_instance(
4224
0
            &zclient->mi_redist[afi][type], instance))
4225
0
        return;
4226
0
      redist_add_instance(&zclient->mi_redist[afi][type],
4227
0
              instance);
4228
0
    } else {
4229
0
      if (!redist_check_instance(
4230
0
            &zclient->mi_redist[afi][type], instance))
4231
0
        return;
4232
0
      redist_del_instance(&zclient->mi_redist[afi][type],
4233
0
              instance);
4234
0
    }
4235
4236
0
  } else {
4237
0
    if (command == ZEBRA_REDISTRIBUTE_ADD) {
4238
0
      if (vrf_bitmap_check(zclient->redist[afi][type],
4239
0
               vrf_id))
4240
0
        return;
4241
0
      vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
4242
0
    } else {
4243
0
      if (!vrf_bitmap_check(zclient->redist[afi][type],
4244
0
                vrf_id))
4245
0
        return;
4246
0
      vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
4247
0
    }
4248
0
  }
4249
4250
0
  if (zclient->sock > 0)
4251
0
    zebra_redistribute_send(command, zclient, afi, type, instance,
4252
0
          vrf_id);
4253
0
}
4254
4255
4256
void zclient_redistribute_default(int command, struct zclient *zclient,
4257
          afi_t afi, vrf_id_t vrf_id)
4258
0
{
4259
4260
0
  if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
4261
0
    if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
4262
0
      return;
4263
0
    vrf_bitmap_set(zclient->default_information[afi], vrf_id);
4264
0
  } else {
4265
0
    if (!vrf_bitmap_check(zclient->default_information[afi],
4266
0
              vrf_id))
4267
0
      return;
4268
0
    vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
4269
0
  }
4270
4271
0
  if (zclient->sock > 0)
4272
0
    zebra_redistribute_default_send(command, zclient, afi, vrf_id);
4273
0
}
4274
4275
static void zclient_event(enum zclient_event event, struct zclient *zclient)
4276
3
{
4277
3
  switch (event) {
4278
3
  case ZCLIENT_SCHEDULE:
4279
3
    event_add_event(zclient->master, zclient_connect, zclient, 0,
4280
3
        &zclient->t_connect);
4281
3
    break;
4282
0
  case ZCLIENT_CONNECT:
4283
0
    if (zclient_debug)
4284
0
      zlog_debug(
4285
0
        "zclient connect failures: %d schedule interval is now %d",
4286
0
        zclient->fail, zclient->fail < 3 ? 10 : 60);
4287
0
    event_add_timer(zclient->master, zclient_connect, zclient,
4288
0
        zclient->fail < 3 ? 10 : 60,
4289
0
        &zclient->t_connect);
4290
0
    break;
4291
0
  case ZCLIENT_READ:
4292
0
    zclient->t_read = NULL;
4293
0
    event_add_read(zclient->master, zclient_read, zclient,
4294
0
             zclient->sock, &zclient->t_read);
4295
0
    break;
4296
3
  }
4297
3
}
4298
4299
enum zclient_send_status zclient_interface_set_master(struct zclient *client,
4300
                  struct interface *master,
4301
                  struct interface *slave)
4302
0
{
4303
0
  struct stream *s;
4304
4305
0
  s = client->obuf;
4306
0
  stream_reset(s);
4307
4308
0
  zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER,
4309
0
            master->vrf->vrf_id);
4310
4311
0
  stream_putl(s, master->vrf->vrf_id);
4312
0
  stream_putl(s, master->ifindex);
4313
0
  stream_putl(s, slave->vrf->vrf_id);
4314
0
  stream_putl(s, slave->ifindex);
4315
4316
0
  stream_putw_at(s, 0, stream_get_endp(s));
4317
0
  return zclient_send_message(client);
4318
0
}
4319
4320
/*
4321
 * Send capabilities message to zebra
4322
 */
4323
enum zclient_send_status zclient_capabilities_send(uint32_t cmd,
4324
               struct zclient *zclient,
4325
               struct zapi_cap *api)
4326
0
{
4327
4328
0
  struct stream *s;
4329
4330
0
  if (zclient == NULL)
4331
0
    return ZCLIENT_SEND_FAILURE;
4332
4333
0
  s = zclient->obuf;
4334
0
  stream_reset(s);
4335
0
  zclient_create_header(s, cmd, 0);
4336
0
  stream_putl(s, api->cap);
4337
4338
0
  switch (api->cap) {
4339
0
  case ZEBRA_CLIENT_GR_CAPABILITIES:
4340
0
  case ZEBRA_CLIENT_RIB_STALE_TIME:
4341
0
    stream_putl(s, api->stale_removal_time);
4342
0
    stream_putl(s, api->vrf_id);
4343
0
    break;
4344
0
  case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4345
0
  case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4346
0
    stream_putl(s, api->afi);
4347
0
    stream_putl(s, api->safi);
4348
0
    stream_putl(s, api->vrf_id);
4349
0
    break;
4350
0
  case ZEBRA_CLIENT_GR_DISABLE:
4351
0
    stream_putl(s, api->vrf_id);
4352
0
    break;
4353
0
  }
4354
4355
  /* Put length at the first point of the stream */
4356
0
  stream_putw_at(s, 0, stream_get_endp(s));
4357
4358
0
  return zclient_send_message(zclient);
4359
0
}
4360
4361
/*
4362
 * Process capabilities message from zebra
4363
 */
4364
int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
4365
0
{
4366
4367
0
  memset(api, 0, sizeof(*api));
4368
4369
0
  api->safi = SAFI_UNICAST;
4370
4371
0
  STREAM_GETL(s, api->cap);
4372
0
  switch (api->cap) {
4373
0
  case ZEBRA_CLIENT_GR_CAPABILITIES:
4374
0
  case ZEBRA_CLIENT_RIB_STALE_TIME:
4375
0
    STREAM_GETL(s, api->stale_removal_time);
4376
0
    STREAM_GETL(s, api->vrf_id);
4377
0
    break;
4378
0
  case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4379
0
  case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4380
0
    STREAM_GETL(s, api->afi);
4381
0
    STREAM_GETL(s, api->safi);
4382
0
    STREAM_GETL(s, api->vrf_id);
4383
0
    break;
4384
0
  case ZEBRA_CLIENT_GR_DISABLE:
4385
0
    STREAM_GETL(s, api->vrf_id);
4386
0
    break;
4387
0
  }
4388
0
stream_failure:
4389
0
  return 0;
4390
0
}
4391
4392
enum zclient_send_status
4393
zclient_send_neigh_discovery_req(struct zclient *zclient,
4394
         const struct interface *ifp,
4395
         const struct prefix *p)
4396
0
{
4397
0
  struct stream *s;
4398
4399
0
  s = zclient->obuf;
4400
0
  stream_reset(s);
4401
4402
0
  zclient_create_header(s, ZEBRA_NEIGH_DISCOVER, ifp->vrf->vrf_id);
4403
0
  stream_putl(s, ifp->ifindex);
4404
4405
0
  stream_putc(s, p->family);
4406
0
  stream_putc(s, p->prefixlen);
4407
0
  stream_put(s, &p->u.prefix, prefix_blen(p));
4408
4409
0
  stream_putw_at(s, 0, stream_get_endp(s));
4410
0
  return zclient_send_message(zclient);
4411
0
}
4412
4413
/*
4414
 * Get a starting nhg point for a routing protocol
4415
 */
4416
uint32_t zclient_get_nhg_start(uint32_t proto)
4417
0
{
4418
0
  assert(proto < ZEBRA_ROUTE_MAX);
4419
4420
0
  return ZEBRA_NHG_PROTO_SPACING * proto;
4421
0
}
4422
4423
char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len)
4424
0
{
4425
0
  if (flags == 0) {
4426
0
    snprintfrr(buf, len, "None ");
4427
0
    return buf;
4428
0
  }
4429
4430
0
  snprintfrr(
4431
0
    buf, len, "%s%s%s%s%s%s%s%s%s%s",
4432
0
    CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION) ? "Recursion "
4433
0
                    : "",
4434
0
    CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) ? "Self " : "",
4435
0
    CHECK_FLAG(flags, ZEBRA_FLAG_IBGP) ? "iBGP " : "",
4436
0
    CHECK_FLAG(flags, ZEBRA_FLAG_SELECTED) ? "Selected " : "",
4437
0
    CHECK_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE) ? "Override " : "",
4438
0
    CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE) ? "Evpn " : "",
4439
0
    CHECK_FLAG(flags, ZEBRA_FLAG_RR_USE_DISTANCE) ? "RR Distance "
4440
0
                    : "",
4441
0
    CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED) ? "Trapped " : "",
4442
0
    CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED) ? "Offloaded " : "",
4443
0
    CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED) ? "Offload Failed "
4444
0
                   : "");
4445
0
  return buf;
4446
0
}
4447
4448
char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, size_t len)
4449
0
{
4450
0
  if (flags == 0) {
4451
0
    snprintfrr(buf, len, "None ");
4452
0
    return buf;
4453
0
  }
4454
4455
0
  snprintfrr(
4456
0
    buf, len, "%s%s%s%s%s%s%s",
4457
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? "Sticky MAC " : "",
4458
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? "Gateway MAC " : "",
4459
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? "Router "
4460
0
                : "",
4461
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_OVERRIDE_FLAG) ? "Override "
4462
0
                  : "",
4463
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP) ? "SVI MAC " : "",
4464
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT) ? "Proxy "
4465
0
                 : "",
4466
0
    CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SYNC_PATH) ? "Sync " : "");
4467
4468
0
  return buf;
4469
0
}
4470
4471
static int zclient_neigh_ip_read_entry(struct stream *s, struct ipaddr *add)
4472
0
{
4473
0
  uint8_t family;
4474
4475
0
  STREAM_GETC(s, family);
4476
0
  if (family != AF_INET && family != AF_INET6)
4477
0
    return -1;
4478
4479
0
  STREAM_GET(&add->ip.addr, s, family2addrsize(family));
4480
0
  add->ipa_type = family;
4481
0
  return 0;
4482
0
 stream_failure:
4483
0
  return -1;
4484
0
}
4485
4486
int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in,
4487
          union sockunion *out, struct interface *ifp,
4488
          int ndm_state)
4489
0
{
4490
0
  int ret = 0;
4491
4492
0
  zclient_create_header(s, cmd, ifp->vrf->vrf_id);
4493
0
  stream_putc(s, sockunion_family(in));
4494
0
  stream_write(s, sockunion_get_addr(in), sockunion_get_addrlen(in));
4495
0
  if (out && sockunion_family(out) != AF_UNSPEC) {
4496
0
    stream_putc(s, sockunion_family(out));
4497
0
    stream_write(s, sockunion_get_addr(out),
4498
0
           sockunion_get_addrlen(out));
4499
0
  } else
4500
0
    stream_putc(s, AF_UNSPEC);
4501
0
  stream_putl(s, ifp->ifindex);
4502
0
  if (out)
4503
0
    stream_putl(s, ndm_state);
4504
0
  else
4505
0
    stream_putl(s, ZEBRA_NEIGH_STATE_FAILED);
4506
0
  return ret;
4507
0
}
4508
4509
int zclient_neigh_ip_decode(struct stream *s, struct zapi_neigh_ip *api)
4510
0
{
4511
0
  int ret;
4512
4513
0
  ret = zclient_neigh_ip_read_entry(s, &api->ip_in);
4514
0
  if (ret < 0)
4515
0
    return -1;
4516
0
  zclient_neigh_ip_read_entry(s, &api->ip_out);
4517
4518
0
  STREAM_GETL(s, api->index);
4519
0
  STREAM_GETL(s, api->ndm_state);
4520
0
  return 0;
4521
0
 stream_failure:
4522
0
  return -1;
4523
0
}
4524
4525
int zclient_send_zebra_gre_request(struct zclient *client,
4526
           struct interface *ifp)
4527
0
{
4528
0
  struct stream *s;
4529
4530
0
  if (!client || client->sock < 0) {
4531
0
    zlog_err("%s : zclient not ready", __func__);
4532
0
    return -1;
4533
0
  }
4534
0
  s = client->obuf;
4535
0
  stream_reset(s);
4536
0
  zclient_create_header(s, ZEBRA_GRE_GET, ifp->vrf->vrf_id);
4537
0
  stream_putl(s, ifp->ifindex);
4538
0
  stream_putw_at(s, 0, stream_get_endp(s));
4539
0
  zclient_send_message(client);
4540
0
  return 0;
4541
0
}