Revision cf7f0645 nest/neighbor.c

View differences:

nest/neighbor.c
103 103
 * If the node is not connected directly or *@a is not a valid unicast
104 104
 * IP address, neigh_find() returns %NULL.
105 105
 */
106

  
107

  
108 106
neighbor *
109 107
neigh_find(struct proto *p, ip_addr *a, unsigned flags)
110 108
{
......
219 217
  debug("\n");
220 218
}
221 219

  
220
static void
221
neigh_up(neighbor *n, struct iface *i, int scope)
222
{
223
  n->iface = i;
224
  n->scope = scope;
225
  add_tail(&i->neighbors, &n->if_n);
226
  rem_node(&n->n);
227
  add_tail(&neigh_hash_table[neigh_hash(n->proto, &n->addr)], &n->n);
228
  DBG("Waking up sticky neighbor %I\n", n->addr);
229
  if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
230
    n->proto->neigh_notify(n);
231
}
232

  
233
static void
234
neigh_down(neighbor *n)
235
{
236
  DBG("Flushing neighbor %I on %s\n", n->addr, i->name);
237
  rem_node(&n->if_n);
238
  n->iface = NULL;
239
  if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
240
    n->proto->neigh_notify(n);
241
  rem_node(&n->n);
242
  if (n->flags & NEF_STICKY)
243
    add_tail(&sticky_neigh_list, &n->n);
244
  else
245
    sl_free(neigh_slab, n);
246
}
247

  
248

  
222 249
/**
223 250
 * neigh_if_up: notify neighbor cache about interface up event
224 251
 * @i: interface in question
......
236 263

  
237 264
  WALK_LIST_DELSAFE(n, next, sticky_neigh_list)
238 265
    if ((scope = if_connected(&n->addr, i)) >= 0)
239
      {
240
	n->iface = i;
241
	n->scope = scope;
242
	add_tail(&i->neighbors, &n->if_n);
243
	rem_node(&n->n);
244
	add_tail(&neigh_hash_table[neigh_hash(n->proto, &n->addr)], &n->n);
245
	DBG("Waking up sticky neighbor %I\n", n->addr);
246
	if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
247
	  n->proto->neigh_notify(n);
248
      }
266
      neigh_up(n, i, scope);
249 267
}
250 268

  
251 269
/**
......
263 281
  node *x, *y;
264 282

  
265 283
  WALK_LIST_DELSAFE(x, y, i->neighbors)
266
    {
267
      neighbor *n = SKIP_BACK(neighbor, if_n, x);
268
      DBG("Flushing neighbor %I on %s\n", n->addr, i->name);
269
      rem_node(&n->if_n);
270
      n->iface = NULL;
271
      if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
272
	n->proto->neigh_notify(n);
273
      rem_node(&n->n);
274
      if (n->flags & NEF_STICKY)
275
	add_tail(&sticky_neigh_list, &n->n);
276
      else
277
	sl_free(neigh_slab, n);
278
    }
284
    neigh_down(SKIP_BACK(neighbor, if_n, x));
279 285
}
280 286

  
281 287
/**
......
286 292
 * All owners of neighbor entries connected to this interface are
287 293
 * notified.
288 294
 */
289

  
290 295
void
291 296
neigh_if_link(struct iface *i)
292 297
{
......
300 305
    }
301 306
}
302 307

  
308
/**
309
 * neigh_ifa_update: notify neighbor cache about interface address add or remove event
310
 * @ifa: interface address in question
311
 *
312
 * Tell the neighbor cache that an address was added or removed.
313
 *
314
 * The neighbor cache wakes up all inactive sticky neighbors with
315
 * addresses belonging to prefixes of the interface belonging to @ifa
316
 * and causes all unreachable neighbors to be flushed.
317
 */
318
void
319
neigh_ifa_update(struct ifa *a)
320
{
321
  struct iface *i = a->iface;
322
  node *x, *y;
323
 
324
  /* Remove all neighbors whose scope has changed */
325
  WALK_LIST_DELSAFE(x, y, i->neighbors)
326
    {
327
      neighbor *n = SKIP_BACK(neighbor, if_n, x);
328
      if (if_connected(&n->addr, i) != n->scope)
329
	neigh_down(n);
330
    }
331

  
332
  /* Wake up all sticky neighbors that are reachable now */
333
  neigh_if_up(i);
334
}
335

  
303 336
static inline void
304 337
neigh_prune_one(neighbor *n)
305 338
{

Also available in: Unified diff