~ubuntu-branches/ubuntu/warty/quagga/warty

« back to all changes in this revision

Viewing changes to lib/zclient.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-06-29 09:50:59 UTC
  • Revision ID: james.westby@ubuntu.com-20040629095059-px1m2m108z4qw1mr
Tags: upstream-0.96.5
ImportĀ upstreamĀ versionĀ 0.96.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Zebra's client library.
 
2
 * Copyright (C) 1999 Kunihiro Ishiguro
 
3
 *
 
4
 * This file is part of GNU Zebra.
 
5
 *
 
6
 * GNU Zebra is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published
 
8
 * by the Free Software Foundation; either version 2, or (at your
 
9
 * option) any later version.
 
10
 *
 
11
 * GNU Zebra is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 
18
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
19
 * MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include <zebra.h>
 
23
 
 
24
#include "prefix.h"
 
25
#include "stream.h"
 
26
#include "network.h"
 
27
#include "if.h"
 
28
#include "log.h"
 
29
#include "thread.h"
 
30
#include "zclient.h"
 
31
#include "memory.h"
 
32
#include "table.h"
 
33
 
 
34
#include "zebra/rib.h"
 
35
#include "zebra/zserv.h"
 
36
 
 
37
/* Zebra client events. */
 
38
enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT};
 
39
 
 
40
/* Prototype for event manager. */
 
41
static void zclient_event (enum event, struct zclient *);
 
42
 
 
43
/* This file local debug flag. */
 
44
int zclient_debug = 0;
 
45
 
 
46
/* Allocate zclient structure. */
 
47
struct zclient *
 
48
zclient_new ()
 
49
{
 
50
  struct zclient *zclient;
 
51
  zclient = XMALLOC (MTYPE_ZCLIENT, sizeof (struct zclient));
 
52
  memset (zclient, 0, sizeof (struct zclient));
 
53
 
 
54
  zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
 
55
  zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);
 
56
 
 
57
  return zclient;
 
58
}
 
59
 
 
60
/* Free zclient structure. */
 
61
void
 
62
zclient_free (struct zclient *zclient)
 
63
{
 
64
  XFREE (MTYPE_ZCLIENT, zclient);
 
65
}
 
66
 
 
67
/* Initialize zebra client.  Argument redist_default is unwanted
 
68
   redistribute route type. */
 
69
void
 
70
zclient_init (struct zclient *zclient, int redist_default)
 
71
{
 
72
  int i;
 
73
  
 
74
  /* Enable zebra client connection by default. */
 
75
  zclient->enable = 1;
 
76
 
 
77
  /* Set -1 to the default socket value. */
 
78
  zclient->sock = -1;
 
79
 
 
80
  /* Clear redistribution flags. */
 
81
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
82
    zclient->redist[i] = 0;
 
83
 
 
84
  /* Set unwanted redistribute route.  bgpd does not need BGP route
 
85
     redistribution. */
 
86
  zclient->redist_default = redist_default;
 
87
  zclient->redist[redist_default] = 1;
 
88
 
 
89
  /* Set default-information redistribute to zero. */
 
90
  zclient->default_information = 0;
 
91
 
 
92
  /* Schedule first zclient connection. */
 
93
  if (zclient_debug)
 
94
    zlog_info ("zclient start scheduled");
 
95
 
 
96
  zclient_event (ZCLIENT_SCHEDULE, zclient);
 
97
}
 
98
 
 
99
/* Stop zebra client services. */
 
100
void
 
101
zclient_stop (struct zclient *zclient)
 
102
{
 
103
  if (zclient_debug)
 
104
    zlog_info ("zclient stopped");
 
105
 
 
106
  /* Stop threads. */
 
107
  if (zclient->t_read)
 
108
    {
 
109
      thread_cancel (zclient->t_read);
 
110
      zclient->t_read = NULL;
 
111
   }
 
112
  if (zclient->t_connect)
 
113
    {
 
114
      thread_cancel (zclient->t_connect);
 
115
      zclient->t_connect = NULL;
 
116
    }
 
117
 
 
118
  /* Close socket. */
 
119
  if (zclient->sock >= 0)
 
120
    {
 
121
      close (zclient->sock);
 
122
      zclient->sock = -1;
 
123
    }
 
124
  zclient->fail = 0;
 
125
}
 
