-
Notifications
You must be signed in to change notification settings - Fork 773
Fix network interface identification for VLAN in IPv6 #553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
461050e
448e722
06e83ba
af5ed8b
d4bf3bb
8a29abc
1a1d387
38f63fa
b9c6535
7c90dae
14d37fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,6 +41,10 @@ | |
| #include "../../security/include/policy_manager_impl.hpp" | ||
| #include "../../security/include/security.hpp" | ||
|
|
||
| #if defined(__linux__) | ||
| #include <ifaddrs.h> | ||
| #endif | ||
|
|
||
| namespace vsomeip_v3 { | ||
| namespace cfg { | ||
|
|
||
|
|
@@ -1380,6 +1384,58 @@ void configuration_impl::load_trace_filter_match( | |
| } | ||
| } | ||
|
|
||
| #if defined(__linux__) | ||
| int configuration_impl::get_nic(const std::string& _local_address) { | ||
| // creating structures to browse through the available network interfaces | ||
| struct ifaddrs* ifaddr, *ifa; | ||
| int family, n; | ||
| sockaddr_in6* p_addrIP6; | ||
| std::vector<int> nic(0); // the network interface card id. Vector in case | ||
| // more than one interface contains the searched IP address | ||
| struct sockaddr_in6 searched_address; | ||
| searched_address.sin6_family = AF_INET6; | ||
| searched_address.sin6_addr = in6addr_any; | ||
| searched_address.sin6_port = htons( 0xdead ); | ||
| inet_pton( AF_INET6, _local_address.c_str(), &searched_address.sin6_addr ); // actually copying | ||
|
|
||
| if (getifaddrs(&ifaddr) == -1) { // "-1" is an error value | ||
| VSOMEIP_WARNING << __func__ << ": " << strerror(errno); | ||
| return -1; | ||
| } | ||
|
|
||
| /* Walk through linked list of network interfaces*/ | ||
| for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { | ||
| if (ifa->ifa_addr == NULL) | ||
| continue; | ||
| family = ifa->ifa_addr->sa_family; | ||
|
|
||
| /* For an AF_INET6 interface address, compare the address of the NIC | ||
| with the searched address */ | ||
| if (family == AF_INET6) { | ||
| p_addrIP6 = reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr); | ||
| if (::bcmp(p_addrIP6->sin6_addr.s6_addr, searched_address.sin6_addr.s6_addr, 16) == 0) { | ||
| nic.push_back(if_nametoindex(ifa->ifa_name)); | ||
| } | ||
| } | ||
| } | ||
| if (nic.size() > 1) { | ||
| VSOMEIP_WARNING << __func__ << ": Found multiple network interfaces " << | ||
| "with IP address " << _local_address << ". Please check your " << | ||
| "network settings. In the meanwhile, using the first NIC."; | ||
| // message must be in sync with "return nic[0]" | ||
| } | ||
| else if (nic.size() == 0) { | ||
| VSOMEIP_WARNING << __func__ << ": NO network interfaces available" << | ||
| "with IP address " << _local_address << ". Please check your " << | ||
| "network settings."; | ||
| return -1; | ||
| } // the good case 'nic.size() == 1' needs no error handling | ||
|
|
||
| freeifaddrs(ifaddr); | ||
| return nic[0]; | ||
| } | ||
| #endif | ||
|
|
||
| void configuration_impl::load_suppress_events(const configuration_element &_element) { | ||
| try { | ||
| auto its_missing_events = _element.tree_.get_child("suppress_missing_event_logs"); | ||
|
|
@@ -1557,7 +1613,22 @@ void configuration_impl::load_unicast_address(const configuration_element &_elem | |
| VSOMEIP_WARNING << "Multiple definitions for unicast." | ||
| "Ignoring definition from " << _element.name_; | ||
| } else { | ||
| unicast_ = unicast_.from_string(its_value); | ||
| #if defined(__linux__) | ||
| boost::asio::ip::address temp = unicast_.from_string(its_value); | ||
| if (temp.is_v6()) { | ||
| int scope_id = get_nic(its_value); | ||
| if (scope_id >= 0) { | ||
| // below: '%' is the delimiter to distinguish between IP-address and scope-id, e.g. "beef::1%7" | ||
| unicast_ = boost::asio::ip::make_address(its_value + "%" + std::to_string(scope_id)); | ||
| } // else, keep the default scope_id in local_ | ||
| else unicast_ = unicast_.from_string(its_value); | ||
| } | ||
| else if (temp.is_v4()) { // IPv4 somehow "automatically" processes the network interface and does NOT require special treatment | ||
| unicast_ = unicast_.from_string(its_value); | ||
| } | ||
| #else | ||
| unicast_ = unicast_.from_string(its_value); | ||
| #endif | ||
| is_configured_[ET_UNICAST] = true; | ||
| } | ||
| } catch (...) { | ||
|
|
@@ -2542,7 +2613,7 @@ void configuration_impl::load_payload_sizes(const configuration_element &_elemen | |
| buffer_shrink_threshold_ = static_cast<std::uint32_t>( | ||
| std::stoul(s.c_str(), NULL, 10)); | ||
| } catch (const std::exception &e) { | ||
| VSOMEIP_ERROR<< __func__ << ": " << buffer_shrink_threshold | ||
| VSOMEIP_ERROR<< << ": " << buffer_shrink_threshold | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please do not remove the __ func __ |
||
| << " " << e.what(); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -228,7 +228,19 @@ void routing_manager_impl::start() { | |
| << ", " | ||
| << its_netmask_or_prefix.str(); | ||
|
|
||
| netlink_connector_ = std::make_shared<netlink_connector>( | ||
| boost::asio::ip::address temp {configuration_->get_unicast_address()}; | ||
|
|
||
| // PRECONDITION: netlink_connector_ has troubles to create a correct object, | ||
| // if network interface is part of unicast-address-string. So strip it! | ||
| char delimiter {'%'}; // "%" is a symbol for the device, e.g. "beef::1%7", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is 7 a hardcoded value for the Network Interface you want to use?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The feature is the "delimiter", not the value "7". The example string is for instrumental purposes so that other developers know, why the delimiter was chosen the way it is. |
||
| // where 7 is the network interface #7 | ||
| if (its_unicast.to_string().find(delimiter) != std::string::npos) | ||
| { | ||
| std::string temp_address = its_unicast.to_string().substr(0, (size_t)its_unicast.to_string().find(delimiter)); | ||
| netlink_connector_ = std::make_shared<netlink_connector>( | ||
| host_->get_io(), boost::asio::ip::address::from_string(temp_address), its_multicast); | ||
| } | ||
| else netlink_connector_ = std::make_shared<netlink_connector>( | ||
| host_->get_io(), configuration_->get_unicast_address(), its_multicast); | ||
| netlink_connector_->register_net_if_changes_handler( | ||
| std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot accept a PR that breaks our windows build, this is linux only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
if defined(__linux__) .... #endifto address it