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