]> git.proxmox.com Git - mirror_frr.git/blob - lib/zclient.c
Merge pull request #2055 from opensourcerouting/fix-pathspace
[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
40 DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
41 DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
42
43 /* Zebra client events. */
44 enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
45
46 /* Prototype for event manager. */
47 static void zclient_event(enum event, struct zclient *);
48
49 struct sockaddr_storage zclient_addr;
50 socklen_t zclient_addr_len;
51
52 /* This file local debug flag. */
53 int zclient_debug = 0;
54
55 struct zclient_options zclient_options_default = {.receive_notify = false};
56
57 /* Allocate zclient structure. */
58 struct zclient *zclient_new_notify(struct thread_master *master,
59 struct zclient_options *opt)
60 {
61 struct zclient *zclient;
62 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
63
64 zclient->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
65 zclient->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
66 zclient->wb = buffer_new(0);
67 zclient->master = master;
68
69 zclient->receive_notify = opt->receive_notify;
70
71 return zclient;
72 }
73
74 /* This function is only called when exiting, because
75 many parts of the code do not check for I/O errors, so they could
76 reference an invalid pointer if the structure was ever freed.
77
78 Free zclient structure. */
79 void zclient_free(struct zclient *zclient)
80 {
81 if (zclient->ibuf)
82 stream_free(zclient->ibuf);
83 if (zclient->obuf)
84 stream_free(zclient->obuf);
85 if (zclient->wb)
86 buffer_free(zclient->wb);
87
88 XFREE(MTYPE_ZCLIENT, zclient);
89 }
90
91 unsigned short *redist_check_instance(struct redist_proto *red,
92 unsigned short instance)
93 {
94 struct listnode *node;
95 unsigned short *id;
96
97 if (!red->instances)
98 return NULL;
99
100 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
101 if (*id == instance)
102 return id;
103
104 return NULL;
105 }
106
107 void redist_add_instance(struct redist_proto *red, unsigned short instance)
108 {
109 unsigned short *in;
110
111 red->enabled = 1;
112
113 if (!red->instances)
114 red->instances = list_new();
115
116 in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
117 *in = instance;
118 listnode_add(red->instances, in);
119 }
120
121 void redist_del_instance(struct redist_proto *red, unsigned short instance)
122 {
123 unsigned short *id;
124
125 id = redist_check_instance(red, instance);
126 if (!id)
127 return;
128
129 listnode_delete(red->instances, id);
130 XFREE(MTYPE_REDIST_INST, id);
131 if (!red->instances->count) {
132 red->enabled = 0;
133 list_delete_and_null(&red->instances);
134 }
135 }
136
137 /* Stop zebra client services. */
138 void zclient_stop(struct zclient *zclient)
139 {
140 afi_t afi;
141 int i;
142
143 if (zclient_debug)
144 zlog_debug("zclient stopped");
145
146 /* Stop threads. */
147 THREAD_OFF(zclient->t_read);
148 THREAD_OFF(zclient->t_connect);
149 THREAD_OFF(zclient->t_write);
150
151 /* Reset streams. */
152 stream_reset(zclient->ibuf);
153 stream_reset(zclient->obuf);
154
155 /* Empty the write buffer. */
156 buffer_reset(zclient->wb);
157
158 /* Close socket. */
159 if (zclient->sock >= 0) {
160 close(zclient->sock);
161 zclient->sock = -1;
162 }
163 zclient->fail = 0;
164
165 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
166 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
167 vrf_bitmap_free(zclient->redist[afi][i]);
168 zclient->redist[afi][i] = VRF_BITMAP_NULL;
169 }
170 redist_del_instance(
171 &zclient->mi_redist[afi][zclient->redist_default],
172 zclient->instance);
173 }
174
175 vrf_bitmap_free(zclient->default_information);
176 zclient->default_information = VRF_BITMAP_NULL;
177 }
178
179 void zclient_reset(struct zclient *zclient)
180 {
181 afi_t afi;
182
183 zclient_stop(zclient);
184
185 for (afi = AFI_IP; afi < AFI_MAX; afi++)
186 redist_del_instance(
187 &zclient->mi_redist[afi][zclient->redist_default],
188 zclient->instance);
189
190 zclient_init(zclient, zclient->redist_default, zclient->instance,
191 zclient->privs);
192 }
193
194 /**
195 * Connect to zebra daemon.
196 * @param zclient a pointer to zclient structure
197 * @return socket fd just to make sure that connection established
198 * @see zclient_init
199 * @see zclient_new_notify
200 */
201 int zclient_socket_connect(struct zclient *zclient)
202 {
203 int sock;
204 int ret;
205
206 /* We should think about IPv6 connection. */
207 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
208 if (sock < 0)
209 return -1;
210
211 set_cloexec(sock);
212
213 zclient->privs->change(ZPRIVS_RAISE);
214 setsockopt_so_sendbuf(sock, 1048576);
215 zclient->privs->change(ZPRIVS_LOWER);
216
217 /* Connect to zebra. */
218 ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
219 if (ret < 0) {
220 if (zclient_debug)
221 zlog_warn("%s connect failure: %d(%s)",
222 __PRETTY_FUNCTION__, errno,
223 safe_strerror(errno));
224 close(sock);
225 return -1;
226 }
227
228 zclient->sock = sock;
229 return sock;
230 }
231
232 static int zclient_failed(struct zclient *zclient)
233 {
234 zclient->fail++;
235 zclient_stop(zclient);
236 zclient_event(ZCLIENT_CONNECT, zclient);
237 return -1;
238 }
239
240 static int zclient_flush_data(struct thread *thread)
241 {
242 struct zclient *zclient = THREAD_ARG(thread);
243
244 zclient->t_write = NULL;
245 if (zclient->sock < 0)
246 return -1;
247 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
248 case BUFFER_ERROR:
249 zlog_warn(
250 "%s: buffer_flush_available failed on zclient fd %d, closing",
251 __func__, zclient->sock);
252 return zclient_failed(zclient);
253 break;
254 case BUFFER_PENDING:
255 zclient->t_write = NULL;
256 thread_add_write(zclient->master, zclient_flush_data, zclient,
257 zclient->sock, &zclient->t_write);
258 break;
259 case BUFFER_EMPTY:
260 break;
261 }
262 return 0;
263 }
264
265 int zclient_send_message(struct zclient *zclient)
266 {
267 if (zclient->sock < 0)
268 return -1;
269 switch (buffer_write(zclient->wb, zclient->sock,
270 STREAM_DATA(zclient->obuf),
271 stream_get_endp(zclient->obuf))) {
272 case BUFFER_ERROR:
273 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
274 __func__, zclient->sock);
275 return zclient_failed(zclient);
276 break;
277 case BUFFER_EMPTY:
278 THREAD_OFF(zclient->t_write);
279 break;
280 case BUFFER_PENDING:
281 thread_add_write(zclient->master, zclient_flush_data, zclient,
282 zclient->sock, &zclient->t_write);
283 break;
284 }
285 return 0;
286 }
287
288 void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
289 {
290 /* length placeholder, caller can update */
291 stream_putw(s, ZEBRA_HEADER_SIZE);
292 stream_putc(s, ZEBRA_HEADER_MARKER);
293 stream_putc(s, ZSERV_VERSION);
294 stream_putl(s, vrf_id);
295 stream_putw(s, command);
296 }
297
298 int zclient_read_header(struct stream *s, int sock, uint16_t *size,
299 uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id,
300 uint16_t *cmd)
301 {
302 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
303 return -1;
304
305 STREAM_GETW(s, *size);
306 *size -= ZEBRA_HEADER_SIZE;
307 STREAM_GETC(s, *marker);
308 STREAM_GETC(s, *version);
309 STREAM_GETL(s, *vrf_id);
310 STREAM_GETW(s, *cmd);
311
312 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
313 zlog_err(
314 "%s: socket %d version mismatch, marker %d, version %d",
315 __func__, sock, *marker, *version);
316 return -1;
317 }
318
319 if (*size && stream_read(s, sock, *size) != *size)
320 return -1;
321
322 stream_failure:
323 return 0;
324 }
325
326 bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
327 {
328 STREAM_GETW(zmsg, hdr->length);
329 STREAM_GETC(zmsg, hdr->marker);
330 STREAM_GETC(zmsg, hdr->version);
331 STREAM_GETL(zmsg, hdr->vrf_id);
332 STREAM_GETW(zmsg, hdr->command);
333 return true;
334 stream_failure:
335 return false;
336 }
337
338 /* Send simple Zebra message. */
339 static int zebra_message_send(struct zclient *zclient, int command,
340 vrf_id_t vrf_id)
341 {
342 struct stream *s;
343
344 /* Get zclient output buffer. */
345 s = zclient->obuf;
346 stream_reset(s);
347
348 /* Send very simple command only Zebra message. */
349 zclient_create_header(s, command, vrf_id);
350
351 return zclient_send_message(zclient);
352 }
353
354 static int zebra_hello_send(struct zclient *zclient)
355 {
356 struct stream *s;
357
358 if (zclient->redist_default) {
359 s = zclient->obuf;
360 stream_reset(s);
361
362 /* The VRF ID in the HELLO message is always 0. */
363 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
364 stream_putc(s, zclient->redist_default);
365 stream_putw(s, zclient->instance);
366 if (zclient->receive_notify)
367 stream_putc(s, 1);
368 else
369 stream_putc(s, 0);
370
371 stream_putw_at(s, 0, stream_get_endp(s));
372 return zclient_send_message(zclient);
373 }
374
375 return 0;
376 }
377
378 void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
379 mpls_label_t label, enum lsp_types_t ltype)
380 {
381 struct stream *s;
382
383 s = zclient->obuf;
384 stream_reset(s);
385
386 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
387 stream_putl(s, label);
388 stream_putc(s, afi);
389 stream_putc(s, ltype);
390 stream_putw_at(s, 0, stream_get_endp(s));
391 zclient_send_message(zclient);
392 }
393
394 /* Send register requests to zebra daemon for the information in a VRF. */
395 void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
396 {
397 int i;
398 afi_t afi;
399
400 /* If not connected to the zebra yet. */
401 if (zclient->sock < 0)
402 return;
403
404 if (zclient_debug)
405 zlog_debug("%s: send register messages for VRF %u", __func__,
406 vrf_id);
407
408 /* We need router-id information. */
409 zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
410
411 /* We need interface information. */
412 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
413
414 /* Set unwanted redistribute route. */
415 for (afi = AFI_IP; afi < AFI_MAX; afi++)
416 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
417 vrf_id);
418
419 /* Flush all redistribute request. */
420 if (vrf_id == VRF_DEFAULT) {
421 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
422 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
423 if (!zclient->mi_redist[afi][i].enabled)
424 continue;
425
426 struct listnode *node;
427 unsigned short *id;
428
429 for (ALL_LIST_ELEMENTS_RO(
430 zclient->mi_redist[afi][i]
431 .instances,
432 node, id))
433 if (!(i == zclient->redist_default
434 && *id == zclient->instance))
435 zebra_redistribute_send(
436 ZEBRA_REDISTRIBUTE_ADD,
437 zclient, afi, i, *id,
438 VRF_DEFAULT);
439 }
440 }
441 }
442
443 /* Resend all redistribute request. */
444 for (afi = AFI_IP; afi < AFI_MAX; afi++)
445 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
446 if (i != zclient->redist_default
447 && vrf_bitmap_check(zclient->redist[afi][i],
448 vrf_id))
449 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
450 zclient, afi, i, 0,
451 vrf_id);
452
453 /* If default information is needed. */
454 if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
455 zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
456 vrf_id);
457 }
458
459 /* Send unregister requests to zebra daemon for the information in a VRF. */
460 void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
461 {
462 int i;
463 afi_t afi;
464
465 /* If not connected to the zebra yet. */
466 if (zclient->sock < 0)
467 return;
468
469 if (zclient_debug)
470 zlog_debug("%s: send deregister messages for VRF %u", __func__,
471 vrf_id);
472
473 /* We need router-id information. */
474 zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
475
476 /* We need interface information. */
477 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
478
479 /* Set unwanted redistribute route. */
480 for (afi = AFI_IP; afi < AFI_MAX; afi++)
481 vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
482 vrf_id);
483
484 /* Flush all redistribute request. */
485 if (vrf_id == VRF_DEFAULT) {
486 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
487 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
488 if (!zclient->mi_redist[afi][i].enabled)
489 continue;
490
491 struct listnode *node;
492 unsigned short *id;
493
494 for (ALL_LIST_ELEMENTS_RO(
495 zclient->mi_redist[afi][i]
496 .instances,
497 node, id))
498 if (!(i == zclient->redist_default
499 && *id == zclient->instance))
500 zebra_redistribute_send(
501 ZEBRA_REDISTRIBUTE_DELETE,
502 zclient, afi, i, *id,
503 VRF_DEFAULT);
504 }
505 }
506 }
507
508 /* Flush all redistribute request. */
509 for (afi = AFI_IP; afi < AFI_MAX; afi++)
510 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
511 if (i != zclient->redist_default
512 && vrf_bitmap_check(zclient->redist[afi][i],
513 vrf_id))
514 zebra_redistribute_send(
515 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
516 i, 0, vrf_id);
517
518 /* If default information is needed. */
519 if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
520 zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
521 vrf_id);
522 }
523
524 /* Send request to zebra daemon to start or stop RA. */
525 void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
526 struct interface *ifp, int enable,
527 int ra_interval)
528 {
529 struct stream *s;
530
531 /* If not connected to the zebra yet. */
532 if (zclient->sock < 0)
533 return;
534
535 /* Form and send message. */
536 s = zclient->obuf;
537 stream_reset(s);
538
539 if (enable)
540 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
541 else
542 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
543
544 stream_putl(s, ifp->ifindex);
545 stream_putl(s, ra_interval);
546
547 stream_putw_at(s, 0, stream_get_endp(s));
548
549 zclient_send_message(zclient);
550 }
551
552 /* Make connection to zebra daemon. */
553 int zclient_start(struct zclient *zclient)
554 {
555 if (zclient_debug)
556 zlog_info("zclient_start is called");
557
558 /* If already connected to the zebra. */
559 if (zclient->sock >= 0)
560 return 0;
561
562 /* Check connect thread. */
563 if (zclient->t_connect)
564 return 0;
565
566 if (zclient_socket_connect(zclient) < 0) {
567 if (zclient_debug)
568 zlog_debug("zclient connection fail");
569 zclient->fail++;
570 zclient_event(ZCLIENT_CONNECT, zclient);
571 return -1;
572 }
573
574 if (set_nonblocking(zclient->sock) < 0)
575 zlog_warn("%s: set_nonblocking(%d) failed", __func__,
576 zclient->sock);
577
578 /* Clear fail count. */
579 zclient->fail = 0;
580 if (zclient_debug)
581 zlog_debug("zclient connect success with socket [%d]",
582 zclient->sock);
583
584 /* Create read thread. */
585 zclient_event(ZCLIENT_READ, zclient);
586
587 zebra_hello_send(zclient);
588
589 /* Inform the successful connection. */
590 if (zclient->zebra_connected)
591 (*zclient->zebra_connected)(zclient);
592
593 return 0;
594 }
595
596 /* Initialize zebra client. Argument redist_default is unwanted
597 redistribute route type. */
598 void zclient_init(struct zclient *zclient, int redist_default,
599 unsigned short instance, struct zebra_privs_t *privs)
600 {
601 int afi, i;
602
603 /* Set -1 to the default socket value. */
604 zclient->sock = -1;
605 zclient->privs = privs;
606
607 /* Clear redistribution flags. */
608 for (afi = AFI_IP; afi < AFI_MAX; afi++)
609 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
610 zclient->redist[afi][i] = vrf_bitmap_init();
611
612 /* Set unwanted redistribute route. bgpd does not need BGP route
613 redistribution. */
614 zclient->redist_default = redist_default;
615 zclient->instance = instance;
616 /* Pending: make afi(s) an arg. */
617 for (afi = AFI_IP; afi < AFI_MAX; afi++)
618 redist_add_instance(&zclient->mi_redist[afi][redist_default],
619 instance);
620
621 /* Set default-information redistribute to zero. */
622 zclient->default_information = vrf_bitmap_init();
623
624 if (zclient_debug)
625 zlog_debug("zclient_start is called");
626
627 zclient_event(ZCLIENT_SCHEDULE, zclient);
628 }
629
630 /* This function is a wrapper function for calling zclient_start from
631 timer or event thread. */
632 static int zclient_connect(struct thread *t)
633 {
634 struct zclient *zclient;
635
636 zclient = THREAD_ARG(t);
637 zclient->t_connect = NULL;
638
639 if (zclient_debug)
640 zlog_debug("zclient_connect is called");
641
642 return zclient_start(zclient);
643 }
644
645 int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
646 bool exact_match, vrf_id_t vrf_id)
647 {
648 struct stream *s;
649
650 s = zclient->obuf;
651 stream_reset(s);
652 zclient_create_header(s, command, vrf_id);
653 stream_putc(s, (exact_match) ? 1 : 0);
654
655 stream_putw(s, PREFIX_FAMILY(p));
656 stream_putc(s, p->prefixlen);
657 switch (PREFIX_FAMILY(p)) {
658 case AF_INET:
659 stream_put_in_addr(s, &p->u.prefix4);
660 break;
661 case AF_INET6:
662 stream_put(s, &(p->u.prefix6), 16);
663 break;
664 default:
665 break;
666 }
667 stream_putw_at(s, 0, stream_get_endp(s));
668
669 return zclient_send_message(zclient);
670 }
671
672 /*
673 * "xdr_encode"-like interface that allows daemon (client) to send
674 * a message to zebra server for a route that needs to be
675 * added/deleted to the kernel. Info about the route is specified
676 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
677 * the info down the zclient socket using the stream_* functions.
678 *
679 * The corresponding read ("xdr_decode") function on the server
680 * side is zread_ipv4_add()/zread_ipv4_delete().
681 *
682 * 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
683 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
684 * | Length (2) | Command | Route Type |
685 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
686 * | ZEBRA Flags | Message Flags | Prefix length |
687 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
688 * | Destination IPv4 Prefix for route |
689 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
690 * | Nexthop count |
691 * +-+-+-+-+-+-+-+-+
692 *
693 *
694 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
695 * described, as per the Nexthop count. Each nexthop described as:
696 *
697 * +-+-+-+-+-+-+-+-+
698 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
699 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
700 * | IPv4 Nexthop address or Interface Index number |
701 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
702 *
703 * Alternatively, if the route is a blackhole route, then Nexthop count
704 * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
705 * nexthop.
706 *
707 * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
708 * infrastructure was built around the traditional (32-bit "gate OR
709 * ifindex") nexthop data unit. A special encoding can be used to feed
710 * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
711 * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
712 * fields as follows:
713 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
714 * - .nexthop_num == .ifindex_num
715 * - .nexthop and .ifindex are filled with gate and ifindex parts of
716 * each compound nexthop, both in the same order
717 *
718 * zapi_ipv4_route() will produce two nexthop data units for each such
719 * interleaved 64-bit nexthop. On the zserv side of the socket it will be
720 * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
721 *
722 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
723 * byte value.
724 *
725 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
726 * byte value.
727 *
728 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
729 *
730 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
731 *
732 * XXX: No attention paid to alignment.
733 */
734 int zapi_ipv4_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv4 *p,
735 struct zapi_ipv4 *api)
736 {
737 int i;
738 int psize;
739 struct stream *s;
740
741 /* Reset stream. */
742 s = zclient->obuf;
743 stream_reset(s);
744
745 /* Some checks for labeled-unicast. The current expectation is that each
746 * nexthop is accompanied by a label in the case of labeled-unicast.
747 */
748 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
749 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
750 /* We expect prefixes installed with labels and the number to
751 * match
752 * the number of nexthops.
753 */
754 assert(api->label_num == api->nexthop_num);
755 }
756
757 zclient_create_header(s, cmd, api->vrf_id);
758
759 /* Put type and nexthop. */
760 stream_putc(s, api->type);
761 stream_putw(s, api->instance);
762 stream_putl(s, api->flags);
763 stream_putc(s, api->message);
764 stream_putw(s, api->safi);
765
766 /* Put prefix information. */
767 psize = PSIZE(p->prefixlen);
768 stream_putc(s, p->prefixlen);
769 stream_write(s, (uint8_t *)&p->prefix, psize);
770
771 /* Nexthop, ifindex, distance and metric information. */
772 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
773 stream_putc(s, api->nexthop_num + api->ifindex_num);
774
775 for (i = 0; i < api->nexthop_num; i++) {
776 stream_putc(s, NEXTHOP_TYPE_IPV4);
777 stream_put_in_addr(s, api->nexthop[i]);
778 /* For labeled-unicast, each nexthop is followed by
779 * label. */
780 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
781 stream_putl(s, api->label[i]);
782 }
783 for (i = 0; i < api->ifindex_num; i++) {
784 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
785 stream_putl(s, api->ifindex[i]);
786 }
787 }
788
789 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
790 stream_putc(s, api->distance);
791 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
792 stream_putl(s, api->metric);
793 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
794 stream_putl(s, api->tag);
795 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
796 stream_putl(s, api->mtu);
797
798 /* Put length at the first point of the stream. */
799 stream_putw_at(s, 0, stream_get_endp(s));
800
801 return zclient_send_message(zclient);
802 }
803
804 int zapi_ipv4_route_ipv6_nexthop(uint8_t cmd, struct zclient *zclient,
805 struct prefix_ipv4 *p, struct zapi_ipv6 *api)
806 {
807 int i;
808 int psize;
809 struct stream *s;
810
811 /* Reset stream. */
812 s = zclient->obuf;
813 stream_reset(s);
814
815 /* Some checks for labeled-unicast. The current expectation is that each
816 * nexthop is accompanied by a label in the case of labeled-unicast.
817 */
818 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
819 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
820 /* We expect prefixes installed with labels and the number to
821 * match
822 * the number of nexthops.
823 */
824 assert(api->label_num == api->nexthop_num);
825 }
826
827 zclient_create_header(s, cmd, api->vrf_id);
828
829 /* Put type and nexthop. */
830 stream_putc(s, api->type);
831 stream_putw(s, api->instance);
832 stream_putl(s, api->flags);
833 stream_putc(s, api->message);
834 stream_putw(s, api->safi);
835
836 /* Put prefix information. */
837 psize = PSIZE(p->prefixlen);
838 stream_putc(s, p->prefixlen);
839 stream_write(s, (uint8_t *)&p->prefix, psize);
840
841 /* Nexthop, ifindex, distance and metric information. */
842 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
843 stream_putc(s, api->nexthop_num + api->ifindex_num);
844
845 for (i = 0; i < api->nexthop_num; i++) {
846 stream_putc(s, NEXTHOP_TYPE_IPV6);
847 stream_write(s, (uint8_t *)api->nexthop[i], 16);
848 /* For labeled-unicast, each nexthop is followed by
849 * label. */
850 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
851 stream_putl(s, api->label[i]);
852 }
853 for (i = 0; i < api->ifindex_num; i++) {
854 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
855 stream_putl(s, api->ifindex[i]);
856 }
857 }
858
859 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
860 stream_putc(s, api->distance);
861 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
862 stream_putl(s, api->metric);
863 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
864 stream_putl(s, api->tag);
865 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
866 stream_putl(s, api->mtu);
867
868 /* Put length at the first point of the stream. */
869 stream_putw_at(s, 0, stream_get_endp(s));
870
871 return zclient_send_message(zclient);
872 }
873
874 int zapi_ipv6_route(uint8_t cmd, struct zclient *zclient, struct prefix_ipv6 *p,
875 struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
876 {
877 int i;
878 int psize;
879 struct stream *s;
880
881 /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL
882 */
883 assert(!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
884
885 /* Reset stream. */
886 s = zclient->obuf;
887 stream_reset(s);
888
889 /* Some checks for labeled-unicast. The current expectation is that each
890 * nexthop is accompanied by a label in the case of labeled-unicast.
891 */
892 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
893 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
894 /* We expect prefixes installed with labels and the number to
895 * match
896 * the number of nexthops.
897 */
898 assert(api->label_num == api->nexthop_num);
899 }
900
901 zclient_create_header(s, cmd, api->vrf_id);
902
903 /* Put type and nexthop. */
904 stream_putc(s, api->type);
905 stream_putw(s, api->instance);
906 stream_putl(s, api->flags);
907 stream_putc(s, api->message);
908 stream_putw(s, api->safi);
909
910 /* Put prefix information. */
911 psize = PSIZE(p->prefixlen);
912 stream_putc(s, p->prefixlen);
913 stream_write(s, (uint8_t *)&p->prefix, psize);
914
915 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
916 psize = PSIZE(src_p->prefixlen);
917 stream_putc(s, src_p->prefixlen);
918 stream_write(s, (uint8_t *)&src_p->prefix, psize);
919 }
920
921 /* Nexthop, ifindex, distance and metric information. */
922 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
923 stream_putc(s, api->nexthop_num + api->ifindex_num);
924
925 for (i = 0; i < api->nexthop_num; i++) {
926 stream_putc(s, NEXTHOP_TYPE_IPV6);
927 stream_write(s, (uint8_t *)api->nexthop[i], 16);
928 /* For labeled-unicast, each nexthop is followed by
929 * label. */
930 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
931 stream_putl(s, api->label[i]);
932 }
933 for (i = 0; i < api->ifindex_num; i++) {
934 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
935 stream_putl(s, api->ifindex[i]);
936 }
937 }
938
939 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
940 stream_putc(s, api->distance);
941 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
942 stream_putl(s, api->metric);
943 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
944 stream_putl(s, api->tag);
945 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
946 stream_putl(s, api->mtu);
947
948 /* Put length at the first point of the stream. */
949 stream_putw_at(s, 0, stream_get_endp(s));
950
951 return zclient_send_message(zclient);
952 }
953
954 int zclient_route_send(uint8_t cmd, struct zclient *zclient,
955 struct zapi_route *api)
956 {
957 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
958 return -1;
959 return zclient_send_message(zclient);
960 }
961
962 int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
963 {
964 struct zapi_nexthop *api_nh;
965 int i;
966 int psize;
967
968 stream_reset(s);
969 zclient_create_header(s, cmd, api->vrf_id);
970
971 stream_putc(s, api->type);
972 stream_putw(s, api->instance);
973 stream_putl(s, api->flags);
974 stream_putc(s, api->message);
975 stream_putc(s, api->safi);
976 if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
977 stream_put(s, &(api->rmac), sizeof(struct ethaddr));
978
979 /* Put prefix information. */
980 stream_putc(s, api->prefix.family);
981 psize = PSIZE(api->prefix.prefixlen);
982 stream_putc(s, api->prefix.prefixlen);
983 stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
984
985 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
986 psize = PSIZE(api->src_prefix.prefixlen);
987 stream_putc(s, api->src_prefix.prefixlen);
988 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
989 }
990
991 /* Nexthops. */
992 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
993 /* limit the number of nexthops if necessary */
994 if (api->nexthop_num > MULTIPATH_NUM) {
995 char buf[PREFIX2STR_BUFFER];
996
997 prefix2str(&api->prefix, buf, sizeof(buf));
998 zlog_warn(
999 "%s: prefix %s: can't encode %u nexthops "
1000 "(maximum is %u)",
1001 __func__, buf, api->nexthop_num, MULTIPATH_NUM);
1002 return -1;
1003 }
1004
1005 stream_putw(s, api->nexthop_num);
1006
1007 for (i = 0; i < api->nexthop_num; i++) {
1008 api_nh = &api->nexthops[i];
1009
1010 stream_putl(s, api_nh->vrf_id);
1011 stream_putc(s, api_nh->type);
1012 switch (api_nh->type) {
1013 case NEXTHOP_TYPE_BLACKHOLE:
1014 stream_putc(s, api_nh->bh_type);
1015 break;
1016 case NEXTHOP_TYPE_IPV4:
1017 stream_put_in_addr(s, &api_nh->gate.ipv4);
1018 break;
1019 case NEXTHOP_TYPE_IPV4_IFINDEX:
1020 stream_put_in_addr(s, &api_nh->gate.ipv4);
1021 stream_putl(s, api_nh->ifindex);
1022 break;
1023 case NEXTHOP_TYPE_IFINDEX:
1024 stream_putl(s, api_nh->ifindex);
1025 break;
1026 case NEXTHOP_TYPE_IPV6:
1027 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
1028 16);
1029 break;
1030 case NEXTHOP_TYPE_IPV6_IFINDEX:
1031 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
1032 16);
1033 stream_putl(s, api_nh->ifindex);
1034 break;
1035 default:
1036 zlog_warn(
1037 "%s: Specified Nexthop type %d does not exist",
1038 __PRETTY_FUNCTION__, api_nh->type);
1039 return -1;
1040 }
1041
1042 /* MPLS labels for BGP-LU or Segment Routing */
1043 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
1044 if (api_nh->label_num > MPLS_MAX_LABELS) {
1045 char buf[PREFIX2STR_BUFFER];
1046 prefix2str(&api->prefix, buf,
1047 sizeof(buf));
1048 zlog_err(
1049 "%s: prefix %s: can't encode "
1050 "%u labels (maximum is %u)",
1051 __func__, buf,
1052 api_nh->label_num,
1053 MPLS_MAX_LABELS);
1054 return -1;
1055 }
1056
1057 stream_putc(s, api_nh->label_num);
1058 stream_put(s, &api_nh->labels[0],
1059 api_nh->label_num
1060 * sizeof(mpls_label_t));
1061 }
1062 }
1063 }
1064
1065 /* Attributes. */
1066 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1067 stream_putc(s, api->distance);
1068 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1069 stream_putl(s, api->metric);
1070 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1071 stream_putl(s, api->tag);
1072 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1073 stream_putl(s, api->mtu);
1074 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1075 stream_putl(s, api->tableid);
1076
1077 /* Put length at the first point of the stream. */
1078 stream_putw_at(s, 0, stream_get_endp(s));
1079
1080 return 0;
1081 }
1082
1083 int zapi_route_decode(struct stream *s, struct zapi_route *api)
1084 {
1085 struct zapi_nexthop *api_nh;
1086 int i;
1087
1088 memset(api, 0, sizeof(*api));
1089
1090 /* Type, flags, message. */
1091 STREAM_GETC(s, api->type);
1092 if (api->type > ZEBRA_ROUTE_MAX) {
1093 zlog_warn("%s: Specified route type: %d is not a legal value\n",
1094 __PRETTY_FUNCTION__, api->type);
1095 return -1;
1096 }
1097
1098 STREAM_GETW(s, api->instance);
1099 STREAM_GETL(s, api->flags);
1100 STREAM_GETC(s, api->message);
1101 STREAM_GETC(s, api->safi);
1102 if (CHECK_FLAG(api->flags, ZEBRA_FLAG_EVPN_ROUTE))
1103 STREAM_GET(&(api->rmac), s, sizeof(struct ethaddr));
1104
1105 /* Prefix. */
1106 STREAM_GETC(s, api->prefix.family);
1107 STREAM_GETC(s, api->prefix.prefixlen);
1108 switch (api->prefix.family) {
1109 case AF_INET:
1110 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1111 zlog_warn(
1112 "%s: V4 prefixlen is %d which should not be more than 32",
1113 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1114 return -1;
1115 }
1116 break;
1117 case AF_INET6:
1118 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1119 zlog_warn(
1120 "%s: v6 prefixlen is %d which should not be more than 128",
1121 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1122 return -1;
1123 }
1124 break;
1125 default:
1126 zlog_warn("%s: Specified family %d is not v4 or v6",
1127 __PRETTY_FUNCTION__, api->prefix.family);
1128 return -1;
1129 }
1130 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1131
1132 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1133 api->src_prefix.family = AF_INET6;
1134 STREAM_GETC(s, api->src_prefix.prefixlen);
1135 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1136 zlog_warn(
1137 "%s: SRC Prefix prefixlen received: %d is too large",
1138 __PRETTY_FUNCTION__, api->src_prefix.prefixlen);
1139 return -1;
1140 }
1141 STREAM_GET(&api->src_prefix.prefix, s,
1142 PSIZE(api->src_prefix.prefixlen));
1143
1144 if (api->prefix.family != AF_INET6
1145 || api->src_prefix.prefixlen == 0) {
1146 zlog_warn(
1147 "%s: SRC prefix specified in some manner that makes no sense",
1148 __PRETTY_FUNCTION__);
1149 return -1;
1150 }
1151 }
1152
1153 /* Nexthops. */
1154 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1155 STREAM_GETW(s, api->nexthop_num);
1156 if (api->nexthop_num > MULTIPATH_NUM) {
1157 zlog_warn("%s: invalid number of nexthops (%u)",
1158 __func__, api->nexthop_num);
1159 return -1;
1160 }
1161
1162 for (i = 0; i < api->nexthop_num; i++) {
1163 api_nh = &api->nexthops[i];
1164
1165 STREAM_GETL(s, api_nh->vrf_id);
1166 STREAM_GETC(s, api_nh->type);
1167 switch (api_nh->type) {
1168 case NEXTHOP_TYPE_BLACKHOLE:
1169 STREAM_GETC(s, api_nh->bh_type);
1170 break;
1171 case NEXTHOP_TYPE_IPV4:
1172 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1173 IPV4_MAX_BYTELEN);
1174 break;
1175 case NEXTHOP_TYPE_IPV4_IFINDEX:
1176 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1177 IPV4_MAX_BYTELEN);
1178 STREAM_GETL(s, api_nh->ifindex);
1179 break;
1180 case NEXTHOP_TYPE_IFINDEX:
1181 STREAM_GETL(s, api_nh->ifindex);
1182 break;
1183 case NEXTHOP_TYPE_IPV6:
1184 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1185 break;
1186 case NEXTHOP_TYPE_IPV6_IFINDEX:
1187 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1188 STREAM_GETL(s, api_nh->ifindex);
1189 break;
1190 default:
1191 zlog_warn(
1192 "%s: Specified nexthop type %d does not exist",
1193 __PRETTY_FUNCTION__, api_nh->type);
1194 return -1;
1195 }
1196
1197 /* MPLS labels for BGP-LU or Segment Routing */
1198 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
1199 STREAM_GETC(s, api_nh->label_num);
1200
1201 if (api_nh->label_num > MPLS_MAX_LABELS) {
1202 zlog_warn(
1203 "%s: invalid number of MPLS "
1204 "labels (%u)",
1205 __func__, api_nh->label_num);
1206 return -1;
1207 }
1208
1209 STREAM_GET(&api_nh->labels[0], s,
1210 api_nh->label_num
1211 * sizeof(mpls_label_t));
1212 }
1213 }
1214 }
1215
1216 /* Attributes. */
1217 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1218 STREAM_GETC(s, api->distance);
1219 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1220 STREAM_GETL(s, api->metric);
1221 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1222 STREAM_GETL(s, api->tag);
1223 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1224 STREAM_GETL(s, api->mtu);
1225 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1226 STREAM_GETL(s, api->tableid);
1227
1228 stream_failure:
1229 return 0;
1230 }
1231
1232 bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1233 uint32_t *tableid,
1234 enum zapi_route_notify_owner *note)
1235 {
1236 uint32_t t;
1237
1238 STREAM_GET(note, s, sizeof(*note));
1239
1240 STREAM_GETC(s, p->family);
1241 STREAM_GETC(s, p->prefixlen);
1242 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
1243 STREAM_GETL(s, t);
1244
1245 *tableid = t;
1246
1247 return true;
1248
1249 stream_failure:
1250 return false;
1251 }
1252
1253 bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1254 uint32_t *priority, uint32_t *unique,
1255 ifindex_t *ifindex,
1256 enum zapi_rule_notify_owner *note)
1257 {
1258 uint32_t prio, seq, uni;
1259 ifindex_t ifi;
1260
1261 STREAM_GET(note, s, sizeof(*note));
1262
1263 STREAM_GETL(s, seq);
1264 STREAM_GETL(s, prio);
1265 STREAM_GETL(s, uni);
1266 STREAM_GETL(s, ifi);
1267
1268 if (zclient_debug)
1269 zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__,
1270 seq, prio, uni, ifi);
1271 *seqno = seq;
1272 *priority = prio;
1273 *unique = uni;
1274 *ifindex = ifi;
1275
1276 return true;
1277
1278 stream_failure:
1279 return false;
1280 }
1281
1282 struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
1283 {
1284 struct nexthop *n = nexthop_new();
1285
1286 n->type = znh->type;
1287 n->vrf_id = znh->vrf_id;
1288 n->ifindex = znh->ifindex;
1289 n->gate = znh->gate;
1290
1291 /*
1292 * This function currently handles labels
1293 */
1294 if (znh->label_num) {
1295 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
1296 znh->labels);
1297 }
1298
1299 return n;
1300 }
1301
1302 bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1303 {
1304 uint32_t i;
1305
1306 memset(nhr, 0, sizeof(*nhr));
1307
1308 STREAM_GETW(s, nhr->prefix.family);
1309 STREAM_GETC(s, nhr->prefix.prefixlen);
1310 switch (nhr->prefix.family) {
1311 case AF_INET:
1312 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1313 break;
1314 case AF_INET6:
1315 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1316 break;
1317 default:
1318 break;
1319 }
1320
1321 STREAM_GETC(s, nhr->type);
1322 STREAM_GETW(s, nhr->instance);
1323 STREAM_GETC(s, nhr->distance);
1324 STREAM_GETL(s, nhr->metric);
1325 STREAM_GETC(s, nhr->nexthop_num);
1326
1327 for (i = 0; i < nhr->nexthop_num; i++) {
1328 STREAM_GETC(s, nhr->nexthops[i].type);
1329 switch (nhr->nexthops[i].type) {
1330 case NEXTHOP_TYPE_IPV4:
1331 case NEXTHOP_TYPE_IPV4_IFINDEX:
1332 STREAM_GET(&nhr->nexthops[i].gate.ipv4.s_addr, s,
1333 IPV4_MAX_BYTELEN);
1334 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1335 break;
1336 case NEXTHOP_TYPE_IFINDEX:
1337 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1338 break;
1339 case NEXTHOP_TYPE_IPV6:
1340 case NEXTHOP_TYPE_IPV6_IFINDEX:
1341 STREAM_GET(&nhr->nexthops[i].gate.ipv6, s,
1342 IPV6_MAX_BYTELEN);
1343 STREAM_GETL(s, nhr->nexthops[i].ifindex);
1344 break;
1345 case NEXTHOP_TYPE_BLACKHOLE:
1346 break;
1347 }
1348 STREAM_GETC(s, nhr->nexthops[i].label_num);
1349 if (nhr->nexthops[i].label_num > MPLS_MAX_LABELS) {
1350 zlog_warn("%s: invalid number of MPLS labels (%u)",
1351 __func__, nhr->nexthops[i].label_num);
1352 return false;
1353 }
1354 if (nhr->nexthops[i].label_num)
1355 STREAM_GET(&nhr->nexthops[i].labels[0], s,
1356 nhr->nexthops[i].label_num
1357 * sizeof(mpls_label_t));
1358 }
1359
1360 return true;
1361 stream_failure:
1362 return false;
1363 }
1364
1365 /*
1366 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1367 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
1368 * then set/unset redist[type] in the client handle (a struct zserv) for the
1369 * sending client
1370 */
1371 int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1372 int type, unsigned short instance, vrf_id_t vrf_id)
1373 {
1374 struct stream *s;
1375
1376 s = zclient->obuf;
1377 stream_reset(s);
1378
1379 zclient_create_header(s, command, vrf_id);
1380 stream_putc(s, afi);
1381 stream_putc(s, type);
1382 stream_putw(s, instance);
1383
1384 stream_putw_at(s, 0, stream_get_endp(s));
1385
1386 return zclient_send_message(zclient);
1387 }
1388
1389 /* Get prefix in ZServ format; family should be filled in on prefix */
1390 static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
1391 {
1392 size_t plen = prefix_blen(p);
1393 uint8_t c;
1394 p->prefixlen = 0;
1395
1396 if (plen == 0)
1397 return;
1398
1399 stream_get(&p->u.prefix, s, plen);
1400 STREAM_GETC(s, c);
1401 p->prefixlen = MIN(plen * 8, c);
1402
1403 stream_failure:
1404 return;
1405 }
1406
1407 /* Router-id update from zebra daemon. */
1408 void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
1409 {
1410 /* Fetch interface address. */
1411 STREAM_GETC(s, rid->family);
1412
1413 zclient_stream_get_prefix(s, rid);
1414
1415 stream_failure:
1416 return;
1417 }
1418
1419 /* Interface addition from zebra daemon. */
1420 /*
1421 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1422 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1423 * 0 1 2 3
1424 * 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
1425 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1426 * | ifname |
1427 * | |
1428 * | |
1429 * | |
1430 * | |
1431 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1432 * | ifindex |
1433 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1434 * | status |
1435 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1436 * | if_flags |
1437 * | |
1438 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1439 * | metric |
1440 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1441 * | speed |
1442 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1443 * | ifmtu |
1444 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1445 * | ifmtu6 |
1446 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1447 * | bandwidth |
1448 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1449 * | Link Layer Type |
1450 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1451 * | Harware Address Length |
1452 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1453 * | Hardware Address if HW lenght different from 0 |
1454 * | ... max INTERFACE_HWADDR_MAX |
1455 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1456 * | Link_params? | Whether a link-params follows: 1 or 0.
1457 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1458 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1459 * | .... (struct if_link_params). |
1460 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1461 */
1462
1463 static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1464 {
1465 struct vrf *vrf;
1466 char vrfname_tmp[VRF_NAMSIZ];
1467 struct vrf_data data;
1468
1469 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1470 /* Read interface name. */
1471 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1472
1473 /* Lookup/create vrf by vrf_id. */
1474 vrf = vrf_get(vrf_id, vrfname_tmp);
1475 vrf->data.l.table_id = data.l.table_id;
1476 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
1477 vrf_enable(vrf);
1478 }
1479
1480 static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1481 {
1482 struct vrf *vrf;
1483
1484 /* Lookup vrf by vrf_id. */
1485 vrf = vrf_lookup_by_id(vrf_id);
1486
1487 /*
1488 * If a routing protocol doesn't know about a
1489 * vrf that is about to be deleted. There is
1490 * no point in attempting to delete it.
1491 */
1492 if (!vrf)
1493 return;
1494
1495 vrf_delete(vrf);
1496 }
1497
1498 struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
1499 {
1500 struct interface *ifp;
1501 char ifname_tmp[INTERFACE_NAMSIZ];
1502
1503 /* Read interface name. */
1504 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1505
1506 /* Lookup/create interface by name. */
1507 ifp = if_get_by_name(ifname_tmp, vrf_id, 0);
1508
1509 zebra_interface_if_set_value(s, ifp);
1510
1511 return ifp;
1512 }
1513
1514 /*
1515 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1516 * from zebra server. The format of this message is the same as
1517 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1518 * comments for zebra_interface_add_read), except that no sockaddr_dl
1519 * is sent at the tail of the message.
1520 */
1521 struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
1522 {
1523 struct interface *ifp;
1524 char ifname_tmp[INTERFACE_NAMSIZ];
1525
1526 /* Read interface name. */
1527 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1528
1529 /* Lookup this by interface index. */
1530 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
1531 if (ifp == NULL) {
1532 zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1533 ifname_tmp, vrf_id);
1534 return NULL;
1535 }
1536
1537 zebra_interface_if_set_value(s, ifp);
1538
1539 return ifp;
1540 }
1541
1542 static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
1543 {
1544
1545 if (iflp == NULL)
1546 return;
1547
1548 iflp->lp_status = stream_getl(s);
1549 iflp->te_metric = stream_getl(s);
1550 iflp->max_bw = stream_getf(s);
1551 iflp->max_rsv_bw = stream_getf(s);
1552 uint32_t bwclassnum = stream_getl(s);
1553 {
1554 unsigned int i;
1555 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1556 iflp->unrsv_bw[i] = stream_getf(s);
1557 if (i < bwclassnum)
1558 zlog_err(
1559 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1560 " - outdated library?",
1561 __func__, bwclassnum, MAX_CLASS_TYPE);
1562 }
1563 iflp->admin_grp = stream_getl(s);
1564 iflp->rmt_as = stream_getl(s);
1565 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1566
1567 iflp->av_delay = stream_getl(s);
1568 iflp->min_delay = stream_getl(s);
1569 iflp->max_delay = stream_getl(s);
1570 iflp->delay_var = stream_getl(s);
1571
1572 iflp->pkt_loss = stream_getf(s);
1573 iflp->res_bw = stream_getf(s);
1574 iflp->ava_bw = stream_getf(s);
1575 iflp->use_bw = stream_getf(s);
1576 }
1577
1578 struct interface *zebra_interface_link_params_read(struct stream *s)
1579 {
1580 struct if_link_params *iflp;
1581 ifindex_t ifindex;
1582
1583 assert(s);
1584
1585 ifindex = stream_getl(s);
1586
1587 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
1588
1589 if (ifp == NULL) {
1590 zlog_err("%s: unknown ifindex %u, shouldn't happen", __func__,
1591 ifindex);
1592 return NULL;
1593 }
1594
1595 if ((iflp = if_link_params_get(ifp)) == NULL)
1596 return NULL;
1597
1598 link_params_set_value(s, iflp);
1599
1600 return ifp;
1601 }
1602
1603 void zebra_interface_if_set_value(struct stream *s, struct interface *ifp)
1604 {
1605 uint8_t link_params_status = 0;
1606
1607 /* Read interface's index. */
1608 if_set_index(ifp, stream_getl(s));
1609 ifp->status = stream_getc(s);
1610
1611 /* Read interface's value. */
1612 ifp->flags = stream_getq(s);
1613 ifp->ptm_enable = stream_getc(s);
1614 ifp->ptm_status = stream_getc(s);
1615 ifp->metric = stream_getl(s);
1616 ifp->speed = stream_getl(s);
1617 ifp->mtu = stream_getl(s);
1618 ifp->mtu6 = stream_getl(s);
1619 ifp->bandwidth = stream_getl(s);
1620 ifp->ll_type = stream_getl(s);
1621 ifp->hw_addr_len = stream_getl(s);
1622 if (ifp->hw_addr_len)
1623 stream_get(ifp->hw_addr, s,
1624 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1625
1626 /* Read Traffic Engineering status */
1627 link_params_status = stream_getc(s);
1628 /* Then, Traffic Engineering parameters if any */
1629 if (link_params_status) {
1630 struct if_link_params *iflp = if_link_params_get(ifp);
1631 link_params_set_value(s, iflp);
1632 }
1633 }
1634
1635 size_t zebra_interface_link_params_write(struct stream *s,
1636 struct interface *ifp)
1637 {
1638 size_t w;
1639 struct if_link_params *iflp;
1640 int i;
1641
1642 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1643 return 0;
1644
1645 iflp = ifp->link_params;
1646 w = 0;
1647
1648 w += stream_putl(s, iflp->lp_status);
1649
1650 w += stream_putl(s, iflp->te_metric);
1651 w += stream_putf(s, iflp->max_bw);
1652 w += stream_putf(s, iflp->max_rsv_bw);
1653
1654 w += stream_putl(s, MAX_CLASS_TYPE);
1655 for (i = 0; i < MAX_CLASS_TYPE; i++)
1656 w += stream_putf(s, iflp->unrsv_bw[i]);
1657
1658 w += stream_putl(s, iflp->admin_grp);
1659 w += stream_putl(s, iflp->rmt_as);
1660 w += stream_put_in_addr(s, &iflp->rmt_ip);
1661
1662 w += stream_putl(s, iflp->av_delay);
1663 w += stream_putl(s, iflp->min_delay);
1664 w += stream_putl(s, iflp->max_delay);
1665 w += stream_putl(s, iflp->delay_var);
1666
1667 w += stream_putf(s, iflp->pkt_loss);
1668 w += stream_putf(s, iflp->res_bw);
1669 w += stream_putf(s, iflp->ava_bw);
1670 w += stream_putf(s, iflp->use_bw);
1671
1672 return w;
1673 }
1674
1675 /*
1676 * format of message for address additon is:
1677 * 0
1678 * 0 1 2 3 4 5 6 7
1679 * +-+-+-+-+-+-+-+-+
1680 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1681 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1682 * | |
1683 * + +
1684 * | ifindex |
1685 * + +
1686 * | |
1687 * + +
1688 * | |
1689 * +-+-+-+-+-+-+-+-+
1690 * | ifc_flags | flags for connected address
1691 * +-+-+-+-+-+-+-+-+
1692 * | addr_family |
1693 * +-+-+-+-+-+-+-+-+
1694 * | addr... |
1695 * : :
1696 * | |
1697 * +-+-+-+-+-+-+-+-+
1698 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1699 * +-+-+-+-+-+-+-+-+
1700 * | daddr.. |
1701 * : :
1702 * | |
1703 * +-+-+-+-+-+-+-+-+
1704 */
1705
1706 static int memconstant(const void *s, int c, size_t n)
1707 {
1708 const uint8_t *p = s;
1709
1710 while (n-- > 0)
1711 if (*p++ != c)
1712 return 0;
1713 return 1;
1714 }
1715
1716
1717 struct connected *zebra_interface_address_read(int type, struct stream *s,
1718 vrf_id_t vrf_id)
1719 {
1720 ifindex_t ifindex;
1721 struct interface *ifp;
1722 struct connected *ifc;
1723 struct prefix p, d, *dp;
1724 int plen;
1725 uint8_t ifc_flags;
1726
1727 memset(&p, 0, sizeof(p));
1728 memset(&d, 0, sizeof(d));
1729
1730 /* Get interface index. */
1731 ifindex = stream_getl(s);
1732
1733 /* Lookup index. */
1734 ifp = if_lookup_by_index(ifindex, vrf_id);
1735 if (ifp == NULL) {
1736 zlog_warn("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1737 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1738 ifindex, vrf_id);
1739 return NULL;
1740 }
1741
1742 /* Fetch flag. */
1743 ifc_flags = stream_getc(s);
1744
1745 /* Fetch interface address. */
1746 d.family = p.family = stream_getc(s);
1747 plen = prefix_blen(&d);
1748
1749 zclient_stream_get_prefix(s, &p);
1750
1751 /* Fetch destination address. */
1752 stream_get(&d.u.prefix, s, plen);
1753
1754 /* N.B. NULL destination pointers are encoded as all zeroes */
1755 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1756
1757 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1758 ifc = connected_lookup_prefix_exact(ifp, &p);
1759 if (!ifc) {
1760 /* N.B. NULL destination pointers are encoded as all
1761 * zeroes */
1762 ifc = connected_add_by_prefix(ifp, &p, dp);
1763 }
1764 if (ifc) {
1765 ifc->flags = ifc_flags;
1766 if (ifc->destination)
1767 ifc->destination->prefixlen =
1768 ifc->address->prefixlen;
1769 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1770 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1771 * "peer" */
1772 char buf[PREFIX_STRLEN];
1773 zlog_warn(
1774 "warning: interface %s address %s "
1775 "with peer flag set, but no peer address!",
1776 ifp->name, prefix2str(ifc->address, buf,
1777 sizeof buf));
1778 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1779 }
1780 }
1781 } else {
1782 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1783 ifc = connected_delete_by_prefix(ifp, &p);
1784 }
1785
1786 return ifc;
1787 }
1788
1789 /*
1790 * format of message for neighbor connected address is:
1791 * 0
1792 * 0 1 2 3 4 5 6 7
1793 * +-+-+-+-+-+-+-+-+
1794 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1795 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1796 * | |
1797 * + +
1798 * | ifindex |
1799 * + +
1800 * | |
1801 * + +
1802 * | |
1803 * +-+-+-+-+-+-+-+-+
1804 * | addr_family |
1805 * +-+-+-+-+-+-+-+-+
1806 * | addr... |
1807 * : :
1808 * | |
1809 * +-+-+-+-+-+-+-+-+
1810 * | addr_len | len of addr.
1811 * +-+-+-+-+-+-+-+-+
1812 */
1813 struct nbr_connected *
1814 zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
1815 {
1816 unsigned int ifindex;
1817 struct interface *ifp;
1818 struct prefix p;
1819 struct nbr_connected *ifc;
1820
1821 /* Get interface index. */
1822 ifindex = stream_getl(s);
1823
1824 /* Lookup index. */
1825 ifp = if_lookup_by_index(ifindex, vrf_id);
1826 if (ifp == NULL) {
1827 zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1828 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
1829 : "DELETE",
1830 ifindex, vrf_id);
1831 return NULL;
1832 }
1833
1834 p.family = stream_getc(s);
1835 stream_get(&p.u.prefix, s, prefix_blen(&p));
1836 p.prefixlen = stream_getc(s);
1837
1838 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
1839 /* Currently only supporting P2P links, so any new RA source
1840 address is
1841 considered as the replacement of the previously learnt
1842 Link-Local address. */
1843 if (!(ifc = listnode_head(ifp->nbr_connected))) {
1844 ifc = nbr_connected_new();
1845 ifc->address = prefix_new();
1846 ifc->ifp = ifp;
1847 listnode_add(ifp->nbr_connected, ifc);
1848 }
1849
1850 prefix_copy(ifc->address, &p);
1851 } else {
1852 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1853
1854 ifc = nbr_connected_check(ifp, &p);
1855 if (ifc)
1856 listnode_delete(ifp->nbr_connected, ifc);
1857 }
1858
1859 return ifc;
1860 }
1861
1862 struct interface *zebra_interface_vrf_update_read(struct stream *s,
1863 vrf_id_t vrf_id,
1864 vrf_id_t *new_vrf_id)
1865 {
1866 unsigned int ifindex;
1867 struct interface *ifp;
1868 vrf_id_t new_id;
1869
1870 /* Get interface index. */
1871 ifindex = stream_getl(s);
1872
1873 /* Lookup interface. */
1874 ifp = if_lookup_by_index(ifindex, vrf_id);
1875 if (ifp == NULL) {
1876 zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1877 ifindex, vrf_id);
1878 return NULL;
1879 }
1880
1881 /* Fetch new VRF Id. */
1882 new_id = stream_getw(s);
1883
1884 *new_vrf_id = new_id;
1885 return ifp;
1886 }
1887
1888 /* filter unwanted messages until the expected one arrives */
1889 static int zclient_read_sync_response(struct zclient *zclient,
1890 uint16_t expected_cmd)
1891 {
1892 struct stream *s;
1893 uint16_t size = -1;
1894 uint8_t marker;
1895 uint8_t version;
1896 vrf_id_t vrf_id;
1897 uint16_t cmd;
1898 fd_set readfds;
1899 int ret;
1900
1901 ret = 0;
1902 cmd = expected_cmd + 1;
1903 while (ret == 0 && cmd != expected_cmd) {
1904 s = zclient->ibuf;
1905 stream_reset(s);
1906
1907 /* wait until response arrives */
1908 FD_ZERO(&readfds);
1909 FD_SET(zclient->sock, &readfds);
1910 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
1911 if (!FD_ISSET(zclient->sock, &readfds))
1912 continue;
1913 /* read response */
1914 ret = zclient_read_header(s, zclient->sock, &size, &marker,
1915 &version, &vrf_id, &cmd);
1916 if (zclient_debug)
1917 zlog_debug("%s: Response (%d bytes) received", __func__,
1918 size);
1919 }
1920 if (ret != 0) {
1921 zlog_err("%s: Invalid Sync Message Reply", __func__);
1922 return -1;
1923 }
1924
1925 return 0;
1926 }
1927 /**
1928 * Connect to label manager in a syncronous way
1929 *
1930 * It first writes the request to zcient output buffer and then
1931 * immediately reads the answer from the input buffer.
1932 *
1933 * @param zclient Zclient used to connect to label manager (zebra)
1934 * @result Result of response
1935 */
1936 int lm_label_manager_connect(struct zclient *zclient)
1937 {
1938 int ret;
1939 struct stream *s;
1940 uint8_t result;
1941
1942 if (zclient_debug)
1943 zlog_debug("Connecting to Label Manager");
1944
1945 if (zclient->sock < 0)
1946 return -1;
1947
1948 /* send request */
1949 s = zclient->obuf;
1950 stream_reset(s);
1951 zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
1952
1953 /* proto */
1954 stream_putc(s, zclient->redist_default);
1955 /* instance */
1956 stream_putw(s, zclient->instance);
1957
1958 /* Put length at the first point of the stream. */
1959 stream_putw_at(s, 0, stream_get_endp(s));
1960
1961 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1962 if (ret < 0) {
1963 zlog_err("%s: can't write to zclient->sock", __func__);
1964 close(zclient->sock);
1965 zclient->sock = -1;
1966 return -1;
1967 }
1968 if (ret == 0) {
1969 zlog_err("%s: zclient->sock connection closed", __func__);
1970 close(zclient->sock);
1971 zclient->sock = -1;
1972 return -1;
1973 }
1974 if (zclient_debug)
1975 zlog_debug("%s: Label manager connect request (%d bytes) sent",
1976 __func__, ret);
1977
1978 /* read response */
1979 if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
1980 != 0)
1981 return -1;
1982
1983 /* result */
1984 s = zclient->ibuf;
1985 result = stream_getc(s);
1986 if (zclient_debug)
1987 zlog_debug(
1988 "%s: Label Manager connect response received, result %u",
1989 __func__, result);
1990
1991 return (int)result;
1992 }
1993
1994 /*
1995 * Asynchronous label chunk request
1996 *
1997 * @param zclient Zclient used to connect to label manager (zebra)
1998 * @param keep Avoid garbage collection
1999 * @param chunk_size Amount of labels requested
2000 * @result 0 on success, -1 otherwise
2001 */
2002 int zclient_send_get_label_chunk(
2003 struct zclient *zclient,
2004 uint8_t keep,
2005 uint32_t chunk_size)
2006 {
2007 struct stream *s;
2008
2009 if (zclient_debug)
2010 zlog_debug("Getting Label Chunk");
2011
2012 if (zclient->sock < 0)
2013 return -1;
2014
2015 s = zclient->obuf;
2016 stream_reset(s);
2017
2018 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2019 stream_putc(s, keep);
2020 stream_putl(s, chunk_size);
2021
2022 /* Put length at the first point of the stream. */
2023 stream_putw_at(s, 0, stream_get_endp(s));
2024
2025 return zclient_send_message(zclient);
2026 }
2027
2028 /**
2029 * Function to request a label chunk in a syncronous way
2030 *
2031 * It first writes the request to zlcient output buffer and then
2032 * immediately reads the answer from the input buffer.
2033 *
2034 * @param zclient Zclient used to connect to label manager (zebra)
2035 * @param keep Avoid garbage collection
2036 * @param chunk_size Amount of labels requested
2037 * @param start To write first assigned chunk label to
2038 * @param end To write last assigned chunk label to
2039 * @result 0 on success, -1 otherwise
2040 */
2041 int lm_get_label_chunk(struct zclient *zclient, uint8_t keep,
2042 uint32_t chunk_size, uint32_t *start, uint32_t *end)
2043 {
2044 int ret;
2045 struct stream *s;
2046 uint8_t response_keep;
2047
2048 if (zclient_debug)
2049 zlog_debug("Getting Label Chunk");
2050
2051 if (zclient->sock < 0)
2052 return -1;
2053
2054 /* send request */
2055 s = zclient->obuf;
2056 stream_reset(s);
2057 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2058 /* keep */
2059 stream_putc(s, keep);
2060 /* chunk size */
2061 stream_putl(s, chunk_size);
2062 /* Put length at the first point of the stream. */
2063 stream_putw_at(s, 0, stream_get_endp(s));
2064
2065 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2066 if (ret < 0) {
2067 zlog_err("%s: can't write to zclient->sock", __func__);
2068 close(zclient->sock);
2069 zclient->sock = -1;
2070 return -1;
2071 }
2072 if (ret == 0) {
2073 zlog_err("%s: zclient->sock connection closed", __func__);
2074 close(zclient->sock);
2075 zclient->sock = -1;
2076 return -1;
2077 }
2078 if (zclient_debug)
2079 zlog_debug("%s: Label chunk request (%d bytes) sent", __func__,
2080 ret);
2081
2082 /* read response */
2083 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2084 return -1;
2085
2086 s = zclient->ibuf;
2087 /* keep */
2088 response_keep = stream_getc(s);
2089 /* start and end labels */
2090 *start = stream_getl(s);
2091 *end = stream_getl(s);
2092
2093 /* not owning this response */
2094 if (keep != response_keep) {
2095 zlog_err(
2096 "%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2097 __func__, *start, *end, keep, response_keep);
2098 }
2099 /* sanity */
2100 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2101 || *end > MPLS_LABEL_UNRESERVED_MAX) {
2102 zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
2103 *end);
2104 return -1;
2105 }
2106
2107 if (zclient_debug)
2108 zlog_debug("Label Chunk assign: %u - %u (%u) ", *start, *end,
2109 response_keep);
2110
2111 return 0;
2112 }
2113
2114 /**
2115 * Function to release a label chunk
2116 *
2117 * @param zclient Zclient used to connect to label manager (zebra)
2118 * @param start First label of chunk
2119 * @param end Last label of chunk
2120 * @result 0 on success, -1 otherwise
2121 */
2122 int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2123 uint32_t end)
2124 {
2125 int ret;
2126 struct stream *s;
2127
2128 if (zclient_debug)
2129 zlog_debug("Releasing Label Chunk");
2130
2131 if (zclient->sock < 0)
2132 return -1;
2133
2134 /* send request */
2135 s = zclient->obuf;
2136 stream_reset(s);
2137 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2138
2139 /* start */
2140 stream_putl(s, start);
2141 /* end */
2142 stream_putl(s, end);
2143
2144 /* Put length at the first point of the stream. */
2145 stream_putw_at(s, 0, stream_get_endp(s));
2146
2147 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2148 if (ret < 0) {
2149 zlog_err("%s: can't write to zclient->sock", __func__);
2150 close(zclient->sock);
2151 zclient->sock = -1;
2152 return -1;
2153 }
2154 if (ret == 0) {
2155 zlog_err("%s: zclient->sock connection closed", __func__);
2156 close(zclient->sock);
2157 zclient->sock = -1;
2158 return -1;
2159 }
2160
2161 return 0;
2162 }
2163
2164 /**
2165 * Connect to table manager in a syncronous way
2166 *
2167 * It first writes the request to zcient output buffer and then
2168 * immediately reads the answer from the input buffer.
2169 *
2170 * @param zclient Zclient used to connect to table manager (zebra)
2171 * @result Result of response
2172 */
2173 int tm_table_manager_connect(struct zclient *zclient)
2174 {
2175 int ret;
2176 struct stream *s;
2177 uint8_t result;
2178
2179 if (zclient_debug)
2180 zlog_debug("Connecting to Table Manager");
2181
2182 if (zclient->sock < 0)
2183 return -1;
2184
2185 /* send request */
2186 s = zclient->obuf;
2187 stream_reset(s);
2188 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2189
2190 /* proto */
2191 stream_putc(s, zclient->redist_default);
2192 /* instance */
2193 stream_putw(s, zclient->instance);
2194
2195 /* Put length at the first point of the stream. */
2196 stream_putw_at(s, 0, stream_get_endp(s));
2197
2198 ret = zclient_send_message(zclient);
2199 if (ret < 0)
2200 return -1;
2201
2202 if (zclient_debug)
2203 zlog_debug("%s: Table manager connect request sent",
2204 __func__);
2205
2206 /* read response */
2207 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2208 != 0)
2209 return -1;
2210
2211 /* result */
2212 s = zclient->ibuf;
2213 STREAM_GETC(s, result);
2214 if (zclient_debug)
2215 zlog_debug(
2216 "%s: Table Manager connect response received, result %u",
2217 __func__, result);
2218
2219 return (int)result;
2220 stream_failure:
2221 return 0;
2222 }
2223
2224 /**
2225 * Function to request a table chunk in a syncronous way
2226 *
2227 * It first writes the request to zclient output buffer and then
2228 * immediately reads the answer from the input buffer.
2229 *
2230 * @param zclient Zclient used to connect to table manager (zebra)
2231 * @param chunk_size Amount of table requested
2232 * @param start to write first assigned chunk table RT ID to
2233 * @param end To write last assigned chunk table RT ID to
2234 * @result 0 on success, -1 otherwise
2235 */
2236 int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2237 uint32_t *start, uint32_t *end)
2238 {
2239 int ret;
2240 struct stream *s;
2241
2242 if (zclient_debug)
2243 zlog_debug("Getting Table Chunk");
2244
2245 if (zclient->sock < 0)
2246 return -1;
2247
2248 /* send request */
2249 s = zclient->obuf;
2250 stream_reset(s);
2251 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2252 /* chunk size */
2253 stream_putl(s, chunk_size);
2254 /* Put length at the first point of the stream. */
2255 stream_putw_at(s, 0, stream_get_endp(s));
2256
2257 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2258 if (ret < 0) {
2259 zlog_err("%s: can't write to zclient->sock", __func__);
2260 close(zclient->sock);
2261 zclient->sock = -1;
2262 return -1;
2263 }
2264 if (ret == 0) {
2265 zlog_err("%s: zclient->sock connection closed", __func__);
2266 close(zclient->sock);
2267 zclient->sock = -1;
2268 return -1;
2269 }
2270 if (zclient_debug)
2271 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2272 ret);
2273
2274 /* read response */
2275 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2276 return -1;
2277
2278 s = zclient->ibuf;
2279 /* start and end table IDs */
2280 STREAM_GETL(s, *start);
2281 STREAM_GETL(s, *end);
2282
2283 if (zclient_debug)
2284 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2285
2286 stream_failure:
2287 return 0;
2288 }
2289
2290 /**
2291 * Function to release a table chunk
2292 *
2293 * @param zclient Zclient used to connect to table manager (zebra)
2294 * @param start First label of table
2295 * @param end Last label of chunk
2296 * @result 0 on success, -1 otherwise
2297 */
2298 int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2299 uint32_t end)
2300 {
2301 struct stream *s;
2302
2303 if (zclient_debug)
2304 zlog_debug("Releasing Table Chunk");
2305
2306 if (zclient->sock < 0)
2307 return -1;
2308
2309 /* send request */
2310 s = zclient->obuf;
2311 stream_reset(s);
2312 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2313
2314 /* start */
2315 stream_putl(s, start);
2316 /* end */
2317 stream_putl(s, end);
2318
2319 /* Put length at the first point of the stream. */
2320 stream_putw_at(s, 0, stream_get_endp(s));
2321
2322 return zclient_send_message(zclient);
2323 }
2324
2325
2326 int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
2327 {
2328 struct stream *s;
2329
2330 /* Reset stream. */
2331 s = zclient->obuf;
2332 stream_reset(s);
2333
2334 zclient_create_header(s, command, VRF_DEFAULT);
2335 stream_write(s, pw->ifname, IF_NAMESIZE);
2336 stream_putl(s, pw->ifindex);
2337
2338 /* Put type */
2339 stream_putl(s, pw->type);
2340
2341 /* Put nexthop */
2342 stream_putl(s, pw->af);
2343 switch (pw->af) {
2344 case AF_INET:
2345 stream_put_in_addr(s, &pw->nexthop.ipv4);
2346 break;
2347 case AF_INET6:
2348 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
2349 break;
2350 default:
2351 zlog_err("%s: unknown af", __func__);
2352 return -1;
2353 }
2354
2355 /* Put labels */
2356 stream_putl(s, pw->local_label);
2357 stream_putl(s, pw->remote_label);
2358
2359 /* Put flags */
2360 stream_putc(s, pw->flags);
2361
2362 /* Protocol specific fields */
2363 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
2364
2365 /* Put length at the first point of the stream. */
2366 stream_putw_at(s, 0, stream_get_endp(s));
2367
2368 return zclient_send_message(zclient);
2369 }
2370
2371 /*
2372 * Receive PW status update from Zebra and send it to LDE process.
2373 */
2374 void zebra_read_pw_status_update(int command, struct zclient *zclient,
2375 zebra_size_t length, vrf_id_t vrf_id,
2376 struct zapi_pw_status *pw)
2377 {
2378 struct stream *s;
2379
2380 memset(pw, 0, sizeof(struct zapi_pw_status));
2381 s = zclient->ibuf;
2382
2383 /* Get data. */
2384 stream_get(pw->ifname, s, IF_NAMESIZE);
2385 pw->ifindex = stream_getl(s);
2386 pw->status = stream_getl(s);
2387 }
2388
2389 /* Zebra client message read function. */
2390 static int zclient_read(struct thread *thread)
2391 {
2392 size_t already;
2393 uint16_t length, command;
2394 uint8_t marker, version;
2395 vrf_id_t vrf_id;
2396 struct zclient *zclient;
2397
2398 /* Get socket to zebra. */
2399 zclient = THREAD_ARG(thread);
2400 zclient->t_read = NULL;
2401
2402 /* Read zebra header (if we don't have it already). */
2403 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2404 ssize_t nbyte;
2405 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2406 ZEBRA_HEADER_SIZE - already))
2407 == 0)
2408 || (nbyte == -1)) {
2409 if (zclient_debug)
2410 zlog_debug(
2411 "zclient connection closed socket [%d].",
2412 zclient->sock);
2413 return zclient_failed(zclient);
2414 }
2415 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2416 /* Try again later. */
2417 zclient_event(ZCLIENT_READ, zclient);
2418 return 0;
2419 }
2420 already = ZEBRA_HEADER_SIZE;
2421 }
2422
2423 /* Reset to read from the beginning of the incoming packet. */
2424 stream_set_getp(zclient->ibuf, 0);
2425
2426 /* Fetch header values. */
2427 length = stream_getw(zclient->ibuf);
2428 marker = stream_getc(zclient->ibuf);
2429 version = stream_getc(zclient->ibuf);
2430 vrf_id = stream_getl(zclient->ibuf);
2431 command = stream_getw(zclient->ibuf);
2432
2433 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
2434 zlog_err(
2435 "%s: socket %d version mismatch, marker %d, version %d",
2436 __func__, zclient->sock, marker, version);
2437 return zclient_failed(zclient);
2438 }
2439
2440 if (length < ZEBRA_HEADER_SIZE) {
2441 zlog_err("%s: socket %d message length %u is less than %d ",
2442 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
2443 return zclient_failed(zclient);
2444 }
2445
2446 /* Length check. */
2447 if (length > STREAM_SIZE(zclient->ibuf)) {
2448 struct stream *ns;
2449 zlog_warn(
2450 "%s: message size %u exceeds buffer size %lu, expanding...",
2451 __func__, length,
2452 (unsigned long)STREAM_SIZE(zclient->ibuf));
2453 ns = stream_new(length);
2454 stream_copy(ns, zclient->ibuf);
2455 stream_free(zclient->ibuf);
2456 zclient->ibuf = ns;
2457 }
2458
2459 /* Read rest of zebra packet. */
2460 if (already < length) {
2461 ssize_t nbyte;
2462 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2463 length - already))
2464 == 0)
2465 || (nbyte == -1)) {
2466 if (zclient_debug)
2467 zlog_debug(
2468 "zclient connection closed socket [%d].",
2469 zclient->sock);
2470 return zclient_failed(zclient);
2471 }
2472 if (nbyte != (ssize_t)(length - already)) {
2473 /* Try again later. */
2474 zclient_event(ZCLIENT_READ, zclient);
2475 return 0;
2476 }
2477 }
2478
2479 length -= ZEBRA_HEADER_SIZE;
2480
2481 if (zclient_debug)
2482 zlog_debug("zclient 0x%p command 0x%x VRF %u\n",
2483 (void *)zclient, command, vrf_id);
2484
2485 switch (command) {
2486 case ZEBRA_ROUTER_ID_UPDATE:
2487 if (zclient->router_id_update)
2488 (*zclient->router_id_update)(command, zclient, length,
2489 vrf_id);
2490 break;
2491 case ZEBRA_VRF_ADD:
2492 zclient_vrf_add(zclient, vrf_id);
2493 break;
2494 case ZEBRA_VRF_DELETE:
2495 zclient_vrf_delete(zclient, vrf_id);
2496 break;
2497 case ZEBRA_INTERFACE_ADD:
2498 if (zclient->interface_add)
2499 (*zclient->interface_add)(command, zclient, length,
2500 vrf_id);
2501 break;
2502 case ZEBRA_INTERFACE_DELETE:
2503 if (zclient->interface_delete)
2504 (*zclient->interface_delete)(command, zclient, length,
2505 vrf_id);
2506 break;
2507 case ZEBRA_INTERFACE_ADDRESS_ADD:
2508 if (zclient->interface_address_add)
2509 (*zclient->interface_address_add)(command, zclient,
2510 length, vrf_id);
2511 break;
2512 case ZEBRA_INTERFACE_ADDRESS_DELETE:
2513 if (zclient->interface_address_delete)
2514 (*zclient->interface_address_delete)(command, zclient,
2515 length, vrf_id);
2516 break;
2517 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
2518 if (zclient->interface_bfd_dest_update)
2519 (*zclient->interface_bfd_dest_update)(command, zclient,
2520 length, vrf_id);
2521 break;
2522 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
2523 if (zclient->interface_nbr_address_add)
2524 (*zclient->interface_nbr_address_add)(command, zclient,
2525 length, vrf_id);
2526 break;
2527 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
2528 if (zclient->interface_nbr_address_delete)
2529 (*zclient->interface_nbr_address_delete)(
2530 command, zclient, length, vrf_id);
2531 break;
2532 case ZEBRA_INTERFACE_UP:
2533 if (zclient->interface_up)
2534 (*zclient->interface_up)(command, zclient, length,
2535 vrf_id);
2536 break;
2537 case ZEBRA_INTERFACE_DOWN:
2538 if (zclient->interface_down)
2539 (*zclient->interface_down)(command, zclient, length,
2540 vrf_id);
2541 break;
2542 case ZEBRA_INTERFACE_VRF_UPDATE:
2543 if (zclient->interface_vrf_update)
2544 (*zclient->interface_vrf_update)(command, zclient,
2545 length, vrf_id);
2546 break;
2547 case ZEBRA_NEXTHOP_UPDATE:
2548 if (zclient_debug)
2549 zlog_debug("zclient rcvd nexthop update\n");
2550 if (zclient->nexthop_update)
2551 (*zclient->nexthop_update)(command, zclient, length,
2552 vrf_id);
2553 break;
2554 case ZEBRA_IMPORT_CHECK_UPDATE:
2555 if (zclient_debug)
2556 zlog_debug("zclient rcvd import check update\n");
2557 if (zclient->import_check_update)
2558 (*zclient->import_check_update)(command, zclient,
2559 length, vrf_id);
2560 break;
2561 case ZEBRA_BFD_DEST_REPLAY:
2562 if (zclient->bfd_dest_replay)
2563 (*zclient->bfd_dest_replay)(command, zclient, length,
2564 vrf_id);
2565 break;
2566 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
2567 if (zclient->redistribute_route_add)
2568 (*zclient->redistribute_route_add)(command, zclient,
2569 length, vrf_id);
2570 break;
2571 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
2572 if (zclient->redistribute_route_del)
2573 (*zclient->redistribute_route_del)(command, zclient,
2574 length, vrf_id);
2575 break;
2576 case ZEBRA_INTERFACE_LINK_PARAMS:
2577 if (zclient->interface_link_params)
2578 (*zclient->interface_link_params)(command, zclient,
2579 length);
2580 break;
2581 case ZEBRA_FEC_UPDATE:
2582 if (zclient_debug)
2583 zlog_debug("zclient rcvd fec update\n");
2584 if (zclient->fec_update)
2585 (*zclient->fec_update)(command, zclient, length);
2586 break;
2587 case ZEBRA_VNI_ADD:
2588 if (zclient->local_vni_add)
2589 (*zclient->local_vni_add)(command, zclient, length,
2590 vrf_id);
2591 break;
2592 case ZEBRA_VNI_DEL:
2593 if (zclient->local_vni_del)
2594 (*zclient->local_vni_del)(command, zclient, length,
2595 vrf_id);
2596 break;
2597 case ZEBRA_L3VNI_ADD:
2598 if (zclient->local_l3vni_add)
2599 (*zclient->local_l3vni_add)(command, zclient, length,
2600 vrf_id);
2601 break;
2602 case ZEBRA_L3VNI_DEL:
2603 if (zclient->local_l3vni_del)
2604 (*zclient->local_l3vni_del)(command, zclient, length,
2605 vrf_id);
2606 break;
2607 case ZEBRA_MACIP_ADD:
2608 if (zclient->local_macip_add)
2609 (*zclient->local_macip_add)(command, zclient, length,
2610 vrf_id);
2611 break;
2612 case ZEBRA_MACIP_DEL:
2613 if (zclient->local_macip_del)
2614 (*zclient->local_macip_del)(command, zclient, length,
2615 vrf_id);
2616 break;
2617 case ZEBRA_IP_PREFIX_ROUTE_ADD:
2618 if (zclient->local_ip_prefix_add)
2619 (*zclient->local_ip_prefix_add)(command, zclient,
2620 length, vrf_id);
2621 break;
2622 case ZEBRA_IP_PREFIX_ROUTE_DEL:
2623 if (zclient->local_ip_prefix_del)
2624 (*zclient->local_ip_prefix_del)(command, zclient,
2625 length, vrf_id);
2626 break;
2627 case ZEBRA_PW_STATUS_UPDATE:
2628 if (zclient->pw_status_update)
2629 (*zclient->pw_status_update)(command, zclient, length,
2630 vrf_id);
2631 break;
2632 case ZEBRA_ROUTE_NOTIFY_OWNER:
2633 if (zclient->route_notify_owner)
2634 (*zclient->route_notify_owner)(command, zclient, length,
2635 vrf_id);
2636 break;
2637 case ZEBRA_RULE_NOTIFY_OWNER:
2638 if (zclient->rule_notify_owner)
2639 (*zclient->rule_notify_owner)(command, zclient, length,
2640 vrf_id);
2641 break;
2642 case ZEBRA_GET_LABEL_CHUNK:
2643 if (zclient->label_chunk)
2644 (*zclient->label_chunk)(command, zclient, length,
2645 vrf_id);
2646 break;
2647 default:
2648 break;
2649 }
2650
2651 if (zclient->sock < 0)
2652 /* Connection was closed during packet processing. */
2653 return -1;
2654
2655 /* Register read thread. */
2656 stream_reset(zclient->ibuf);
2657 zclient_event(ZCLIENT_READ, zclient);
2658
2659 return 0;
2660 }
2661
2662 void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
2663 int type, unsigned short instance, vrf_id_t vrf_id)
2664 {
2665
2666 if (instance) {
2667 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2668 if (redist_check_instance(
2669 &zclient->mi_redist[afi][type], instance))
2670 return;
2671 redist_add_instance(&zclient->mi_redist[afi][type],
2672 instance);
2673 } else {
2674 if (!redist_check_instance(
2675 &zclient->mi_redist[afi][type], instance))
2676 return;
2677 redist_del_instance(&zclient->mi_redist[afi][type],
2678 instance);
2679 }
2680
2681 } else {
2682 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2683 if (vrf_bitmap_check(zclient->redist[afi][type],
2684 vrf_id))
2685 return;
2686 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
2687 } else {
2688 if (!vrf_bitmap_check(zclient->redist[afi][type],
2689 vrf_id))
2690 return;
2691 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
2692 }
2693 }
2694
2695 if (zclient->sock > 0)
2696 zebra_redistribute_send(command, zclient, afi, type, instance,
2697 vrf_id);
2698 }
2699
2700
2701 void zclient_redistribute_default(int command, struct zclient *zclient,
2702 vrf_id_t vrf_id)
2703 {
2704
2705 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
2706 if (vrf_bitmap_check(zclient->default_information, vrf_id))
2707 return;
2708 vrf_bitmap_set(zclient->default_information, vrf_id);
2709 } else {
2710 if (!vrf_bitmap_check(zclient->default_information, vrf_id))
2711 return;
2712 vrf_bitmap_unset(zclient->default_information, vrf_id);
2713 }
2714
2715 if (zclient->sock > 0)
2716 zebra_message_send(zclient, command, vrf_id);
2717 }
2718
2719 static void zclient_event(enum event event, struct zclient *zclient)
2720 {
2721 switch (event) {
2722 case ZCLIENT_SCHEDULE:
2723 thread_add_event(zclient->master, zclient_connect, zclient, 0,
2724 &zclient->t_connect);
2725 break;
2726 case ZCLIENT_CONNECT:
2727 if (zclient_debug)
2728 zlog_debug(
2729 "zclient connect failures: %d schedule interval is now %d",
2730 zclient->fail, zclient->fail < 3 ? 10 : 60);
2731 thread_add_timer(zclient->master, zclient_connect, zclient,
2732 zclient->fail < 3 ? 10 : 60,
2733 &zclient->t_connect);
2734 break;
2735 case ZCLIENT_READ:
2736 zclient->t_read = NULL;
2737 thread_add_read(zclient->master, zclient_read, zclient,
2738 zclient->sock, &zclient->t_read);
2739 break;
2740 }
2741 }
2742
2743 void zclient_interface_set_master(struct zclient *client,
2744 struct interface *master,
2745 struct interface *slave)
2746 {
2747 struct stream *s;
2748
2749 s = client->obuf;
2750 stream_reset(s);
2751
2752 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
2753
2754 stream_putl(s, master->vrf_id);
2755 stream_putl(s, master->ifindex);
2756 stream_putl(s, slave->vrf_id);
2757 stream_putl(s, slave->ifindex);
2758
2759 stream_putw_at(s, 0, stream_get_endp(s));
2760 zclient_send_message(client);
2761 }