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