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