Revision f4a60a9b nest/proto.c

View differences:

nest/proto.c
21 21
#include "filter/filter.h"
22 22

  
23 23
pool *proto_pool;
24
list  proto_list;
24 25

  
25 26
static list protocol_list;
26
static list proto_list;
27 27

  
28 28
#define PD(pr, msg, args...) do { if (pr->debug & D_STATES) { log(L_TRACE "%s: " msg, pr->name , ## args); } } while(0)
29 29

  
30
list active_proto_list;
31
static list inactive_proto_list;
32
static list initial_proto_list;
33
static list flush_proto_list;
34
static struct proto *initial_device_proto;
35

  
36
static event *proto_flush_event;
37 30
static timer *proto_shutdown_timer;
38 31
static timer *gr_wait_timer;
39 32

  
......
46 39
static u32 graceful_restart_locks;
47 40

  
48 41
static char *p_states[] = { "DOWN", "START", "UP", "STOP" };
49
static char *c_states[] = { "HUNGRY", "???", "HAPPY", "FLUSHING" };
50 42

  
51
static void proto_flush_loop(void *);
43
extern struct protocol proto_unix_iface;
44

  
52 45
static void proto_shutdown_loop(struct timer *);
53 46
static void proto_rethink_goal(struct proto *p);
54
static void proto_want_export_up(struct proto *p);
55
static void proto_fell_down(struct proto *p);
56 47
static char *proto_state_name(struct proto *p);
48
static void channel_verify_limits(struct channel *c);
49
static void channel_reset_limit(struct channel_limit *l);
57 50

  
58
static void
59
proto_relink(struct proto *p)
60
{
61
  list *l = NULL;
62 51

  
63
  switch (p->core_state)
64
    {
65
    case FS_HUNGRY:
66
      l = &inactive_proto_list;
67
      break;
68
    case FS_HAPPY:
69
      l = &active_proto_list;
70
      break;
71
    case FS_FLUSHING:
72
      l = &flush_proto_list;
73
      break;
74
    default:
75
      ASSERT(0);
76
    }
52
static inline int proto_is_done(struct proto *p)
53
{ return (p->proto_state == PS_DOWN) && (p->active_channels == 0); }
77 54

  
78
  rem_node(&p->n);
79
  add_tail(l, &p->n);
80
}
55
static inline int channel_is_active(struct channel *c)
56
{ return (c->channel_state == CS_START) || (c->channel_state == CS_UP); }
81 57

  
82 58
static void
83 59
proto_log_state_change(struct proto *p)
84 60
{
85 61
  if (p->debug & D_STATES)
62
  {
63
    char *name = proto_state_name(p);
64
    if (name != p->last_state_name_announced)
86 65
    {
87
      char *name = proto_state_name(p);
88
      if (name != p->last_state_name_announced)
89
	{
90
	  p->last_state_name_announced = name;
91
	  PD(p, "State changed to %s", proto_state_name(p));
92
	}
66
      p->last_state_name_announced = name;
67
      PD(p, "State changed to %s", proto_state_name(p));
93 68
    }
69
  }
94 70
  else
95 71
    p->last_state_name_announced = NULL;
96 72
}
97 73

  
98 74

  
99
/**
100
 * proto_new - create a new protocol instance
101
 * @c: protocol configuration
102
 * @size: size of protocol data structure (each protocol instance is represented by
103
 * a structure starting with generic part [struct &proto] and continued
104
 * with data specific to the protocol)
105
 *
106
 * When a new configuration has been read in, the core code starts
107
 * initializing all the protocol instances configured by calling their
108
 * init() hooks with the corresponding instance configuration. The initialization
109
 * code of the protocol is expected to create a new instance according to the
110
 * configuration by calling this function and then modifying the default settings
111
 * to values wanted by the protocol.
112
 */
113
void *
114
proto_new(struct proto_config *c, unsigned size)
75
struct channel_config *
76
proto_cf_find_channel(struct proto_config *pc, uint net_type)
115 77
{
116
  struct protocol *pr = c->protocol;
117
  struct proto *p = mb_allocz(proto_pool, size);
118

  
119
  p->cf = c;
120
  p->debug = c->debug;
121
  p->mrtdump = c->mrtdump;
122
  p->name = c->name;
123
  p->preference = c->preference;
124
  p->disabled = c->disabled;
125
  p->proto = pr;
126
  p->table = c->table->table;
127
  p->hash_key = random_u32();
128
  c->proto = p;
129
  return p;
78
  struct channel_config *cc;
79

  
80
  WALK_LIST(cc, pc->channels)
81
    if (cc->net_type == net_type)
82
      return cc;
83

  
84
  return NULL;
130 85
}
131 86

  
132
static void
133
proto_init_instance(struct proto *p)
87
/**
88
 * proto_find_channel_by_table - find channel connected to a routing table
89
 * @p: protocol instance
90
 * @t: routing table
91
 *
92
 * Returns pointer to channel or NULL
93
 */
94
struct channel *
95
proto_find_channel_by_table(struct proto *p, struct rtable *t)
134 96
{
135
  /* Here we cannot use p->cf->name since it won't survive reconfiguration */
136
  p->pool = rp_new(proto_pool, p->proto->name);
137
  p->attn = ev_new(p->pool);
138
  p->attn->data = p;
97
  struct channel *c;
139 98

  
140
  if (graceful_restart_state == GRS_INIT)
141
    p->gr_recovery = 1;
99
  WALK_LIST(c, p->channels)
100
    if (c->table == t)
101
      return c;
142 102

  
143
  if (! p->proto->multitable)
144
    rt_lock_table(p->table);
103
  return NULL;
145 104
}
146 105

  
147
extern pool *rt_table_pool;
148 106
/**
149
 * proto_add_announce_hook - connect protocol to a routing table
107
 * proto_add_channel - connect protocol to a routing table
150 108
 * @p: protocol instance
151
 * @t: routing table to connect to
152
 * @stats: per-table protocol statistics
153
 *
154
 * This function creates a connection between the protocol instance @p and the
155
 * routing table @t, making the protocol hear all changes in the table.
109
 * @cf: channel configuration
156 110
 *
157
 * The announce hook is linked in the protocol ahook list. Announce hooks are
158
 * allocated from the routing table resource pool and when protocol accepts
159
 * routes also in the table ahook list. The are linked to the table ahook list
160
 * and unlinked from it depending on export_state (in proto_want_export_up() and
161
 * proto_want_export_down()) and they are automatically freed after the protocol
162
 * is flushed (in proto_fell_down()).
111
 * This function creates a channel between the protocol instance @p and the
112
 * routing table specified in the configuration @cf, making the protocol hear
113
 * all changes in the table and allowing the protocol to update routes in the
114
 * table.
163 115
 *
164
 * Unless you want to listen to multiple routing tables (as the Pipe protocol
165
 * does), you needn't to worry about this function since the connection to the
166
 * protocol's primary routing table is initialized automatically by the core
167
 * code.
116
 * The channel is linked in the protocol channel list and when active also in
117
 * the table channel list. Channels are allocated from the global resource pool
118
 * (@proto_pool) and they are automatically freed when the protocol is removed.
168 119
 */
