Revision 11361a10

View differences:

nest/proto.c
585 585
{
586 586
  DBG("%s: Scheduling meal\n", p->name);
587 587
  p->core_state = FS_FEEDING;
588
  p->refeeding = !initial;
588 589
  proto_relink(p);
589 590
  p->attn->hook = initial ? proto_feed_initial : proto_feed_more;
590 591
  ev_schedule(p->attn);
nest/protocol.h
134 134
  unsigned core_state;			/* Core state machine (see below) */
135 135
  unsigned core_goal;			/* State we want to reach (see below) */
136 136
  unsigned reconfiguring;		/* We're shutting down due to reconfiguration */
137
  unsigned refeeding;			/* We are refeeding (valid only if core_state == FS_FEEDING) */
137 138
  u32 hash_key;				/* Random key used for hashing of neighbors */
138 139
  bird_clock_t last_state_change;	/* Time of last state transition */
139 140
  char *last_state_name_announced;	/* Last state name we've announced to the user */
nest/rt-table.c
158 158
}
159 159

  
160 160
static inline void
161
do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class)
161
do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed)
162 162
{
163 163
  struct proto *p = a->proto;
164 164
  rte *new0 = new;
......
199 199
  else
200 200
    p->stats.exp_withdraws_received++;
201 201

  
202
  /* This is a tricky part - we don't know whether route 'old' was
203
     exported to protocol 'p' or was filtered by the export filter.
204
     We try tu run the export filter to know this to have a correct
205
     value in 'old' argument of rt_update (and proper filter value)
206

  
207
     FIXME - this is broken because 'configure soft' may change
208
     filters but keep routes */
209

  
210
  if (old)
202
  /*
203
   * This is a tricky part - we don't know whether route 'old' was
204
   * exported to protocol 'p' or was filtered by the export filter.
205
   * We try tu run the export filter to know this to have a correct
206
   * value in 'old' argument of rt_update (and proper filter value)
207
   *
208
   * FIXME - this is broken because 'configure soft' may change
209
   * filters but keep routes. Refeed is expected to be called after
210
   * change of the filters and with old == new, therefore we do not
211
   * even try to run the filter on an old route, This may lead to 
212
   * 'spurious withdraws' but ensure that there are no 'missing
213
   * withdraws'.
214
   *
215
   * This is not completely safe as there is a window between
216
   * reconfiguration and the end of refeed - if a newly filtered
217
   * route disappears during this period, proper withdraw is not
218
   * sent (because old would be also filtered) and the route is
219
   * not refeeded (because it disappeared before that).
220
   */
221

  
222
  if (old && !refeed)
211 223
    {
212 224
      if (p->out_filter == FILTER_REJECT)
213 225
	old = NULL;
......
313 325
    {
314 326
      ASSERT(a->proto->core_state == FS_HAPPY || a->proto->core_state == FS_FEEDING);
315 327
      if (a->proto->accept_ra_types == type)
316
	do_rte_announce(a, type, net, new, old, tmpa, class);
328
	do_rte_announce(a, type, net, new, old, tmpa, class, 0);
317 329
    }
318 330
}
319 331

  
......
973 985

  
974 986
  rte_update_lock();
975 987
  tmpa = q->make_tmp_attrs ? q->make_tmp_attrs(e, rte_update_pool) : NULL;
976
  do_rte_announce(h, type, n, e, NULL, tmpa, ipa_classify(n->n.prefix));
988
  do_rte_announce(h, type, n, e, p->refeeding ? e : NULL, tmpa, ipa_classify(n->n.prefix), p->refeeding);
977 989
  rte_update_unlock();
978 990
}
979 991

  

Also available in: Unified diff