126
 
 
127
void
 
128
zclient_reset (struct zclient *zclient)
 
129
{
 
130
  zclient_stop (zclient);
 
131
  zclient_init (zclient, zclient->redist_default);
 
132
}
 
133
 
 
134
/* Make socket to zebra daemon. Return zebra socket. */
 
135
int
 
136
zclient_socket ()
 
137
{
 
138
  int sock;
 
139
  int ret;
 
140
  struct sockaddr_in serv;
 
141
 
 
142
  /* We should think about IPv6 connection. */
 
143
  sock = socket (AF_INET, SOCK_STREAM, 0);
 
144
  if (sock < 0)
 
145
    return -1;
 
146
  
 
147
  /* Make server socket. */ 
 
148
  memset (&serv, 0, sizeof (struct sockaddr_in));
 
149
  serv.sin_family = AF_INET;
 
150
  serv.sin_port = htons (ZEBRA_PORT);
 
151
#ifdef HAVE_SIN_LEN
 
152
  serv.sin_len = sizeof (struct sockaddr_in);
 
153
#endif /* HAVE_SIN_LEN */
 
154
  serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
 
155
 
 
156
  /* Connect to zebra. */
 
157
  ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv));
 
158
  if (ret < 0)
 
159
    {
 
160
      close (sock);
 
161
      return -1;
 
162
    }
 
163
  return sock;
 
164
}
 
165
 
 
166
/* For sockaddr_un. */
 
167
#include <sys/un.h>
 
168
 
 
169
int
 
170
zclient_socket_un (char *path)
 
171
{
 
172
  int ret;
 
173
  int sock, len;
 
174
  struct sockaddr_un addr;
 
175
 
 
176
  sock = socket (AF_UNIX, SOCK_STREAM, 0);
 
177
  if (sock < 0)
 
178
    return -1;
 
179
  
 
180
  /* Make server socket. */ 
 
181
  memset (&addr, 0, sizeof (struct sockaddr_un));
 
182
  addr.sun_family = AF_UNIX;
 
183
  strncpy (addr.sun_path, path, strlen (path));
 
184
#ifdef HAVE_SUN_LEN
 
185
  len = addr.sun_len = SUN_LEN(&addr);
 
186
#else
 
187
  len = sizeof (addr.sun_family) + strlen (addr.sun_path);
 
188
#endif /* HAVE_SUN_LEN */
 
189
 
 
190
  ret = connect (sock, (struct sockaddr *) &addr, len);
 
191
  if (ret < 0)
 
192
    {
 
193
      close (sock);
 
194
      return -1;
 
195
    }
 
196
  return sock;
 
197
}
 
198
 
 
199
/* Send simple Zebra message. */
 
200
int
 
201
zebra_message_send (struct zclient *zclient, int command)
 
202
{
 
203
  struct stream *s;
 
204
 
 
205
  /* Get zclient output buffer. */
 
206
  s = zclient->obuf;
 
207
  stream_reset (s);
 
208
 
 
209
  /* Send very simple command only Zebra message. */
 
210
  stream_putw (s, 3);
 
211
  stream_putc (s, command);
 
212
 
 
213
  return writen (zclient->sock, s->data, 3);
 
214
}
 
215
 
 
216
/* Make connection to zebra daemon. */
 
217
int
 
218
zclient_start (struct zclient *zclient)
 
219
{
 
220
  int i;
 
221
 
 
222
  if (zclient_debug)
 
223
    zlog_info ("zclient_start is called");
 
224
 
 
225
  /* zclient is disabled. */
 
226
  if (! zclient->enable)
 
227
    return 0;
 
228
 
 
229
  /* If already connected to the zebra. */
 
230
  if (zclient->sock >= 0)
 
231
    return 0;
 
232
 
 
233
  /* Check connect thread. */
 
234
  if (zclient->t_connect)
 
235
    return 0;
 
236
 
 
237
  /* Make socket. */
 
238
#ifdef HAVE_TCP_ZEBRA
 
239
  zclient->sock = zclient_socket ();
 
240
#else
 
241
  zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH);
 
