|
|
| 108 |
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); |
108 |
NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); |
| 109 |
uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); |
109 |
uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); |
| 110 |
|
110 |
|
| 111 |
// Multicast recognition; handle local delivery here |
111 |
retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif); |
| 112 |
// |
112 |
if (retVal == true) |
| 113 |
if (header.GetDestination().IsMulticast ()) |
|
|
| 114 |
{ |
113 |
{ |
| 115 |
#ifdef NOTYET |
114 |
NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery"); |
| 116 |
if (m_ipv4->MulticastCheckGroup (iif, header.GetDestination ())) |
115 |
if (header.GetDestination ().IsMulticast ()) |
| 117 |
#endif |
|
|
| 118 |
if (true) |
| 119 |
{ |
116 |
{ |
| 120 |
NS_LOG_LOGIC ("Multicast packet for me-- local deliver"); |
|
|
| 121 |
Ptr<Packet> packetCopy = p->Copy(); |
117 |
Ptr<Packet> packetCopy = p->Copy(); |
| 122 |
// Here may want to disable lcb callback in recursive RouteInput |
|
|
| 123 |
// call below |
| 124 |
lcb (packetCopy, header, iif); |
118 |
lcb (packetCopy, header, iif); |
| 125 |
// Fall through-- we may also need to forward this |
|
|
| 126 |
retVal = true; |
119 |
retVal = true; |
|
|
120 |
// Fall through |
| 127 |
} |
121 |
} |
| 128 |
for (Ipv4RoutingProtocolList::const_iterator rprotoIter = |
122 |
else |
| 129 |
m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); |
|
|
| 130 |
rprotoIter++) |
| 131 |
{ |
123 |
{ |
| 132 |
NS_LOG_LOGIC ("Multicast packet for me-- trying to forward"); |
124 |
lcb (p, header, iif); |
| 133 |
if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) |
125 |
return true; |
| 134 |
{ |
|
|
| 135 |
retVal = true; |
| 136 |
} |
| 137 |
} |
| 138 |
return retVal; |
| 139 |
} |
| 140 |
|
| 141 |
if (header.GetDestination ().IsBroadcast ()) |
| 142 |
{ |
| 143 |
NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)"); |
| 144 |
// TODO: Local Deliver for broadcast |
| 145 |
// TODO: Forward broadcast |
| 146 |
} |
| 147 |
|
| 148 |
// TODO: Configurable option to enable RFC 1222 Strong End System Model |
| 149 |
// Right now, we will be permissive and allow a source to send us |
| 150 |
// a packet to one of our other interface addresses; that is, the |
| 151 |
// destination unicast address does not match one of the iif addresses, |
| 152 |
// but we check our other interfaces. This could be an option |
| 153 |
// (to remove the outer loop immediately below and just check iif). |
| 154 |
for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++) |
| 155 |
{ |
| 156 |
for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++) |
| 157 |
{ |
| 158 |
Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i); |
| 159 |
Ipv4Address addr = iaddr.GetLocal (); |
| 160 |
if (addr.IsEqual (header.GetDestination ())) |
| 161 |
{ |
| 162 |
if (j == iif) |
| 163 |
{ |
| 164 |
NS_LOG_LOGIC ("For me (destination " << addr << " match)"); |
| 165 |
} |
| 166 |
else |
| 167 |
{ |
| 168 |
NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ()); |
| 169 |
} |
| 170 |
lcb (p, header, iif); |
| 171 |
return true; |
| 172 |
} |
| 173 |
if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ())) |
| 174 |
{ |
| 175 |
NS_LOG_LOGIC ("For me (interface broadcast address)"); |
| 176 |
lcb (p, header, iif); |
| 177 |
return true; |
| 178 |
} |
| 179 |
NS_LOG_LOGIC ("Address "<< addr << " not a match"); |
| 180 |
} |
126 |
} |
| 181 |
} |
127 |
} |
| 182 |
// Check if input device supports IP forwarding |
128 |
// Check if input device supports IP forwarding |
|
|
| 187 |
return false; |
133 |
return false; |
| 188 |
} |
134 |
} |
| 189 |
// Next, try to find a route |
135 |
// Next, try to find a route |
|
|
136 |
// If we have already delivered a packet locally (e.g. multicast) |
| 137 |
// we suppress further downstream local delivery by nulling the callback |
| 138 |
LocalDeliverCallback downstreamLcb = lcb; |
| 139 |
if (retVal == true) |
| 140 |
{ |
| 141 |
downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header &, uint32_t > (); |
| 142 |
} |
| 190 |
for (Ipv4RoutingProtocolList::const_iterator rprotoIter = |
143 |
for (Ipv4RoutingProtocolList::const_iterator rprotoIter = |
| 191 |
m_routingProtocols.begin (); |
144 |
m_routingProtocols.begin (); |
| 192 |
rprotoIter != m_routingProtocols.end (); |
145 |
rprotoIter != m_routingProtocols.end (); |
| 193 |
rprotoIter++) |
146 |
rprotoIter++) |
| 194 |
{ |
147 |
{ |
| 195 |
if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) |
148 |
if (retVal == false) |
| 196 |
{ |
149 |
{ |
| 197 |
return true; |
150 |
if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb)) |
|
|
151 |
{ |
| 152 |
return true; |
| 153 |
} |
| 198 |
} |
154 |
} |
| 199 |
} |
155 |
} |
| 200 |
// No routing protocol has found a route. |
156 |
// No routing protocol has found a route. |