Revision 9b136840

View differences:

lib/Modules
31 31
checksum.c
32 32
checksum.h
33 33
alloca.h
34
net.c
lib/net.c
8 8
  [NET_IP6] = sizeof(net_addr_ip6),
9 9
  [NET_VPN4] = sizeof(net_addr_vpn4),
10 10
  [NET_VPN6] = sizeof(net_addr_vpn6)
11
}
11
};
12 12

  
13
char *
13
int
14 14
net_format(const net_addr *N, char *buf, int buflen)
15 15
{
16 16
  net_addr_union *n = (void *) N;
......
27 27
  case NET_VPN6:
28 28
    return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
29 29
  }
30

  
31
  return 0;
32
}
33

  
34

  
35
ip_addr
36
net_pxmask(const net_addr *a)
37
{
38
  switch (a->type)
39
  {
40
  case NET_IP4:
41
  case NET_VPN4:
42
    return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
43

  
44
  case NET_IP6:
45
  case NET_VPN6:
46
    return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
47

  
48
  default:
49
    return IPA_NONE;
50
  }
51
}
52

  
53

  
54
static inline int net_validate_ip4(const net_addr_ip4 *n)
55
{
56
  return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
57
    ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
58
}
59

  
60
static inline int net_validate_ip6(const net_addr_ip6 *n)
61
{
62
  return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
63
    ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
64
}
65

  
66
int
67
net_validate(const net_addr *N)
68
{
69
  switch (a->type)
70
  {
71
  case NET_IP4:
72
  case NET_VPN4:
73
    return net_validate_ip4((net_addr_ip4 *) N);
74

  
75
  case NET_IP6:
76
  case NET_VPN6:
77
    return net_validate_ip6((net_addr_ip6 *) N);
78

  
79
  default:
80
    return 0;
81
  }
30 82
}
31 83

  
32 84
int
......
42 94

  
43 95
  case NET_IP6:
44 96
  case NET_VPN6:
45
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(n->ip6.prefix);
97
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
46 98
  }
99

  
100
  return 0;