169
struct announce_hook *
170
proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats)
120

  
121
struct channel *
122
proto_add_channel(struct proto *p, struct channel_config *cf)
123
{
124
  struct channel *c = mb_allocz(proto_pool, cf->channel->channel_size);
125

  
126
  c->name = cf->name;
127
  c->channel = cf->channel;
128
  c->proto = p;
129
  c->table = cf->table->table;
130

  
131
  c->in_filter = cf->in_filter;
132
  c->out_filter = cf->out_filter;
133
  c->rx_limit = cf->rx_limit;
134
  c->in_limit = cf->in_limit;
135
  c->out_limit = cf->out_limit;
136

  
137
  c->net_type = cf->net_type;
138
  c->ra_mode = cf->ra_mode;
139
  c->preference = cf->preference;
140
  c->merge_limit = cf->merge_limit;
141
  c->in_keep_filtered = cf->in_keep_filtered;
142

  
143
  c->channel_state = CS_DOWN;
144
  c->export_state = ES_DOWN;
145
  c->last_state_change = now;
146
  c->reloadable = 1;
147

  
148
  CALL(c->channel->init, c, cf);
149

  
150
  add_tail(&p->channels, &c->n);
151

  
152
  PD(p, "Channel %s connected to table %s", c->name, c->table->name);
153

  
154
  return c;
155
}
156

  
157
void
158
proto_remove_channel(struct proto *p, struct channel *c)
159
{
160
  ASSERT(c->channel_state == CS_DOWN);
161

  
162
  PD(p, "Channel %s removed", c->name);
163

  
164
  rem_node(&c->n);
165
  mb_free(c);
166
}
167

  
168

  
169
static void
170
proto_start_channels(struct proto *p)
171
{
172
  struct channel *c;
173
  WALK_LIST(c, p->channels)
174
    if (!c->disabled)
175
      channel_set_state(c, CS_UP);
176
}
177

  
178
static void
179
proto_pause_channels(struct proto *p)
171 180
{
172
  struct announce_hook *h;
181
  struct channel *c;
182
  WALK_LIST(c, p->channels)
183
    if (!c->disabled && channel_is_active(c))
184
      channel_set_state(c, CS_START);
185
}
173 186

  
174
  DBG("Connecting protocol %s to table %s\n", p->name, t->name);
175
  PD(p, "Connected to table %s", t->name);
187
static void
188
proto_stop_channels(struct proto *p)
189
{
190
  struct channel *c;
191
  WALK_LIST(c, p->channels)
192
    if (!c->disabled && channel_is_active(c))
193
      channel_set_state(c, CS_FLUSHING);
194
}
176 195

  
177
  h = mb_allocz(rt_table_pool, sizeof(struct announce_hook));
178
  h->table = t;
179
  h->proto = p;
180
  h->stats = stats;
196
static void
197
proto_remove_channels(struct proto *p)
198
{
199
  struct channel *c;
200
  WALK_LIST_FIRST(c, p->channels)
201
    proto_remove_channel(p, c);
202
}
203

  
204
static void
205
channel_schedule_feed(struct channel *c, int initial)
206
{
207
  // DBG("%s: Scheduling meal\n", p->name);
208
  ASSERT(c->channel_state == CS_UP);
181 209

  
182
  h->next = p->ahooks;
183
  p->ahooks = h;
210
  c->export_state = ES_FEEDING;
211
  c->refeeding = !initial;
184 212

  
185
  if (p->rt_notify && (p->export_state != ES_DOWN))
186
    add_tail(&t->hooks, &h->n);
187
  return h;
213
  ev_schedule(c->feed_event);
214
}
215

  
216
static void
217
channel_feed_loop(void *ptr)
218
{
219
  struct channel *c = ptr;
220

  
221
  if (c->export_state != ES_FEEDING)
222
    return;
223

  
224
  if (!c->feed_active)
225
    if (c->proto->feed_begin)
226
      c->proto->feed_begin(c, !c->refeeding);
227

  
228
  // DBG("Feeding protocol %s continued\n", p->name);
229
  if (!rt_feed_channel(c))
230
  {
231
    ev_schedule(c->feed_event);
232
    return;
233
  }
234

  
235
  // DBG("Feeding protocol %s finished\n", p->name);
236
  c->export_state = ES_READY;
237
  // proto_log_state_change(p);
238

  
239
  if (c->proto->feed_end)
240
    c->proto->feed_end(c);
241
}
242

  
243

  
244
static void
245
channel_start_export(struct channel *c)
246
{
247
  ASSERT(c->channel_state == CS_UP);
248
  ASSERT(c->export_state == ES_DOWN);
249

  
250
  channel_schedule_feed(c, 1);	/* Sets ES_FEEDING */
251
}
252

  
253
static void
254
channel_stop_export(struct channel *c)
255
{
256
  /* Need to abort feeding */
257
  if (c->export_state == ES_FEEDING)
258
    rt_feed_channel_abort(c);
259

  
260
  c->export_state = ES_DOWN;
261
}
262

  
263
static void
264
channel_do_start(struct channel *c)
265
{
266
  rt_lock_table(c->table);
267
  add_tail(&c->table->channels, &c->table_node);
268
  c->proto->active_channels++;
269

  
270
  c->feed_event = ev_new(c->proto->pool);
271
  c->feed_event->data = c;
272
  c->feed_event->hook = channel_feed_loop;
273

  
274
  channel_reset_limit(&c->rx_limit);
275
  channel_reset_limit(&c->in_limit);
276
  channel_reset_limit(&c->out_limit);
277

  
278
  CALL(c->channel->start, c);
279
}
280

  
281
static void
282
channel_do_flush(struct channel *c)
283
{
284
  rt_schedule_prune(c->table);
285

  
286
  c->gr_wait = 0;
287
  if (c->gr_lock)
288
    channel_graceful_restart_unlock(c);
289

  
290
  CALL(c->channel->shutdown, c);
291
}
292

  
293
static void
294
channel_do_down(struct channel *c)
295
{
296
  rem2_node(&c->table_node);
297
  rt_unlock_table(c->table);
298
  c->proto->active_channels--;
299

  
300
  if ((c->stats.imp_routes + c->stats.filt_routes) != 0)
301
    log(L_ERR "%s: Channel %s is down but still has some routes", c->proto->name, c->name);
302

  
303
  memset(&c->stats, 0, sizeof(struct proto_stats));
304

  
305
  /* Schedule protocol shutddown */
306
  if (proto_is_done(c->proto))
307
    ev_schedule(c->proto->event);
308
}
309

  
310
void
311
channel_set_state(struct channel *c, uint state)
312
{
313
  uint cs = c->channel_state;
314
  uint es = c->export_state;
315

  
316
  DBG("%s reporting state transition %s/%s -> */%s\n", p->name, c_states[cs], p_states[ops], p_states[ps]);
317
  if (state == cs)
318
    return;
319

  
320
  c->channel_state = state;
321
  c->last_state_change = now;
322

  
323
  switch (state)
324
  {
325
  case CS_START:
326
    ASSERT(cs == CS_DOWN || cs == CS_UP);
327

  
328
    if (cs == CS_DOWN)
329
      channel_do_start(c);
330

  
331
    if (es != ES_DOWN)
332
      channel_stop_export(c);
333

  
334
    break;
335

  
336
  case CS_UP:
337
    ASSERT(cs == CS_DOWN || cs == CS_START);
338

  
339
    if (cs == CS_DOWN)
340
      channel_do_start(c);
341

  
342
    if (!c->gr_wait)
343
      channel_start_export(c);
344

  
345
    break;
346

  
347
  case CS_FLUSHING:
348
    ASSERT(cs == CS_START || cs == CS_UP);
349

  
350
    if (es != ES_DOWN)
351
      channel_stop_export(c);
352

  
353
    channel_do_flush(c);
354
    break;
355

  
356
  case CS_DOWN:
357
    ASSERT(cs == CS_FLUSHING);
358

  
359
    channel_do_down(c);
360
    break;
361

  
362
  default:
363
    ASSERT(0);
364
  }
365
  // XXXX proto_log_state_change(c);
188 366
}
189 367

  
190 368
/**
191
 * proto_find_announce_hook - find announce hooks
192
 * @p: protocol instance
193
 * @t: routing table
369
 * channel_request_feeding - request feeding routes to the channel
370
 * @c: given channel
194 371
 *
195
 * Returns pointer to announce hook or NULL
372
 * Sometimes it is needed to send again all routes to the channel. This is
373
 * called feeding and can be requested by this function. This would cause
374
 * channel export state transition to ES_FEEDING (during feeding) and when
375
 * completed, it will switch back to ES_READY. This function can be called
376
 * even when feeding is already running, in that case it is restarted.
196 377
 */
