INET Framework for OMNeT++/OMNEST
inet::eigrp::EigrpDual< IPAddress > Class Template Reference

Class represents DUAL automaton. More...

#include <EigrpDual.h>

Inheritance diagram for inet::eigrp::EigrpDual< IPAddress >:

Public Types

enum  DualEvent {
  RECV_UPDATE = 0, RECV_QUERY, RECV_REPLY, NEIGHBOR_DOWN,
  INTERFACE_DOWN, INTERFACE_UP, LOST_ROUTE
}
 

Public Member Functions

 EigrpDual (IEigrpPdm< IPAddress > *pdm)
 
void processEvent (DualEvent event, EigrpRouteSource< IPAddress > *source, int neighborId, bool isSourceNew)
 The entry point for processing events. More...
 

Protected Member Functions

void invalidateRoute (EigrpRouteSource< IPAddress > *routeSrc)
 Invalidates specified route. More...
 
void processQo0 (DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processQo1Passive (DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processQo1Active (DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processQo2 (DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processQo3 (DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processTransition1 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition2 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition3 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition4 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition5 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition6 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition7 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition8 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 
void processTransition9 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition10 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition11 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition12 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition13 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition14 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition15 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition16 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
 
void processTransition17 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
 
void processTransition18 (int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
 

Protected Attributes

IEigrpPdm< IPAddress > * pdm
 Protocol dependent module interface. More...
 

Detailed Description

template<typename IPAddress>
class inet::eigrp::EigrpDual< IPAddress >

Class represents DUAL automaton.

Member Enumeration Documentation

◆ DualEvent

template<typename IPAddress >
enum inet::eigrp::EigrpDual::DualEvent
Enumerator
RECV_UPDATE 

Change of route distance in received update message or on interface.

RECV_QUERY 

Received query message.

RECV_REPLY 

Received reply message.

NEIGHBOR_DOWN 

Neighbor went down.

INTERFACE_DOWN 

EIGRP disabled on interface - only for connected route.

INTERFACE_UP 

EIGRP enabled on interface.

LOST_ROUTE 

Route in RT deleted, but not by EIGRP.

33  {
34  RECV_UPDATE = 0,
35  RECV_QUERY,
36  RECV_REPLY,
39  INTERFACE_UP,
40  LOST_ROUTE,
41  };

Constructor & Destructor Documentation

◆ EigrpDual()

template<typename IPAddress >
inet::eigrp::EigrpDual< IPAddress >::EigrpDual ( IEigrpPdm< IPAddress > *  pdm)
inline
79 { this->pdm = pdm; }

Member Function Documentation

◆ invalidateRoute()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::invalidateRoute ( EigrpRouteSource< IPAddress > *  routeSrc)
protected

Invalidates specified route.

46 {
47  if (routeSrc->isValid()) {
48  routeSrc->setValid(false);
49  EV_DEBUG << "DUAL: invalidate route via " << routeSrc->getNextHop() << " in TT" << endl;
50  }
51 }

◆ processEvent()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processEvent ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
int  neighborId,
bool  isSourceNew 
)

The entry point for processing events.

Parameters
eventtype of event
sourceroute
neighborIdsource of the event
isSourceNewif route was created now
eventType of input event
sourceData from messages are stored into source. If the source is new, then it is not inserted into route.
routeContains actual metric and RD. Dij remains unchanged.
61 {
62  EigrpRoute<IPAddress> *route = source->getRouteInfo();
63 
64  if (event == NEIGHBOR_DOWN || event == INTERFACE_DOWN)
65  source->setUnreachableMetric(); // Must be there
66 
67  EV_DEBUG << "DUAL: " << eigrpDual::userMsgs[event];
68  EV_DEBUG << " for route " << route->getRouteAddress() << " via " << source->getNextHop();
69  EV_DEBUG << " (" << source->getMetric() << "/" << source->getRd() << ")" << endl;
70  EV_DEBUG << "QueryOrigin je: " << route->getQueryOrigin() << " , replyStatusSum je: " << route->getReplyStatusSum() << endl;
71  EV_DEBUG << "Event: " << event << endl;
72  switch (route->getQueryOrigin()) {
73  case 0: // active state
74  processQo0(event, source, route, neighborId, isSourceNew);
75  break;
76 
77  case 1:
78  if (route->getReplyStatusSum() == 0) { // passive state
79  processQo1Passive(event, source, route, neighborId, isSourceNew);
80  }
81  else { // active state
82  processQo1Active(event, source, route, neighborId, isSourceNew);
83  }
84  break;
85 
86  case 2: // active state
87  processQo2(event, source, route, neighborId, isSourceNew);
88  break;
89 
90  case 3: // active state
91  processQo3(event, source, route, neighborId, isSourceNew);
92  break;
93 
94  default:
95  // DUAL detected invalid state of route
96  ASSERT(false);
97  break;
98  }
99 }

◆ processQo0()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processQo0 ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
107 {
108  uint64_t dmin;
109  bool hasReplyStatus;
110 
111  switch (event) {
112  case INTERFACE_UP:
113  processTransition7(event, source, route, neighborId);
114  break;
115 
116  case RECV_UPDATE:
117  processTransition7(event, source, route, neighborId);
118  break;
119 
120  case RECV_QUERY:
121  if (source->isSuccessor())
122  processTransition5(event, source, route, neighborId);
123  else
124  processTransition6(event, source, route, neighborId);
125  break;
126 
127  case RECV_REPLY:
128  case NEIGHBOR_DOWN:
129  case INTERFACE_DOWN:
130  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
131  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
132 
133  if (route->getReplyStatusSum() == 0) { // As last reply from neighbor
134  // Check FC with FDij(t)
135  if (pdm->hasFeasibleSuccessor(route, dmin))
136  processTransition14(event, source, route, dmin, neighborId);
137  else
138  processTransition11(event, source, route, dmin, neighborId);
139  }
140  else if (hasReplyStatus) { // As not last reply from neighbor
141  processTransition8(event, source, route, neighborId, isSourceNew);
142  }
143  // else do nothing (connected source)
144  break;
145 
146  case LOST_ROUTE:
147  // do nothing
148  break;
149 
150  default:
151  EV_DEBUG << "DUAL received invalid input event num. " << event << " in active state 0" << endl;
152  ASSERT(false);
153  break;
154  }
155 }

◆ processQo1Active()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processQo1Active ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
207 {
208  bool hasReplyStatus;
209 
210  switch (event) {
211  case INTERFACE_UP:
212  processTransition17(event, source, route, neighborId);
213  break;
214 
215  case RECV_UPDATE:
216  if (source->isSuccessor())
217  processTransition9(event, source, route, neighborId);
218  else
219  processTransition17(event, source, route, neighborId);
220  break;
221 
222  case RECV_QUERY:
223  if (source->isSuccessor())
224  processTransition5(event, source, route, neighborId);
225  else
226  processTransition6(event, source, route, neighborId);
227  break;
228 
229  case RECV_REPLY:
230  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
231  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
232 
233  if (route->getReplyStatusSum() == 0) // Last reply
234  processTransition15(event, source, route, neighborId);
235  else if (hasReplyStatus) // Not last reply
236  processTransition18(event, source, route, neighborId, isSourceNew);
237  // else do nothing
238  break;
239 
240  case NEIGHBOR_DOWN:
241  case INTERFACE_DOWN:
242  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
243  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
244 
245  // Transition 9 should take precedence over transition 15 (fail of link
246  // to S (as last reply) versus fail of link to not S (as last reply)
247  // TODO ověřit!
248  if (source->isSuccessor())
249  processTransition9(event, source, route, neighborId);
250 
251  if (route->getReplyStatusSum() == 0) { // As last reply from neighbor
252  processTransition15(event, source, route, neighborId);
253  }
254  else if (hasReplyStatus) { // As not last reply from neighbor
255  processTransition18(event, source, route, neighborId, isSourceNew);
256  }
257  // else do nothing
258  break;
259 
260  case LOST_ROUTE:
261  // do nothing
262  break;
263 
264  default:
265  ASSERT(false);
266  EV_DEBUG << "DUAL received invalid input event in active state 1, skipped" << endl;
267  break;
268  }
269 }

◆ processQo1Passive()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processQo1Passive ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
159 {
160  uint64_t dmin;
161 
162  switch (event) {
163  case LOST_ROUTE:
164  case INTERFACE_UP:
165  case RECV_UPDATE:
166  if (event == LOST_ROUTE) // Force loss of all sources of the route
167  route->setFd(0);
168 
169  if (pdm->hasFeasibleSuccessor(route, dmin))
170  processTransition2(event, source, route, dmin, neighborId);
171  else
172  processTransition4(event, source, route, dmin, neighborId);
173  break;
174 
175  case NEIGHBOR_DOWN:
176  case INTERFACE_DOWN:
177  if (pdm->hasFeasibleSuccessor(route, dmin))
178  processTransition2(event, source, route, dmin, neighborId);
179  else
180  processTransition4(event, source, route, dmin, neighborId);
181  break;
182 
183  case RECV_QUERY:
184  if (route->getNumSucc() == 0 || pdm->hasFeasibleSuccessor(route, dmin)) { // No successor to the destination or FC satisfied
185  if (source->isSuccessor())
186  processTransition2(event, source, route, dmin, neighborId);
187  else
188  processTransition1(event, source, route, dmin, neighborId);
189  }
190  else {
191  if (source->isSuccessor())
192  processTransition3(event, source, route, dmin, neighborId);
193  else
194  processTransition4(event, source, route, dmin, neighborId);
195  }
196  break;
197 
198  default:
199  ASSERT(false);
200  EV_DEBUG << "DUAL received invalid input event in passive state 0, skipped" << endl;
201  break;
202  }
203 }

◆ processQo2()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processQo2 ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
273 {
274  uint64_t dmin;
275  bool hasReplyStatus;
276 
277  switch (event) {
278  case INTERFACE_UP:
279  processTransition7(event, source, route, neighborId);
280  break;
281 
282  case RECV_UPDATE:
283  processTransition7(event, source, route, neighborId);
284  break;
285 
286  case RECV_QUERY:
287  if (!source->isSuccessor())
288  processTransition6(event, source, route, neighborId);
289 
290  else {
291  ASSERT(false);
292  // do nothing (DUAL can not receive Query form S when it is in active state oij=2)
293  }
294  break;
295 
296  case RECV_REPLY:
297  case NEIGHBOR_DOWN:
298  case INTERFACE_DOWN:
299  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
300  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
301 
302  if (route->getReplyStatusSum() == 0) { // As last reply from neighbor
303  // Check FC with FDij(t)
304  if (pdm->hasFeasibleSuccessor(route, dmin))
305  processTransition16(event, source, route, dmin, neighborId);
306  else
307  processTransition12(event, source, route, dmin, neighborId);
308  }
309  else if (hasReplyStatus) { // As not last reply from neighbor
310  processTransition8(event, source, route, neighborId, isSourceNew);
311  }
312  // else do nothing (connected source)
313  break;
314 
315  case LOST_ROUTE:
316  // do nothing
317  break;
318 
319  default:
320  ASSERT(false);
321  EV_DEBUG << "DUAL received invalid input event in active state 2, skipped" << endl;
322  break;
323  }
324 }

◆ processQo3()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processQo3 ( DualEvent  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
328 {
329  bool hasReplyStatus;
330 
331  switch (event) {
332  case INTERFACE_UP:
333  processTransition17(event, source, route, neighborId);
334  break;
335 
336  case RECV_UPDATE:
337  if (source->isSuccessor())
338  processTransition10(event, source, route, neighborId);
339  else
340  processTransition17(event, source, route, neighborId);
341  break;
342 
343  case RECV_QUERY:
344  if (!source->isSuccessor())
345  processTransition6(event, source, route, neighborId);
346  else {
347  ASSERT(false);
348  // do nothing (DUAL can not receive Query form S when it is in active state oij=3)
349  }
350  break;
351 
352  case RECV_REPLY:
353  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
354  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
355 
356  if (route->getReplyStatusSum() == 0) // Last reply
357  processTransition13(event, source, route, neighborId);
358  else if (hasReplyStatus) // Not last reply
359  processTransition18(event, source, route, neighborId, isSourceNew);
360  // else do nothing
361  break;
362 
363  case NEIGHBOR_DOWN:
364  case INTERFACE_DOWN:
365  if ((hasReplyStatus = route->unsetReplyStatus(neighborId)) == true)
366  EV_DEBUG << " Clear handle, reply status summary = " << route->getReplyStatusSum() << endl;
367 
368  // Transition 10 should take precedence over transition 13 (fail of link
369  // to S (as last reply) versus fail of link to not S (as last reply)
370  // TODO ověřit!
371  if (source->isSuccessor())
372  processTransition10(event, source, route, neighborId);
373 
374  if (route->getReplyStatusSum() == 0) { // As last reply from neighbor
375  processTransition13(event, source, route, neighborId);
376  }
377  else if (hasReplyStatus) { // As not last reply from neighbor
378  processTransition18(event, source, route, neighborId, isSourceNew);
379  }
380  // else do nothing
381  break;
382 
383  case LOST_ROUTE:
384  // do nothing
385  break;
386 
387  default:
388  ASSERT(false);
389  EV_DEBUG << "DUAL received invalid input event in active state 3, skipped" << endl;
390  break;
391  }
392 }

◆ processTransition1()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition1 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
399 {
400  EV_DEBUG << "DUAL: transit from oij=1 (passive) to oij=1 (passive) by transition 1" << endl;
401 
402  EigrpRouteSource<IPAddress> *successor = pdm->getBestSuccessor(route);
403  if (successor == nullptr) { // There is no successor, reply with unreachable route
404  pdm->sendReply(route, neighborId, source, false, true);
405  }
406  else
407  pdm->sendReply(route, neighborId, successor);
408 
409  // Route will be removed after router receives Ack from neighbor for Reply
410  if (source->isUnreachable())
411  pdm->setDelayedRemove(neighborId, source);
412 }

◆ processTransition10()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition10 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
601 {
602  EV_DEBUG << "DUAL: transit from oij=3 (active) to oij=2 (active) by transition 10" << endl;
603 
604  route->setQueryOrigin(2);
605 
606  // Actualize Dij of route
607  route->setDij(source->getMetric());
608 
609  if (route->getReplyStatusSum() == 0) { // Reply status table is empty, go to passive state or start new diffusing computation
610  uint64_t dmin;
611  if (pdm->hasFeasibleSuccessor(route, dmin))
612  processTransition16(event, source, route, dmin, neighborId);
613  else
614  processTransition12(event, source, route, dmin, neighborId);
615  }
616 
617  // Do not remove unreachable route (this will be done after transition to passive state)
618 }

◆ processTransition11()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition11 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
622 {
623  EV_DEBUG << "DUAL: transit from oij=0 (active) to oij=1 (active) by transition 11" << endl;
624 
625  int numPeers = 0, numStubs = 0;
626  bool gotoActive;
627 
628  route->setQueryOrigin(1);
629 
630  gotoActive = pdm->setReplyStatusTable(route, source, false, &numPeers, &numStubs);
631  EV_DEBUG << "DUAL: peers = " << numPeers << ", stubs = " << numStubs << endl;
632  if (gotoActive) { // Start new diffusion computation
633  int srcNeighbor = (neighborId != IEigrpPdm<IPAddress>::UNSPEC_RECEIVER) ? neighborId : IEigrpPdm<IPAddress>::UNSPEC_SENDER;
634  pdm->sendQuery(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, source, srcNeighbor);
635  }
636  else { // Go to passive state
637  processTransition15(event, source, route, neighborId);
638  return;
639  }
640 
641  // Do not remove unreachable route (this will be done after transition to passive state)
642 }

◆ processTransition12()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition12 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
646 {
647  EV_DEBUG << "DUAL: transit from oij=2 (active) to oij=3 (active) by transition 12" << endl;
648 
649  int numPeers = 0, numStubs = 0;
650  bool gotoActive;
651 
652  route->setQueryOrigin(3);
653 
654  gotoActive = pdm->setReplyStatusTable(route, source, false, &numPeers, &numStubs);
655  EV_DEBUG << "DUAL: peers = " << numPeers << ", stubs = " << numStubs << endl;
656  if (gotoActive) { // Start new diffusion computation
657  pdm->sendQuery(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, source);
658  }
659  else { // Go to passive state
660  processTransition13(event, source, route, neighborId);
661  return;
662  }
663 
664  // Do not remove unreachable route (this will be done after transition to passive state)
665 }

◆ processTransition13()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition13 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
669 {
670  EV_DEBUG << "DUAL: transit from oij=3 (active) to oij=1 (passive) by transition 13" << endl;
671 
672  EigrpRouteSource<IPAddress> *successor;
673  // Old successor is originator of Query
674  EigrpRouteSource<IPAddress> *oldSuccessor = pdm->getBestSuccessor(route);
675  uint64_t oldDij = route->getDij();
676  uint64_t dmin;
677  bool rtableChanged = false;
678 
679  route->setQueryOrigin(1);
680 
681  // Set FD to max
682  route->setFd(EigrpMetricHelper::METRIC_INF);
683 
684  // Find min distance
685  dmin = pdm->findRouteDMin(route);
686 
687  // Find successor and update distance of the route
688  successor = pdm->updateRoute(route, dmin, &rtableChanged, true);
689  if (source->isUnreachable())
690  invalidateRoute(source);
691 
692  // Send Reply to old successor
693  if (oldSuccessor != nullptr) {
694  if (successor == nullptr) { // Send old Successor
695  // Route will be removed after router receives Ack from neighbor for Reply
696  if (oldSuccessor->isUnreachable())
697  pdm->setDelayedRemove(oldSuccessor->getNexthopId(), oldSuccessor);
698  pdm->sendReply(route, oldSuccessor->getNexthopId(), oldSuccessor, true);
699  }
700  else
701  pdm->sendReply(route, oldSuccessor->getNexthopId(), successor, true);
702  }
703 
704  // Send update about change of metric only if there is successor
705  if (successor != nullptr && pdm->hasNeighborForUpdate(successor)) {
706  if (rtableChanged)
707  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, true, "RT changed");
708  else if (route->getDij() != oldDij) {
709  bool forcePoisonRev = successor->getNexthopId() == IEigrpPdm<IPAddress>::CONNECTED_ROUTE;
710  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, forcePoisonRev, "metric changed");
711  }
712  }
713 
714  pdm->sendUpdateToStubs(successor, oldSuccessor, route);
715 }

◆ processTransition14()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition14 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
719 {
720  EV_DEBUG << "DUAL: transit from oij=0 (active) to oij=1 (passive) by transition 14" << endl;
721 
722  EigrpRouteSource<IPAddress> *successor = nullptr, *oldSuccessor = nullptr;
723  uint64_t oldDij = route->getDij();
724  bool rtableChanged = false;
725 
726  route->setQueryOrigin(1);
727  oldSuccessor = pdm->getBestSuccessor(route);
728 
729  // Find successor and update distance of the route
730  successor = pdm->updateRoute(route, dmin, &rtableChanged, true);
731  if (source->isUnreachable()) { // There is not necessary wait for Ack from neighbor before delete source (Reply is not sent)
732  invalidateRoute(source);
733  }
734 
735  // Do not send Reply (Reply was sent in transition 4)
736 
737  // Send update about change of metric
738  if (successor != nullptr && pdm->hasNeighborForUpdate(successor)) {
739  if (rtableChanged)
740  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, true, "RT changed");
741  else if (route->getDij() != oldDij) {
742  bool forcePoisonRev = successor->getNexthopId() == IEigrpPdm<IPAddress>::CONNECTED_ROUTE;
743  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, forcePoisonRev, "metric changed");
744  }
745  }
746 
747  pdm->sendUpdateToStubs(successor, oldSuccessor, route);
748 }

◆ processTransition15()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition15 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
752 {
753  EV_DEBUG << "DUAL: transit from oij=1 (active) to oij=1 (passive) by transition 15" << endl;
754 
755  EigrpRouteSource<IPAddress> *successor = nullptr, *oldSuccessor = nullptr;
756  uint64_t oldDij = route->getDij();
757  uint64_t dmin;
758  bool rtableChanged = false;
759 
760  // Set FD to max
761  route->setFd(EigrpMetricHelper::METRIC_INF);
762 
763  oldSuccessor = pdm->getBestSuccessor(route);
764 
765  if (oldSuccessor == nullptr) { // could happen due to different order of signals (vs 5.0 ANSAversion)
766  return;
767  }
768 
769  // Find min distance
770  dmin = pdm->findRouteDMin(route);
771 
772  successor = pdm->updateRoute(route, dmin, &rtableChanged, true);
773  if (source->isUnreachable()) { // There is not necessary wait for Ack from neighbor before delete source (Reply is not sent)
774  invalidateRoute(source);
775  }
776 
777  // Do not send Reply (Reply was sent in transition 4)
778 
779  // Send update about change
780  if (successor != nullptr && pdm->hasNeighborForUpdate(successor)) {
781  if (rtableChanged)
782  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, true, "RT changed");
783  else if (route->getDij() != oldDij) {
784  bool forcePoisonRev = successor->getNexthopId() == IEigrpPdm<IPAddress>::CONNECTED_ROUTE;
785  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, forcePoisonRev, "metric changed");
786  }
787  }
788 
789  pdm->sendUpdateToStubs(successor, oldSuccessor, route);
790 }