47 101
}
lib/net.h
131 131
static inline uint net_pxlen(const net_addr *a)
132 132
{ return a->pxlen; }
133 133

  
134
ip_addr net_pxmask(const net_addr *a);
135

  
134 136

  
135 137
static inline int net_equal(const net_addr *a, const net_addr *b)
136 138
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
......
203 205
void net_normalize(net_addr *N);
204 206

  
205 207
int net_validate(const net_addr *N);
208

  
206 209
int net_classify(const net_addr *N);
207
char * net_format(const net_addr *N, char *buf, int buflen);
210
int net_format(const net_addr *N, char *buf, int buflen);
208 211

  
209 212

  
210 213
int ipa_in_netX(const ip_addr A, const net_addr *N);
nest/neighbor.c
81 81
	{
82 82
	  if (ipa_in_netX(*a, &b->prefix))
83 83
	    {
84
#ifndef IPV6
85
	      if ((b->pxlen < (BITS_PER_IP_ADDRESS - 1)) &&
86
		  (ipa_equal(*a, b->prefix) ||	/* Network address */
84
	      /* Do not allow IPv4 network and broadcast addresses */
85
	      if (ipa_is_ip4(*a) &&
86
		  (net_pxlen(&b->prefix) < (BITS_PER_IP_ADDRESS - 1)) &&
87
		  (ipa_equal(*a, net_prefix(&b->prefix)) ||	/* Network address */
87 88
		   ipa_equal(*a, b->brd)))	/* Broadcast */
88 89
	      {
89 90
		*ap = NULL;
90 91
		return -1;
91 92
	      }
92
#endif
93 93

  
94 94
	      return b->scope;
95 95
	    }
sysdep/bsd/krt-sock.c
207 207
  msg.rtm.rtm_addrs = RTA_DST;
208 208
  msg.rtm.rtm_flags = RTF_UP | RTF_PROTO1;
209 209

  
210
  if (net->n.pxlen == MAX_PREFIX_LENGTH)
210
  if (net_prefix(net->n.addr) == MAX_PREFIX_LENGTH)
211 211
    msg.rtm.rtm_flags |= RTF_HOST;
212 212
  else
213 213
    msg.rtm.rtm_addrs |= RTA_NETMASK;
......
251 251
    _I0(gw) = 0xfe800000 | (i->index & 0x0000ffff);
252 252
#endif
253 253

  
254
  sockaddr_fill(&dst,  BIRD_AF, net->n.prefix, NULL, 0);
255
  sockaddr_fill(&mask, BIRD_AF, ipa_mkmask(net->n.pxlen), NULL, 0);
256
  sockaddr_fill(&gate, BIRD_AF, gw, NULL, 0);
254
  int af = AF_UNSPEC;
255

  
256
  switch (net->n.addr->type) {
257
    case NET_IP4:
258
      af = AF_INET;
259
      break;
260
    case NET_IP6:
261
      af = AF_INET6;
262
      break;
263
    default:
264
      log(L_ERR "KRT: Not sending VPN route %N to kernel", net->n.addr);
265
      return -1;
266
  }
267

  
268

  
269
  sockaddr_fill(&dst,  af, net_prefix(net->n.addr), NULL, 0);
270
  sockaddr_fill(&mask, af, net_pxmask(net->n.addr), NULL, 0);
271
  sockaddr_fill(&gate, af, gw, NULL, 0);
257 272

  
258 273
  switch (a->dest)
259 274
  {
......
299 314
  msg.rtm.rtm_msglen = l;
300 315

  
301 316
  if ((l = write(p->sys.sk->fd, (char *)&msg, l)) < 0) {
302
    log(L_ERR "KRT: Error sending route %I/%d to kernel: %m", net->n.prefix, net->n.pxlen);
317
    log(L_ERR "KRT: Error sending route %N to kernel: %m", net->n.addr);
303 318
    return -1;
304 319
  }
305 320

  
......
335 350
  net *net;
336 351
  sockaddr dst, gate, mask;
337 352
  ip_addr idst, igate, imask;
353
  net_addr ndst;
338 354
  void *body = (char *)msg->buf;
339 355
  int new = (msg->rtm.rtm_type != RTM_DELETE);
340 356
  char *errmsg = "KRT: Invalid route received";
......
386 402
  if (pxlen < 0)
387 403
    { log(L_ERR "%s (%I) - netmask %I", errmsg, idst, imask); return; }
388 404

  
405
  /* XXXX */
406
  net_fill_ipa(&ndst, idst, pxlen);
407

  
389 408
  if ((flags & RTF_GATEWAY) && ipa_zero(igate))
390
    { log(L_ERR "%s (%I/%d) - missing gateway", errmsg, idst, pxlen); return; }
409
    { log(L_ERR "%s (%N) - missing gateway", errmsg, ndst); return; }
391 410

  
392 411
  u32 self_mask = RTF_PROTO1;
393 412
  u32 alien_mask = RTF_STATIC | RTF_PROTO1 | RTF_GATEWAY;
......
426 445
  else
427 446
    src = KRT_SRC_KERNEL;
428 447

  
429
  net = net_get(p->p.table, idst, pxlen);
448
  net = net_get(p->p.table, &ndst);
430 449

  
431 450
  rta a = {
432 451
    .src = p->p.main_source,
......
455 474
  a.iface = if_find_by_index(msg->rtm.rtm_index);
456 475
  if (!a.iface)
457 476
    {
458
      log(L_ERR "KRT: Received route %I/%d with unknown ifindex %u",
459
	  net->n.prefix, net->n.pxlen, msg->rtm.rtm_index);
477
      log(L_ERR "KRT: Received route %N with unknown ifindex %u",
478
	  net->n.addr, msg->rtm.rtm_index);
460 479
      return;
461 480
    }
462 481

  
......
480 499
        if (ipa_classify(a.gw) == (IADDR_HOST | SCOPE_HOST))
481 500
          return;
482 501

  
483
	log(L_ERR "KRT: Received route %I/%d with strange next-hop %I",
484
	    net->n.prefix, net->n.pxlen, a.gw);
502
	log(L_ERR "KRT: Received route %N with strange next-hop %I",
503
	    net->n.addr, a.gw);
485 504
	return;
486 505
      }
487 506
  }
......
652 671
  imask = ipa_from_sa(&mask);
653 672
  ibrd  = ipa_from_sa(&brd);
654 673

  
655

  
674
  /* XXXX */
656 675
  if ((masklen = ipa_masklen(imask)) < 0)
657 676
  {
658 677
    log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name);
......
673 692
  bzero(&ifa, sizeof(ifa));
674 693
  ifa.iface = iface;
675 694
  ifa.ip = iaddr;
676
  ifa.pxlen = masklen;
677 695

  
678 696
  scope = ipa_classify(ifa.ip);
679 697
  if (scope < 0)
......
685 703

  
686 704
  if (masklen < BITS_PER_IP_ADDRESS)
687 705
  {
688
    ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
706
    net_fill_ipa(&ifa.prefix, ifa.ip, masklen);
707
    net_normalize(&ifa.prefix);
689 708

  
690 709
    if (masklen == (BITS_PER_IP_ADDRESS - 1))
691 710
      ifa.opposite = ipa_opposite_m1(ifa.ip);
......
703 722
  }
704 723
  else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd))
705 724
  {
706
    ifa.prefix = ifa.opposite = ibrd;
725
    net_fill_ipa(&ifa.prefix, ibrd, BITS_PER_IP_ADDRESS);
726
    ifa.opposite = ibrd;
707 727
    ifa.flags |= IA_PEER;
708 728
  }
709 729
  else
710 730
  {
711
    ifa.prefix = ifa.ip;
731
    net_fill_ipa(&ifa.prefix, ifa.ip, BITS_PER_IP_ADDRESS);
712 732
    ifa.flags |= IA_HOST;
713 733
  }
714 734

  
sysdep/linux/netlink.c
241 241
  [IFLA_WIRELESS] = { 1, 0, 0 },
242 242
};
243 243

  
244

  
245 244
#define BIRD_IFA_MAX  (IFA_ANYCAST+1)
246 245

  
247 246
#ifndef IPV6
......
257 256
};
258 257
#endif
259 258

  
260

  
261 259
#define BIRD_RTA_MAX  (RTA_TABLE+1)
262 260

  
263 261
static struct nl_want_attrs mpnh_attr_want4[BIRD_RTA_MAX] = {
......
304 302

  
305 303
      if (want[a->rta_type].checksize && (RTA_PAYLOAD(a) != want[a->rta_type].size))
306 304
	{
307
	  log(L_ERR "nl_parse_attrs: Malformed message received");
305
	  log(L_ERR "nl_parse_attrs: Malformed attribute received");
308 306
	  return 0;
309 307
	}
310 308

  
......
329 327
static inline ip6_addr rta_get_ip6(struct rtattr *a)
330 328
{ return ip6_ntoh(*(ip6_addr *) RTA_DATA(a)); }
331 329

  
330
static inline ip_addr rta_get_ipa(struct rtattr *a)
331
{
332
  if (RTA_PAYLOAD(a) == sizeof(ip4_addr))
333
    return ipa_from_ip4(rta_get_ip4(a));
334
  else
335
    return ipa_from_ip6(rta_get_ip6(a));
336
}
332 337

  
333 338
struct rtattr *
334 339
nl_add_attr(struct nlmsghdr *h, uint bufsize, uint code, const void *data, uint dlen)
......
357 362
}
358 363

  
359 364
static inline void
360
nl_add_attr_ipa(struct nlmsghdr *h, unsigned bufsize, int code, ip_addr ipa)
365
nl_add_attr_ipa(struct nlmsghdr *h, unsigned bufsize, int code, ip_addr ipa, int af)
361 366
{
362
  ipa_hton(ipa);
363
  nl_add_attr(h, bufsize, code, &ipa, sizeof(ipa));
367
  if (af == AF_INET)
368
  {
369
    ip4_addr ip4 = ip4_hton(ipa_to_ip4(ipa));
370
    nl_add_attr(h, bufsize, code, &ip4, sizeof(ip4));
371
  }
372
  else
373
  {
374
    ip6_addr ip6 = ip6_hton(ipa_to_ip6(ipa));
375
    nl_add_attr(h, bufsize, code, &ip6, sizeof(ip6));
376
  }
364 377
}
365 378

  
366 379
static inline struct rtattr *
......
408 421
    rtnh->rtnh_hops = nh->weight;