242
#endif /* HAVE_TCP_ZEBRA */
 
243
  if (zclient->sock < 0)
 
244
    {
 
245
      if (zclient_debug)
 
246
        zlog_info ("zclient connection fail");
 
247
      zclient->fail++;
 
248
      zclient_event (ZCLIENT_CONNECT, zclient);
 
249
      return -1;
 
250
    }
 
251
 
 
252
  /* Clear fail count. */
 
253
  zclient->fail = 0;
 
254
  if (zclient_debug)
 
255
    zlog_info ("zclient connect success with socket [%d]", zclient->sock);
 
256
      
 
257
  /* Create read thread. */
 
258
  zclient_event (ZCLIENT_READ, zclient);
 
259
 
 
260
  /* We need interface information. */
 
261
  zebra_message_send (zclient, ZEBRA_INTERFACE_ADD);
 
262
 
 
263
  /* Flush all redistribute request. */
 
264
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
 
265
    if (i != zclient->redist_default && zclient->redist[i])
 
266
      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, i);
 
267
 
 
268
  /* If default information is needed. */
 
269
  if (zclient->default_information)
 
270
    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
 
271
 
 
272
  return 0;
 
273
}
 
274
 
 
275
/* This function is a wrapper function for calling zclient_start from
 
276
   timer or event thread. */
 
277
int
 
278
zclient_connect (struct thread *t)
 
279
{
 
280
  struct zclient *zclient;
 
281
 
 
282
  zclient = THREAD_ARG (t);
 
283
  zclient->t_connect = NULL;
 
284
 
 
285
  if (zclient_debug)
 
286
    zlog_info ("zclient_connect is called");
 
287
 
 
288
  return zclient_start (zclient);
 
289
}
 
290
 
 
291
int
 
292
zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p,
 
293
               struct zapi_ipv4 *api)
 
294
{
 
295
  int i;
 
296
  int psize;
 
297
  struct stream *s;
 
298
 
 
299
  /* Reset stream. */
 
300
  s = zclient->obuf;
 
301
  stream_reset (s);
 
302
 
 
303
  /* Length place holder. */
 
304
  stream_putw (s, 0);
 
305
 
 
306
  /* Put command, type and nexthop. */
 
307
  stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);
 
308
  stream_putc (s, api->type);
 
309
  stream_putc (s, api->flags);
 
310
  stream_putc (s, api->message);
 
311
  
 
312
  /* Put prefix information. */
 
313
  psize = PSIZE (p->prefixlen);
 
314
  stream_putc (s, p->prefixlen);
 
315
  stream_write (s, (u_char *)&p->prefix, psize);
 
316
 
 
317
  /* Nexthop, ifindex, distance and metric information. */
 
318
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
319
    {
 
320
      if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
 
321
        {
 
322
          stream_putc (s, 1);
 
323
          stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
 
324
          /* XXX assert(api->nexthop_num == 0); */
 
325
          /* XXX assert(api->ifindex_num == 0); */
 
326
        }
 
327
      else
 
328
        stream_putc (s, api->nexthop_num + api->ifindex_num);
 
329
        
 
330
      for (i = 0; i < api->nexthop_num; i++)
 
331
        {
 
332
          stream_putc (s, ZEBRA_NEXTHOP_IPV4);
 
333
          stream_put_in_addr (s, api->nexthop[i]);
 
334
        }
 
335
      for (i = 0; i < api->ifindex_num; i++)
 
336
        {
 
337
          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
338
          stream_putl (s, api->ifindex[i]);
 
339
        }
 
340
    }
 
341
 
 
342
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
343
    stream_putc (s, api->distance);
 
344
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
345
    stream_putl (s, api->metric);
 
346
 
 
347
  /* Put length at the first point of the stream. */
 
348
  stream_putw_at (s, 0, stream_get_endp (s));
 
349
 
 
350
  return writen (zclient->sock, s->data, stream_get_endp (s));
 
