Revision 9b136840 sysdep/linux/netlink.c

View differences:

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