30 #include <boost/range/adaptors.hpp>
31 #include <boost/range/algorithm/copy.hpp>
42 static std::string id(
"ether");
49 m_netifAddConn =
netmon->onInterfaceAdded.connect([
this] (
const auto& netif) {
50 this->applyUnicastConfigToNetif(netif);
51 this->applyMcastConfigToNetif(*netif);
75 UnicastConfig unicastConfig;
76 MulticastConfig mcastConfig;
80 unicastConfig.isEnabled = unicastConfig.wantListen = mcastConfig.isEnabled =
true;
82 for (
const auto& pair : *configSection) {
83 const std::string& key = pair.first;
86 if (key ==
"listen") {
89 else if (key ==
"idle_timeout") {
90 unicastConfig.idleTimeout = time::seconds(ConfigFile::parseNumber<uint32_t>(pair,
"face_system.ether"));
92 else if (key ==
"mcast") {
95 else if (key ==
"mcast_group") {
96 const std::string& valueStr = value.get_value<std::string>();
98 if (mcastConfig.group.isNull()) {
99 NDN_THROW(ConfigFile::Error(
"face_system.ether.mcast_group: '" +
100 valueStr +
"' cannot be parsed as an Ethernet address"));
102 else if (!mcastConfig.group.isMulticast()) {
103 NDN_THROW(ConfigFile::Error(
"face_system.ether.mcast_group: '" +
104 valueStr +
"' is not a multicast address"));
107 else if (key ==
"mcast_ad_hoc") {
111 else if (key ==
"whitelist") {
112 mcastConfig.netifPredicate.parseWhitelist(value);
114 else if (key ==
"blacklist") {
115 mcastConfig.netifPredicate.parseBlacklist(value);
118 NDN_THROW(ConfigFile::Error(
"Unrecognized option face_system.ether." + key));
127 if (unicastConfig.isEnabled) {
128 if (m_unicastConfig.wantListen && !unicastConfig.wantListen && !m_channels.empty()) {
129 NFD_LOG_WARN(
"Cannot stop listening on Ethernet channels");
131 if (m_unicastConfig.idleTimeout != unicastConfig.idleTimeout && !m_channels.empty()) {
132 NFD_LOG_WARN(
"Idle timeout setting applies to new Ethernet channels only");
135 else if (m_unicastConfig.isEnabled && !m_channels.empty()) {
136 NFD_LOG_WARN(
"Cannot disable Ethernet channels after initialization");
139 if (m_mcastConfig.isEnabled != mcastConfig.isEnabled) {
140 if (mcastConfig.isEnabled) {
141 NFD_LOG_INFO(
"enabling multicast on " << mcastConfig.group);
147 else if (mcastConfig.isEnabled) {
148 if (m_mcastConfig.linkType != mcastConfig.linkType && !m_mcastFaces.empty()) {
149 NFD_LOG_WARN(
"Cannot change ad hoc setting on existing faces");
151 if (m_mcastConfig.group != mcastConfig.group) {
152 NFD_LOG_INFO(
"changing multicast group from " << m_mcastConfig.group <<
153 " to " << mcastConfig.group);
155 if (m_mcastConfig.netifPredicate != mcastConfig.netifPredicate) {
162 m_unicastConfig = unicastConfig;
163 m_mcastConfig = mcastConfig;
164 this->applyConfig(context);
168 EthernetFactory::doCreateFace(
const CreateFaceRequest& req,
172 if (!req.localUri || req.localUri->getScheme() !=
"dev") {
173 NFD_LOG_TRACE(
"Cannot create unicast Ethernet face without dev:// LocalUri");
174 onFailure(406,
"Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme");
179 NFD_LOG_TRACE(
"createFace does not support FACE_PERSISTENCY_ON_DEMAND");
180 onFailure(406,
"Outgoing Ethernet faces do not support on-demand persistency");
185 std::string localEndpoint(req.localUri->getHost());
187 if (remoteEndpoint.isMulticast()) {
188 NFD_LOG_TRACE(
"createFace does not support multicast faces");
189 onFailure(406,
"Cannot create multicast Ethernet faces");
193 if (req.params.wantLocalFields) {
195 NFD_LOG_TRACE(
"createFace cannot create non-local face with local fields enabled");
196 onFailure(406,
"Local fields can only be enabled on faces with local scope");
207 for (
const auto& i : m_channels) {
208 if (i.first == localEndpoint) {
209 i.second->connect(remoteEndpoint, req.params, onCreated, onFailure);
214 NFD_LOG_TRACE(
"No channels available to connect to " << remoteEndpoint);
215 onFailure(504,
"No channels available to connect");
218 shared_ptr<EthernetChannel>
220 time::nanoseconds idleTimeout)
222 auto it = m_channels.find(localEndpoint->
getName());
223 if (it != m_channels.end())
226 auto channel = std::make_shared<EthernetChannel>(localEndpoint, idleTimeout);
227 m_channels[localEndpoint->
getName()] = channel;
231 std::vector<shared_ptr<const Channel>>
232 EthernetFactory::doGetChannels()
const
243 auto key = std::make_pair(netif.
getName(), address);
244 auto found = m_mcastFaces.find(key);
245 if (found != m_mcastFaces.end()) {
246 return found->second;
253 auto linkService = make_unique<GenericLinkService>(opts);
254 auto transport = make_unique<MulticastEthernetTransport>(netif, address, m_mcastConfig.linkType);
257 m_mcastFaces[key] = face;
263 shared_ptr<EthernetChannel>
264 EthernetFactory::applyUnicastConfigToNetif(
const shared_ptr<const ndn::net::NetworkInterface>& netif)
266 if (!m_unicastConfig.isEnabled) {
275 if (!netif->
isUp()) {
285 auto channel = this->
createChannel(netif, m_unicastConfig.idleTimeout);
286 if (m_unicastConfig.wantListen && !channel->isListening()) {
288 channel->listen(this->
addFace,
nullptr);
290 catch (
const EthernetChannel::Error& e) {
300 if (!m_mcastConfig.isEnabled) {
305 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": incompatible netif type");
315 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": netif cannot multicast");
320 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": invalid Ethernet address");
324 if (!m_mcastConfig.netifPredicate(netif)) {
325 NFD_LOG_DEBUG(
"Not creating multicast face on " << netif.
getName() <<
": rejected by whitelist/blacklist");
330 shared_ptr<Face> face;
334 catch (
const EthernetTransport::Error& e) {
347 EthernetFactory::applyConfig(
const FaceSystem::ConfigContext&)
349 if (m_unicastConfig.isEnabled) {
357 std::set<shared_ptr<Face>> oldFaces;
358 boost::copy(m_mcastFaces | boost::adaptors::map_values, std::inserter(oldFaces, oldFaces.end()));
361 for (
const auto& netif :
netmon->listNetworkInterfaces()) {
362 this->applyUnicastConfigToNetif(netif);
364 auto face = this->applyMcastConfigToNetif(*netif);
365 if (face !=
nullptr) {
367 oldFaces.erase(face);
372 for (
const auto& face : oldFaces) {