409 422
    rtnh->rtnh_ifindex = nh->iface->index;
410 423

  
411
    nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw);
424
    nl_add_attr_ipa(h, bufsize, RTA_GATEWAY, nh->gw, AF_INET);
412 425

  
413 426
    nl_close_nexthop(h, rtnh);
414 427
  }
......
598 611
}
599 612

  
600 613
static void
601
nl_parse_addr(struct nlmsghdr *h, int scan)
614
nl_parse_addr4(struct ifaddrmsg *i, int scan, int new)
602 615
{
603
  struct ifaddrmsg *i;
604 616
  struct rtattr *a[BIRD_IFA_MAX];
605
  int new = h->nlmsg_type == RTM_NEWADDR;
606
  struct ifa ifa;
607 617
  struct iface *ifi;
608 618
  int scope;
609 619

  
610
  if (!(i = nl_checkin(h, sizeof(*i))))
620
  if (!nl_parse_attrs(IFA_RTA(i), ifa_attr_want4, a, sizeof(a)))
611 621
    return;
612 622

  
613
  switch (i->ifa_family)
623
  if (!a[IFA_LOCAL])
614 624
    {
615
#ifndef IPV6
616
      case AF_INET:
617
	if (!nl_parse_attrs(IFA_RTA(i), ifa_attr_want4, a, sizeof(a)))
618
	  return;
619
	if (!a[IFA_LOCAL])
620
	  {
621
	    log(L_ERR "KIF: Malformed message received (missing IFA_LOCAL)");
622
	    return;
623
	  }
624
	break;
625
#else
626
      case AF_INET6:
627
	if (!nl_parse_attrs(IFA_RTA(i), ifa_attr_want6, a, sizeof(a)))
628
	  return;
629
	break;
630
#endif
631
      default:
632
	return;
625
      log(L_ERR "KIF: Malformed message received (missing IFA_LOCAL)");
626
      return;
633 627
    }
634

  
635 628
  if (!a[IFA_ADDRESS])
636 629
    {
637 630
      log(L_ERR "KIF: Malformed message received (missing IFA_ADDRESS)");
......
645 638
      return;
646 639
    }
647 640

  
641
  struct ifa ifa;
648 642
  bzero(&ifa, sizeof(ifa));
649 643
  ifa.iface = ifi;
650 644
  if (i->ifa_flags & IFA_F_SECONDARY)
651 645
    ifa.flags |= IA_SECONDARY;
652 646

  
653
  /* IFA_LOCAL can be unset for IPv6 interfaces */
654
  memcpy(&ifa.ip, RTA_DATA(a[IFA_LOCAL] ? : a[IFA_ADDRESS]), sizeof(ifa.ip));
655
  ipa_ntoh(ifa.ip);
656
  ifa.pxlen = i->ifa_prefixlen;
647
  ifa.ip = rta_get_ipa(a[IFA_LOCAL]);
648

  
657 649
  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS)