351
}
 
352
 
 
353
int
 
354
zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p,
 
355
                  struct zapi_ipv4 *api)
 
356
{
 
357
  int i;
 
358
  int psize;
 
359
  struct stream *s;
 
360
 
 
361
  /* Reset stream. */
 
362
  s = zclient->obuf;
 
363
  stream_reset (s);
 
364
 
 
365
  /* Length place holder. */
 
366
  stream_putw (s, 0);
 
367
 
 
368
  /* Put command, type and nexthop. */
 
369
  stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE);
 
370
  stream_putc (s, api->type);
 
371
  stream_putc (s, api->flags);
 
372
  stream_putc (s, api->message);
 
373
  
 
374
  /* Put prefix information. */
 
375
  psize = PSIZE (p->prefixlen);
 
376
  stream_putc (s, p->prefixlen);
 
377
  stream_write (s, (u_char *)&p->prefix, psize);
 
378
 
 
379
  /* Nexthop, ifindex, distance and metric information. */
 
380
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
381
    {
 
382
      if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE))
 
383
        {
 
384
          stream_putc (s, 1);
 
385
          stream_putc (s, ZEBRA_NEXTHOP_BLACKHOLE);
 
386
          /* XXX assert(api->nexthop_num == 0); */
 
387
          /* XXX assert(api->ifindex_num == 0); */
 
388
        }
 
389
      else
 
390
        stream_putc (s, api->nexthop_num + api->ifindex_num);
 
391
 
 
392
      for (i = 0; i < api->nexthop_num; i++)
 
393
        {
 
394
          stream_putc (s, ZEBRA_NEXTHOP_IPV4);
 
395
          stream_put_in_addr (s, api->nexthop[i]);
 
396
        }
 
397
      for (i = 0; i < api->ifindex_num; i++)
 
398
        {
 
399
          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
400
          stream_putl (s, api->ifindex[i]);
 
401
        }
 
402
    }
 
403
 
 
404
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
405
    stream_putc (s, api->distance);
 
406
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
407
    stream_putl (s, api->metric);
 
408
 
 
409
  /* Put length at the first point of the stream. */
 
410
  stream_putw_at (s, 0, stream_get_endp (s));
 
411
 
 
412
  return writen (zclient->sock, s->data, stream_get_endp (s));
 
413
}
 
414
 
 
415
#ifdef HAVE_IPV6
 
416
int
 
417
zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p,
 
418
               struct zapi_ipv6 *api)
 
419
{
 
420
  int i;
 
421
  int psize;
 
422
  struct stream *s;
 
423
 
 
424
  /* Reset stream. */
 
425
  s = zclient->obuf;
 
426
  stream_reset (s);
 
427
 
 
428
  /* Length place holder. */
 
429
  stream_putw (s, 0);
 
430
 
 
431
  /* Put command, type and nexthop. */
 
432
  stream_putc (s, ZEBRA_IPV6_ROUTE_ADD);
 
433
  stream_putc (s, api->type);
 
434
  stream_putc (s, api->flags);
 
435
  stream_putc (s, api->message);
 
436
  
 
437
  /* Put prefix information. */
 
438
  psize = PSIZE (p->prefixlen);
 
439
  stream_putc (s, p->prefixlen);
 
440
  stream_write (s, (u_char *)&p->prefix, psize);
 
441
 
 
442
  /* Nexthop, ifindex, distance and metric information. */
 
443
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
444
    {
 
445
      stream_putc (s, api->nexthop_num + api->ifindex_num);
 
446
 
 
447
      for (i = 0; i < api->nexthop_num; i++)
 
448
        {
 
449
          stream_putc (s, ZEBRA_NEXTHOP_IPV6);
 
450
          stream_write (s, (u_char *)api->nexthop[i], 16);
 
451
        }
 
452
      for (i = 0; i < api->ifindex_num; i++)
 
453
        {
 
454
          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
455
          stream_putl (s, api->ifindex[i]);
 
456
        }
 
457
    }
 
458
 
 
459
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
460
    stream_putc (s, api->distance);
 
461
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
462
    stream_putl (s, api->metric);
 
463
 
 
464
  /* Put length at the first point of the stream. */
 
465
  stream_putw_at (s, 0, stream_get_endp (s));
 
466
 
 
467
  return writen (zclient->sock, s->data, stream_get_endp (s));
 
468
}
 
