Revision 2d0b7e24 nest/neighbor.c

View differences:

nest/neighbor.c
56 56
}
57 57

  
58 58
static int
59
if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
59
if_connected(ip_addr *a, struct iface *i, struct ifa **ap)
60 60
{
61 61
  struct ifa *b;
62 62

  
63 63
  if (!(i->flags & IF_UP))
64
  {
65
    *ap = NULL;
64 66
    return -1;
67
  }
68

  
65 69
  WALK_LIST(b, i->addrs)
66 70
    {
71
      *ap = b;
72

  
67 73
      if (ipa_equal(*a, b->ip))
68 74
	return SCOPE_HOST;
69 75
      if (b->flags & IA_PEER)
......
79 85
	      if ((b->pxlen < (BITS_PER_IP_ADDRESS - 1)) &&
80 86
		  (ipa_equal(*a, b->prefix) ||	/* Network address */
81 87
		   ipa_equal(*a, b->brd)))	/* Broadcast */
88
	      {
89
		*ap = NULL;
82 90
		return -1;
91
	      }
83 92
#endif
84 93

  
85 94
	      return b->scope;
86 95
	    }
87 96
	}
88 97
      }
98

  
99
  *ap = NULL;
89 100
  return -1;
90 101
}
91 102

  
......
117 128
  int class, scope = -1;
118 129
  unsigned int h = neigh_hash(p, a);
119 130
  struct iface *i;
131
  struct ifa *addr;
120 132

  
121 133
  WALK_LIST(n, neigh_hash_table[h])	/* Search the cache */
122 134
    if (n->proto == p && ipa_equal(*a, n->addr) && (!ifa || (ifa == n->iface)))
......
132 144

  
133 145
  if (ifa)
134 146
    {
135
      scope = if_connected(a, ifa);
147
      scope = if_connected(a, ifa, &addr);
136 148
      flags |= NEF_BIND;
137 149

  
138 150
      if ((scope < 0) && (flags & NEF_ONLINK))
......
140 152
    }
141 153
  else
142 154
    WALK_LIST(i, iface_list)
143
      if ((scope = if_connected(a, i)) >= 0)
155
      if ((scope = if_connected(a, i, &addr)) >= 0)
144 156
	{
145 157
	  ifa = i;
146 158
	  break;
......
165 177
      scope = -1;
166 178
    }
167 179
  n->iface = ifa;
180
  n->ifa = addr;
168 181
  n->proto = p;
169 182
  n->data = NULL;
170 183
  n->aux = 0;
......
216 229
}
217 230

  
218 231
static void
219
neigh_up(neighbor *n, struct iface *i, int scope)
232
neigh_up(neighbor *n, struct iface *i, int scope, struct ifa *a)
220 233
{
221 234
  n->iface = i;
235
  n->ifa = a;
222 236
  n->scope = scope;
223 237
  add_tail(&i->neighbors, &n->if_n);
224 238
  rem_node(&n->n);
......
235 249
  rem_node(&n->if_n);
236 250
  if (! (n->flags & NEF_BIND))
237 251
    n->iface = NULL;
252
  n->ifa = NULL;
238 253
  n->scope = -1;
239 254
  if (n->proto->neigh_notify && n->proto->core_state != FS_FLUSHING)
240 255
    n->proto->neigh_notify(n);
......
245 260

  
246 261
      /* Respawn neighbor if there is another matching prefix */
247 262
      struct iface *i;
263
      struct ifa *a;
248 264
      int scope;
249 265

  
250 266
      if (!n->iface)
251 267
	WALK_LIST(i, iface_list)
252
	  if ((scope = if_connected(&n->addr, i)) >= 0)
268
	  if ((scope = if_connected(&n->addr, i, &a)) >= 0)
253 269
	    {
254
	      neigh_up(n, i, scope);
270
	      neigh_up(n, i, scope, a);
255 271
	      return;
256 272
	    }
257 273
    }
......
272 288
void
273 289
neigh_if_up(struct iface *i)
274 290
{
291
  struct ifa *a;
275 292
  neighbor *n, *next;
276 293
  int scope;
277 294

  
278 295
  WALK_LIST_DELSAFE(n, next, sticky_neigh_list)
279 296
    if ((!n->iface || n->iface == i) &&
280
	((scope = if_connected(&n->addr, i)) >= 0))
281
      neigh_up(n, i, scope);
297
	((scope = if_connected(&n->addr, i, &a)) >= 0))
298
      neigh_up(n, i, scope, a);
282 299
}
283 300

  
284 301
/**
......
339 356
  /* Remove all neighbors whose scope has changed */
340 357
  WALK_LIST_DELSAFE(x, y, i->neighbors)
341 358
    {
359
      struct ifa *aa;
342 360
      neighbor *n = SKIP_BACK(neighbor, if_n, x);
343
      if (if_connected(&n->addr, i) != n->scope)
361
      if (if_connected(&n->addr, i, &aa) != n->scope)
344 362
	neigh_down(n);
345 363
    }
346 364

  

Also available in: Unified diff