658 650
    {
659 651
      log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
......
661 653
    }
662 654
  if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
663 655
    {
664
      ip_addr addr;
665
      memcpy(&addr, RTA_DATA(a[IFA_ADDRESS]), sizeof(addr));
666
      ipa_ntoh(addr);
667
      ifa.prefix = ifa.brd = addr;
656
      ifa.brd = rta_get_ipa(a[IFA_ADDRESS]);
657
      net_fill_ip4(&ifa.prefix, rta_get_ip4(a[IFA_ADDRESS]), i->ifa_prefixlen);
668 658

  
669 659
      /* It is either a host address or a peer address */
670
      if (ipa_equal(ifa.ip, addr))
660
      if (ipa_equal(ifa.ip, ifa.brd))
671 661
	ifa.flags |= IA_HOST;
672 662
      else
673 663
	{
674 664
	  ifa.flags |= IA_PEER;
675
	  ifa.opposite = addr;
665
	  ifa.opposite = ifa.brd;
676 666
	}
677 667
    }
678 668
  else
679 669
    {
680
      ip_addr netmask = ipa_mkmask(ifa.pxlen);
681
      ifa.prefix = ipa_and(ifa.ip, netmask);
682
      ifa.brd = ipa_or(ifa.ip, ipa_not(netmask));
670
      net_fill_ip4(&ifa.prefix, ipa_to_ip4(ifa.ip), i->ifa_prefixlen);
671
      net_normalize(&ifa.prefix);
672

  
683 673
      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
684 674
	ifa.opposite = ipa_opposite_m1(ifa.ip);
685 675

  
686
#ifndef IPV6
687 676
      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 2)
