]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
lib: migrate to new memory-type handling
[mirror_frr.git] / lib / zclient.c
CommitLineData
718e3744 1/* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
634f9ea2 3 * Copyright (C) 2005 Andrew J. Schorr
718e3744 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
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 * MA 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "prefix.h"
26#include "stream.h"
634f9ea2 27#include "buffer.h"
718e3744 28#include "network.h"
29#include "if.h"
30#include "log.h"
31#include "thread.h"
32#include "zclient.h"
33#include "memory.h"
34#include "table.h"
5b30316e 35#include "nexthop.h"
6b0655a2 36
718e3744 37/* Zebra client events. */
38enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
39
40/* Prototype for event manager. */
41static void zclient_event (enum event, struct zclient *);
42
744f4685 43const char *zclient_serv_path = NULL;
b5114685 44
718e3744 45/* This file local debug flag. */
46int zclient_debug = 0;
6b0655a2 47
718e3744 48/* Allocate zclient structure. */
49struct zclient *
4140ca4d 50zclient_new (struct thread_master *master)
718e3744 51{
52 struct zclient *zclient;
393deb9b 53 zclient = XCALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
718e3744 54
55 zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
56 zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
634f9ea2 57 zclient->wb = buffer_new(0);
4140ca4d 58 zclient->master = master;
718e3744 59
60 return zclient;
61}
62
228da428 63/* This function is only called when exiting, because
634f9ea2 64 many parts of the code do not check for I/O errors, so they could
65 reference an invalid pointer if the structure was ever freed.
634f9ea2 66
228da428 67 Free zclient structure. */
718e3744 68void
69zclient_free (struct zclient *zclient)
70{
634f9ea2 71 if (zclient->ibuf)
72 stream_free(zclient->ibuf);
73 if (zclient->obuf)
74 stream_free(zclient->obuf);
75 if (zclient->wb)
76 buffer_free(zclient->wb);
77
718e3744 78 XFREE (MTYPE_ZCLIENT, zclient);
79}
80
7c8ff89e
DS
81int
82redist_check_instance (struct redist_proto *red, u_short instance)
83{
84 struct listnode *node;
85 u_short *id;
86
87 if (!red->instances)
88 return 0;
89
90 for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
91 if (*id == instance)
92 return 1;
93
94 return 0;
95}
96
97void
98redist_add_instance (struct redist_proto *red, u_short instance)
99{
100 u_short *in;
101
102 red->enabled = 1;
103
104 if (!red->instances)
105 red->instances = list_new();
106
107 in = (u_short *)calloc(1, sizeof(u_short));
108 *in = instance;
109 listnode_add (red->instances, in);
110}
111
112void
113redist_del_instance (struct redist_proto *red, u_short instance)
114{
115 struct listnode *node;
116 u_short *id = NULL;
117
118 if (!red->instances)
24873f0c 119 return;
7c8ff89e
DS
120
121 for (ALL_LIST_ELEMENTS_RO (red->instances, node, id))
122 if (*id == instance)
123 break;
124
125 if (id)
126 {
127 listnode_delete(red->instances, id);
128 if (!red->instances->count)
129 {
130 red->enabled = 0;
131 list_free(red->instances);
132 red->instances = NULL;
133 }
134 }
135}
136
718e3744 137/* Stop zebra client services. */
138void
139zclient_stop (struct zclient *zclient)
140{
141 if (zclient_debug)
8ddca704 142 zlog_debug ("zclient stopped");
718e3744 143
144 /* Stop threads. */
634f9ea2 145 THREAD_OFF(zclient->t_read);
146 THREAD_OFF(zclient->t_connect);
147 THREAD_OFF(zclient->t_write);
148
149 /* Reset streams. */
150 stream_reset(zclient->ibuf);
151 stream_reset(zclient->obuf);
152
153 /* Empty the write buffer. */
154 buffer_reset(zclient->wb);
718e3744 155
156 /* Close socket. */
157 if (zclient->sock >= 0)
158 {
159 close (zclient->sock);
160 zclient->sock = -1;
161 }
162 zclient->fail = 0;
163}
164
165void
166zclient_reset (struct zclient *zclient)
167{
7076bb2f 168 afi_t afi;
3d68677e 169
718e3744 170 zclient_stop (zclient);
3d68677e
DS
171
172 for (afi = AFI_IP; afi < AFI_MAX; afi++)
7076bb2f 173 redist_del_instance (&zclient->mi_redist[afi][zclient->redist_default], zclient->instance);
3d68677e 174
7c8ff89e 175 zclient_init (zclient, zclient->redist_default, zclient->instance);
718e3744 176}
177
b5114685
VT
178#ifdef HAVE_TCP_ZEBRA
179
718e3744 180/* Make socket to zebra daemon. Return zebra socket. */
b5114685 181static int
634f9ea2 182zclient_socket(void)
718e3744 183{
184 int sock;
185 int ret;
186 struct sockaddr_in serv;
187
188 /* We should think about IPv6 connection. */
189 sock = socket (AF_INET, SOCK_STREAM, 0);
190 if (sock < 0)
191 return -1;
192
193 /* Make server socket. */
194 memset (&serv, 0, sizeof (struct sockaddr_in));
195 serv.sin_family = AF_INET;
196 serv.sin_port = htons (ZEBRA_PORT);
6f0e3f6e 197#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
718e3744 198 serv.sin_len = sizeof (struct sockaddr_in);
6f0e3f6e 199#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
718e3744 200 serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
201
202 /* Connect to zebra. */
203 ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
204 if (ret < 0)
205 {
4ecc09d3 206 zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
718e3744 207 close (sock);
208 return -1;
209 }
210 return sock;
211}
212
3414d035 213#else
b5114685 214
718e3744 215/* For sockaddr_un. */
216#include <sys/un.h>
217
1b91e000 218static int
8c328f11 219zclient_socket_un (const char *path)
718e3744 220{
221 int ret;
222 int sock, len;
223 struct sockaddr_un addr;
224
225 sock = socket (AF_UNIX, SOCK_STREAM, 0);
226 if (sock < 0)
227 return -1;
228
229 /* Make server socket. */
230 memset (&addr, 0, sizeof (struct sockaddr_un));
231 addr.sun_family = AF_UNIX;
232 strncpy (addr.sun_path, path, strlen (path));
6f0e3f6e 233#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
718e3744 234 len = addr.sun_len = SUN_LEN(&addr);
235#else
236 len = sizeof (addr.sun_family) + strlen (addr.sun_path);
6f0e3f6e 237#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
718e3744 238
239 ret = connect (sock, (struct sockaddr *) &addr, len);
240 if (ret < 0)
241 {
4ecc09d3 242 zlog_warn ("%s connect failure: %d", __PRETTY_FUNCTION__, errno);
718e3744 243 close (sock);
244 return -1;
245 }
246 return sock;
247}
248
3414d035
VT
249#endif /* HAVE_TCP_ZEBRA */
250
b5114685
VT
251/**
252 * Connect to zebra daemon.
253 * @param zclient a pointer to zclient structure
254 * @return socket fd just to make sure that connection established
255 * @see zclient_init
256 * @see zclient_new
257 */
258int
259zclient_socket_connect (struct zclient *zclient)
260{
261#ifdef HAVE_TCP_ZEBRA
262 zclient->sock = zclient_socket ();
263#else
12e41d03 264 zclient->sock = zclient_socket_un (zclient_serv_path_get());
b5114685
VT
265#endif
266 return zclient->sock;
267}
268
634f9ea2 269static int
270zclient_failed(struct zclient *zclient)
271{
272 zclient->fail++;
273 zclient_stop(zclient);
274 zclient_event(ZCLIENT_CONNECT, zclient);
275 return -1;
276}
277
278static int
279zclient_flush_data(struct thread *thread)
280{
281 struct zclient *zclient = THREAD_ARG(thread);
282
283 zclient->t_write = NULL;
284 if (zclient->sock < 0)
285 return -1;
286 switch (buffer_flush_available(zclient->wb, zclient->sock))
287 {
288 case BUFFER_ERROR:
289 zlog_warn("%s: buffer_flush_available failed on zclient fd %d, closing",
290 __func__, zclient->sock);
291 return zclient_failed(zclient);
292 break;
293 case BUFFER_PENDING:
4140ca4d 294 zclient->t_write = thread_add_write(zclient->master, zclient_flush_data,
634f9ea2 295 zclient, zclient->sock);
296 break;
297 case BUFFER_EMPTY:
298 break;
299 }
300 return 0;
301}
302
718e3744 303int
634f9ea2 304zclient_send_message(struct zclient *zclient)
305{
306 if (zclient->sock < 0)
307 return -1;
308 switch (buffer_write(zclient->wb, zclient->sock, STREAM_DATA(zclient->obuf),
309 stream_get_endp(zclient->obuf)))
310 {
311 case BUFFER_ERROR:
312 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
313 __func__, zclient->sock);
314 return zclient_failed(zclient);
315 break;
316 case BUFFER_EMPTY:
317 THREAD_OFF(zclient->t_write);
318 break;
319 case BUFFER_PENDING:
4140ca4d 320 THREAD_WRITE_ON(zclient->master, zclient->t_write,
634f9ea2 321 zclient_flush_data, zclient, zclient->sock);
322 break;
323 }
324 return 0;
325}
326
d211086a 327void
7076bb2f 328zclient_create_header (struct stream *s, uint16_t command, vrf_id_t vrf_id)
c1b9800a 329{
330 /* length placeholder, caller can update */
331 stream_putw (s, ZEBRA_HEADER_SIZE);
332 stream_putc (s, ZEBRA_HEADER_MARKER);
333 stream_putc (s, ZSERV_VERSION);
7076bb2f 334 stream_putw (s, vrf_id);
c1b9800a 335 stream_putw (s, command);
336}
337
55119089
ND
338int
339zclient_read_header (struct stream *s, int sock, u_int16_t *size, u_char *marker,
e7a2870b 340 u_char *version, vrf_id_t *vrf_id, u_int16_t *cmd)
55119089
ND
341{
342 if (stream_read (s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
343 return -1;
344
345 *size = stream_getw (s) - ZEBRA_HEADER_SIZE;
346 *marker = stream_getc (s);
347 *version = stream_getc (s);
348 *vrf_id = stream_getw (s);
349 *cmd = stream_getw (s);
350
195dd232
DS
351 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER)
352 {
353 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
354 __func__, sock, *marker, *version);
355 return -1;
356 }
357
55119089
ND
358 if (*size && stream_read (s, sock, *size) != *size)
359 return -1;
360
361 return 0;
362}
363
634f9ea2 364/* Send simple Zebra message. */
365static int
7076bb2f 366zebra_message_send (struct zclient *zclient, int command, vrf_id_t vrf_id)
718e3744 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. */
7076bb2f 375 zclient_create_header (s, command, vrf_id);
c1b9800a 376
634f9ea2 377 return zclient_send_message(zclient);
718e3744 378}
379
2ea1ab1c
VT
380static int
381zebra_hello_send (struct zclient *zclient)
382{
383 struct stream *s;
384
385 if (zclient->redist_default)
386 {
387 s = zclient->obuf;
388 stream_reset (s);
389
7076bb2f
FL
390 /* The VRF ID in the HELLO message is always 0. */
391 zclient_create_header (s, ZEBRA_HELLO, VRF_DEFAULT);
2ea1ab1c 392 stream_putc (s, zclient->redist_default);
7c8ff89e 393 stream_putw (s, zclient->instance);
2ea1ab1c
VT
394 stream_putw_at (s, 0, stream_get_endp (s));
395 return zclient_send_message(zclient);
396 }
397
398 return 0;
399}
400
0e5223e7 401/* Send register requests to zebra daemon for the information in a VRF. */
7076bb2f 402void
0e5223e7 403zclient_send_reg_requests (struct zclient *zclient, vrf_id_t vrf_id)
7076bb2f
FL
404{
405 int i;
406 afi_t afi;
407
408 /* zclient is disabled. */
409 if (! zclient->enable)
410 return;
411
412 /* If not connected to the zebra yet. */
413 if (zclient->sock < 0)
414 return;
415
416 if (zclient_debug)
0e5223e7 417 zlog_debug ("%s: send register messages for VRF %u", __func__, vrf_id);
7076bb2f
FL
418
419 /* We need router-id information. */
420 zebra_message_send (zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
421
422 /* We need interface information. */
423 zebra_message_send (zclient, ZEBRA_INTERFACE_ADD, vrf_id);
424
425 /* Set unwanted redistribute route. */
426 for (afi = AFI_IP; afi < AFI_MAX; afi++)
427 vrf_bitmap_set (zclient->redist[afi][zclient->redist_default], vrf_id);
428
429 /* Flush all redistribute request. */
430 if (vrf_id == VRF_DEFAULT)
431 for (afi = AFI_IP; afi < AFI_MAX; afi++)
432 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
433 if (zclient->mi_redist[afi][i].enabled)
434 {
435 struct listnode *node;
436 u_short *id;
437
438 for (ALL_LIST_ELEMENTS_RO(zclient->mi_redist[afi][i].instances, node, id))
439 if (!(i == zclient->redist_default && *id == zclient->instance))
440 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, i,
441 *id, VRF_DEFAULT);
442 }
443
444 /* Flush all redistribute request. */
445 for (afi = AFI_IP; afi < AFI_MAX; afi++)
446 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
447 if (i != zclient->redist_default &&
448 vrf_bitmap_check (zclient->redist[afi][i], vrf_id))
449 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, i, 0, vrf_id);
450
451 /* If default information is needed. */
452 if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT))
453 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD, vrf_id);
454}
455
0e5223e7 456/* Send unregister requests to zebra daemon for the information in a VRF. */
457void
458zclient_send_dereg_requests (struct zclient *zclient, vrf_id_t vrf_id)
459{
460 int i;
461 afi_t afi;
462
463 /* zclient is disabled. */
464 if (! zclient->enable)
465 return;
466
467 /* If not connected to the zebra yet. */
468 if (zclient->sock < 0)
469 return;
470
471 if (zclient_debug)
472 zlog_debug ("%s: send deregister messages for VRF %u", __func__, vrf_id);
473
474 /* We need router-id information. */
475 zebra_message_send (zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
476
477 /* We need interface information. */
478 zebra_message_send (zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
479
480 /* Set unwanted redistribute route. */
481 for (afi = AFI_IP; afi < AFI_MAX; afi++)
482 vrf_bitmap_set (zclient->redist[afi][zclient->redist_default], 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 {
490 struct listnode *node;
491 u_short *id;
492
493 for (ALL_LIST_ELEMENTS_RO(zclient->mi_redist[afi][i].instances, node, id))
494 if (!(i == zclient->redist_default && *id == zclient->instance))
495 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, i,
496 *id, VRF_DEFAULT);
497 }
498
499 /* Flush all redistribute request. */
500 for (afi = AFI_IP; afi < AFI_MAX; afi++)
501 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
502 if (i != zclient->redist_default &&
503 vrf_bitmap_check (zclient->redist[afi][i], vrf_id))
504 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, i, 0, vrf_id);
505
506 /* If default information is needed. */
507 if (vrf_bitmap_check (zclient->default_information, VRF_DEFAULT))
508 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, vrf_id);
509}
510
4a04e5f7 511/* Send request to zebra daemon to start or stop RA. */
512void
513zclient_send_interface_radv_req (struct zclient *zclient, vrf_id_t vrf_id,
5c81b96a 514 struct interface *ifp, int enable, int ra_interval)
4a04e5f7 515{
516 struct stream *s;
517
518 /* zclient is disabled. */
519 if (!zclient->enable)
520 return;
521
522 /* If not connected to the zebra yet. */
523 if (zclient->sock < 0)
524 return;
525
526 /* Form and send message. */
527 s = zclient->obuf;
528 stream_reset (s);
529
530 if (enable)
531 zclient_create_header (s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
532 else
533 zclient_create_header (s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
534
535 stream_putl (s, ifp->ifindex);
5c81b96a 536 stream_putl (s, ra_interval);
4a04e5f7 537
538 stream_putw_at (s, 0, stream_get_endp (s));
539
540 zclient_send_message(zclient);
541}
542
718e3744 543/* Make connection to zebra daemon. */
544int
545zclient_start (struct zclient *zclient)
546{
7076bb2f
FL
547 if (zclient_debug)
548 zlog_info ("zclient_start is called");
549
550 /* zclient is disabled. */
551 if (! zclient->enable)
552 return 0;
718e3744 553
718e3744 554 /* If already connected to the zebra. */
555 if (zclient->sock >= 0)
556 return 0;
557
558 /* Check connect thread. */
559 if (zclient->t_connect)
560 return 0;
561
4ecc09d3
DS
562 /*
563 * If we fail to connect to the socket on initialization,
564 * Let's wait a second and see if we can reconnect.
565 * Cause if we don't connect, we never attempt to
566 * reconnect. On startup if zebra is slow we
567 * can get into this situation.
568 */
569 while (zclient_socket_connect(zclient) < 0 && zclient->fail < 5)
7076bb2f
FL
570 {
571 if (zclient_debug)
572 zlog_debug ("zclient connection fail");
573 zclient->fail++;
4ecc09d3
DS
574 sleep (1);
575 }
576
577 if (zclient->sock < 0)
578 {
7076bb2f
FL
579 zclient_event (ZCLIENT_CONNECT, zclient);
580 return -1;
581 }
718e3744 582
7076bb2f
FL
583 if (set_nonblocking(zclient->sock) < 0)
584 zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock);
718e3744 585
7076bb2f
FL
586 /* Clear fail count. */
587 zclient->fail = 0;
588 if (zclient_debug)
589 zlog_debug ("zclient connect success with socket [%d]", zclient->sock);
718e3744 590
7076bb2f
FL
591 /* Create read thread. */
592 zclient_event (ZCLIENT_READ, zclient);
718e3744 593
7076bb2f 594 zebra_hello_send (zclient);
718e3744 595
7076bb2f
FL
596 /* Inform the successful connection. */
597 if (zclient->zebra_connected)
598 (*zclient->zebra_connected) (zclient);
718e3744 599
7076bb2f 600 return 0;
718e3744 601}
6b0655a2 602
078430f6
DS
603/* Initialize zebra client. Argument redist_default is unwanted
604 redistribute route type. */
605void
606zclient_init (struct zclient *zclient, int redist_default, u_short instance)
607{
608 int afi, i;
609
610 /* Enable zebra client connection by default. */
611 zclient->enable = 1;
612
613 /* Set -1 to the default socket value. */
614 zclient->sock = -1;
615
616 /* Clear redistribution flags. */
617 for (afi = AFI_IP; afi < AFI_MAX; afi++)
618 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
7076bb2f 619 zclient->redist[afi][i] = vrf_bitmap_init();
078430f6
DS
620
621 /* Set unwanted redistribute route. bgpd does not need BGP route
622 redistribution. */
623 zclient->redist_default = redist_default;
624 zclient->instance = instance;
625 /* Pending: make afi(s) an arg. */
626 for (afi = AFI_IP; afi < AFI_MAX; afi++)
7076bb2f 627 redist_add_instance (&zclient->mi_redist[afi][redist_default], instance);
078430f6
DS
628
629 /* Set default-information redistribute to zero. */
7076bb2f 630 zclient->default_information = vrf_bitmap_init ();;
078430f6
DS
631
632 if (zclient_debug)
633 zlog_debug ("zclient_start is called");
634
7076bb2f
FL
635 zclient_event (ZCLIENT_SCHEDULE, zclient);
636}
078430f6 637
7076bb2f
FL
638/* This function is a wrapper function for calling zclient_start from
639 timer or event thread. */
640static int
641zclient_connect (struct thread *t)
642{
643 struct zclient *zclient;
078430f6 644
7076bb2f
FL
645 zclient = THREAD_ARG (t);
646 zclient->t_connect = NULL;
078430f6 647
078430f6 648 if (zclient_debug)
7076bb2f 649 zlog_debug ("zclient_connect is called");
078430f6 650
7076bb2f 651 return zclient_start (zclient);
078430f6
DS
652}
653
0a589359 654 /*
655 * "xdr_encode"-like interface that allows daemon (client) to send
656 * a message to zebra server for a route that needs to be
657 * added/deleted to the kernel. Info about the route is specified
658 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
659 * the info down the zclient socket using the stream_* functions.
660 *
661 * The corresponding read ("xdr_decode") function on the server
662 * side is zread_ipv4_add()/zread_ipv4_delete().
663 *
664 * 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
665 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
666 * | Length (2) | Command | Route Type |
667 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
668 * | ZEBRA Flags | Message Flags | Prefix length |
669 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
670 * | Destination IPv4 Prefix for route |
671 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
672 * | Nexthop count |
673 * +-+-+-+-+-+-+-+-+
674 *
675 *
676 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
677 * described, as per the Nexthop count. Each nexthop described as:
678 *
679 * +-+-+-+-+-+-+-+-+
680 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
681 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
682 * | IPv4 Nexthop address or Interface Index number |
683 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
684 *
685 * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or
686 * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_
687 * nexthop information is provided, and the message describes a prefix
688 * to blackhole or reject route.
689 *
c8a1cb5c
DS
690 * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
691 * infrastructure was built around the traditional (32-bit "gate OR
692 * ifindex") nexthop data unit. A special encoding can be used to feed
693 * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
694 * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
695 * fields as follows:
696 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
697 * - .nexthop_num == .ifindex_num
698 * - .nexthop and .ifindex are filled with gate and ifindex parts of
699 * each compound nexthop, both in the same order
700 *
701 * zapi_ipv4_route() will produce two nexthop data units for each such
702 * interleaved 64-bit nexthop. On the zserv side of the socket it will be
703 * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
704 *
0a589359 705 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
706 * byte value.
707 *
708 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
709 * byte value.
710 *
0d9551dc
DS
711 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 2 byte value
712 *
c50ca33a
TT
713 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
714 *
0a589359 715 * XXX: No attention paid to alignment.
716 */
718e3744 717int
0a589359 718zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
719 struct zapi_ipv4 *api)
718e3744 720{
721 int i;
722 int psize;
723 struct stream *s;
724
725 /* Reset stream. */
726 s = zclient->obuf;
727 stream_reset (s);
7076bb2f
FL
728
729 zclient_create_header (s, cmd, api->vrf_id);
c1b9800a 730
731 /* Put type and nexthop. */
718e3744 732 stream_putc (s, api->type);
7c8ff89e 733 stream_putw (s, api->instance);
718e3744 734 stream_putc (s, api->flags);
735 stream_putc (s, api->message);
5a616c08 736 stream_putw (s, api->safi);
718e3744 737
718e3744 738 /* Put prefix information. */
739 psize = PSIZE (p->prefixlen);
740 stream_putc (s, p->prefixlen);
0a589359 741 stream_write (s, (u_char *) & p->prefix, psize);
718e3744 742
743 /* Nexthop, ifindex, distance and metric information. */
d44ca835 744 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
c8a1cb5c
DS
745 {
746 /* traditional 32-bit data units */
595db7f1 747 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
748 {
749 stream_putc (s, 1);
5b30316e 750 stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
0a589359 751 /* XXX assert(api->nexthop_num == 0); */
752 /* XXX assert(api->ifindex_num == 0); */
595db7f1 753 }
754 else
755 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 756
757 for (i = 0; i < api->nexthop_num; i++)
595db7f1 758 {
5b30316e 759 stream_putc (s, NEXTHOP_TYPE_IPV4);
595db7f1 760 stream_put_in_addr (s, api->nexthop[i]);
761 }
718e3744 762 for (i = 0; i < api->ifindex_num; i++)
595db7f1 763 {
5b30316e 764 stream_putc (s, NEXTHOP_TYPE_IFINDEX);
595db7f1 765 stream_putl (s, api->ifindex[i]);
766 }
718e3744 767 }
768
769 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
770 stream_putc (s, api->distance);
771 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
772 stream_putl (s, api->metric);
0d9551dc
DS
773 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
774 stream_putw (s, api->tag);
c50ca33a
TT
775 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
776 stream_putl (s, api->mtu);
718e3744 777
778 /* Put length at the first point of the stream. */
779 stream_putw_at (s, 0, stream_get_endp (s));
780
634f9ea2 781 return zclient_send_message(zclient);
718e3744 782}
783
784#ifdef HAVE_IPV6
8a92a8a0
DS
785int
786zapi_ipv4_route_ipv6_nexthop (u_char cmd, struct zclient *zclient,
787 struct prefix_ipv4 *p, struct zapi_ipv6 *api)
788{
789 int i;
790 int psize;
791 struct stream *s;
792
793 /* Reset stream. */
794 s = zclient->obuf;
795 stream_reset (s);
796
7076bb2f 797 zclient_create_header (s, cmd, api->vrf_id);
8a92a8a0
DS
798
799 /* Put type and nexthop. */
800 stream_putc (s, api->type);
801 stream_putw (s, api->instance);
802 stream_putc (s, api->flags);
803 stream_putc (s, api->message);
804 stream_putw (s, api->safi);
805
806 /* Put prefix information. */
807 psize = PSIZE (p->prefixlen);
808 stream_putc (s, p->prefixlen);
809 stream_write (s, (u_char *) & p->prefix, psize);
810
811 /* Nexthop, ifindex, distance and metric information. */
812 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
813 {
814 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
815 {
816 stream_putc (s, 1);
5b30316e 817 stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
8a92a8a0
DS
818 /* XXX assert(api->nexthop_num == 0); */
819 /* XXX assert(api->ifindex_num == 0); */
820 }
821 else
822 stream_putc (s, api->nexthop_num + api->ifindex_num);
823
824 for (i = 0; i < api->nexthop_num; i++)
825 {
5b30316e 826 stream_putc (s, NEXTHOP_TYPE_IPV6);
8a92a8a0
DS
827 stream_write (s, (u_char *)api->nexthop[i], 16);
828 }
829 for (i = 0; i < api->ifindex_num; i++)
830 {
5b30316e 831 stream_putc (s, NEXTHOP_TYPE_IFINDEX);
8a92a8a0
DS
832 stream_putl (s, api->ifindex[i]);
833 }
834 }
835
836 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
837 stream_putc (s, api->distance);
838 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
839 stream_putl (s, api->metric);
840 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
841 stream_putw (s, api->tag);
c50ca33a
TT
842 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
843 stream_putl (s, api->mtu);
8a92a8a0
DS
844
845 /* Put length at the first point of the stream. */
846 stream_putw_at (s, 0, stream_get_endp (s));
847
848 return zclient_send_message(zclient);
849}
850
718e3744 851int
0a589359 852zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
718e3744 853 struct zapi_ipv6 *api)
854{
855 int i;
856 int psize;
857 struct stream *s;
858
859 /* Reset stream. */
860 s = zclient->obuf;
861 stream_reset (s);
862
7076bb2f 863 zclient_create_header (s, cmd, api->vrf_id);
718e3744 864
c1b9800a 865 /* Put type and nexthop. */
718e3744 866 stream_putc (s, api->type);
7c8ff89e 867 stream_putw (s, api->instance);
718e3744 868 stream_putc (s, api->flags);
869 stream_putc (s, api->message);
c7ec179a 870 stream_putw (s, api->safi);
718e3744 871
872 /* Put prefix information. */
873 psize = PSIZE (p->prefixlen);
874 stream_putc (s, p->prefixlen);
875 stream_write (s, (u_char *)&p->prefix, psize);
876
877 /* Nexthop, ifindex, distance and metric information. */
878 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
879 {
c3c0ac83
DS
880 if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
881 {
882 stream_putc (s, 1);
5b30316e 883 stream_putc (s, NEXTHOP_TYPE_BLACKHOLE);
c3c0ac83
DS
884 /* XXX assert(api->nexthop_num == 0); */
885 /* XXX assert(api->ifindex_num == 0); */
886 }
887 else
888 stream_putc (s, api->nexthop_num + api->ifindex_num);
718e3744 889
890 for (i = 0; i < api->nexthop_num; i++)
891 {
5b30316e 892 stream_putc (s, NEXTHOP_TYPE_IPV6);
718e3744 893 stream_write (s, (u_char *)api->nexthop[i], 16);
894 }
895 for (i = 0; i < api->ifindex_num; i++)
896 {
5b30316e 897 stream_putc (s, NEXTHOP_TYPE_IFINDEX);
718e3744 898 stream_putl (s, api->ifindex[i]);
899 }
900 }
901
902 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
903 stream_putc (s, api->distance);
904 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
905 stream_putl (s, api->metric);
0d9551dc
DS
906 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_TAG))
907 stream_putw (s, api->tag);
c50ca33a
TT
908 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_MTU))
909 stream_putl (s, api->mtu);
718e3744 910
911 /* Put length at the first point of the stream. */
912 stream_putw_at (s, 0, stream_get_endp (s));
913
634f9ea2 914 return zclient_send_message(zclient);
718e3744 915}
718e3744 916#endif /* HAVE_IPV6 */
917
0a589359 918/*
919 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
920 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
921 * then set/unset redist[type] in the client handle (a struct zserv) for the
922 * sending client
923 */
718e3744 924int
8bb0831e 925zebra_redistribute_send (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 926 u_short instance, vrf_id_t vrf_id)
718e3744 927{
718e3744 928 struct stream *s;
929
634f9ea2 930 s = zclient->obuf;
931 stream_reset(s);
718e3744 932
7076bb2f 933 zclient_create_header (s, command, vrf_id);
8bb0831e 934 stream_putc (s, afi);
718e3744 935 stream_putc (s, type);
7c8ff89e 936 stream_putw (s, instance);
c1b9800a 937
938 stream_putw_at (s, 0, stream_get_endp (s));
939
634f9ea2 940 return zclient_send_message(zclient);
718e3744 941}
942
18a6dce6 943/* Router-id update from zebra daemon. */
944void
945zebra_router_id_update_read (struct stream *s, struct prefix *rid)
946{
947 int plen;
948
949 /* Fetch interface address. */
950 rid->family = stream_getc (s);
951
952 plen = prefix_blen (rid);
953 stream_get (&rid->u.prefix, s, plen);
954 rid->prefixlen = stream_getc (s);
955}
956
718e3744 957/* Interface addition from zebra daemon. */
0a589359 958/*
959 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
960 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
961 * 0 1 2 3
962 * 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
0a589359 963 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
964 * | ifname |
965 * | |
966 * | |
967 * | |
968 * | |
969 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
970 * | ifindex |
971 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
972 * | status |
0a589359 973 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 974 * | if_flags |
c77d4546 975 * | |
0a589359 976 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
977 * | metric |
978 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
979 * | ifmtu |
980 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
981 * | ifmtu6 |
982 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
983 * | bandwidth |
984 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
985 * | Link Layer Type |
0a589359 986 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 987 * | Harware Address Length |
0a589359 988 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
989 * | Hardware Address if HW lenght different from 0 |
990 * | ... max INTERFACE_HWADDR_MAX |
0a589359 991 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 992 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 993 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
994 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
995 * | .... (struct if_link_params). |
0a589359 996 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
997 */
998
2fcc254e 999static void
ebe32f70 1000zclient_vrf_add (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1001{
1002 struct vrf *vrf;
1003 char vrfname_tmp[VRF_NAMSIZ];
1004
1005 /* Read interface name. */
ebe32f70 1006 stream_get (vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e
DS
1007
1008 /* Lookup/create vrf by vrf_id. */
1009 vrf = vrf_get (vrf_id, vrfname_tmp);
1010
2fcc254e 1011 vrf_enable (vrf);
1892f15e
DS
1012}
1013
2fcc254e 1014static void
ebe32f70 1015zclient_vrf_delete (struct zclient *zclient, vrf_id_t vrf_id)
1892f15e
DS
1016{
1017 struct vrf *vrf;
1018
1019 /* Lookup vrf by vrf_id. */
1020 vrf = vrf_lookup (vrf_id);
1021
beef1990
DS
1022 /*
1023 * If a routing protocol doesn't know about a
1024 * vrf that is about to be deleted. There is
1025 * no point in attempting to delete it.
1026 */
1027 if (!vrf)
1028 return;
1029
2fcc254e 1030 vrf_delete (vrf);
1892f15e
DS
1031}
1032
718e3744 1033struct interface *
7076bb2f 1034zebra_interface_add_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1035{
1036 struct interface *ifp;
02ff83c5 1037 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1038
1039 /* Read interface name. */
1040 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1041
a349198f 1042 /* Lookup/create interface by name. */
7076bb2f
FL
1043 ifp = if_get_by_name_len_vrf (ifname_tmp,
1044 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
85f9da7f 1045 vrf_id, 0);
718e3744 1046
51d4ef83 1047 zebra_interface_if_set_value (s, ifp);
718e3744 1048
718e3744 1049 return ifp;
1050}
1051
0a589359 1052/*
1053 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1054 * from zebra server. The format of this message is the same as
1055 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1056 * comments for zebra_interface_add_read), except that no sockaddr_dl
1057 * is sent at the tail of the message.
1058 */
718e3744 1059struct interface *
7076bb2f 1060zebra_interface_state_read (struct stream *s, vrf_id_t vrf_id)
718e3744 1061{
1062 struct interface *ifp;
02ff83c5 1063 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1064
1065 /* Read interface name. */
1066 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
1067
1068 /* Lookup this by interface index. */
7076bb2f
FL
1069 ifp = if_lookup_by_name_len_vrf (ifname_tmp,
1070 strnlen (ifname_tmp, INTERFACE_NAMSIZ),
1071 vrf_id);
b4dd5eaa 1072 if (ifp == NULL)
1073 {
1074 zlog_warn ("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1075 ifname_tmp, vrf_id);
1076 return NULL;
1077 }
718e3744 1078
51d4ef83 1079 zebra_interface_if_set_value (s, ifp);
718e3744 1080
1081 return ifp;
1082}
1083
16f1b9ee
OD
1084static void
1085link_params_set_value(struct stream *s, struct if_link_params *iflp)
1086{
1087
1088 if (iflp == NULL)
1089 return;
1090
1091 iflp->lp_status = stream_getl (s);
1092 iflp->te_metric = stream_getl (s);
1093 iflp->max_bw = stream_getf (s);
1094 iflp->max_rsv_bw = stream_getf (s);
1095 uint32_t bwclassnum = stream_getl (s);
1096 {
1097 unsigned int i;
1098 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1099 iflp->unrsv_bw[i] = stream_getf (s);
1100 if (i < bwclassnum)
1101 zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1102 " - outdated library?",
1103 __func__, bwclassnum, MAX_CLASS_TYPE);
1104 }
1105 iflp->admin_grp = stream_getl (s);
1106 iflp->rmt_as = stream_getl (s);
1107 iflp->rmt_ip.s_addr = stream_get_ipv4 (s);
1108
1109 iflp->av_delay = stream_getl (s);
1110 iflp->min_delay = stream_getl (s);
1111 iflp->max_delay = stream_getl (s);
1112 iflp->delay_var = stream_getl (s);
1113
1114 iflp->pkt_loss = stream_getf (s);
1115 iflp->res_bw = stream_getf (s);
1116 iflp->ava_bw = stream_getf (s);
1117 iflp->use_bw = stream_getf (s);
1118}
1119
1120struct interface *
1121zebra_interface_link_params_read (struct stream *s)
1122{
1123 struct if_link_params *iflp;
1124 uint32_t ifindex = stream_getl (s);
1125
1126 struct interface *ifp = if_lookup_by_index (ifindex);
1127
1128 if (ifp == NULL || s == NULL)
1129 {
1130 zlog_err ("%s: unknown ifindex %u, shouldn't happen",
1131 __func__, ifindex);
1132 return NULL;
1133 }
1134
1135 if ((iflp = if_link_params_get (ifp)) == NULL)
1136 return NULL;
1137
1138 link_params_set_value(s, iflp);
1139
1140 return ifp;
1141}
1142
1143void
1144zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
1145{
1146 u_char link_params_status = 0;
1147
1148 /* Read interface's index. */
1149 ifp->ifindex = stream_getl (s);
1150 ifp->status = stream_getc (s);
1151
1152 /* Read interface's value. */
1153 ifp->flags = stream_getq (s);
1154 ifp->ptm_enable = stream_getc (s);
1155 ifp->ptm_status = stream_getc (s);
1156 ifp->metric = stream_getl (s);
1157 ifp->mtu = stream_getl (s);
1158 ifp->mtu6 = stream_getl (s);
1159 ifp->bandwidth = stream_getl (s);
1160 ifp->ll_type = stream_getl (s);
1161 ifp->hw_addr_len = stream_getl (s);
1162 if (ifp->hw_addr_len)
1163 stream_get (ifp->hw_addr, s, MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1164
1165 /* Read Traffic Engineering status */
1166 link_params_status = stream_getc (s);
1167 /* Then, Traffic Engineering parameters if any */
1168 if (link_params_status)
1169 {
1170 struct if_link_params *iflp = if_link_params_get (ifp);
1171 link_params_set_value(s, iflp);
1172 }
1173}
1174
1175size_t
1176zebra_interface_link_params_write (struct stream *s, struct interface *ifp)
1177{
1178 size_t w;
1179 struct if_link_params *iflp;
1180 int i;
1181
1182 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1183 return 0;
1184
1185 iflp = ifp->link_params;
1186 w = 0;
1187
1188 w += stream_putl (s, iflp->lp_status);
1189
1190 w += stream_putl (s, iflp->te_metric);
1191 w += stream_putf (s, iflp->max_bw);
1192 w += stream_putf (s, iflp->max_rsv_bw);
1193
1194 w += stream_putl (s, MAX_CLASS_TYPE);
1195 for (i = 0; i < MAX_CLASS_TYPE; i++)
1196 w += stream_putf (s, iflp->unrsv_bw[i]);
1197
1198 w += stream_putl (s, iflp->admin_grp);
1199 w += stream_putl (s, iflp->rmt_as);
1200 w += stream_put_in_addr (s, &iflp->rmt_ip);
1201
1202 w += stream_putl (s, iflp->av_delay);
1203 w += stream_putl (s, iflp->min_delay);
1204 w += stream_putl (s, iflp->max_delay);
1205 w += stream_putl (s, iflp->delay_var);
1206
1207 w += stream_putf (s, iflp->pkt_loss);
1208 w += stream_putf (s, iflp->res_bw);
1209 w += stream_putf (s, iflp->ava_bw);
1210 w += stream_putf (s, iflp->use_bw);
1211
1212 return w;
1213}
1214
1215/*
0a589359 1216 * format of message for address additon is:
1217 * 0
1218 * 0 1 2 3 4 5 6 7
1219 * +-+-+-+-+-+-+-+-+
1220 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1221 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1222 * | |
1223 * + +
1224 * | ifindex |
1225 * + +
1226 * | |
1227 * + +
1228 * | |
1229 * +-+-+-+-+-+-+-+-+
1230 * | ifc_flags | flags for connected address
1231 * +-+-+-+-+-+-+-+-+
1232 * | addr_family |
1233 * +-+-+-+-+-+-+-+-+
1234 * | addr... |
1235 * : :
1236 * | |
1237 * +-+-+-+-+-+-+-+-+
1238 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1239 * +-+-+-+-+-+-+-+-+
1240 * | daddr.. |
1241 * : :
1242 * | |
1243 * +-+-+-+-+-+-+-+-+
0a589359 1244 */
1245
3fb9cd6e 1246static int
1247memconstant(const void *s, int c, size_t n)
1248{
1249 const u_char *p = s;
1250
1251 while (n-- > 0)
1252 if (*p++ != c)
1253 return 0;
1254 return 1;
1255}
1256
d5a5c8f0 1257
718e3744 1258struct connected *
7076bb2f 1259zebra_interface_address_read (int type, struct stream *s, vrf_id_t vrf_id)
718e3744 1260{
b892f1dd 1261 ifindex_t ifindex;
718e3744 1262 struct interface *ifp;
1263 struct connected *ifc;
0a589359 1264 struct prefix p, d;
718e3744 1265 int family;
1266 int plen;
0a589359 1267 u_char ifc_flags;
718e3744 1268
0a589359 1269 memset (&p, 0, sizeof(p));
1270 memset (&d, 0, sizeof(d));
718e3744 1271
1272 /* Get interface index. */
1273 ifindex = stream_getl (s);
1274
1275 /* Lookup index. */
7076bb2f 1276 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
718e3744 1277 if (ifp == NULL)
1278 {
b4dd5eaa 1279 zlog_warn ("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1280 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1281 ifindex, vrf_id);
718e3744 1282 return NULL;
1283 }
1284
1285 /* Fetch flag. */
0a589359 1286 ifc_flags = stream_getc (s);
718e3744 1287
1288 /* Fetch interface address. */
1289 family = p.family = stream_getc (s);
1290
0a589359 1291 plen = prefix_blen (&p);
1292 stream_get (&p.u.prefix, s, plen);
718e3744 1293 p.prefixlen = stream_getc (s);
1294
1295 /* Fetch destination address. */
0a589359 1296 stream_get (&d.u.prefix, s, plen);
718e3744 1297 d.family = family;
1298
0a589359 1299 if (type == ZEBRA_INTERFACE_ADDRESS_ADD)
1300 {
38485402
DS
1301 ifc = connected_lookup_prefix_exact (ifp, &p);
1302 if (!ifc)
1303 {
1304 /* N.B. NULL destination pointers are encoded as all zeroes */
1305 ifc = connected_add_by_prefix(ifp, &p, (memconstant(&d.u.prefix,0,plen) ?
1306 NULL : &d));
1307 }
1308 if (ifc)
e4529636
AS
1309 {
1310 ifc->flags = ifc_flags;
1311 if (ifc->destination)
1312 ifc->destination->prefixlen = ifc->address->prefixlen;
90444ca3
DL
1313 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
1314 {
1315 /* carp interfaces on OpenBSD with 0.0.0.0/0 as "peer" */
855110bb 1316 char buf[PREFIX_STRLEN];
90444ca3
DL
1317 zlog_warn("warning: interface %s address %s "
1318 "with peer flag set, but no peer address!",
855110bb
TT
1319 ifp->name,
1320 prefix2str (ifc->address, buf, sizeof buf));
90444ca3
DL
1321 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1322 }
e4529636 1323 }
0a589359 1324 }
1325 else
1326 {
1327 assert (type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1328 ifc = connected_delete_by_prefix(ifp, &p);
1329 }
718e3744 1330
1331 return ifc;
1332}
0a589359 1333
a80beece
DS
1334/*
1335 * format of message for neighbor connected address is:
1336 * 0
1337 * 0 1 2 3 4 5 6 7
1338 * +-+-+-+-+-+-+-+-+
1339 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1340 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1341 * | |
1342 * + +
1343 * | ifindex |
1344 * + +
1345 * | |
1346 * + +
1347 * | |
1348 * +-+-+-+-+-+-+-+-+
1349 * | addr_family |
1350 * +-+-+-+-+-+-+-+-+
1351 * | addr... |
1352 * : :
1353 * | |
1354 * +-+-+-+-+-+-+-+-+
1355 * | addr_len | len of addr.
1356 * +-+-+-+-+-+-+-+-+
1357 */
1358struct nbr_connected *
7076bb2f 1359zebra_interface_nbr_address_read (int type, struct stream *s, vrf_id_t vrf_id)
a80beece
DS
1360{
1361 unsigned int ifindex;
1362 struct interface *ifp;
1363 struct prefix p;
1364 struct nbr_connected *ifc;
1365
1366 /* Get interface index. */
1367 ifindex = stream_getl (s);
1368
1369 /* Lookup index. */
f1aa3df6 1370 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
a80beece
DS
1371 if (ifp == NULL)
1372 {
f1aa3df6 1373 zlog_warn ("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1374 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD" : "DELETE",
1375 ifindex, vrf_id);
a80beece
DS
1376 return NULL;
1377 }
1378
1379 p.family = stream_getc (s);
1380 stream_get (&p.u.prefix, s, prefix_blen (&p));
1381 p.prefixlen = stream_getc (s);
1382
1383 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD)
1384 {
1385 /* Currently only supporting P2P links, so any new RA source address is
1386 considered as the replacement of the previously learnt Link-Local address. */
1387 if (!(ifc = listnode_head(ifp->nbr_connected)))
1388 {
1389 ifc = nbr_connected_new ();
1390 ifc->address = prefix_new ();
1391 ifc->ifp = ifp;
1392 listnode_add (ifp->nbr_connected, ifc);
1393 }
1394
1395 prefix_copy(ifc->address, &p);
1396 }
1397 else
1398 {
1399 assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1400
1401 ifc = nbr_connected_check(ifp, &p);
1402 if (ifc)
1403 listnode_delete (ifp->nbr_connected, ifc);
1404 }
1405
1406 return ifc;
1407}
6b0655a2 1408
c8e264b6 1409struct interface *
1410zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
1411 vrf_id_t *new_vrf_id)
1412{
1413 unsigned int ifindex;
1414 struct interface *ifp;
1415 vrf_id_t new_id = VRF_DEFAULT;
1416
1417 /* Get interface index. */
1418 ifindex = stream_getl (s);
1419
1420 /* Lookup interface. */
1421 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
1422 if (ifp == NULL)
1423 {
1424 zlog_warn ("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1425 ifindex, vrf_id);
1426 return NULL;
1427 }
1428
1429 /* Fetch new VRF Id. */
1430 new_id = stream_getw (s);
1431
1432 *new_vrf_id = new_id;
1433 return ifp;
1434}
1435
718e3744 1436/* Zebra client message read function. */
634f9ea2 1437static int
718e3744 1438zclient_read (struct thread *thread)
1439{
634f9ea2 1440 size_t already;
c1b9800a 1441 uint16_t length, command;
1442 uint8_t marker, version;
7076bb2f 1443 vrf_id_t vrf_id;
718e3744 1444 struct zclient *zclient;
1445
1446 /* Get socket to zebra. */
718e3744 1447 zclient = THREAD_ARG (thread);
1448 zclient->t_read = NULL;
1449
634f9ea2 1450 /* Read zebra header (if we don't have it already). */
1451 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE)
718e3744 1452 {
634f9ea2 1453 ssize_t nbyte;
1454 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1455 ZEBRA_HEADER_SIZE-already)) == 0) ||
1456 (nbyte == -1))
1457 {
1458 if (zclient_debug)
1459 zlog_debug ("zclient connection closed socket [%d].", zclient->sock);
1460 return zclient_failed(zclient);
1461 }
1462 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already))
1463 {
1464 /* Try again later. */
1465 zclient_event (ZCLIENT_READ, zclient);
1466 return 0;
1467 }
1468 already = ZEBRA_HEADER_SIZE;
718e3744 1469 }
1470
634f9ea2 1471 /* Reset to read from the beginning of the incoming packet. */
1472 stream_set_getp(zclient->ibuf, 0);
718e3744 1473
c1b9800a 1474 /* Fetch header values. */
718e3744 1475 length = stream_getw (zclient->ibuf);
c1b9800a 1476 marker = stream_getc (zclient->ibuf);
1477 version = stream_getc (zclient->ibuf);
7076bb2f 1478 vrf_id = stream_getw (zclient->ibuf);
c1b9800a 1479 command = stream_getw (zclient->ibuf);
1480
1481 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
1482 {
1483 zlog_err("%s: socket %d version mismatch, marker %d, version %d",
1484 __func__, zclient->sock, marker, version);
1485 return zclient_failed(zclient);
1486 }
1487
634f9ea2 1488 if (length < ZEBRA_HEADER_SIZE)
1489 {
1490 zlog_err("%s: socket %d message length %u is less than %d ",
1491 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
1492 return zclient_failed(zclient);
1493 }
1494
718e3744 1495 /* Length check. */
634f9ea2 1496 if (length > STREAM_SIZE(zclient->ibuf))
718e3744 1497 {
634f9ea2 1498 struct stream *ns;
1499 zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...",
1500 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
1501 ns = stream_new(length);
1502 stream_copy(ns, zclient->ibuf);
718e3744 1503 stream_free (zclient->ibuf);
634f9ea2 1504 zclient->ibuf = ns;
718e3744 1505 }
718e3744 1506
1507 /* Read rest of zebra packet. */
634f9ea2 1508 if (already < length)
1509 {
1510 ssize_t nbyte;
1511 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
1512 length-already)) == 0) ||
1513 (nbyte == -1))
1514 {
1515 if (zclient_debug)
1516 zlog_debug("zclient connection closed socket [%d].", zclient->sock);
1517 return zclient_failed(zclient);
1518 }
1519 if (nbyte != (ssize_t)(length-already))
1520 {
1521 /* Try again later. */
1522 zclient_event (ZCLIENT_READ, zclient);
1523 return 0;
1524 }
1525 }
1526
1527 length -= ZEBRA_HEADER_SIZE;
718e3744 1528
0a589359 1529 if (zclient_debug)
7076bb2f 1530 zlog_debug("zclient 0x%p command 0x%x VRF %u\n", (void *)zclient, command, vrf_id);
0a589359 1531
718e3744 1532 switch (command)
1533 {
18a6dce6 1534 case ZEBRA_ROUTER_ID_UPDATE:
1535 if (zclient->router_id_update)
7076bb2f 1536 (*zclient->router_id_update) (command, zclient, length, vrf_id);
18a6dce6 1537 break;
1892f15e 1538 case ZEBRA_VRF_ADD:
ebe32f70 1539 zclient_vrf_add (zclient, vrf_id);
1892f15e
DS
1540 break;
1541 case ZEBRA_VRF_DELETE:
ebe32f70 1542 zclient_vrf_delete (zclient, vrf_id);
1892f15e 1543 break;
718e3744 1544 case ZEBRA_INTERFACE_ADD:
1545 if (zclient->interface_add)
7076bb2f 1546 (*zclient->interface_add) (command, zclient, length, vrf_id);
718e3744 1547 break;
1548 case ZEBRA_INTERFACE_DELETE:
1549 if (zclient->interface_delete)
7076bb2f 1550 (*zclient->interface_delete) (command, zclient, length, vrf_id);
718e3744 1551 break;
1552 case ZEBRA_INTERFACE_ADDRESS_ADD:
1553 if (zclient->interface_address_add)
7076bb2f 1554 (*zclient->interface_address_add) (command, zclient, length, vrf_id);
718e3744 1555 break;
1556 case ZEBRA_INTERFACE_ADDRESS_DELETE:
1557 if (zclient->interface_address_delete)
7076bb2f 1558 (*zclient->interface_address_delete) (command, zclient, length, vrf_id);
718e3744 1559 break;
68fe91d6 1560 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
1561 if (zclient->interface_bfd_dest_update)
7076bb2f 1562 (*zclient->interface_bfd_dest_update) (command, zclient, length, vrf_id);
d5a5c8f0 1563 break;
a80beece
DS
1564 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
1565 if (zclient->interface_nbr_address_add)
7076bb2f 1566 (*zclient->interface_nbr_address_add) (command, zclient, length, vrf_id);
a80beece
DS
1567 break;
1568 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
1569 if (zclient->interface_nbr_address_delete)
7076bb2f 1570 (*zclient->interface_nbr_address_delete) (command, zclient, length, vrf_id);
a80beece 1571 break;
718e3744 1572 case ZEBRA_INTERFACE_UP:
1573 if (zclient->interface_up)
7076bb2f 1574 (*zclient->interface_up) (command, zclient, length, vrf_id);
718e3744 1575 break;
1576 case ZEBRA_INTERFACE_DOWN:
1577 if (zclient->interface_down)
7076bb2f 1578 (*zclient->interface_down) (command, zclient, length, vrf_id);
c8e264b6 1579 break;
1580 case ZEBRA_INTERFACE_VRF_UPDATE:
1581 if (zclient->interface_vrf_update)
1582 (*zclient->interface_vrf_update) (command, zclient, length, vrf_id);
718e3744 1583 break;
1584 case ZEBRA_IPV4_ROUTE_ADD:
1585 if (zclient->ipv4_route_add)
7076bb2f 1586 (*zclient->ipv4_route_add) (command, zclient, length, vrf_id);
718e3744 1587 break;
1588 case ZEBRA_IPV4_ROUTE_DELETE:
1589 if (zclient->ipv4_route_delete)
7076bb2f 1590 (*zclient->ipv4_route_delete) (command, zclient, length, vrf_id);
718e3744 1591 break;
1592 case ZEBRA_IPV6_ROUTE_ADD:
1593 if (zclient->ipv6_route_add)
7076bb2f 1594 (*zclient->ipv6_route_add) (command, zclient, length, vrf_id);
718e3744 1595 break;
1596 case ZEBRA_IPV6_ROUTE_DELETE:
1597 if (zclient->ipv6_route_delete)
7076bb2f 1598 (*zclient->ipv6_route_delete) (command, zclient, length, vrf_id);
718e3744 1599 break;
fb018d25
DS
1600 case ZEBRA_NEXTHOP_UPDATE:
1601 if (zclient_debug)
1602 zlog_debug("zclient rcvd nexthop update\n");
1603 if (zclient->nexthop_update)
7076bb2f 1604 (*zclient->nexthop_update) (command, zclient, length, vrf_id);
fb018d25 1605 break;
078430f6
DS
1606 case ZEBRA_IMPORT_CHECK_UPDATE:
1607 if (zclient_debug)
1608 zlog_debug("zclient rcvd import check update\n");
1609 if (zclient->import_check_update)
7076bb2f 1610 (*zclient->import_check_update) (command, zclient, length, vrf_id);
078430f6 1611 break;
c43ed2e4
DS
1612 case ZEBRA_BFD_DEST_REPLAY:
1613 if (zclient->bfd_dest_replay)
7076bb2f 1614 (*zclient->bfd_dest_replay) (command, zclient, length, vrf_id);
c43ed2e4 1615 break;
5048fe14 1616 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
1617 if (zclient->redistribute_route_ipv4_add)
7076bb2f 1618 (*zclient->redistribute_route_ipv4_add) (command, zclient, length, vrf_id);
5048fe14 1619 break;
1620 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
1621 if (zclient->redistribute_route_ipv4_del)
7076bb2f 1622 (*zclient->redistribute_route_ipv4_del) (command, zclient, length, vrf_id);
5048fe14 1623 break;
1624 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
1625 if (zclient->redistribute_route_ipv6_add)
7076bb2f 1626 (*zclient->redistribute_route_ipv6_add) (command, zclient, length, vrf_id);
5048fe14 1627 break;
1628 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
1629 if (zclient->redistribute_route_ipv6_del)
7076bb2f 1630 (*zclient->redistribute_route_ipv6_del) (command, zclient, length, vrf_id);
16f1b9ee
OD
1631 case ZEBRA_INTERFACE_LINK_PARAMS:
1632 if (zclient->interface_link_params)
1633 (*zclient->interface_link_params) (command, zclient, length);
5048fe14 1634 break;
718e3744 1635 default:
1636 break;
1637 }
1638
634f9ea2 1639 if (zclient->sock < 0)
1640 /* Connection was closed during packet processing. */
1641 return -1;
1642
718e3744 1643 /* Register read thread. */
634f9ea2 1644 stream_reset(zclient->ibuf);
718e3744 1645 zclient_event (ZCLIENT_READ, zclient);
1646
1647 return 0;
1648}
1649
1650void
8bb0831e 1651zclient_redistribute (int command, struct zclient *zclient, afi_t afi, int type,
7076bb2f 1652 u_short instance, vrf_id_t vrf_id)
718e3744 1653{
718e3744 1654
7076bb2f
FL
1655 if (instance) {
1656 if (command == ZEBRA_REDISTRIBUTE_ADD)
1657 {
1658 if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
1659 return;
1660 redist_add_instance(&zclient->mi_redist[afi][type], instance);
1661 }
1662 else
1663 {
1664 if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
1665 return;
1666 redist_del_instance(&zclient->mi_redist[afi][type], instance);
1667 }
1668
1669 } else {
1670 if (command == ZEBRA_REDISTRIBUTE_ADD)
1671 {
1672 if (vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1673 return;
1674 vrf_bitmap_set (zclient->redist[afi][type], vrf_id);
1675 }
1676 else
1677 {
1678 if (!vrf_bitmap_check (zclient->redist[afi][type], vrf_id))
1679 return;
1680 vrf_bitmap_unset (zclient->redist[afi][type], vrf_id);
1681 }
1682 }
718e3744 1683
1684 if (zclient->sock > 0)
7076bb2f 1685 zebra_redistribute_send (command, zclient, afi, type, instance, vrf_id);
718e3744 1686}
1687
718e3744 1688
1689void
7076bb2f
FL
1690zclient_redistribute_default (int command, struct zclient *zclient,
1691 vrf_id_t vrf_id)
718e3744 1692{
718e3744 1693
0a589359 1694 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD)
1695 {
7076bb2f 1696 if (vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 1697 return;
7076bb2f 1698 vrf_bitmap_set (zclient->default_information, vrf_id);
0a589359 1699 }
1700 else
1701 {
7076bb2f 1702 if (!vrf_bitmap_check (zclient->default_information, vrf_id))
0a589359 1703 return;
7076bb2f 1704 vrf_bitmap_unset (zclient->default_information, vrf_id);
0a589359 1705 }
718e3744 1706
1707 if (zclient->sock > 0)
7076bb2f 1708 zebra_message_send (zclient, command, vrf_id);
718e3744 1709}
1710
718e3744 1711static void
1712zclient_event (enum event event, struct zclient *zclient)
1713{
1714 switch (event)
1715 {
1716 case ZCLIENT_SCHEDULE:
1717 if (! zclient->t_connect)
1718 zclient->t_connect =
4140ca4d 1719 thread_add_event (zclient->master, zclient_connect, zclient, 0);
718e3744 1720 break;
1721 case ZCLIENT_CONNECT:
1722 if (zclient->fail >= 10)
1723 return;
1724 if (zclient_debug)
8ddca704 1725 zlog_debug ("zclient connect schedule interval is %d",
718e3744 1726 zclient->fail < 3 ? 10 : 60);
1727 if (! zclient->t_connect)
1728 zclient->t_connect =
4140ca4d 1729 thread_add_timer (zclient->master, zclient_connect, zclient,
718e3744 1730 zclient->fail < 3 ? 10 : 60);
1731 break;
1732 case ZCLIENT_READ:
1733 zclient->t_read =
4140ca4d 1734 thread_add_read (zclient->master, zclient_read, zclient, zclient->sock);
718e3744 1735 break;
1736 }
1737}
b5114685 1738
744f4685 1739const char *zclient_serv_path_get()
12e41d03
DL
1740{
1741 return zclient_serv_path ? zclient_serv_path : ZEBRA_SERV_PATH;
1742}
1743
b5114685
VT
1744void
1745zclient_serv_path_set (char *path)
1746{
1747 struct stat sb;
1748
1749 /* reset */
1750 zclient_serv_path = NULL;
1751
1752 /* test if `path' is socket. don't set it otherwise. */
1753 if (stat(path, &sb) == -1)
1754 {
1755 zlog_warn ("%s: zebra socket `%s' does not exist", __func__, path);
1756 return;
1757 }
1758
1759 if ((sb.st_mode & S_IFMT) != S_IFSOCK)
1760 {
1761 zlog_warn ("%s: `%s' is not unix socket, sir", __func__, path);
1762 return;
1763 }
1764
1765 /* it seems that path is unix socket */
1766 zclient_serv_path = path;
1767}
1768