197
struct announce_hook *
198
proto_find_announce_hook(struct proto *p, struct rtable *t)
378
void
379
channel_request_feeding(struct channel *c)
199 380
{
200
  struct announce_hook *a;
381
  ASSERT(c->channel_state == CS_UP);
201 382

  
202
  for (a = p->ahooks; a; a = a->next)
203
    if (a->table == t)
204
      return a;
383
  /* Do nothing if we are still waiting for feeding */
384
  if (c->export_state == ES_DOWN)
385
    return;
205 386

  
206
  return NULL;
387
  /* If we are already feeding, we want to restart it */
388
  if (c->export_state == ES_FEEDING)
389
  {
390
    /* Unless feeding is in initial state */
391
    if (!c->feed_active)
392
	return;
393

  
394
    rt_feed_channel_abort(c);
395
  }
396

  
397
  channel_reset_limit(&c->out_limit);
398

  
399
  /* Hack: reset exp_routes during refeed, and do not decrease it later */
400
  c->stats.exp_routes = 0;
401

  
402
  channel_schedule_feed(c, 0);	/* Sets ES_FEEDING */
403
  // proto_log_state_change(c);
404
}
405

  
406
static inline int
407
channel_reloadable(struct channel *c)
408
{
409
  return c->proto->reload_routes && c->reloadable;
207 410
}
208 411

  
209 412
static void
210
proto_link_ahooks(struct proto *p)
413
channel_request_reload(struct channel *c)
211 414
{
212
  struct announce_hook *h;
415
  ASSERT(c->channel_state == CS_UP);
416
  // ASSERT(channel_reloadable(c));
417

  
418
  c->proto->reload_routes(c);
213 419

  
214
  if (p->rt_notify)
215
    for(h=p->ahooks; h; h=h->next)
216
      add_tail(&h->table->hooks, &h->n);
420
  /*
421
   * Should this be done before reload_routes() hook?
422
   * Perhaps, but routes are updated asynchronously.
423
   */
424
  channel_reset_limit(&c->rx_limit);
425
  channel_reset_limit(&c->in_limit);
217 426
}
218 427

  
219
static void
220
proto_unlink_ahooks(struct proto *p)
428
const struct channel_class channel_basic = {
429
  .channel_size = sizeof(struct channel),
430
  .config_size = sizeof(struct channel_config)
431
};
432

  
433
void *
434
channel_config_new(const struct channel_class *cc, uint net_type, struct proto_config *proto)
435
{
436
  struct channel_config *cf = NULL;
437
  struct rtable_config *tab = NULL;
438
  const char *name = NULL;
439

  
440
  if (net_type)
441
  {
442
    if (!net_val_match(net_type, proto->protocol->channel_mask))
443
      cf_error("Unsupported channel type");
444

  
445
    if (proto->net_type && (net_type != proto->net_type))
446
      cf_error("Different channel type");
447

  
448
    tab = new_config->def_tables[net_type];
449
    name = net_label[net_type];
450
  }
451

  
452
  if (!cc)
453
    cc = &channel_basic;
454

  
455
  cf = cfg_allocz(cc->config_size);
456
  cf->name = name;
457
  cf->channel = cc;
458
  cf->table = tab;
459
  cf->out_filter = FILTER_REJECT;
460

  
461
  cf->net_type = net_type;
462
  cf->ra_mode = RA_OPTIMAL;
463
  cf->preference = proto->protocol->preference;
464

  
465
  add_tail(&proto->channels, &cf->n);
466

  
467
  return cf;
468
}
469

  
470
struct channel_config *
471
channel_copy_config(struct channel_config *src, struct proto_config *proto)
472
{
473
  struct channel_config *dst = cfg_alloc(src->channel->config_size);
474

  
475
  memcpy(dst, src, src->channel->config_size);
476
  add_tail(&proto->channels, &dst->n);
477
  CALL(src->channel->copy_config, dst, src);
478

  
479
  return dst;
480
}
481

  
482

  
483
static int reconfigure_type;  /* Hack to propagate type info to channel_reconfigure() */
484

  
485
int
486
channel_reconfigure(struct channel *c, struct channel_config *cf)
487
{
488
  /* FIXME: better handle these changes, also handle in_keep_filtered */
489
  if ((c->table != cf->table->table) || (c->ra_mode != cf->ra_mode))
490
    return 0;
491

  
492
  int import_changed = !filter_same(c->in_filter, cf->in_filter);
493
  int export_changed = !filter_same(c->out_filter, cf->out_filter);
494

  
495
  if (c->preference != cf->preference)
496
    import_changed = 1;
497

  
498
  if (c->merge_limit != cf->merge_limit)
499
    export_changed = 1;
500

  
501
  /* Reconfigure channel fields */
502
  c->in_filter = cf->in_filter;
503
  c->out_filter = cf->out_filter;
504
  c->rx_limit = cf->rx_limit;
505
  c->in_limit = cf->in_limit;
506
  c->out_limit = cf->out_limit;
507

  
508
  // c->ra_mode = cf->ra_mode;
509
  c->merge_limit = cf->merge_limit;
510
  c->preference = cf->preference;
511
  c->in_keep_filtered = cf->in_keep_filtered;
512

  
513
  channel_verify_limits(c);
514

  
515
  CALL(c->channel->reconfigure, c, cf);
516

  
517
  /* If the channel is not open, it has no routes and we cannot reload it anyways */
518
  if (c->channel_state != CS_UP)
519
    return 1;
520

  
521
  if (reconfigure_type == RECONFIG_SOFT)
522
  {
523
    if (import_changed)
524
      log(L_INFO "Channel %s.%s changed import", c->proto->name, c->name);
525

  
526
    if (export_changed)
527
      log(L_INFO "Channel %s.%s changed export", c->proto->name, c->name);
528

  
529
    return 1;
530
  }
531

  
532
  /* Route reload may be not supported */
533
  if (import_changed && !channel_reloadable(c))
534
    return 0;
535

  
536
  if (import_changed || export_changed)
537
    log(L_INFO "Reloading channel %s.%s", c->proto->name, c->name);
538

  
539
  if (import_changed)
540
    channel_request_reload(c);
541

  
542
  if (export_changed)
543
    channel_request_feeding(c);
544

  
545
  return 1;
546
}
547

  
548

  
549
int
550
proto_configure_channel(struct proto *p, struct channel **pc, struct channel_config *cf)
221 551
{
222
  struct announce_hook *h;
552
  struct channel *c = *pc;
223 553

  
224
  if (p->rt_notify)
225
    for(h=p->ahooks; h; h=h->next)
226
      rem_node(&h->n);
554
  if (!c && cf)
555
  {
556
    *pc = proto_add_channel(p, cf);
557
  }
558
  else if (c && !cf)
559
  {
560
    if (c->channel_state != CS_DOWN)
561
    {
562
      log(L_INFO "Cannot remove channel %s.%s", c->proto->name, c->name);
563
      return 0;
564
    }
565

  
566
    proto_remove_channel(p, c);
567
    *pc = NULL;
568
  }
569
  else if (c && cf)
570
  {
571
    if (!channel_reconfigure(c, cf))
572
    {
573
      log(L_INFO "Cannot reconfigure channel %s.%s", c->proto->name, c->name);
574
      return 0;
575
    }
576
  }
577

  
578
  return 1;
227 579
}
228 580

  
581

  
229 582
static void
230
proto_free_ahooks(struct proto *p)
583
proto_event(void *ptr)
231 584
{
232
  struct announce_hook *h, *hn;
585
  struct proto *p = ptr;
586

  
587
  if (p->do_start)
588
  {
589
    if_feed_baby(p);
590
    p->do_start = 0;
591
  }
233 592

  
234
  for(h = p->ahooks; h; h = hn)
593
  if (p->do_stop)
235 594
  {
236
    hn = h->next;
237
    mb_free(h);
595
    if (p->proto == &proto_unix_iface)
596
      if_flush_ifaces(p);
597
    p->do_stop = 0;
238 598
  }
239 599

  
240
  p->ahooks = NULL;
241
  p->main_ahook = NULL;
600
  if (proto_is_done(p))
601
  {
602
    if (p->proto->cleanup)
603
      p->proto->cleanup(p);
604

  
605
    p->active = 0;
606
    proto_log_state_change(p);
607
    proto_rethink_goal(p);
608
  }
609
}
610

  
611

  
612
/**
613
 * proto_new - create a new protocol instance
614
 * @c: protocol configuration
615
 *
616
 * When a new configuration has been read in, the core code starts
617
 * initializing all the protocol instances configured by calling their
618
 * init() hooks with the corresponding instance configuration. The initialization
619
 * code of the protocol is expected to create a new instance according to the
620
 * configuration by calling this function and then modifying the default settings
621
 * to values wanted by the protocol.
622
 */
