Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions implementation/configuration/include/configuration_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,15 @@ class configuration_impl:
void load_partition(const boost::property_tree::ptree &_tree);

private:
#if defined(__linux__)
//! @brief Returns the network interface (NIC) that contains the given local
//! address. Relevant for VLAN communication in IPv6.
//! @param[in] _local_address The IP address in IPv6 format that should be
//! used as a host.
//! @param[out] The network interface identifier that "contains" the IP
//! address.
int get_nic(const std::string& _local_address);
#endif
std::mutex mutex_;

const std::string default_unicast_;
Expand Down
75 changes: 73 additions & 2 deletions implementation/configuration/src/configuration_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
#include "../../security/include/policy_manager_impl.hpp"
#include "../../security/include/security.hpp"

#if defined(__linux__)
#include <ifaddrs.h>
Copy link
Collaborator

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.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added if defined(__linux__) .... #endif to address it

#endif

namespace vsomeip_v3 {
namespace cfg {

Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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 (...) {
Expand Down Expand Up @@ -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
Copy link
Contributor

@goncaloalmeida goncaloalmeida Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not remove the __ func __

<< " " << e.what();
}
}
Expand Down
14 changes: 13 additions & 1 deletion implementation/routing/src/routing_manager_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Copy link
Collaborator

Choose a reason for hiding this comment

The 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?
If yes, we will need another solution not using an hardcoded value

Copy link
Author

Choose a reason for hiding this comment

The 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,
Expand Down