◆ processTransition16()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition16 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
794 {
795  EV_DEBUG << "DUAL: transit from oij=2 (active) to oij=1 (passive) by transition 16" << endl;
796 
797  EigrpRouteSource<IPAddress> *successor;
798  // Old successor is originator of Query
799  EigrpRouteSource<IPAddress> *oldSuccessor = pdm->getBestSuccessor(route);
800  uint64_t oldDij = route->getDij();
801  bool rtableChanged = false;
802 
803  route->setQueryOrigin(1);
804 
805  // Find successor and update distance of the route
806  successor = pdm->updateRoute(route, dmin, &rtableChanged, true);
807  ASSERT(successor != nullptr); // There must be successor
808 
809  if (source->isUnreachable()) { // There is not necessary wait for Ack from neighbor for Reply before delete source (successor may not be nullptr)
810  invalidateRoute(source);
811  }
812 
813  // Send Reply to old successor
814  if (oldSuccessor != nullptr)
815  pdm->sendReply(route, oldSuccessor->getNexthopId(), successor, true);
816 
817  // Send update about change of metric
818  if (pdm->hasNeighborForUpdate(successor)) {
819  if (rtableChanged)
820  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, true, "RT changed");
821  else if (route->getDij() != oldDij) {
822  bool forcePoisonRev = successor->getNexthopId() == IEigrpPdm<IPAddress>::CONNECTED_ROUTE;
823  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, forcePoisonRev, "metric changed");
824  }
825  }
826 
827  pdm->sendUpdateToStubs(successor, oldSuccessor, route);
828 }