623
void *
624
proto_new(struct proto_config *cf)
625
{
626
  struct proto *p = mb_allocz(proto_pool, cf->protocol->proto_size);
627

  
628
  p->cf = cf;
629
  p->debug = cf->debug;
630
  p->mrtdump = cf->mrtdump;
631
  p->name = cf->name;
632
  p->proto = cf->protocol;
633
  p->net_type = cf->net_type;
634
  p->disabled = cf->disabled;
635
  p->hash_key = random_u32();
636
  cf->proto = p;
637

  
638
  init_list(&p->channels);
639

  
640
  return p;
641
}
642

  
643
static struct proto *
644
proto_init(struct proto_config *c, node *n)
645
{
646
  struct protocol *pr = c->protocol;
647
  struct proto *p = pr->init(c);
648

  
649
  p->proto_state = PS_DOWN;
650
  p->last_state_change = now;
651
  insert_node(&p->n, n);
652

  
653
  p->event = ev_new(proto_pool);
654
  p->event->hook = proto_event;
655
  p->event->data = p;
656

  
657
  PD(p, "Initializing%s", p->disabled ? " [disabled]" : "");
658

  
659
  return p;
660
}
661

  
662
static void
663
proto_start(struct proto *p)
664
{
665
  /* Here we cannot use p->cf->name since it won't survive reconfiguration */
666
  p->pool = rp_new(proto_pool, p->proto->name);
667

  
668
  if (graceful_restart_state == GRS_INIT)
669
    p->gr_recovery = 1;
242 670
}
243 671

  
244 672

  
......
263 691
void *
264 692
proto_config_new(struct protocol *pr, int class)
265 693
{
266
  struct proto_config *c = cfg_allocz(pr->config_size);
694
  struct proto_config *cf = cfg_allocz(pr->config_size);
267 695

  
268 696
  if (class == SYM_PROTO)
269
    add_tail(&new_config->protos, &c->n);
270
  c->global = new_config;
271
  c->protocol = pr;
272
  c->name = pr->name;
273
  c->preference = pr->preference;
274
  c->class = class;
275
  c->out_filter = FILTER_REJECT;
276
  c->table = c->global->master_rtc;
277
  c->debug = new_config->proto_default_debug;
278
  c->mrtdump = new_config->proto_default_mrtdump;
279
  return c;
697
    add_tail(&new_config->protos, &cf->n);
698

  
699
  cf->global = new_config;
700
  cf->protocol = pr;
701
  cf->name = pr->name;
702
  cf->class = class;
703
  cf->debug = new_config->proto_default_debug;
704
  cf->mrtdump = new_config->proto_default_mrtdump;
705

  
706
  init_list(&cf->channels);
707

  
708
  return cf;
280 709
}
281 710

  
711

  
282 712
/**
283 713
 * proto_copy_config - copy a protocol configuration
284 714
 * @dest: destination protocol configuration
......
293 723
void
294 724
proto_copy_config(struct proto_config *dest, struct proto_config *src)
295 725
{
726
  struct channel_config *cc;
296 727
  node old_node;
297 728
  int old_class;
298 729
  char *old_name;
......
305 736

  
306 737
  DBG("Copying configuration from %s to %s\n", src->name, dest->name);
307 738

  
308
  /* 
739
  /*
309 740
   * Copy struct proto_config here. Keep original node, class and name.
310 741
   * protocol-specific config copy is handled by protocol copy_config() hook
311 742
   */