469
 
 
470
int
 
471
zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p,
 
472
                  struct zapi_ipv6 *api)
 
473
{
 
474
  int i;
 
475
  int psize;
 
476
  struct stream *s;
 
477
 
 
478
  /* Reset stream. */
 
479
  s = zclient->obuf;
 
480
  stream_reset (s);
 
481
 
 
482
  /* Length place holder. */
 
483
  stream_putw (s, 0);
 
484
 
 
485
  /* Put command, type and nexthop. */
 
486
  stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE);
 
487
  stream_putc (s, api->type);
 
488
  stream_putc (s, api->flags);
 
489
  stream_putc (s, api->message);
 
490
  
 
491
  /* Put prefix information. */
 
492
  psize = PSIZE (p->prefixlen);
 
493
  stream_putc (s, p->prefixlen);
 
494
  stream_write (s, (u_char *)&p->prefix, psize);
 
495
 
 
496
  /* Nexthop, ifindex, distance and metric information. */
 
497
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP))
 
498
    {
 
499
      stream_putc (s, api->nexthop_num + api->ifindex_num);
 
500
 
 
501
      for (i = 0; i < api->nexthop_num; i++)
 
502
        {
 
503
          stream_putc (s, ZEBRA_NEXTHOP_IPV6);
 
504
          stream_write (s, (u_char *)api->nexthop[i], 16);
 
505
        }
 
506
      for (i = 0; i < api->ifindex_num; i++)
 
507
        {
 
508
          stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);
 
509
          stream_putl (s, api->ifindex[i]);
 
510
        }
 
511
    }
 
512
 
 
513
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE))
 
514
    stream_putc (s, api->distance);
 
515
  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
 
516
    stream_putl (s, api->metric);
 
517
 
 
518
  /* Put length at the first point of the stream. */
 
519
  stream_putw_at (s, 0, stream_get_endp (s));
 
520
 
 
521
  return writen (zclient->sock, s->data, stream_get_endp (s));
 
522
}
 
523
 
 
524
#endif /* HAVE_IPV6 */
 
525
 
 
526
int
 
527
zebra_redistribute_send (int command, int sock, int type)
 
528
{
 
529
  int ret;
 
530
  struct stream *s;
 
531
 
 
532
  s = stream_new (ZEBRA_MAX_PACKET_SIZ);
 
533
 
 
534
  /* Total length of the messages. */
 
535
  stream_putw (s, 4);
 
536
  
 
537
  stream_putc (s, command);
 
538
  stream_putc (s, type);
 
539
 
 
540
  ret = writen (sock, s->data, 4);
 
541
 
 
542
  stream_free (s);
 
543
 
 
544
  return ret;
 
545
}
 
546
 
 
547
/* Interface addition from zebra daemon. */
 
548
struct interface *
 
549
zebra_interface_add_read (struct stream *s)
 
550
{
 
551
  struct interface *ifp;
 
552
  u_char ifname_tmp[INTERFACE_NAMSIZ];
 
553
 
 
554
  /* Read interface name. */
 
555
  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
 
556
 
 
557
  /* Lookup this by interface name. */
 
558
  ifp = if_lookup_by_name (ifname_tmp);
 
559
 
 
560
  /* If such interface does not exist, make new one. */
 
561
  if (! ifp)
 
562
    ifp = if_create (ifname_tmp, INTERFACE_NAMSIZ);
 
563
 
 
564
  /* Read interface's index. */
 
565
  ifp->ifindex = stream_getl (s);
 
566
 
 
567
  /* Read interface's value. */
 
568
  ifp->status = stream_getc (s);
 
569
  ifp->flags = stream_getl (s);
 
570
  ifp->metric = stream_getl (s);
 
571
  ifp->mtu = stream_getl (s);
 
572
  ifp->bandwidth = stream_getl (s);
 
573
#ifdef HAVE_SOCKADDR_DL
 
574
  stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
 
575
#else
 
576
  ifp->hw_addr_len = stream_getl (s);
 
577
  if (ifp->hw_addr_len)
 
578
    stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
 
579
#endif /* HAVE_SOCKADDR_DL */
 
580
  
 
581
  return ifp;
 
582
}
 