◆ processTransition17()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition17 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
832 {
833  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=" << route->getQueryOrigin() << " (active) by transition 17" << endl;
834 
835  // Do not actualize Dij of route by new distance via successor (in transition to passive state DUAL can not detect change of Dij)
836 // route->setDij(source->getMetric());
837 }

◆ processTransition18()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition18 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
841 {
842  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=" << route->getQueryOrigin() << " (active) by transition 18" << endl;
843 
844  if (source->isUnreachable() && isSourceNew)
845  invalidateRoute(source);
846 }

◆ processTransition2()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition2 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
416 {
417  EV_DEBUG << "DUAL: transit from oij=1 (passive) to oij=1 (passive) by transition 2" << endl;
418 
419  EigrpRouteSource<IPAddress> *successor;
420  uint64_t oldDij; // Dij before the event
421  bool rtableChanged = false;
422 
423  oldDij = route->getDij();
424 
425  // Find successors and update route in TT and RT
426  successor = pdm->updateRoute(route, dmin, &rtableChanged);
427 
428  if (event == RECV_QUERY) {
429  ASSERT(successor != nullptr);
430  if (neighborId == successor->getNexthopId()) // Poison Reverse
431  pdm->sendReply(route, neighborId, successor, true);
432  else
433  pdm->sendReply(route, neighborId, successor);
434  // When Reply is sent, remove unreachable route after receiving Ack (According to Cisco EIGRP 10.0)
435  if (source->isUnreachable())
436  pdm->setDelayedRemove(neighborId, source);
437  }
438  else { // When Reply is not sent, remove unreachable route immediately
439  if (source->isUnreachable())
440  invalidateRoute(source);
441  }
442 
443  // Send Update about new Successor
444  if (successor != nullptr && pdm->hasNeighborForUpdate(successor)) {
445  if (rtableChanged)
446  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, true, "RT changed");
447  // Nedavno zmeneno: pokud nastane zmena metriky a cesta neni connected, pak se uplatni Split Horizon (ne Poison Reverse), sem nepatri zmena z inf na non inf hodnotu (to pokryje zmena tabulky)
448  else if (route->getDij() != oldDij) {
449  bool forcePoisonRev = successor->getNexthopId() == IEigrpPdm<IPAddress>::CONNECTED_ROUTE;
450  pdm->sendUpdate(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, successor, forcePoisonRev, "metric changed");
451  }
452  }
453 }