......
314 745
  old_class = dest->class;
315 746
  old_name = dest->name;
316 747

  
317
  memcpy(dest, src, sizeof(struct proto_config));
748
  memcpy(dest, src, src->protocol->config_size);
318 749

  
319 750
  dest->n = old_node;
320 751
  dest->class = old_class;
321 752
  dest->name = old_name;
753
  init_list(&dest->channels);
322 754

  
755
  WALK_LIST(cc, src->channels)
756
    channel_copy_config(cc, dest);
757

  
758
  /* FIXME: allow for undefined copy_config */
323 759
  dest->protocol->copy_config(dest, src);
324 760
}
325 761

  
......
339 775
  init_list(&c->protos);
340 776
  DBG("Protocol preconfig:");
341 777
  WALK_LIST(p, protocol_list)
342
    {
343
      DBG(" %s", p->name);
344
      p->name_counter = 0;
345
      if (p->preconfig)
346
	p->preconfig(p, c);
347
    }
348
  DBG("\n");
349
}
350

  
351
/**
352
 * protos_postconfig - post-configuration processing
353
 * @c: new configuration
354
 *
355
 * This function calls the postconfig() hooks of all protocol
356
 * instances specified in configuration @c. The hooks are not
357
 * called for protocol templates.
358
 */
359
void
360
protos_postconfig(struct config *c)
361
{
362
  struct proto_config *x;
363
  struct protocol *p;
364

  
365
  DBG("Protocol postconfig:");
366
  WALK_LIST(x, c->protos)
367
    {
368
      DBG(" %s", x->name);
369

  
370
      p = x->protocol;
371
      if (p->postconfig)
372
	p->postconfig(x);
373
    }
778
  {
779
    DBG(" %s", p->name);
780
    p->name_counter = 0;
781
    if (p->preconfig)
782
      p->preconfig(p, c);
783
  }
374 784
  DBG("\n");
375 785
}
376 786

  
377
extern struct protocol proto_unix_iface;
378

  
379
static struct proto *
380
proto_init(struct proto_config *c)
381
{
382
  struct protocol *p = c->protocol;
383
  struct proto *q = p->init(c);
384

  
385
  q->proto_state = PS_DOWN;
386
  q->core_state = FS_HUNGRY;
387
  q->export_state = ES_DOWN;
388
  q->last_state_change = now;
389

  
390
  add_tail(&initial_proto_list, &q->n);
391

  
392
  if (p == &proto_unix_iface)
393
    initial_device_proto = q;
394

  
395
  add_tail(&proto_list, &q->glob_node);
396
  PD(q, "Initializing%s", q->disabled ? " [disabled]" : "");
397
  return q;
398
}
399

  
400
int proto_reconfig_type;  /* Hack to propagate type info to pipe reconfigure hook */
401

  
402 787
static int
403 788
proto_reconfigure(struct proto *p, struct proto_config *oc, struct proto_config *nc, int type)
404 789
{
......
408 793

  
409 794
  /* If there is a too big change in core attributes, ... */
410 795
  if ((nc->protocol != oc->protocol) ||
411
      (nc->disabled != p->disabled) ||
412
      (nc->table->table != oc->table->table))
796
      (nc->net_type != oc->net_type) ||
797
      (nc->disabled != p->disabled))
798

  
413 799
    return 0;
414 800

  
801
  p->name = nc->name;
415 802
  p->debug = nc->debug;
416 803
  p->mrtdump = nc->mrtdump;
417
  proto_reconfig_type = type;
804
  reconfigure_type = type;
418 805

  
419 806
  /* Execute protocol specific reconfigure hook */
420
  if (! (p->proto->reconfigure && p->proto->reconfigure(p, nc)))
807
  if (!p->proto->reconfigure || !p->proto->reconfigure(p, nc))
421 808
    return 0;
422 809

  
423 810
  DBG("\t%s: same\n", oc->name);
424 811
  PD(p, "Reconfigured");
425 812
  p->cf = nc;
426
  p->name = nc->name;
427
  p->preference = nc->preference;
428

  
429

  
430
  /* Multitable protocols handle rest in their reconfigure hooks */
431
  if (p->proto->multitable)
432
    return 1;
433

  
434
  /* Update filters and limits in the main announce hook
435
     Note that this also resets limit state */
436
  if (p->main_ahook)
437
    {  
438
      struct announce_hook *ah = p->main_ahook;
439
      ah->in_filter = nc->in_filter;
440
      ah->out_filter = nc->out_filter;
441
      ah->rx_limit = nc->rx_limit;
442
      ah->in_limit = nc->in_limit;
443
      ah->out_limit = nc->out_limit;
444
      ah->in_keep_filtered = nc->in_keep_filtered;
445
      proto_verify_limits(ah);
446
    }