583
 
 
584
/* Read interface up/down msg from zebra daemon. */
 
585
struct interface *
 
586
zebra_interface_state_read (struct stream *s)
 
587
{
 
588
  struct interface *ifp;
 
589
  u_char ifname_tmp[INTERFACE_NAMSIZ];
 
590
 
 
591
  /* Read interface name. */
 
592
  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);
 
593
 
 
594
  /* Lookup this by interface index. */
 
595
  ifp = if_lookup_by_name (ifname_tmp);
 
596
 
 
597
  /* If such interface does not exist, indicate an error */
 
598
  if (! ifp)
 
599
     return NULL;
 
600
 
 
601
  /* Read interface's index. */
 
602
  ifp->ifindex = stream_getl (s);
 
603
 
 
604
  /* Read interface's value. */
 
605
  ifp->status = stream_getc (s);
 
606
  ifp->flags = stream_getl (s);
 
607
  ifp->metric = stream_getl (s);
 
608
  ifp->mtu = stream_getl (s);
 
609
  ifp->bandwidth = stream_getl (s);
 
610
 
 
611
  return ifp;
 
612
}
 
613
 
 
614
struct connected *
 
615
zebra_interface_address_add_read (struct stream *s)
 
616
{
 
617
  unsigned int ifindex;
 
618
  struct interface *ifp;
 
619
  struct connected *ifc;
 
620
  struct prefix *p;
 
621
  int family;
 
622
  int plen;
 
623
 
 
624
  /* Get interface index. */
 
625
  ifindex = stream_getl (s);
 
626
 
 
627
  /* Lookup index. */
 
628
  ifp = if_lookup_by_index (ifindex);
 
629
  if (ifp == NULL)
 
630
    {
 
631
      zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex);
 
632
      return NULL;
 
633
    }
 
634
 
 
635
  /* Allocate new connected address. */
 
636
  ifc = connected_new ();
 
637
  ifc->ifp = ifp;
 
638
 
 
639
  /* Fetch flag. */
 
640
  ifc->flags = stream_getc (s);
 
641
 
 
642
  /* Fetch interface address. */
 
643
  p = prefix_new ();
 
644
  family = p->family = stream_getc (s);
 
645
 
 
646
  plen = prefix_blen (p);
 
647
  stream_get (&p->u.prefix, s, plen);
 
648
  p->prefixlen = stream_getc (s);
 
649
  ifc->address = p;
 
650
 
 
651
  /* Fetch destination address. */
 
652
  p = prefix_new ();
 
653
  stream_get (&p->u.prefix, s, plen);
 
654
  p->family = family;
 
655
 
 
656
  ifc->destination = p;
 
657
 
 
658
  p = ifc->address;
 
659
 
 
660
  /* Add connected address to the interface. */
 
661
  listnode_add (ifp->connected, ifc);
 
662
 
 
663
  return ifc;
 
664
}
 
665
 
 
666
struct connected *
 
667
zebra_interface_address_delete_read (struct stream *s)
 
668
{
 
669
  unsigned int ifindex;
 
670
  struct interface *ifp;
 
671
  struct connected *ifc;
 
672
  struct prefix p;
 
673
  struct prefix d;
 
674
  int family;
 
675
  int len;
 
676
  u_char flags;
 
677
 
 
678
  /* Get interface index. */
 
679
  ifindex = stream_getl (s);
 
680
 
 
681
  /* Lookup index. */
 
682
  ifp = if_lookup_by_index (ifindex);
 
683
  if (ifp == NULL)
 
684
    {
 
685
      zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex);
 
686
      return NULL;
 
687
    }
 
688
 
 
689
  /* Fetch flag. */
 
690
  flags = stream_getc (s);
 