688 677
	ifa.opposite = ipa_opposite_m2(ifa.ip);
689 678

  
690 679
      if ((ifi->flags & IF_BROADCAST) && a[IFA_BROADCAST])
691 680
	{
692
	  ip_addr xbrd;
693
	  memcpy(&xbrd, RTA_DATA(a[IFA_BROADCAST]), sizeof(xbrd));
694
	  ipa_ntoh(xbrd);
695
	  if (ipa_equal(xbrd, ifa.prefix) || ipa_equal(xbrd, ifa.brd))
696
	    ifa.brd = xbrd;
681
	  ip4_addr xbrd = rta_get_ip4(a[IFA_BROADCAST]);
682
	  ip4_addr ybrd = ip4_or(ipa_to_ip4(ifa.ip), ip4_not(ip4_mkmask(i->ifa_prefixlen)));
683

  
684
	  if (ip4_equal(xbrd, net4_prefix(&ifa.prefix)) || ip4_equal(xbrd, ybrd))
685
	    ifa.brd = ipa_from_ip4(xbrd);
697 686
	  else if (ifi->flags & IF_TMP_DOWN) /* Complain only during the first scan */
698
	    log(L_ERR "KIF: Invalid broadcast address %I for %s", xbrd, ifi->name);
687
	    {
688
	      log(L_ERR "KIF: Invalid broadcast address %I for %s", xbrd, ifi->name);
689
	      ifa.brd = ipa_from_ip4(ybrd);
690
	    }
699 691
	}
700
#endif
701 692
    }
702 693

  
703 694
  scope = ipa_classify(ifa.ip);
......
708 699
    }
709 700
  ifa.scope = scope & IADDR_SCOPE_MASK;
710 701

  
711
  DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %I/%d, brd %I, opp %I\n",
702
  DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %N, brd %I, opp %I\n",
703
      ifi->index, ifi->name,
704
      new ? "added" : "removed",
705
      ifa.ip, ifa.flags, ifa.prefix, ifa.brd, ifa.opposite);
706

  
707
  if (new)
708
    ifa_update(&ifa);
709
  else
710
    ifa_delete(&ifa);
711

  
712
  if (!scan)
713
    if_end_partial_update(ifi);
714
}
715

  
716
static void
717
nl_parse_addr6(struct ifaddrmsg *i, int scan, int new)
718
{
719
  struct rtattr *a[BIRD_IFA_MAX];
720
  struct iface *ifi;
721
  int scope;
722

  
723
  if (!nl_parse_attrs(IFA_RTA(i), ifa_attr_want6, a, sizeof(a)))
724
    return;
725

  
726
  if (!a[IFA_ADDRESS])
727
    {
728
      log(L_ERR "KIF: Malformed message received (missing IFA_ADDRESS)");
729
      return;
730
    }
731

  
732
  ifi = if_find_by_index(i->ifa_index);
733
  if (!ifi)
734
    {
735
      log(L_ERR "KIF: Received address message for unknown interface %d", i->ifa_index);
736
      return;
737
    }
738

  
739
  struct ifa ifa;
740
  bzero(&ifa, sizeof(ifa));
741
  ifa.iface = ifi;
742
  if (i->ifa_flags & IFA_F_SECONDARY)
743
    ifa.flags |= IA_SECONDARY;
744

  
745
  /* IFA_LOCAL can be unset for IPv6 interfaces */
746

  
747
  ifa.ip = rta_get_ipa(a[IFA_LOCAL] ? : a[IFA_ADDRESS]);
748

  
749
  if (i->ifa_prefixlen > BITS_PER_IP_ADDRESS)
750
    {
751
      log(L_ERR "KIF: Invalid prefix length for interface %s: %d", ifi->name, i->ifa_prefixlen);
752
      new = 0;
753
    }
754
  if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS)
755
    {
756
      ifa.brd = rta_get_ipa(a[IFA_ADDRESS]);
757
      net_fill_ip6(&ifa.prefix, rta_get_ip6(a[IFA_ADDRESS]), i->ifa_prefixlen);
758

  
759
      /* It is either a host address or a peer address */
760
      if (ipa_equal(ifa.ip, ifa.brd))
761
	ifa.flags |= IA_HOST;
762
      else
763
	{
764
	  ifa.flags |= IA_PEER;
765
	  ifa.opposite = ifa.brd;
766
	}
767
    }