◆ processTransition3()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition3 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
457 {
458  EV_DEBUG << "DUAL: transit from oij=1 (passive) to oij=3 (active) by transition 3" << endl;
459  // Note: source is successor
460 
461  int numPeers = 0, numStubs = 0;
462  bool gotoActive;
463  route->setQueryOrigin(3);
464 
465  // Actualize distance of route and FD in TT
466 // route->setDij(source->getMetric()); // not there (in transition to passive state DUAL can not detect change of Dij)
467  route->setRdPar(source->getMetricParams());
468  route->setFd(route->getDij());
469 
470  // Send Query with actual distance via successor to all peers
471  gotoActive = pdm->setReplyStatusTable(route, source, false, &numPeers, &numStubs);
472  EV_DEBUG << "DUAL: peers = " << numPeers << ", stubs = " << numStubs << endl;
473 
474  if (gotoActive) {
475  pdm->sendQuery(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, source);
476  }
477  else { // Diffusion computation can not be performed, go back to passive state
478  processTransition13(event, source, route, neighborId);
479  return;
480  }
481 
482  // Do not remove source
483 }

◆ processTransition4()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition4 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
uint64_t  dmin,
int  neighborId 
)
protected
487 {
488  EV_DEBUG << "DUAL: transit from oij=1 (passive) to oij=1 (active) by transition 4" << endl;
489 
490  int numPeers = 0, numStubs = 0;
491  bool gotoActive;
492  EigrpRouteSource<IPAddress> *oldSuccessor;
493 
494  route->setQueryOrigin(1);
495 
496  // Get old successor
497  oldSuccessor = pdm->getBestSuccessor(route);
498  // Old successor may not be null
499  if (oldSuccessor == nullptr) oldSuccessor = source;
500 
501  // Actualize distance of route in TT
502  if (event == LOST_ROUTE) // Set distance and router RD to inf
503  route->setUnreachable();
504  else {
505  route->setDij(oldSuccessor->getMetric());
506  route->setRdPar(oldSuccessor->getMetricParams());
507  }
508  // Actualize FD in TT
509  route->setFd(route->getDij());
510 
511  // Send Reply with RDij if input event is Query
512  if (event == RECV_QUERY)
513  pdm->sendReply(route, neighborId, oldSuccessor);
514 
515  // Start own diffusion computation
516  gotoActive = pdm->setReplyStatusTable(route, source, true, &numPeers, &numStubs);
517  EV_DEBUG << "DUAL: peers = " << numPeers << ", stubs = " << numStubs << endl;
518  if (gotoActive) {
519  pdm->sendQuery(IEigrpPdm<IPAddress>::UNSPEC_RECEIVER, route, oldSuccessor, true);
520  }
521  else { // Go to passive state
522  processTransition15(event, source, route, neighborId);
523  return;
524  }
525 
526  // Do not remove source
527 }