691
 
 
692
  /* Fetch interface address. */
 
693
  family = p.family = stream_getc (s);
 
694
 
 
695
  len = prefix_blen (&p);
 
696
  stream_get (&p.u.prefix, s, len);
 
697
  p.prefixlen = stream_getc (s);
 
698
 
 
699
  /* Fetch destination address. */
 
700
  stream_get (&d.u.prefix, s, len);
 
701
  d.family = family;
 
702
 
 
703
  ifc = connected_delete_by_prefix (ifp, &p);
 
704
 
 
705
  return ifc;
 
706
}
 
707
 
 
708
/* Zebra client message read function. */
 
709
int
 
710
zclient_read (struct thread *thread)
 
711
{
 
712
  int ret;
 
713
  int nbytes;
 
714
  int sock;
 
715
  zebra_size_t length;
 
716
  zebra_command_t command;
 
717
  struct zclient *zclient;
 
718
 
 
719
  /* Get socket to zebra. */
 
720
  sock = THREAD_FD (thread);
 
721
  zclient = THREAD_ARG (thread);
 
722
  zclient->t_read = NULL;
 
723
 
 
724
  /* Clear input buffer. */
 
725
  stream_reset (zclient->ibuf);
 
726
 
 
727
  /* Read zebra header. */
 
728
  nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE);
 
729
 
 
730
  /* zebra socket is closed. */
 
731
  if (nbytes == 0) 
 
732
    {
 
733
      if (zclient_debug)
 
734
        zlog_info ("zclient connection closed socket [%d].", sock);
 
735
      zclient->fail++;
 
736
      zclient_stop (zclient);
 
737
      zclient_event (ZCLIENT_CONNECT, zclient);
 
738
      return -1;
 
739
    }
 
740
 
 
741
  /* zebra read error. */
 
742
  if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE)
 
743
    {
 
744
      if (zclient_debug)
 
745
        zlog_info ("Can't read all packet (length %d).", nbytes);
 
746
      zclient->fail++;
 
747
      zclient_stop (zclient);
 
748
      zclient_event (ZCLIENT_CONNECT, zclient);
 
749
      return -1;
 
750
    }
 
751
 
 
752
  /* Fetch length and command. */
 
753
  length = stream_getw (zclient->ibuf);
 
754
  command = stream_getc (zclient->ibuf);
 
755
 
 
756
  /* Length check. */
 
757
  if (length >= zclient->ibuf->size)
 
758
    {
 
759
      stream_free (zclient->ibuf);
 
760
      zclient->ibuf = stream_new (length + 1);
 
761
    }
 
762
  length -= ZEBRA_HEADER_SIZE;
 
763
 
 
764
  /* Read rest of zebra packet. */
 
765
  nbytes = stream_read (zclient->ibuf, sock, length);
 
766
 if (nbytes != length)
 
767
   {
 
768
     if (zclient_debug)
 
769
       zlog_info ("zclient connection closed socket [%d].", sock);
 
770
     zclient->fail++;
 
771
     zclient_stop (zclient);
 
772
     zclient_event (ZCLIENT_CONNECT, zclient);
 
773
     return -1;
 
774
   }
 
775
 
 
776
  switch (command)
 
