| | 656 | * get the refcount of a virtual ip |
|---|
| | 657 | */ |
|---|
| | 658 | static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip) |
|---|
| | 659 | { |
|---|
| | 660 | iterator_t *ifaces, *addrs; |
|---|
| | 661 | iface_entry_t *iface; |
|---|
| | 662 | addr_entry_t *addr; |
|---|
| | 663 | int refcount = 0; |
|---|
| | 664 | |
|---|
| | 665 | ifaces = this->ifaces->create_iterator(this->ifaces, TRUE); |
|---|
| | 666 | while (ifaces->iterate(ifaces, (void**)&iface)) |
|---|
| | 667 | { |
|---|
| | 668 | addrs = iface->addrs->create_iterator(iface->addrs, TRUE); |
|---|
| | 669 | while (addrs->iterate(addrs, (void**)&addr)) |
|---|
| | 670 | { |
|---|
| | 671 | if (addr->virtual && (iface->flags & IFF_UP) && |
|---|
| | 672 | ip->ip_equals(ip, addr->ip)) |
|---|
| | 673 | { |
|---|
| | 674 | refcount = addr->refcount; |
|---|
| | 675 | break; |
|---|
| | 676 | } |
|---|
| | 677 | } |
|---|
| | 678 | addrs->destroy(addrs); |
|---|
| | 679 | if (refcount) |
|---|
| | 680 | { |
|---|
| | 681 | break; |
|---|
| | 682 | } |
|---|
| | 683 | } |
|---|
| | 684 | ifaces->destroy(ifaces); |
|---|
| | 685 | |
|---|
| | 686 | return refcount; |
|---|
| | 687 | } |
|---|
| | 688 | |
|---|
| | 689 | /** |
|---|
| | 905 | * process RTM_NEWROUTE from kernel |
|---|
| | 906 | */ |
|---|
| | 907 | static void process_route(private_kernel_interface_t *this, struct nlmsghdr *hdr) |
|---|
| | 908 | { |
|---|
| | 909 | struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr)); |
|---|
| | 910 | struct rtattr *rta = RTM_RTA(msg); |
|---|
| | 911 | size_t rtasize = RTM_PAYLOAD(hdr); |
|---|
| | 912 | host_t *host = NULL; |
|---|
| | 913 | |
|---|
| | 914 | while(RTA_OK(rta, rtasize)) |
|---|
| | 915 | { |
|---|
| | 916 | switch (rta->rta_type) |
|---|
| | 917 | { |
|---|
| | 918 | case RTA_PREFSRC: |
|---|
| | 919 | host = host_create_from_chunk(msg->rtm_family, |
|---|
| | 920 | chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0); |
|---|
| | 921 | break; |
|---|
| | 922 | } |
|---|
| | 923 | rta = RTA_NEXT(rta, rtasize); |
|---|
| | 924 | } |
|---|
| | 925 | if (host) |
|---|
| | 926 | { |
|---|
| | 927 | if (!get_vip_refcount(this, host)) |
|---|
| | 928 | { /* ignore routes added for virtual IPs */ |
|---|
| | 929 | fire_roam_job(this, FALSE); |
|---|
| | 930 | } |
|---|
| | 931 | host->destroy(host); |
|---|
| | 932 | } |
|---|
| | 933 | } |
|---|
| | 934 | |
|---|
| | 935 | /** |
|---|
| 1434 | | } |
|---|
| 1435 | | |
|---|
| 1436 | | /** |
|---|
| 1437 | | * get the refcount of a virtual ip |
|---|
| 1438 | | */ |
|---|
| 1439 | | static int get_vip_refcount(private_kernel_interface_t *this, host_t* ip) |
|---|
| 1440 | | { |
|---|
| 1441 | | iterator_t *ifaces, *addrs; |
|---|
| 1442 | | iface_entry_t *iface; |
|---|
| 1443 | | addr_entry_t *addr; |
|---|
| 1444 | | int refcount = 0; |
|---|
| 1445 | | |
|---|
| 1446 | | ifaces = this->ifaces->create_iterator(this->ifaces, TRUE); |
|---|
| 1447 | | while (ifaces->iterate(ifaces, (void**)&iface)) |
|---|
| 1448 | | { |
|---|
| 1449 | | addrs = iface->addrs->create_iterator(iface->addrs, TRUE); |
|---|
| 1450 | | while (addrs->iterate(addrs, (void**)&addr)) |
|---|
| 1451 | | { |
|---|
| 1452 | | if (addr->virtual && (iface->flags & IFF_UP) && |
|---|
| 1453 | | ip->ip_equals(ip, addr->ip)) |
|---|
| 1454 | | { |
|---|
| 1455 | | refcount = addr->refcount; |
|---|
| 1456 | | break; |
|---|
| 1457 | | } |
|---|
| 1458 | | } |
|---|
| 1459 | | addrs->destroy(addrs); |
|---|
| 1460 | | if (refcount) |
|---|
| 1461 | | { |
|---|
| 1462 | | break; |
|---|
| 1463 | | } |
|---|
| 1464 | | } |
|---|
| 1465 | | ifaces->destroy(ifaces); |
|---|
| 1466 | | |
|---|
| 1467 | | return refcount; |
|---|