◆ processTransition5()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition5 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
531 {
532  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=2 (active) by transition 5" << endl;
533 
534  route->setQueryOrigin(2);
535 
536  // Do not delete source
537 }

◆ processTransition6()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition6 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
541 {
542  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=" << route->getQueryOrigin() << " (active) by transition 6" << endl;
543 
544  EigrpRouteSource<IPAddress> *oldSuccessor = pdm->getBestSuccessor(route);
545  ASSERT(oldSuccessor != nullptr); // Old successor must be available until transition to passive state
546  /*if (oldSuccessor == nullptr) // Send route with unreachable distance (not Poison Reverse)
547  pdm->sendReply(route, neighborId, source, false, true);
548  else*/
549 
550  if (source->isSuccessor()) // Send route with unreachable distance to old Successor (Poison Reverse)
551  pdm->sendReply(route, neighborId, oldSuccessor, true);
552  else
553  pdm->sendReply(route, neighborId, oldSuccessor);
554 
555  // Do not remove unreachable route (this will be done after transition to passive state)
556 }

◆ processTransition7()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition7 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
560 {
561  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=" << route->getQueryOrigin() << " (active) by transition 7" << endl;
562 
563  // Do not actualize Dij of route by new distance via successor (in transition to passive state DUAL can not detect change of Dij)
564 // route->setDij(source->getMetric());
565 
566  // Do not remove unreachable route (this will be done after transition to passive state)
567 }

