void Rip::DoSendRouteUpdate()

in simulation/src/internet/model/rip.cc [1091:1180]


void Rip::DoSendRouteUpdate (bool periodic)
{
  NS_LOG_FUNCTION (this << (periodic ? " periodic" : " triggered"));

  for (SocketListI iter = m_unicastSocketList.begin (); iter != m_unicastSocketList.end (); iter++ )
    {
      uint32_t interface = iter->second;

      if (m_interfaceExclusions.find (interface) == m_interfaceExclusions.end ())
        {
          uint16_t mtu = m_ipv4->GetMtu (interface);
          uint16_t maxRte = (mtu - Ipv4Header ().GetSerializedSize () - UdpHeader ().GetSerializedSize () - RipHeader ().GetSerializedSize ()) / RipRte ().GetSerializedSize ();

          Ptr<Packet> p = Create<Packet> ();
          SocketIpTtlTag tag;
          tag.SetTtl (1);
          p->AddPacketTag (tag);

          RipHeader hdr;
          hdr.SetCommand (RipHeader::RESPONSE);

          for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
            {
              bool splitHorizoning = (rtIter->first->GetInterface () == interface);
              Ipv4InterfaceAddress rtDestAddr = Ipv4InterfaceAddress(rtIter->first->GetDestNetwork (), rtIter->first->GetDestNetworkMask ());

              NS_LOG_DEBUG ("Processing RT " << rtDestAddr << " " << int(rtIter->first->IsRouteChanged ()));

              bool isGlobal = (rtDestAddr.GetScope () == Ipv4InterfaceAddress::GLOBAL);
              bool isDefaultRoute = ((rtIter->first->GetDestNetwork () == Ipv4Address::GetAny ()) &&
                  (rtIter->first->GetDestNetworkMask () == Ipv4Mask::GetZero ()) &&
                  (rtIter->first->GetInterface () != interface));

              bool sameNetwork = false;
              for (uint32_t index = 0; index < m_ipv4->GetNAddresses (interface); index++)
                {
                  Ipv4InterfaceAddress addr = m_ipv4->GetAddress (interface, index);
                  if (addr.GetLocal ().CombineMask (addr.GetMask ()) == rtIter->first->GetDestNetwork ())
                    {
                      sameNetwork = true;
                    }
                }

              if ((isGlobal || isDefaultRoute) &&
                  (periodic || rtIter->first->IsRouteChanged ()) &&
                  !sameNetwork)
                {
                  RipRte rte;
                  rte.SetPrefix (rtIter->first->GetDestNetwork ());
                  rte.SetSubnetMask (rtIter->first->GetDestNetworkMask ());
                  if (m_splitHorizonStrategy == POISON_REVERSE && splitHorizoning)
                    {
                      rte.SetRouteMetric (m_linkDown);
                    }
                  else
                    {
                      rte.SetRouteMetric (rtIter->first->GetRouteMetric ());
                    }
                  rte.SetRouteTag (rtIter->first->GetRouteTag ());
                  if (m_splitHorizonStrategy == SPLIT_HORIZON && !splitHorizoning)
                    {
                      hdr.AddRte (rte);
                    }
                  else if (m_splitHorizonStrategy != SPLIT_HORIZON)
                    {
                      hdr.AddRte (rte);
                    }
                }
              if (hdr.GetRteNumber () == maxRte)
                {
                  p->AddHeader (hdr);
                  NS_LOG_DEBUG ("SendTo: " << *p);
                  iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
                  p->RemoveHeader (hdr);
                  hdr.ClearRtes ();
                }
            }
          if (hdr.GetRteNumber () > 0)
            {
              p->AddHeader (hdr);
              NS_LOG_DEBUG ("SendTo: " << *p);
              iter->first->SendTo (p, 0, InetSocketAddress (RIP_ALL_NODE, RIP_PORT));
            }
        }
    }
  for (RoutesI rtIter = m_routes.begin (); rtIter != m_routes.end (); rtIter++)
    {
      rtIter->first->SetRouteChanged (false);
    }
}