Revision a2697f02

View differences:

TODO
26 26
- iface: when seen an invalid broadcast, fix it up or at least report
27 27
- iface: we always need ifindex at least for PtP links (OSPF)
28 28
- iface: interface filters should support filtering by IP address as well
29
- iface: SIOCGIFINDEX exists on glibc systems, but it doesn't work on 2.0.x kernels!
29 30

  
30 31
- socket: Use IP_RECVERR for BGP TCP sockets?
31 32

  
nest/iface.c
361 361
	    DBG("Interface %s changed too much -- forcing down/up transition\n", i->name);
362 362
	    if_change_flags(i, i->flags | IF_TMP_DOWN);
363 363
	    rem_node(&i->n);
364
	    WALK_LIST_DELSAFE(a, b, i->addrs)
365
	      ifa_delete(a);
364
	    new->addr = i->addr;
365
	    memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
366
	    memcpy(i, new, sizeof(*i));
366 367
	    goto newif;
367 368
	  }
368 369
	else if (c)
......
374 375
	return i;
375 376
      }
376 377
  i = mb_alloc(if_pool, sizeof(struct iface));
377
newif:
378 378
  memcpy(i, new, sizeof(*i));
379 379
  init_list(&i->addrs);
380
newif:
380 381
  i->flags |= IF_UPDATED | IF_TMP_DOWN;		/* Tmp down as we don't have addresses yet */
381 382
  add_tail(&iface_list, &i->n);
382 383
  return i;
......
543 544
	    ifa_recalc_primary(i);
544 545
	  }
545 546
	mb_free(b);
547
	return;
546 548
      }
547 549
}
548 550

  
sysdep/linux/netlink/netlink.c
316 316
  struct ifaddrmsg *i;
317 317
  struct rtattr *a[IFA_ANYCAST+1];
318 318
  int new = h->nlmsg_type == RTM_NEWADDR;
319
  struct iface f;
319
  struct ifa ifa;
320 320
  struct iface *ifi;
321 321

  
322 322
  if (!(i = nl_checkin(h, sizeof(*i))) || !nl_parse_attrs(IFA_RTA(i), a, sizeof(a)))
......
330 330
      log(L_ERR "nl_parse_addr: Malformed message received");
331 331
      return;
332 332
    }
333
  if (i->ifa_flags & IFA_F_SECONDARY)
334
    {
335
      DBG("KIF: Received address message for secondary address which is not supported.\n"); /* FIXME */
336
      return;
337
    }
338 333

  
339 334
  ifi = if_find_by_index(i->ifa_index);
340 335
  if (!ifi)
......
342 337
      log(L_ERR "KIF: Received address message for unknown interface %d\n", i->ifa_index);
343 338
      return;
344 339
    }
345
  memcpy(&f, ifi, sizeof(f));
346 340

  
347 341
  if (i->ifa_prefixlen > 32 || i->ifa_prefixlen == 31 ||
348
      (f.flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
342
      (ifi->flags & IF_UNNUMBERED) && i->ifa_prefixlen != 32)
349 343
    {
350
      log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", f.name, i->ifa_prefixlen);
344
      log(L_ERR "KIF: Invalid prefix length for interface %s: %d\n", ifi->name, i->ifa_prefixlen);
351 345
      new = 0;
352 346
    }
353 347

  
354
  f.ip = f.brd = f.opposite = IPA_NONE;
355
  if (!new)
348
  bzero(&ifa, sizeof(ifa));
349
  ifa.iface = ifi;
350
  if (i->ifa_flags & IFA_F_SECONDARY)
351
    ifa.flags |= IA_SECONDARY;
352
  memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(ifa.ip));
353
  ifa.ip = ipa_ntoh(ifa.ip);
354
  ifa.pxlen = i->ifa_prefixlen;
355
  if (ifi->flags & IF_UNNUMBERED)
356 356
    {
357
      DBG("KIF: IF%d IP address deleted\n");
358
      f.pxlen = 0;
357
      memcpy(&ifa.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(ifa.opposite));
358
      ifa.opposite = ifa.brd = ipa_ntoh(ifa.opposite);
359 359
    }
360
  else
360
  else if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
361 361
    {
362
      memcpy(&f.ip, RTA_DATA(a[IFA_LOCAL]), sizeof(f.ip));
363
      f.ip = ipa_ntoh(f.ip);
364
      f.pxlen = i->ifa_prefixlen;
365
      if (f.flags & IF_UNNUMBERED)
366
	{
367
	  memcpy(&f.opposite, RTA_DATA(a[IFA_ADDRESS]), sizeof(f.opposite));
368
	  f.opposite = f.brd = ipa_ntoh(f.opposite);
369
	}
370
      else if ((f.flags & IF_BROADCAST) && a[IFA_BROADCAST])
371
	{
372
	  memcpy(&f.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(f.brd));
373
	  f.brd = ipa_ntoh(f.brd);
374
	}
375
      /* else a NBMA link */
376
      f.prefix = ipa_and(f.ip, ipa_mkmask(f.pxlen));
377
      DBG("KIF: IF%d IP address set to %I, net %I/%d, brd %I, opp %I\n", f.index, f.ip, f.prefix, f.pxlen, f.brd, f.opposite);
362
      memcpy(&ifa.brd, RTA_DATA(a[IFA_BROADCAST]), sizeof(ifa.brd));
363
      ifa.brd = ipa_ntoh(ifa.brd);
378 364
    }
379
  if_update(&f);
365
  /* else a NBMA link */
366
  ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(ifa.pxlen));
367

  
368
  DBG("KIF: IF%d(%s): %s IPA %I, net %I/%d, brd %I, opp %I\n",
369
      ifi->index, ifi->name,
370
      new ? "added" : "removed",
371
      ifa.ip, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
372
  if (new)
373
    ifa_update(&ifa);
374
  else
375
    ifa_delete(&ifa);
380 376
}
381 377

  
382 378
void

Also available in: Unified diff