447

  
448
  /* Update routes when filters changed. If the protocol in not UP,
449
     it has no routes and we can ignore such changes */
450
  if ((p->proto_state != PS_UP) || (type == RECONFIG_SOFT))
451
    return 1;
452

  
453
  int import_changed = ! filter_same(nc->in_filter, oc->in_filter);
454
  int export_changed = ! filter_same(nc->out_filter, oc->out_filter);
455

  
456
  /* We treat a change in preferences by reimporting routes */
457
  if (nc->preference != oc->preference)
458
    import_changed = 1;
459

  
460
  if (import_changed || export_changed)
461
    log(L_INFO "Reloading protocol %s", p->name);
462

  
463
  /* If import filter changed, call reload hook */
464
  if (import_changed && ! (p->reload_routes && p->reload_routes(p)))
465
    {
466
      /* Now, the protocol is reconfigured. But route reload failed
467
	 and we have to do regular protocol restart. */
468
      log(L_INFO "Restarting protocol %s", p->name);
469
      p->disabled = 1;
470
      p->down_code = PDC_CF_RESTART;
471
      proto_rethink_goal(p);
472
      p->disabled = 0;
473
      proto_rethink_goal(p);
474
      return 1;
475
    }
476

  
477
  if (export_changed)
478
    proto_request_feeding(p);
479 813

  
480 814
  return 1;
481 815
}
......
512 846
protos_commit(struct config *new, struct config *old, int force_reconfig, int type)
513 847
{
514 848
  struct proto_config *oc, *nc;
515
  struct proto *p, *n;
516 849
  struct symbol *sym;
850
  struct proto *p;
851
  node *n;
852

  
517 853

  
518 854
  DBG("protos_commit:\n");
519 855
  if (old)
856
  {
857
    WALK_LIST(oc, old->protos)
520 858
    {
521
      WALK_LIST(oc, old->protos)
522
	{
523
	  p = oc->proto;
524
	  sym = cf_find_symbol(new, oc->name);
525
	  if (sym && sym->class == SYM_PROTO && !new->shutdown)
526
	    {
527
	      /* Found match, let's check if we can smoothly switch to new configuration */
528
	      /* No need to check description */
529
	      nc = sym->def;
530
	      nc->proto = p;
531

  
532
	      /* We will try to reconfigure protocol p */
533
	      if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
534
		continue;
535

  
536
	      /* Unsuccessful, we will restart it */
537
	      if (!p->disabled && !nc->disabled)
538
		log(L_INFO "Restarting protocol %s", p->name);
539
	      else if (p->disabled && !nc->disabled)
540
		log(L_INFO "Enabling protocol %s", p->name);
541
	      else if (!p->disabled && nc->disabled)
542
		log(L_INFO "Disabling protocol %s", p->name);
543

  
544
	      p->down_code = nc->disabled ? PDC_CF_DISABLE : PDC_CF_RESTART;
545
	      p->cf_new = nc;
546
	    }
547
	  else if (!new->shutdown)
548
	    {
549
	      log(L_INFO "Removing protocol %s", p->name);
550
	      p->down_code = PDC_CF_REMOVE;
551
	      p->cf_new = NULL;
552
	    }
553
	  else /* global shutdown */
554
	    {
555
	      p->down_code = PDC_CMD_SHUTDOWN;
556
	      p->cf_new = NULL;
557
	    }
558

  
559
	  p->reconfiguring = 1;
560
	  config_add_obstacle(old);
561
	  proto_rethink_goal(p);
562
	}
859
      p = oc->proto;
860
      sym = cf_find_symbol(new, oc->name);
861
      if (sym && sym->class == SYM_PROTO && !new->shutdown)
862
      {
863
	/* Found match, let's check if we can smoothly switch to new configuration */
864
	/* No need to check description */
865
	nc = sym->def;
866
	nc->proto = p;
867

  
868
	/* We will try to reconfigure protocol p */
869
	if (! force_reconfig && proto_reconfigure(p, oc, nc, type))
870
	  continue;
871

  
872
	/* Unsuccessful, we will restart it */
873
	if (!p->disabled && !nc->disabled)
874
	  log(L_INFO "Restarting protocol %s", p->name);
875
	else if (p->disabled && !nc->disabled)
876
	  log(L_INFO "Enabling protocol %s", p->name);
877
	else if (!p->disabled && nc->disabled)
878
	  log(L_INFO "Disabling protocol %s", p->name);
879

  
880
	p->down_code = nc->disabled ? PDC_CF_DISABLE : PDC_CF_RESTART;
881
	p->cf_new = nc;
882
      }
883
      else if (!new->shutdown)
884
      {
885
	log(L_INFO "Removing protocol %s", p->name);
886
	p->down_code = PDC_CF_REMOVE;
887
	p->cf_new = NULL;
888
      }
889
      else /* global shutdown */
890
      {
891
	p->down_code = PDC_CMD_SHUTDOWN;
892
	p->cf_new = NULL;
893
      }
894

  
895
      p->reconfiguring = 1;
896
      config_add_obstacle(old);
897
      proto_rethink_goal(p);
563 898
    }
899
  }
900

  
901
  struct proto *first_dev_proto = NULL;
564 902

  
903
  n = NODE &(proto_list.head);
565 904
  WALK_LIST(nc, new->protos)
566 905
    if (!nc->proto)
567
      {
568
	if (old)		/* Not a first-time configuration */
569
	  log(L_INFO "Adding protocol %s", nc->name);
570
	proto_init(nc);
571
      }
572
  DBG("\tdone\n");
906
    {
907
      /* Not a first-time configuration */
908
      if (old)
909
	log(L_INFO "Adding protocol %s", nc->name);
910

  
911
      p = proto_init(nc, n);
912
      n = NODE p;
913

  
914
      if (p->proto == &proto_unix_iface)
915
	first_dev_proto = p;
916
    }
917
    else
918
      n = NODE nc->proto;
573 919

  
574 920
  DBG("Protocol start\n");
575 921

  
576 922
  /* Start device protocol first */
577
  if (initial_device_proto)
578
  {
579
    proto_rethink_goal(initial_device_proto);
580
    initial_device_proto = NULL;
581
  }
923
  if (first_dev_proto)
924
    proto_rethink_goal(first_dev_proto);
582 925

  
583 926
  /* Determine router ID for the first time - it has to be here and not in
584 927
     global_commit() because it is postponed after start of device protocol */
585 928
  if (!config->router_id)
586
    {
587
      config->router_id = if_choose_router_id(config->router_id_from, 0);
588
      if (!config->router_id)
589
	die("Cannot determine router ID, please configure it manually");
590
    }
929
  {
930
    config->router_id = if_choose_router_id(config->router_id_from, 0);
931
    if (!config->router_id)
932
      die("Cannot determine router ID, please configure it manually");
933
  }
591 934

  
592
  /* Start all other protocols */
593
  WALK_LIST_DELSAFE(p, n, initial_proto_list)
935
  /* Start all new protocols */
936
  WALK_LIST_DELSAFE(p, n, proto_list)
594 937
    proto_rethink_goal(p);
595 938
}
596 939

  
......
600 943
  struct protocol *q;