777
    {
 
778
    case ZEBRA_INTERFACE_ADD:
 
779
      if (zclient->interface_add)
 
780
        ret = (*zclient->interface_add) (command, zclient, length);
 
781
      break;
 
782
    case ZEBRA_INTERFACE_DELETE:
 
783
      if (zclient->interface_delete)
 
784
        ret = (*zclient->interface_delete) (command, zclient, length);
 
785
      break;
 
786
    case ZEBRA_INTERFACE_ADDRESS_ADD:
 
787
      if (zclient->interface_address_add)
 
788
        ret = (*zclient->interface_address_add) (command, zclient, length);
 
789
      break;
 
790
    case ZEBRA_INTERFACE_ADDRESS_DELETE:
 
791
      if (zclient->interface_address_delete)
 
792
        ret = (*zclient->interface_address_delete) (command, zclient, length);
 
793
      break;
 
794
    case ZEBRA_INTERFACE_UP:
 
795
      if (zclient->interface_up)
 
796
        ret = (*zclient->interface_up) (command, zclient, length);
 
797
      break;
 
798
    case ZEBRA_INTERFACE_DOWN:
 
799
      if (zclient->interface_down)
 
800
        ret = (*zclient->interface_down) (command, zclient, length);
 
801
      break;
 
802
    case ZEBRA_IPV4_ROUTE_ADD:
 
803
      if (zclient->ipv4_route_add)
 
804
        ret = (*zclient->ipv4_route_add) (command, zclient, length);
 
805
      break;
 
806
    case ZEBRA_IPV4_ROUTE_DELETE:
 
807
      if (zclient->ipv4_route_delete)
 
808
        ret = (*zclient->ipv4_route_delete) (command, zclient, length);
 
809
      break;
 
810
    case ZEBRA_IPV6_ROUTE_ADD:
 
811
      if (zclient->ipv6_route_add)
 
812
        ret = (*zclient->ipv6_route_add) (command, zclient, length);
 
813
      break;
 
814
    case ZEBRA_IPV6_ROUTE_DELETE:
 
815
      if (zclient->ipv6_route_delete)
 
816
        ret = (*zclient->ipv6_route_delete) (command, zclient, length);
 
817
      break;
 
818
    default:
 
819
      break;
 
820
    }
 
821
 
 
822
  /* Register read thread. */
 
823
  zclient_event (ZCLIENT_READ, zclient);
 
824
 
 
825
  return 0;
 
826
}
 
827
 
 
828
void
 
829
zclient_redistribute_set (struct zclient *zclient, int type)
 
830
{
 
831
  if (zclient->redist[type])
 
832
    return;
 
833
 
 
834
  zclient->redist[type] = 1;
 
835
 
 
836
  if (zclient->sock > 0)
 
837
    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);
 
838
}
 
839
 
 
840
void
 
841
zclient_redistribute_unset (struct zclient *zclient, int type)
 
842
{
 
843
  if (! zclient->redist[type])
 
844
    return;
 
845
 
 
846
  zclient->redist[type] = 0;
 
847
 
 
848
  if (zclient->sock > 0)
 
849
    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);
 
850
}
 
851
 
 
852
void
 
853
zclient_redistribute_default_set (struct zclient *zclient)
 
854
{
 
855
  if (zclient->default_information)
 
856
    return;
 
857
 
 
858
  zclient->default_information = 1;
 
859
 
 
860
  if (zclient->sock > 0)
 
861
    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD);
 
862
}
 
863
 
 
864
void
 
865
zclient_redistribute_default_unset (struct zclient *zclient)
 
866
{
 
867
  if (! zclient->default_information)
 
868
    return;
 
869
 
 
870
  zclient->default_information = 0;
 
871
 
 
872
  if (zclient->sock > 0)
 
873
    zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE);
 
874
}
 
875
 
 
876
extern struct thread_master *master;
 
877
 
 
878
static void
 
879
zclient_event (enum event event, struct zclient *zclient)
 
880
{
 
881
  switch (event)
 
882
    {
 
883
    case ZCLIENT_SCHEDULE:
 
884
      if (! zclient->t_connect)
 
885
        zclient->t_connect =
 
886
          thread_add_event (master, zclient_connect, zclient, 0);
 
887
      break;
 
888
    case ZCLIENT_CONNECT:
 
889
      if (zclient->fail >= 10)
 
890
        return;
 
891
      if (zclient_debug)
 
892
        zlog_info ("zclient connect schedule interval is %d", 
 
893
                   zclient->fail < 3 ? 10 : 60);
 
894
      if (! zclient->t_connect)
 
895
        zclient->t_connect = 
 
896
          thread_add_timer (master, zclient_connect, zclient,
 
897
                            zclient->fail < 3 ? 10 : 60);
 
898
      break;
 
899
    case ZCLIENT_READ:
 
900
      zclient->t_read = 
 
901
        thread_add_read (master, zclient_read, zclient, zclient->sock);
 
902
      break;
 
903
    }
 
904
}