| 163 | } |
| 164 | |
| 165 | void netlink_connector::receive_cbk(boost::system::error_code const& _error, std::size_t _bytes) { |
| 166 | bool error_detected = false; |
| 167 | |
| 168 | if (!_error) { |
| 169 | size_t len = _bytes; |
| 170 | struct nlmsghdr* nlh = (struct nlmsghdr*)&recv_buffer_[0]; |
| 171 | |
| 172 | while (NLMSG_OK(nlh, len)) { |
| 173 | switch (nlh->nlmsg_type) { |
| 174 | case RTM_NEWADDR: { |
| 175 | // New Address information |
| 176 | auto ifa = static_cast<const struct ifaddrmsg*>(NLMSG_DATA(nlh)); |
| 177 | if (has_address(ifa, IFA_PAYLOAD(nlh))) { |
| 178 | net_if_index_for_address_ = static_cast<int>(ifa->ifa_index); |
| 179 | auto its_if = net_if_flags_.find(net_if_index_for_address_); |
| 180 | if (its_if != net_if_flags_.end()) { |
| 181 | if ((its_if->second & IFF_UP) && (is_requiring_link_ ? (its_if->second & IFF_RUNNING) : true)) { |
| 182 | set_state(multicast_route_found_ ? state_e::UP_MULTICAST : state_e::UP); |
| 183 | } else { |
| 184 | set_state(state_e::DOWN); |
| 185 | } |
| 186 | } else { |
| 187 | set_state(state_e::DOWN); |
| 188 | } |
| 189 | } |
| 190 | break; |
| 191 | } |
| 192 | case RTM_NEWLINK: { |
| 193 | // New Interface information |
| 194 | auto ifi = static_cast<const struct ifinfomsg*>(NLMSG_DATA(nlh)); |
| 195 | net_if_flags_[ifi->ifi_index] = ifi->ifi_flags; |
| 196 | if (net_if_index_for_address_ == ifi->ifi_index) { |
| 197 | if ((ifi->ifi_flags & IFF_UP) && (is_requiring_link_ ? (ifi->ifi_flags & IFF_RUNNING) : true)) { |
| 198 | set_state(multicast_route_found_ ? state_e::UP_MULTICAST : state_e::UP); |
| 199 | } else { |
| 200 | set_state(state_e::DOWN); |
| 201 | } |
| 202 | } |
| 203 | break; |
| 204 | } |
| 205 | case RTM_NEWROUTE: { |
| 206 | auto routemsg = static_cast<const struct rtmsg*>(NLMSG_DATA(nlh)); |
| 207 | std::string its_route_name; |
| 208 | if (check_sd_multicast_route_match(routemsg, RTM_PAYLOAD(nlh), &its_route_name)) { |
| 209 | multicast_route_found_ = true; |
| 210 | set_state(current_state_ == state_e::UP ? state_e::UP_MULTICAST : current_state_); |
| 211 | } |
| 212 | break; |
| 213 | } |
| 214 | case RTM_DELROUTE: { |
| 215 | auto routemsg = static_cast<const struct rtmsg*>(NLMSG_DATA(nlh)); |
| 216 | std::string its_route_name; |
| 217 | if (check_sd_multicast_route_match(routemsg, RTM_PAYLOAD(nlh), &its_route_name)) { |
| 218 | multicast_route_found_ = true; |
| 219 | set_state(current_state_ == state_e::UP_MULTICAST ? state_e::UP : state_e::DOWN); |
| 220 | } |
| 221 | break; |
| 222 | } |