601 944
  byte goal;
602 945

  
603
  if (p->reconfiguring && p->core_state == FS_HUNGRY && p->proto_state == PS_DOWN)
604
    {
605
      struct proto_config *nc = p->cf_new;
606
      DBG("%s has shut down for reconfiguration\n", p->name);
607
      p->cf->proto = NULL;
608
      config_del_obstacle(p->cf->global);
609
      rem_node(&p->n);
610
      rem_node(&p->glob_node);
611
      mb_free(p);
612
      if (!nc)
613
	return;
614
      p = proto_init(nc);
615
    }
946
  if (p->reconfiguring && !p->active)
947
  {
948
    struct proto_config *nc = p->cf_new;
949
    node *n = p->n.prev;
950
    DBG("%s has shut down for reconfiguration\n", p->name);
951
    p->cf->proto = NULL;
952
    config_del_obstacle(p->cf->global);
953
    proto_remove_channels(p);
954
    rem_node(&p->n);
955
    rfree(p->event);
956
    mb_free(p);
957
    if (!nc)
958
      return;
959
    p = proto_init(nc, n);
960
  }
616 961

  
617 962
  /* Determine what state we want to reach */
618 963
  if (p->disabled || p->reconfiguring)
......
621 966
    goal = PS_UP;
622 967

  
623 968
  q = p->proto;
624
  if (goal == PS_UP) 			/* Going up */
969
  if (goal == PS_UP)
970
  {
971
    if (!p->active)
625 972
    {
626
      if (p->proto_state == PS_DOWN && p->core_state == FS_HUNGRY)
627
	{
628
	  DBG("Kicking %s up\n", p->name);
629
	  PD(p, "Starting");
630
	  proto_init_instance(p);
631
	  proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
632
	}
973
      /* Going up */
974
      DBG("Kicking %s up\n", p->name);
975
      PD(p, "Starting");
976
      proto_start(p);
977
      proto_notify_state(p, (q->start ? q->start(p) : PS_UP));
633 978
    }
634
  else 					/* Going down */
979
  }
980
  else
981
  {
982
    if (p->proto_state == PS_START || p->proto_state == PS_UP)
635 983
    {
636
      if (p->proto_state == PS_START || p->proto_state == PS_UP)
637
	{
638
	  DBG("Kicking %s down\n", p->name);
639
	  PD(p, "Shutting down");
640
	  proto_notify_state(p, (q->shutdown ? q->shutdown(p) : PS_DOWN));
641
	}
984
      /* Going down */
985
      DBG("Kicking %s down\n", p->name);
986
      PD(p, "Shutting down");
987
      proto_notify_state(p, (q->shutdown ? q->shutdown(p) : PS_DOWN));
642 988
    }
989
  }
643 990
}
644 991

  
645 992

  
......
661 1008
 * When graceful restart recovery need is detected during initialization, then
662 1009
 * enabled protocols are marked with @gr_recovery flag before start. Such
663 1010
 * protocols then decide how to proceed with graceful restart, participation is
664
 * voluntary. Protocols could lock the recovery by proto_graceful_restart_lock()
665
 * (stored in @gr_lock flag), which means that they want to postpone the end of
666
 * the recovery until they converge and then unlock it. They also could set
667
 * @gr_wait before advancing to %PS_UP, which means that the core should defer
668
 * route export to that protocol until the end of the recovery. This should be
669
 * done by protocols that expect their neigbors to keep the proper routes
670
 * (kernel table, BGP sessions with BGP graceful restart capability).
1011
 * voluntary. Protocols could lock the recovery for each channel by function
1012
 * channel_graceful_restart_lock() (starte stored in @gr_lock flag), which means
1013
 * that they want to postpone the end of the recovery until they converge and
1014
 * then unlock it. They also could set @gr_wait before advancing to %PS_UP,
1015
 * which means that the core should defer route export to that channel until
1016
 * the end of the recovery. This should be done by protocols that expect their
1017
 * neigbors to keep the proper routes (kernel table, BGP sessions with BGP
1018
 * graceful restart capability).
671 1019
 *
672 1020
 * The graceful restart recovery is finished when either all graceful restart
673 1021
 * locks are unlocked or when graceful restart wait timer fires.
......
705 1053
  log(L_INFO "Graceful restart started");
706 1054

  
707 1055
  if (!graceful_restart_locks)
708
    {
709
      graceful_restart_done(NULL);
710
      return;
711
    }
1056
  {
1057
    graceful_restart_done(NULL);
1058
    return;
1059
  }
712 1060

  
713 1061
  graceful_restart_state = GRS_ACTIVE;
714 1062
  gr_wait_timer = tm_new(proto_pool);