◆ processTransition8()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition8 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId,
bool  isSourceNew 
)
protected
571 {
572  EV_DEBUG << "DUAL: transit from oij=" << route->getQueryOrigin() << " (active) to oij=" << route->getQueryOrigin() << " (active) by transition 8" << endl;
573 
574  if (source->isUnreachable() && isSourceNew)
575  invalidateRoute(source);
576 }

◆ processTransition9()

template<typename IPAddress >
void inet::eigrp::EigrpDual< IPAddress >::processTransition9 ( int  event,
EigrpRouteSource< IPAddress > *  source,
EigrpRoute< IPAddress > *  route,
int  neighborId 
)
protected
580 {
581  EV_DEBUG << "DUAL: transit from oij=1 (active) to oij=0 (active) by transition 9" << endl;
582 
583  route->setQueryOrigin(0);
584 
585  // Actualize Dij of route
586  route->setDij(source->getMetric());
587 
588  if (route->getReplyStatusSum() == 0) { // Reply status table is empty, go to passive state or start new diffusing computation
589  uint64_t dmin;
590  if (pdm->hasFeasibleSuccessor(route, dmin))
591  processTransition14(event, source, route, dmin, neighborId);
592  else
593  processTransition11(event, source, route, dmin, neighborId);
594  }
595 
596  // Do not remove unreachable route (this will be done after transition to passive state)
597 }