768
  else
769
    {
770
      net_fill_ip6(&ifa.prefix, ipa_to_ip6(ifa.ip), i->ifa_prefixlen);
771
      net_normalize(&ifa.prefix);
772

  
773
      if (i->ifa_prefixlen == BITS_PER_IP_ADDRESS - 1)
774
	ifa.opposite = ipa_opposite_m1(ifa.ip);
775
    }
776

  
777
  scope = ipa_classify(ifa.ip);
778
  if (scope < 0)
779
    {
780
      log(L_ERR "KIF: Invalid interface address %I for %s", ifa.ip, ifi->name);
781
      return;
782
    }
783
  ifa.scope = scope & IADDR_SCOPE_MASK;
784

  
785
  DBG("KIF: IF%d(%s): %s IPA %I, flg %x, net %N, brd %I, opp %I\n",
712 786
      ifi->index, ifi->name,
713 787
      new ? "added" : "removed",
714
      ifa.ip, ifa.flags, ifa.prefix, ifa.pxlen, ifa.brd, ifa.opposite);
788
      ifa.ip, ifa.flags, ifa.prefix, ifa.brd, ifa.opposite);
715 789

  
716 790
  if (new)
717 791
    ifa_update(&ifa);
......
722 796
    if_end_partial_update(ifi);
723 797
}
724 798

  
799
static void
800
nl_parse_addr(struct nlmsghdr *h, int scan)
801
{
802
  struct ifaddrmsg *i;
803

  
804
  if (!(i = nl_checkin(h, sizeof(*i))))
805
    return;
806

  
807
  int new = (h->nlmsg_type == RTM_NEWADDR);
808

  
809
  switch (i->ifa_family)
810
    {
811
#ifndef IPV6
812
      case AF_INET:
813
	return nl_parse_addr4(i, scan, new);
814
#else
815
      case AF_INET6:
816
	return nl_parse_addr6(i, scan, new);
817
#endif
818
    }
819
}
820

  
725 821
void
726 822
kif_do_scan(struct kif_proto *p UNUSED)
727 823
{
......
814 910
    char buf[128 + KRT_METRICS_MAX*8 + nh_bufsize(a->nexthops)];
815 911
  } r;
816 912

  
817
  DBG("nl_send_route(%I/%d,new=%d)\n", net->n.prefix, net->n.pxlen, new);
913
  DBG("nl_send_route(%N,new=%d)\n", net->n.addr, new);
818 914

  
819 915
  bzero(&r.h, sizeof(r.h));
820 916
  bzero(&r.r, sizeof(r.r));
......
822 918
  r.h.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
823 919
  r.h.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (new ? NLM_F_CREATE|NLM_F_EXCL : 0);
824 920

  
825
  r.r.rtm_family = BIRD_AF;
826
  r.r.rtm_dst_len = net->n.pxlen;
921
  int af = AF_UNSPEC;
922

  
923
  switch(net->n.addr->type) {
924
    case NET_IP4:
925
      af = AF_INET;
926
      break;
927
    case NET_IP6:
928
      af = AF_INET6;
929
      break;
930
    default:
931
      bug("should not send vpn route to kernel");
932
  }
933

  
934
  r.r.rtm_family = af;
935
  r.r.rtm_dst_len = net_pxlen(net->n.addr);
827 936
  r.r.rtm_protocol = RTPROT_BIRD;
828 937
  r.r.rtm_scope = RT_SCOPE_UNIVERSE;
829
  nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix);
938
  nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net_prefix(net->n.addr), af);
830 939

  
831 940
  if (krt_table_id(p) < 256)
832 941
    r.r.rtm_table = krt_table_id(p);
......
842 951
    nl_add_attr_u32(&r.h, sizeof(r), RTA_PRIORITY, ea->u.data);
843 952

  
844 953
  if (ea = ea_find(eattrs, EA_KRT_PREFSRC))
845
    nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data);
954
    nl_add_attr_ipa(&r.h, sizeof(r), RTA_PREFSRC, *(ip_addr *)ea->u.ptr->data, af);
846 955

  
847 956
  if (ea = ea_find(eattrs, EA_KRT_REALM))
848 957
    nl_add_attr_u32(&r.h, sizeof(r), RTA_FLOW, ea->u.data);
