blob: 5122755676e49263c46d708f737cfffa846e482f [file] [log] [blame]
Eric Newberrya98bf932015-09-21 00:58:47 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Eric Newberry7b0071e2017-07-03 17:33:31 +00002/*
Eric Newberryb49313d2017-12-24 20:22:27 -07003 * Copyright (c) 2014-2018, Regents of the University of California,
Eric Newberrya98bf932015-09-21 00:58:47 -07004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "generic-link-service.hpp"
Eric Newberryb49313d2017-12-24 20:22:27 -070027
Junxiao Shicbc8e942016-09-06 03:17:45 +000028#include <ndn-cxx/lp/tags.hpp>
Eric Newberrya98bf932015-09-21 00:58:47 -070029
Eric Newberryb49313d2017-12-24 20:22:27 -070030#include <cmath>
31
Eric Newberrya98bf932015-09-21 00:58:47 -070032namespace nfd {
33namespace face {
34
Davide Pesaventoa3148082018-04-12 18:21:54 -040035NFD_LOG_INIT(GenericLinkService);
Eric Newberrya98bf932015-09-21 00:58:47 -070036
Eric Newberryb49313d2017-12-24 20:22:27 -070037constexpr uint32_t DEFAULT_CONGESTION_THRESHOLD_DIVISOR = 2;
38
Eric Newberry86d31872015-09-23 16:24:59 -070039GenericLinkService::Options::Options()
40 : allowLocalFields(false)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070041 , allowFragmentation(false)
42 , allowReassembly(false)
Eric Newberryb49313d2017-12-24 20:22:27 -070043 , allowCongestionMarking(false)
44 , baseCongestionMarkingInterval(time::milliseconds(100)) // Interval from RFC 8289 (CoDel)
45 , defaultCongestionThreshold(65536) // This default value works well for a queue capacity of 200KiB
Teng Liangfdcbb4d2018-01-27 16:01:35 -070046 , allowSelfLearning(false)
Eric Newberry86d31872015-09-23 16:24:59 -070047{
48}
49
50GenericLinkService::GenericLinkService(const GenericLinkService::Options& options)
Eric Newberry73bcad32017-04-25 17:57:35 -070051 : m_options(options)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070052 , m_fragmenter(m_options.fragmenterOptions, this)
53 , m_reassembler(m_options.reassemblerOptions, this)
Eric Newberry185ab292017-03-28 06:45:39 +000054 , m_reliability(m_options.reliabilityOptions, this)
Eric Newberry4c3e6b82015-11-10 16:48:42 -070055 , m_lastSeqNo(-2)
Eric Newberryb49313d2017-12-24 20:22:27 -070056 , m_nextMarkTime(time::steady_clock::TimePoint::max())
57 , m_lastMarkTime(time::steady_clock::TimePoint::min())
58 , m_nMarkedSinceInMarkingState(0)
Eric Newberry86d31872015-09-23 16:24:59 -070059{
Junxiao Shi0de23a22015-12-03 20:07:02 +000060 m_reassembler.beforeTimeout.connect(bind([this] { ++this->nReassemblyTimeouts; }));
Eric Newberry41aba102017-11-01 16:42:13 -070061 m_reliability.onDroppedInterest.connect([this] (const Interest& i) { this->notifyDroppedInterest(i); });
Eric Newberry73bcad32017-04-25 17:57:35 -070062 nReassembling.observe(&m_reassembler);
Eric Newberry86d31872015-09-23 16:24:59 -070063}
64
Eric Newberrya98bf932015-09-21 00:58:47 -070065void
Eric Newberry185ab292017-03-28 06:45:39 +000066GenericLinkService::setOptions(const GenericLinkService::Options& options)
67{
68 m_options = options;
69 m_fragmenter.setOptions(m_options.fragmenterOptions);
70 m_reassembler.setOptions(m_options.reassemblerOptions);
71 m_reliability.setOptions(m_options.reliabilityOptions);
72}
73
74void
75GenericLinkService::requestIdlePacket()
76{
77 // No need to request Acks to attach to this packet from LpReliability, as they are already
78 // attached in sendLpPacket
79 this->sendLpPacket({});
80}
81
82void
83GenericLinkService::sendLpPacket(lp::Packet&& pkt)
84{
85 const ssize_t mtu = this->getTransport()->getMtu();
Eric Newberryb49313d2017-12-24 20:22:27 -070086
Eric Newberry185ab292017-03-28 06:45:39 +000087 if (m_options.reliabilityOptions.isEnabled) {
88 m_reliability.piggyback(pkt, mtu);
89 }
90
Eric Newberryb49313d2017-12-24 20:22:27 -070091 if (m_options.allowCongestionMarking) {
92 checkCongestionLevel(pkt);
93 }
94
Eric Newberry185ab292017-03-28 06:45:39 +000095 Transport::Packet tp(pkt.wireEncode());
96 if (mtu != MTU_UNLIMITED && tp.packet.size() > static_cast<size_t>(mtu)) {
97 ++this->nOutOverMtu;
98 NFD_LOG_FACE_WARN("attempted to send packet over MTU limit");
99 return;
100 }
101 this->sendPacket(std::move(tp));
102}
103
104void
Eric Newberrya98bf932015-09-21 00:58:47 -0700105GenericLinkService::doSendInterest(const Interest& interest)
106{
107 lp::Packet lpPacket(interest.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000108
Eric Newberryee400b52016-11-24 14:12:48 +0000109 encodeLpFields(interest, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700110
Eric Newberry41aba102017-11-01 16:42:13 -0700111 this->sendNetPacket(std::move(lpPacket), true);
Eric Newberrya98bf932015-09-21 00:58:47 -0700112}
113
114void
115GenericLinkService::doSendData(const Data& data)
116{
117 lp::Packet lpPacket(data.wireEncode());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000118
Eric Newberryee400b52016-11-24 14:12:48 +0000119 encodeLpFields(data, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700120
Eric Newberry41aba102017-11-01 16:42:13 -0700121 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700122}
123
124void
125GenericLinkService::doSendNack(const lp::Nack& nack)
126{
127 lp::Packet lpPacket(nack.getInterest().wireEncode());
128 lpPacket.add<lp::NackField>(nack.getHeader());
Junxiao Shi0de23a22015-12-03 20:07:02 +0000129
Eric Newberryee400b52016-11-24 14:12:48 +0000130 encodeLpFields(nack, lpPacket);
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700131
Eric Newberry41aba102017-11-01 16:42:13 -0700132 this->sendNetPacket(std::move(lpPacket), false);
Eric Newberrya98bf932015-09-21 00:58:47 -0700133}
134
Junxiao Shi0de23a22015-12-03 20:07:02 +0000135void
Eric Newberry41aba102017-11-01 16:42:13 -0700136GenericLinkService::encodeLpFields(const ndn::PacketBase& netPkt, lp::Packet& lpPacket)
Eric Newberry86d31872015-09-23 16:24:59 -0700137{
Eric Newberryee400b52016-11-24 14:12:48 +0000138 if (m_options.allowLocalFields) {
139 shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = netPkt.getTag<lp::IncomingFaceIdTag>();
140 if (incomingFaceIdTag != nullptr) {
141 lpPacket.add<lp::IncomingFaceIdField>(*incomingFaceIdTag);
142 }
143 }
144
145 shared_ptr<lp::CongestionMarkTag> congestionMarkTag = netPkt.getTag<lp::CongestionMarkTag>();
146 if (congestionMarkTag != nullptr) {
147 lpPacket.add<lp::CongestionMarkField>(*congestionMarkTag);
Eric Newberry86d31872015-09-23 16:24:59 -0700148 }
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700149
150 if (m_options.allowSelfLearning) {
151 shared_ptr<lp::NonDiscoveryTag> nonDiscoveryTag = netPkt.getTag<lp::NonDiscoveryTag>();
152 if (nonDiscoveryTag != nullptr) {
153 lpPacket.add<lp::NonDiscoveryField>(*nonDiscoveryTag);
154 }
155
156 shared_ptr<lp::PrefixAnnouncementTag> prefixAnnouncementTag = netPkt.getTag<lp::PrefixAnnouncementTag>();
157 if (prefixAnnouncementTag != nullptr) {
158 lpPacket.add<lp::PrefixAnnouncementField>(*prefixAnnouncementTag);
159 }
160 }
Eric Newberry86d31872015-09-23 16:24:59 -0700161}
162
Eric Newberrya98bf932015-09-21 00:58:47 -0700163void
Eric Newberry41aba102017-11-01 16:42:13 -0700164GenericLinkService::sendNetPacket(lp::Packet&& pkt, bool isInterest)
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700165{
166 std::vector<lp::Packet> frags;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000167 ssize_t mtu = this->getTransport()->getMtu();
168
169 // Make space for feature fields in fragments
170 if (m_options.reliabilityOptions.isEnabled && mtu != MTU_UNLIMITED) {
171 mtu -= LpReliability::RESERVED_HEADER_SPACE;
Eric Newberry7b0071e2017-07-03 17:33:31 +0000172 }
173
Eric Newberryb49313d2017-12-24 20:22:27 -0700174 if (m_options.allowCongestionMarking && mtu != MTU_UNLIMITED) {
175 mtu -= CONGESTION_MARK_SIZE;
176 }
177
178 BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
179
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700180 if (m_options.allowFragmentation && mtu != MTU_UNLIMITED) {
181 bool isOk = false;
182 std::tie(isOk, frags) = m_fragmenter.fragmentPacket(pkt, mtu);
183 if (!isOk) {
184 // fragmentation failed (warning is logged by LpFragmenter)
Junxiao Shi0de23a22015-12-03 20:07:02 +0000185 ++this->nFragmentationErrors;
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700186 return;
187 }
188 }
189 else {
Eric Newberry41aba102017-11-01 16:42:13 -0700190 if (m_options.reliabilityOptions.isEnabled) {
191 frags.push_back(pkt);
192 }
193 else {
194 frags.push_back(std::move(pkt));
195 }
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700196 }
197
Eric Newberry185ab292017-03-28 06:45:39 +0000198 if (frags.size() == 1) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700199 // even if indexed fragmentation is enabled, the fragmenter should not
200 // fragment the packet if it can fit in MTU
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700201 BOOST_ASSERT(!frags.front().has<lp::FragIndexField>());
202 BOOST_ASSERT(!frags.front().has<lp::FragCountField>());
203 }
204
Eric Newberry7b0071e2017-07-03 17:33:31 +0000205 // Only assign sequences to fragments if packet contains more than 1 fragment
206 if (frags.size() > 1) {
Eric Newberry185ab292017-03-28 06:45:39 +0000207 // Assign sequences to all fragments
208 this->assignSequences(frags);
209 }
210
211 if (m_options.reliabilityOptions.isEnabled && frags.front().has<lp::FragmentField>()) {
Eric Newberry41aba102017-11-01 16:42:13 -0700212 m_reliability.handleOutgoing(frags, std::move(pkt), isInterest);
Eric Newberry185ab292017-03-28 06:45:39 +0000213 }
214
215 for (lp::Packet& frag : frags) {
216 this->sendLpPacket(std::move(frag));
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700217 }
218}
219
220void
221GenericLinkService::assignSequence(lp::Packet& pkt)
222{
223 pkt.set<lp::SequenceField>(++m_lastSeqNo);
224}
225
226void
227GenericLinkService::assignSequences(std::vector<lp::Packet>& pkts)
228{
229 std::for_each(pkts.begin(), pkts.end(), bind(&GenericLinkService::assignSequence, this, _1));
230}
231
232void
Eric Newberryb49313d2017-12-24 20:22:27 -0700233GenericLinkService::checkCongestionLevel(lp::Packet& pkt)
234{
235 ssize_t sendQueueLength = getTransport()->getSendQueueLength();
236 // This operation requires that the transport supports retrieving current send queue length
237 if (sendQueueLength < 0) {
238 return;
239 }
240
241 // To avoid overflowing the queue, set the congestion threshold to at least half of the send
242 // queue capacity.
243 size_t congestionThreshold = m_options.defaultCongestionThreshold;
244 if (getTransport()->getSendQueueCapacity() >= 0) {
245 congestionThreshold = std::min(congestionThreshold,
246 static_cast<size_t>(getTransport()->getSendQueueCapacity()) /
247 DEFAULT_CONGESTION_THRESHOLD_DIVISOR);
248 }
249
250 if (sendQueueLength > 0) {
251 NFD_LOG_FACE_TRACE("txqlen=" << sendQueueLength << " threshold=" << congestionThreshold <<
252 " capacity=" << getTransport()->getSendQueueCapacity());
253 }
254
255 if (static_cast<size_t>(sendQueueLength) > congestionThreshold) { // Send queue is congested
256 const auto now = time::steady_clock::now();
257 if (now >= m_nextMarkTime || now >= m_lastMarkTime + m_options.baseCongestionMarkingInterval) {
258 // Mark at most one initial packet per baseCongestionMarkingInterval
259 if (m_nMarkedSinceInMarkingState == 0) {
260 m_nextMarkTime = now;
261 }
262
263 // Time to mark packet
264 pkt.set<lp::CongestionMarkField>(1);
265 ++nCongestionMarked;
266 NFD_LOG_FACE_DEBUG("LpPacket was marked as congested");
267
268 ++m_nMarkedSinceInMarkingState;
269 // Decrease the marking interval by the inverse of the square root of the number of packets
270 // marked in this incident of congestion
271 m_nextMarkTime += time::nanoseconds(static_cast<time::nanoseconds::rep>(
272 m_options.baseCongestionMarkingInterval.count() /
273 std::sqrt(m_nMarkedSinceInMarkingState)));
274 m_lastMarkTime = now;
275 }
276 }
277 else if (m_nextMarkTime != time::steady_clock::TimePoint::max()) {
278 // Congestion incident has ended, so reset
279 NFD_LOG_FACE_DEBUG("Send queue length dropped below congestion threshold");
280 m_nextMarkTime = time::steady_clock::TimePoint::max();
281 m_nMarkedSinceInMarkingState = 0;
282 }
283}
284
285void
Eric Newberrya98bf932015-09-21 00:58:47 -0700286GenericLinkService::doReceivePacket(Transport::Packet&& packet)
287{
Eric Newberry86d31872015-09-23 16:24:59 -0700288 try {
Eric Newberrya1939ba2015-10-09 12:35:03 -0700289 lp::Packet pkt(packet.packet);
290
Eric Newberry185ab292017-03-28 06:45:39 +0000291 if (m_options.reliabilityOptions.isEnabled) {
292 m_reliability.processIncomingPacket(pkt);
293 }
294
Eric Newberrya1939ba2015-10-09 12:35:03 -0700295 if (!pkt.has<lp::FragmentField>()) {
296 NFD_LOG_FACE_TRACE("received IDLE packet: DROP");
297 return;
298 }
299
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700300 if ((pkt.has<lp::FragIndexField>() || pkt.has<lp::FragCountField>()) &&
301 !m_options.allowReassembly) {
302 NFD_LOG_FACE_WARN("received fragment, but reassembly disabled: DROP");
Eric Newberrya1939ba2015-10-09 12:35:03 -0700303 return;
304 }
305
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700306 bool isReassembled = false;
307 Block netPkt;
308 lp::Packet firstPkt;
309 std::tie(isReassembled, netPkt, firstPkt) = m_reassembler.receiveFragment(packet.remoteEndpoint,
310 pkt);
311 if (isReassembled) {
312 this->decodeNetPacket(netPkt, firstPkt);
313 }
314 }
315 catch (const tlv::Error& e) {
316 ++this->nInLpInvalid;
317 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
318 }
319}
Eric Newberry86d31872015-09-23 16:24:59 -0700320
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700321void
322GenericLinkService::decodeNetPacket(const Block& netPkt, const lp::Packet& firstPkt)
323{
324 try {
Eric Newberry86d31872015-09-23 16:24:59 -0700325 switch (netPkt.type()) {
326 case tlv::Interest:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700327 if (firstPkt.has<lp::NackField>()) {
328 this->decodeNack(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700329 }
330 else {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700331 this->decodeInterest(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700332 }
333 break;
334 case tlv::Data:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700335 this->decodeData(netPkt, firstPkt);
Eric Newberry86d31872015-09-23 16:24:59 -0700336 break;
337 default:
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700338 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700339 NFD_LOG_FACE_WARN("unrecognized network-layer packet TLV-TYPE " << netPkt.type() << ": DROP");
340 return;
Eric Newberrya98bf932015-09-21 00:58:47 -0700341 }
342 }
Eric Newberry86d31872015-09-23 16:24:59 -0700343 catch (const tlv::Error& e) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700344 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700345 NFD_LOG_FACE_WARN("packet parse error (" << e.what() << "): DROP");
346 }
347}
348
Eric Newberry86d31872015-09-23 16:24:59 -0700349void
350GenericLinkService::decodeInterest(const Block& netPkt, const lp::Packet& firstPkt)
351{
352 BOOST_ASSERT(netPkt.type() == tlv::Interest);
353 BOOST_ASSERT(!firstPkt.has<lp::NackField>());
354
355 // forwarding expects Interest to be created with make_shared
356 auto interest = make_shared<Interest>(netPkt);
357
358 if (firstPkt.has<lp::NextHopFaceIdField>()) {
359 if (m_options.allowLocalFields) {
Junxiao Shi0de23a22015-12-03 20:07:02 +0000360 interest->setTag(make_shared<lp::NextHopFaceIdTag>(firstPkt.get<lp::NextHopFaceIdField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700361 }
362 else {
363 NFD_LOG_FACE_WARN("received NextHopFaceId, but local fields disabled: DROP");
364 return;
365 }
366 }
367
368 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700369 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700370 NFD_LOG_FACE_WARN("received CachePolicy with Interest: DROP");
371 return;
372 }
373
374 if (firstPkt.has<lp::IncomingFaceIdField>()) {
375 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
376 }
377
Eric Newberryee400b52016-11-24 14:12:48 +0000378 if (firstPkt.has<lp::CongestionMarkField>()) {
379 interest->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
380 }
381
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700382 if (firstPkt.has<lp::NonDiscoveryField>()) {
383 if (m_options.allowSelfLearning) {
384 interest->setTag(make_shared<lp::NonDiscoveryTag>(firstPkt.get<lp::NonDiscoveryField>()));
385 }
386 else {
387 NFD_LOG_FACE_WARN("received NonDiscovery, but self-learning disabled: IGNORE");
388 }
389 }
390
391 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
392 ++this->nInNetInvalid;
393 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Interest: DROP");
394 return;
395 }
396
Eric Newberry86d31872015-09-23 16:24:59 -0700397 this->receiveInterest(*interest);
398}
399
400void
401GenericLinkService::decodeData(const Block& netPkt, const lp::Packet& firstPkt)
402{
403 BOOST_ASSERT(netPkt.type() == tlv::Data);
404
405 // forwarding expects Data to be created with make_shared
406 auto data = make_shared<Data>(netPkt);
407
408 if (firstPkt.has<lp::NackField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700409 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700410 NFD_LOG_FACE_WARN("received Nack with Data: DROP");
411 return;
412 }
413
414 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700415 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700416 NFD_LOG_FACE_WARN("received NextHopFaceId with Data: DROP");
417 return;
418 }
419
420 if (firstPkt.has<lp::CachePolicyField>()) {
Junxiao Shi6eb02712017-05-27 22:48:02 +0000421 // CachePolicy is unprivileged and does not require allowLocalFields option.
422 // In case of an invalid CachePolicyType, get<lp::CachePolicyField> will throw,
423 // so it's unnecessary to check here.
424 data->setTag(make_shared<lp::CachePolicyTag>(firstPkt.get<lp::CachePolicyField>()));
Eric Newberry86d31872015-09-23 16:24:59 -0700425 }
426
427 if (firstPkt.has<lp::IncomingFaceIdField>()) {
428 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
429 }
430
Eric Newberryee400b52016-11-24 14:12:48 +0000431 if (firstPkt.has<lp::CongestionMarkField>()) {
432 data->setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
433 }
434
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700435 if (firstPkt.has<lp::NonDiscoveryField>()) {
436 ++this->nInNetInvalid;
437 NFD_LOG_FACE_WARN("received NonDiscovery with Data: DROP");
438 return;
439 }
440
441 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
442 if (m_options.allowSelfLearning) {
443 data->setTag(make_shared<lp::PrefixAnnouncementTag>(firstPkt.get<lp::PrefixAnnouncementField>()));
444 }
445 else {
446 NFD_LOG_FACE_WARN("received PrefixAnnouncement, but self-learning disabled: IGNORE");
447 }
448 }
449
Eric Newberry86d31872015-09-23 16:24:59 -0700450 this->receiveData(*data);
451}
452
453void
454GenericLinkService::decodeNack(const Block& netPkt, const lp::Packet& firstPkt)
455{
456 BOOST_ASSERT(netPkt.type() == tlv::Interest);
457 BOOST_ASSERT(firstPkt.has<lp::NackField>());
458
459 lp::Nack nack((Interest(netPkt)));
460 nack.setHeader(firstPkt.get<lp::NackField>());
461
462 if (firstPkt.has<lp::NextHopFaceIdField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700463 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700464 NFD_LOG_FACE_WARN("received NextHopFaceId with Nack: DROP");
465 return;
466 }
467
468 if (firstPkt.has<lp::CachePolicyField>()) {
Eric Newberry4c3e6b82015-11-10 16:48:42 -0700469 ++this->nInNetInvalid;
Eric Newberry86d31872015-09-23 16:24:59 -0700470 NFD_LOG_FACE_WARN("received CachePolicy with Nack: DROP");
471 return;
472 }
473
474 if (firstPkt.has<lp::IncomingFaceIdField>()) {
475 NFD_LOG_FACE_WARN("received IncomingFaceId: IGNORE");
476 }
477
Eric Newberryee400b52016-11-24 14:12:48 +0000478 if (firstPkt.has<lp::CongestionMarkField>()) {
479 nack.setTag(make_shared<lp::CongestionMarkTag>(firstPkt.get<lp::CongestionMarkField>()));
480 }
481
Teng Liangfdcbb4d2018-01-27 16:01:35 -0700482 if (firstPkt.has<lp::NonDiscoveryField>()) {
483 ++this->nInNetInvalid;
484 NFD_LOG_FACE_WARN("received NonDiscovery with Nack: DROP");
485 return;
486 }
487
488 if (firstPkt.has<lp::PrefixAnnouncementField>()) {
489 ++this->nInNetInvalid;
490 NFD_LOG_FACE_WARN("received PrefixAnnouncement with Nack: DROP");
491 return;
492 }
493
Eric Newberry86d31872015-09-23 16:24:59 -0700494 this->receiveNack(nack);
Eric Newberrya98bf932015-09-21 00:58:47 -0700495}
496
497} // namespace face
498} // namespace nfd