Member Data Documentation

◆ pdm

template<typename IPAddress >
IEigrpPdm<IPAddress>* inet::eigrp::EigrpDual< IPAddress >::pdm
protected

Protocol dependent module interface.

Referenced by inet::eigrp::EigrpDual< inet::Ipv4Address >::EigrpDual().


The documentation for this class was generated from the following files:
inet::eigrp::EigrpDual::processTransition3
void processTransition3(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:456
inet::eigrp::EigrpDual::processQo3
void processQo3(DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:327
inet::eigrp::EigrpDual::INTERFACE_UP
@ INTERFACE_UP
EIGRP enabled on interface.
Definition: EigrpDual.h:39
inet::eigrp::EigrpDual::processTransition8
void processTransition8(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:570
inet::eigrp::EigrpDual::invalidateRoute
void invalidateRoute(EigrpRouteSource< IPAddress > *routeSrc)
Invalidates specified route.
Definition: EigrpDual.cc:45
inet::eigrp::EigrpDual::processTransition9
void processTransition9(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:579
inet::eigrp::EigrpDual::processTransition17
void processTransition17(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:831
inet::eigrp::EigrpDual::processQo0
void processQo0(DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:106
inet::eigrp::EigrpDual::processTransition14
void processTransition14(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:718
inet::eigrp::EigrpDual::processTransition13
void processTransition13(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:668
inet::eigrp::EigrpDual::LOST_ROUTE
@ LOST_ROUTE
Route in RT deleted, but not by EIGRP.
Definition: EigrpDual.h:40
inet::eigrp::EigrpDual::RECV_QUERY
@ RECV_QUERY
Received query message.
Definition: EigrpDual.h:35
inet::eigrp::IEigrpPdm::UNSPEC_RECEIVER
static const int UNSPEC_RECEIVER
Unspecified address of receiver - all neighbors.
Definition: IEigrpPdm.h:29
inet::eigrp::EigrpDual::RECV_UPDATE
@ RECV_UPDATE
Change of route distance in received update message or on interface.
Definition: EigrpDual.h:34
inet::eigrp::EigrpDual::processTransition7
void processTransition7(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:559
inet::eigrp::EigrpDual::processQo1Active
void processQo1Active(DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:206
inet::eigrp::eigrpDual::userMsgs
const char * userMsgs[]
Definition: EigrpDual.cc:25
inet::eigrp::EigrpDual::processTransition16
void processTransition16(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:793
inet::eigrp::EigrpDual::processTransition15
void processTransition15(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:751
inet::eigrp::EigrpDual::NEIGHBOR_DOWN
@ NEIGHBOR_DOWN
Neighbor went down.
Definition: EigrpDual.h:37
inet::eigrp::EigrpDual::processQo2
void processQo2(DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:272
inet::eigrp::EigrpDual::processTransition1
void processTransition1(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:398
inet::eigrp::IEigrpPdm::UNSPEC_SENDER
static const int UNSPEC_SENDER
Unspecified address of sender - input event source.
Definition: IEigrpPdm.h:33
inet::eigrp::EigrpDual::processTransition10
void processTransition10(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:600
inet::eigrp::EigrpDual::processTransition18
void processTransition18(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:840
inet::eigrp::EigrpMetricHelper::METRIC_INF
static const uint64_t METRIC_INF
Definition: EigrpMetricHelper.h:50
inet::eigrp::EigrpDual::processTransition6
void processTransition6(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:540
inet::eigrp::EigrpDual::processTransition4
void processTransition4(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:486
inet::eigrp::EigrpDual::processTransition12
void processTransition12(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:645
inet::eigrp::EigrpDual::processTransition11
void processTransition11(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:621
inet::eigrp::IEigrpPdm::CONNECTED_ROUTE
static const int CONNECTED_ROUTE
Definition: IEigrpPdm.h:32
inet::eigrp::EigrpDual::processTransition2
void processTransition2(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, uint64_t dmin, int neighborId)
Definition: EigrpDual.cc:415
inet::eigrp::EigrpDual::INTERFACE_DOWN
@ INTERFACE_DOWN
EIGRP disabled on interface - only for connected route.
Definition: EigrpDual.h:38
inet::eigrp::EigrpDual::pdm
IEigrpPdm< IPAddress > * pdm
Protocol dependent module interface.
Definition: EigrpDual.h:44
inet::eigrp::EigrpDual::RECV_REPLY
@ RECV_REPLY
Received reply message.
Definition: EigrpDual.h:36
inet::eigrp::EigrpDual::processQo1Passive
void processQo1Passive(DualEvent event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId, bool isSourceNew)
Definition: EigrpDual.cc:158
inet::eigrp::EigrpDual::processTransition5
void processTransition5(int event, EigrpRouteSource< IPAddress > *source, EigrpRoute< IPAddress > *route, int neighborId)
Definition: EigrpDual.cc:530