......
870 979
    case RTD_ROUTER:
871 980
      r.r.rtm_type = RTN_UNICAST;
872 981
      nl_add_attr_u32(&r.h, sizeof(r), RTA_OIF, a->iface->index);
873
      nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw);
982
      nl_add_attr_ipa(&r.h, sizeof(r), RTA_GATEWAY, a->gw, af);
874 983
      break;
875 984
    case RTD_DEVICE:
876 985
      r.r.rtm_type = RTN_UNICAST;
......
931 1040
  struct rtattr *a[BIRD_RTA_MAX];
932 1041
  int new = h->nlmsg_type == RTM_NEWROUTE;
933 1042

  
934
  ip_addr dst = IPA_NONE;
1043
  net_addr dst = { 0 };
935 1044
  u32 oif = ~0;
936 1045
  u32 table;
937 1046
  int src;
938 1047

  
1048
  int ipv6 = 0;
1049

  
939 1050
  if (!(i = nl_checkin(h, sizeof(*i))))
940 1051
    return;
941 1052

  
......
950 1061
      case AF_INET6:
951 1062
	if (!nl_parse_attrs(RTM_RTA(i), rtm_attr_want6, a, sizeof(a)))
952 1063
	  return;
1064
	ipv6 = 1;
953 1065
	break;
954 1066
#endif
955 1067
      default:
956 1068
	return;
957 1069
    }
958 1070

  
959

  
960 1071
  if (a[RTA_DST])
961
    {
962
      memcpy(&dst, RTA_DATA(a[RTA_DST]), sizeof(dst));
963
      ipa_ntoh(dst);
964
    }
1072
    net_fill_ipa(&dst, rta_get_ipa(a[RTA_DST]), i->rtm_dst_len);
965 1073

  
966 1074
  if (a[RTA_OIF])
967 1075
    oif = rta_get_u32(a[RTA_OIF]);
......
977 1085
    SKIP("unknown table %d\n", table);
978 1086

  
979 1087

  
980
#ifdef IPV6
981 1088
  if (a[RTA_IIF])
982 1089
    SKIP("IIF set\n");
983
#else
984 1090
  if (i->rtm_tos != 0)			/* We don't support TOS */
985 1091
    SKIP("TOS %02x\n", i->rtm_tos);
986
#endif
987 1092

  
988 1093
  if (scan && !new)
989 1094
    SKIP("RTM_DELROUTE in scan\n");
990 1095

  
991
  int c = ipa_classify_net(dst);
1096
  int c = net_classify(&dst);
992 1097
  if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
993 1098
    SKIP("strange class/scope\n");
994 1099

  
......
1020 1125
      src = KRT_SRC_ALIEN;
1021 1126
    }
1022 1127

  
1023
  net *net = net_get(p->p.table, dst, i->rtm_dst_len);
1128
  net *net = net_get(p->p.table, &dst);
1024 1129

  
1025 1130
  rta ra = {
1026 1131
    .src= p->p.main_source,
......
1060 1165
	  memcpy(&ra.gw, RTA_DATA(a[RTA_GATEWAY]), sizeof(ra.gw));
1061 1166
	  ipa_ntoh(ra.gw);
1062 1167

  
1063
#ifdef IPV6
1064 1168
	  /* Silently skip strange 6to4 routes */
1065
	  if (ipa_in_net(ra.gw, IPA_NONE, 96))
1169
	  if (ipv6 && ipa_in_net(ra.gw, IPA_NONE, 96))
1066 1170
	    return;
1067
#endif
1068 1171

  
1069 1172
	  ng = neigh_find2(&p->p, &ra.gw, ra.iface,
1070 1173
			   (i->rtm_flags & RTNH_F_ONLINK) ? NEF_ONLINK : 0);
......
1107 1210

  
1108 1211
  if (a[RTA_PREFSRC])
1109 1212
    {
1110
      ip_addr ps;
1111
      memcpy(&ps, RTA_DATA(a[RTA_PREFSRC]), sizeof(ps));
1112
      ipa_ntoh(ps);
1213
      ip_addr ps = rta_get_ipa(a[RTA_PREFSRC]);
1113 1214

  
1114 1215
      ea_list *ea = alloca(sizeof(ea_list) + sizeof(eattr));
1115 1216
      ea->next = ra.eattrs;

Also available in: Unified diff