......
728 1076
static void
729 1077
graceful_restart_done(struct timer *t UNUSED)
730 1078
{
731
  struct proto *p;
732
  node *n;
733

  
734 1079
  log(L_INFO "Graceful restart done");
735 1080
  graceful_restart_state = GRS_DONE;
736 1081

  
737
  WALK_LIST2(p, n, proto_list, glob_node)
738
    {
739
      if (!p->gr_recovery)
740
	continue;
1082
  struct proto *p;
1083
  WALK_LIST(p, proto_list)
1084
  {
1085
    if (!p->gr_recovery)
1086
      continue;
741 1087

  
1088
    struct channel *c;
1089
    WALK_LIST(c, p->channels)
1090
    {
742 1091
      /* Resume postponed export of routes */
743
      if ((p->proto_state == PS_UP) && p->gr_wait)
744
      {
745
	proto_want_export_up(p);
746
	proto_log_state_change(p);
747
      }
1092
      if ((c->channel_state == CS_UP) && c->gr_wait)
1093
	channel_start_export(c);
748 1094

  
749 1095
      /* Cleanup */
750
      p->gr_recovery = 0;
751
      p->gr_wait = 0;
752
      p->gr_lock = 0;
1096
      c->gr_wait = 0;
1097
      c->gr_lock = 0;
753 1098
    }
754 1099

  
1100
    p->gr_recovery = 0;
1101
  }
1102

  
755 1103
  graceful_restart_locks = 0;
756 1104
}
757 1105

  
......
762 1110
    return;
763 1111

  
764 1112
  cli_msg(-24, "Graceful restart recovery in progress");
765
  cli_msg(-24, "  Waiting for %d protocols to recover", graceful_restart_locks);
1113
  cli_msg(-24, "  Waiting for %d channels to recover", graceful_restart_locks);
766 1114
  cli_msg(-24, "  Wait timer is %d/%d", tm_remains(gr_wait_timer), config->gr_wait);
767 1115
}
768 1116

  
769 1117
/**
770
 * proto_graceful_restart_lock - lock graceful restart by protocol
771
 * @p: protocol instance
1118
 * channel_graceful_restart_lock - lock graceful restart by channel
1119
 * @p: channel instance
772 1120
 *
773 1121
 * This function allows a protocol to postpone the end of graceful restart
774 1122
 * recovery until it converges. The lock is removed when the protocol calls
775
 * proto_graceful_restart_unlock() or when the protocol is stopped.
1123
 * channel_graceful_restart_unlock() or when the channel is closed.
776 1124
 *
777 1125
 * The function have to be called during the initial phase of graceful restart
778 1126
 * recovery and only for protocols that are part of graceful restart (i.e. their
......
780 1128
 * hooks.
781 1129
 */
782 1130
void
783
proto_graceful_restart_lock(struct proto *p)
1131
channel_graceful_restart_lock(struct channel *c)
784 1132
{
785 1133
  ASSERT(graceful_restart_state == GRS_INIT);
786
  ASSERT(p->gr_recovery);
1134
  ASSERT(c->proto->gr_recovery);
787 1135

  
788
  if (p->gr_lock)
1136
  if (c->gr_lock)
789 1137
    return;
790 1138

  
791
  p->gr_lock = 1;
1139
  c->gr_lock = 1;
792 1140
  graceful_restart_locks++;
793 1141
}
794 1142

  
795 1143
/**
796
 * proto_graceful_restart_unlock - unlock graceful restart by protocol
797
 * @p: protocol instance
1144
 * channel_graceful_restart_unlock - unlock graceful restart by channel
1145
 * @p: channel instance
798 1146
 *
799
 * This function unlocks a lock from proto_graceful_restart_lock(). It is also
1147
 * This function unlocks a lock from channel_graceful_restart_lock(). It is also
800 1148
 * automatically called when the lock holding protocol went down.
801 1149
 */
802 1150
void
803
proto_graceful_restart_unlock(struct proto *p)
1151
channel_graceful_restart_unlock(struct channel *c)
804 1152
{
805
  if (!p->gr_lock)
1153
  if (!c->gr_lock)
806 1154
    return;
807 1155

  
808
  p->gr_lock = 0;
1156
  c->gr_lock = 0;
809 1157
  graceful_restart_locks--;
810 1158

  
811 1159
  if ((graceful_restart_state == GRS_ACTIVE) && !graceful_restart_locks)
......
826 1174
void
827 1175
protos_dump_all(void)
828 1176
{
829
  struct proto *p;
830
  struct announce_hook *a;
831

  
832 1177
  debug("Protocols:\n");
833 1178

  
834
  WALK_LIST(p, active_proto_list)
1179
  struct proto *p;
1180
  WALK_LIST(p, proto_list)
1181
  {
1182
    debug("  protocol %s state %s\n", p->name, p_states[p->proto_state]);
1183

  
1184
    struct channel *c;
1185
    WALK_LIST(c, p->channels)
835 1186
    {
836
      debug("  protocol %s state %s/%s\n", p->name,
837
	    p_states[p->proto_state], c_states[p->core_state]);
838
      for (a = p->ahooks; a; a = a->next)
839
	{
840
	  debug("\tTABLE %s\n", a->table->name);
841
	  if (a->in_filter)
842
	    debug("\tInput filter: %s\n", filter_name(a->in_filter));
843
	  if (a->out_filter != FILTER_REJECT)
844
	    debug("\tOutput filter: %s\n", filter_name(a->out_filter));
845
	}
846
      if (p->disabled)
847
	debug("\tDISABLED\n");
848
      else if (p->proto->dump)
849
	p->proto->dump(p);
1187
      debug("\tTABLE %s\n", c->table->name);
1188
      if (c->in_filter)
1189
	debug("\tInput filter: %s\n", filter_name(c->in_filter));
1190
      if (c->out_filter)
1191
	debug("\tOutput filter: %s\n", filter_name(c->out_filter));
850 1192
    }
851
  WALK_LIST(p, inactive_proto_list)
852
    debug("  inactive %s: state %s/%s\n", p->name, p_states[p->proto_state], c_states[p->core_state]);
853
  WALK_LIST(p, initial_proto_list)
854
    debug("  initial %s\n", p->name);
855
  WALK_LIST(p, flush_proto_list)
856
    debug("  flushing %s\n", p->name);
1193

  
1194
    if (p->proto->dump && (p->proto_state != PS_DOWN))
1195
      p->proto->dump(p);
1196
  }
857 1197
}
858 1198

  
859 1199
/**
......
890 1230
void
891 1231
protos_build(void)
892 1232
{
893
  init_list(&protocol_list);
894 1233
  init_list(&proto_list);
895
  init_list(&active_proto_list);
896
  init_list(&inactive_proto_list);
897
  init_list(&initial_proto_list);
898
  init_list(&flush_proto_list);
1234
  init_list(&protocol_list);
1235

  
899 1236
  proto_build(&proto_device);
900 1237
#ifdef CONFIG_RADV
901 1238
  proto_build(&proto_radv);
......
921 1258
#endif
922 1259

  
923 1260
  proto_pool = rp_new(&root_pool, "Protocols");
924
  proto_flush_event = ev_new(proto_pool);
925
  proto_flush_event->hook = proto_flush_loop;
926 1261
  proto_shutdown_timer = tm_new(proto_pool);
927 1262
  proto_shutdown_timer->hook = proto_shutdown_loop;
928 1263
}
929 1264

  
930
static void
931
proto_feed_more(void *P)
932
{
933
  struct proto *p = P;
934

  
935
  if (p->export_state != ES_FEEDING)
936
    return;
937

  
938
  DBG("Feeding protocol %s continued\n", p->name);
939
  if (rt_feed_baby(p))
940
    {
941
      DBG("Feeding protocol %s finished\n", p->name);
942
      p->export_state = ES_READY;
943
      proto_log_state_change(p);
944

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff