View | Details | Raw Unified | Return to bug 2234
Collapse All | Expand All

(-)a/src/internet/model/ipv6-interface.cc (-21 / +32 lines)
 Lines 94-109    Link Here 
94
        {
94
        {
95
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac64Address::ConvertFrom (addr)), Ipv6Prefix (64));
95
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac64Address::ConvertFrom (addr)), Ipv6Prefix (64));
96
          AddAddress (ifaddr);
96
          AddAddress (ifaddr);
97
          m_linkLocalAddress = ifaddr;
97
        }
98
        }
98
      else if (Mac48Address::IsMatchingType (addr))
99
      else if (Mac48Address::IsMatchingType (addr))
99
        {
100
        {
100
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address::ConvertFrom (addr)), Ipv6Prefix (64));
101
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address::ConvertFrom (addr)), Ipv6Prefix (64));
101
          AddAddress (ifaddr);
102
          AddAddress (ifaddr);
103
          m_linkLocalAddress = ifaddr;
102
        }
104
        }
103
      else if (Mac16Address::IsMatchingType (addr))
105
      else if (Mac16Address::IsMatchingType (addr))
104
        {
106
        {
105
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac16Address::ConvertFrom (addr)), Ipv6Prefix (64));
107
          Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac16Address::ConvertFrom (addr)), Ipv6Prefix (64));
106
          AddAddress (ifaddr);
108
          AddAddress (ifaddr);
109
          m_linkLocalAddress = ifaddr;
107
        }
110
        }
108
      else
111
      else
109
        {
112
        {
 Lines 213-225    Link Here 
213
    {
216
    {
214
      for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
217
      for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
215
        {
218
        {
216
          if ((*it).GetAddress () == addr)
219
          if (it->first.GetAddress () == addr)
217
            {
220
            {
218
              return false;
221
              return false;
219
            }
222
            }
220
        }
223
        }
221
224
222
      m_addresses.push_back (iface);
225
      Ipv6Address solicited = Ipv6Address::MakeSolicitedAddress (iface.GetAddress ());
226
      m_addresses.push_back (std::make_pair (iface, solicited));
223
227
224
      if (!addr.IsAny () || !addr.IsLocalhost ())
228
      if (!addr.IsAny () || !addr.IsLocalhost ())
225
        {
229
        {
 Lines 249-264    Link Here 
249
  /* IPv6 interface has always at least one IPv6 link-local address */
253
  /* IPv6 interface has always at least one IPv6 link-local address */
250
  NS_LOG_FUNCTION_NOARGS ();
254
  NS_LOG_FUNCTION_NOARGS ();
251
255
256
  return m_linkLocalAddress;
257
}
258
259
bool Ipv6Interface::IsSolicitedMulticastAddress (Ipv6Address address) const
260
{
261
  /* IPv6 interface has always at least one IPv6 Solicited Multicast address */
262
  NS_LOG_FUNCTION_NOARGS ();
263
252
  for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
264
  for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
253
    {
265
     {
254
      if ((*it).GetAddress ().IsLinkLocal ())
266
       if (it->second == address)
255
        {
267
         {
256
          return (*it);
268
           return true;
257
        }
269
         }
258
    }
270
     }
259
  NS_ASSERT_MSG (false, "No link-local address on interface " << this);
271
260
  Ipv6InterfaceAddress addr;
272
  return false;
261
  return addr; /* quiet compiler */
262
}
273
}
263
274
264
Ipv6InterfaceAddress Ipv6Interface::GetAddress (uint32_t index) const
275
Ipv6InterfaceAddress Ipv6Interface::GetAddress (uint32_t index) const
 Lines 272-278    Link Here 
272
        {
283
        {
273
          if (i == index)
284
          if (i == index)
274
            {
285
            {
275
              return (*it);
286
              return it->first;
276
            }
287
            }
277
          i++;
288
          i++;
278
        }
289
        }
 Lines 303-309    Link Here 
303
    {
314
    {
304
      if (i == index)
315
      if (i == index)
305
        {
316
        {
306
          Ipv6InterfaceAddress iface = (*it);
317
          Ipv6InterfaceAddress iface = it->first;
307
          m_addresses.erase (it);
318
          m_addresses.erase (it);
308
          return iface;
319
          return iface;
309
        }
320
        }
 Lines 329-337    Link Here 
329
340
330
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
341
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
331
    {
342
    {
332
      if((*it).GetAddress() == address)
343
      if(it->first.GetAddress () == address)
333
        {
344
        {
334
          Ipv6InterfaceAddress iface = (*it);
345
          Ipv6InterfaceAddress iface = it->first;
335
          m_addresses.erase(it);
346
          m_addresses.erase(it);
336
          return iface;
347
          return iface;
337
        }
348
        }
 Lines 345-351    Link Here 
345
356
346
  for (Ipv6InterfaceAddressList::const_iterator it = m_addresses.begin (); it != m_addresses.end (); ++it)
357
  for (Ipv6InterfaceAddressList::const_iterator it = m_addresses.begin (); it != m_addresses.end (); ++it)
347
    {
358
    {
348
      Ipv6InterfaceAddress ifaddr = (*it);
359
      Ipv6InterfaceAddress ifaddr = it->first;
349
360
350
      if (ifaddr.GetPrefix ().IsMatch (ifaddr.GetAddress (), dst))
361
      if (ifaddr.GetPrefix ().IsMatch (ifaddr.GetAddress (), dst))
351
        {
362
        {
 Lines 381-387    Link Here 
381
  /* check if destination is for one of our interface */
392
  /* check if destination is for one of our interface */
382
  for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
393
  for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
383
    {
394
    {
384
      if (dest == (*it).GetAddress ())
395
      if (dest == it->first.GetAddress ())
385
        {
396
        {
386
          ipv6->Receive (m_device, p, Ipv6L3Protocol::PROT_NUMBER,
397
          ipv6->Receive (m_device, p, Ipv6L3Protocol::PROT_NUMBER,
387
                         m_device->GetBroadcast (),
398
                         m_device->GetBroadcast (),
 Lines 483-491    Link Here 
483
494
484
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
495
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
485
    {
496
    {
486
      if ((*it).GetAddress () == address)
497
      if (it->first.GetAddress () == address)
487
        {
498
        {
488
          (*it).SetState (state);
499
          it->first.SetState (state);
489
          return;
500
          return;
490
        }
501
        }
491
    }
502
    }
 Lines 498-506    Link Here 
498
509
499
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
510
  for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
500
    {
511
    {
501
      if ((*it).GetAddress () == address)
512
      if (it->first.GetAddress () == address)
502
        {
513
        {
503
          (*it).SetNsDadUid (uid);
514
          it->first.SetNsDadUid (uid);
504
          return;
515
          return;
505
        }
516
        }
506
    }
517
    }
(-)a/src/internet/model/ipv6-interface.h (-3 / +15 lines)
 Lines 201-206    Link Here 
201
  Ipv6InterfaceAddress GetLinkLocalAddress () const;
201
  Ipv6InterfaceAddress GetLinkLocalAddress () const;
202
202
203
  /**
203
  /**
204
   * \brief Checks if the address is a Solicited Multicast address for this interface.
205
   * \param address the address to check.
206
   * \return true if it is a solicited multicast address.
207
   */
208
  bool IsSolicitedMulticastAddress (Ipv6Address address) const;
209
210
  /**
204
   * \brief Get an address from IPv6 interface.
211
   * \brief Get an address from IPv6 interface.
205
   * \param index index
212
   * \param index index
206
   * \return Ipv6InterfaceAddress address whose index is i
213
   * \return Ipv6InterfaceAddress address whose index is i
 Lines 266-282    Link Here 
266
  /**
273
  /**
267
   * \brief Container for the Ipv6InterfaceAddresses.
274
   * \brief Container for the Ipv6InterfaceAddresses.
268
   */
275
   */
269
  typedef std::list<Ipv6InterfaceAddress> Ipv6InterfaceAddressList;
276
  typedef std::list<std::pair<Ipv6InterfaceAddress, Ipv6Address> > Ipv6InterfaceAddressList;
270
277
271
  /**
278
  /**
272
   * \brief Container Iterator for the Ipv6InterfaceAddresses.
279
   * \brief Container Iterator for the Ipv6InterfaceAddresses.
273
   */
280
   */
274
  typedef std::list<Ipv6InterfaceAddress>::iterator Ipv6InterfaceAddressListI;
281
  typedef std::list<std::pair<Ipv6InterfaceAddress, Ipv6Address> >::iterator Ipv6InterfaceAddressListI;
275
282
276
  /**
283
  /**
277
   * \brief Const Container Iterator for the Ipv6InterfaceAddresses.
284
   * \brief Const Container Iterator for the Ipv6InterfaceAddresses.
278
   */
285
   */
279
  typedef std::list<Ipv6InterfaceAddress>::const_iterator Ipv6InterfaceAddressListCI;
286
  typedef std::list<std::pair<Ipv6InterfaceAddress, Ipv6Address> >::const_iterator Ipv6InterfaceAddressListCI;
280
287
281
  /**
288
  /**
282
   * \brief Initialize interface.
289
   * \brief Initialize interface.
 Lines 289-294    Link Here 
289
  Ipv6InterfaceAddressList m_addresses;
296
  Ipv6InterfaceAddressList m_addresses;
290
297
291
  /**
298
  /**
299
   * \brief The link-local addresses assigned to this interface.
300
   */
301
  Ipv6InterfaceAddress m_linkLocalAddress;
302
303
  /**
292
   * \brief The state of this interface.
304
   * \brief The state of this interface.
293
   */
305
   */
294
  bool m_ifup;
306
  bool m_ifup;
(-)a/src/internet/model/ipv6-l3-protocol.cc (-5 / +96 lines)
 Lines 534-540    Link Here 
534
    }
534
    }
535
  else
535
  else
536
    {
536
    {
537
      NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octects)");
537
      NS_LOG_LOGIC ("Interface " << int(i) << " is set to be down for IPv6. Reason: not respecting minimum IPv6 MTU (1280 octets)");
538
    }
538
    }
539
}
539
}
540
540
 Lines 1006-1019    Link Here 
1006
        }
1006
        }
1007
    }
1007
    }
1008
1008
1009
  // \todo At the moment, forward up any multicast packet.
1009
  if (hdr.GetDestinationAddress ().IsAllNodesMulticast ())
1010
  // This is wrong. We should only forward up what the node is interested into
1011
  // and try to route anything other than ff01 or ff02.
1012
  if (hdr.GetDestinationAddress ().IsLinkLocalMulticast ())
1013
    {
1010
    {
1014
      LocalDeliver (packet, hdr, interface);
1011
      LocalDeliver (packet, hdr, interface);
1015
      return;
1012
      return;
1016
    }
1013
    }
1014
  else if (hdr.GetDestinationAddress ().IsAllRoutersMulticast() && ipv6Interface->IsForwarding ())
1015
    {
1016
      LocalDeliver (packet, hdr, interface);
1017
      return;
1018
    }
1019
  else if (hdr.GetDestinationAddress ().IsMulticast ())
1020
    {
1021
      bool isSolicited = ipv6Interface->IsSolicitedMulticastAddress (hdr.GetDestinationAddress ());
1022
      bool isRegisteredOnInterface = IsRegisteredMulticastAddress (hdr.GetDestinationAddress (), interface);
1023
      bool isRegisteredGlobally = IsRegisteredMulticastAddress (hdr.GetDestinationAddress ());
1024
      if (isSolicited || isRegisteredGlobally || isRegisteredOnInterface)
1025
        {
1026
          LocalDeliver (packet, hdr, interface);
1027
          // do not return, the packet could be handled by a routing protocol
1028
        }
1029
    }
1030
1017
1031
1018
  for (uint32_t j = 0; j < GetNInterfaces (); j++)
1032
  for (uint32_t j = 0; j < GetNInterfaces (); j++)
1019
    {
1033
    {
 Lines 1494-1498    Link Here 
1494
  m_dropTrace (ipHeader, p, dropReason, m_node->GetObject<Ipv6> (), 0);
1508
  m_dropTrace (ipHeader, p, dropReason, m_node->GetObject<Ipv6> (), 0);
1495
}
1509
}
1496
1510
1511
void Ipv6L3Protocol::AddMulticastAddress (Ipv6Address address, uint32_t interface)
1512
{
1513
  NS_LOG_FUNCTION (address << interface);
1514
1515
  if (!address.IsMulticast ())
1516
    {
1517
      NS_LOG_LOGIC ("not adding a non-multicast address " << address);
1518
      return;
1519
    }
1520
1521
  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1522
  m_multicastAddresses[key] = true;
1523
}
1524
1525
void Ipv6L3Protocol::AddMulticastAddress (Ipv6Address address)
1526
{
1527
  NS_LOG_FUNCTION (address);
1528
1529
  if (!address.IsMulticast ())
1530
    {
1531
      NS_LOG_LOGIC ("not adding a non-multicast address " << address);
1532
      return;
1533
    }
1534
1535
  m_multicastAddressesNoInterface[address] = true;
1536
}
1537
1538
void Ipv6L3Protocol::RemoveMulticastAddress (Ipv6Address address, uint32_t interface)
1539
{
1540
  NS_LOG_FUNCTION (address << interface);
1541
1542
  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1543
  m_multicastAddresses.erase (key);
1544
}
1545
1546
void Ipv6L3Protocol::RemoveMulticastAddress (Ipv6Address address)
1547
{
1548
  NS_LOG_FUNCTION (address);
1549
1550
  m_multicastAddressesNoInterface.erase (address);
1551
}
1552
1553
bool Ipv6L3Protocol::IsRegisteredMulticastAddress (Ipv6Address address, uint32_t interface) const
1554
{
1555
  NS_LOG_FUNCTION (address << interface);
1556
1557
  Ipv6RegisteredMulticastAddressKey_t key = std::make_pair (address, interface);
1558
  Ipv6RegisteredMulticastAddressCIter_t iter = m_multicastAddresses.find (key);
1559
1560
  if (iter == m_multicastAddresses.end ())
1561
    {
1562
      return false;
1563
    }
1564
  else if (iter->second == false)
1565
    {
1566
      return false;
1567
    }
1568
  return true;
1569
}
1570
1571
bool Ipv6L3Protocol::IsRegisteredMulticastAddress (Ipv6Address address) const
1572
{
1573
  NS_LOG_FUNCTION (address);
1574
1575
  Ipv6RegisteredMulticastAddressNoInterfaceCIter_t iter = m_multicastAddressesNoInterface.find (address);
1576
1577
  if (iter == m_multicastAddressesNoInterface.end ())
1578
    {
1579
      return false;
1580
    }
1581
  else if (iter->second == false)
1582
    {
1583
      return false;
1584
    }
1585
  return true;
1586
}
1587
1497
} /* namespace ns3 */
1588
} /* namespace ns3 */
1498
1589
(-)a/src/internet/model/ipv6-l3-protocol.h (-1 / +87 lines)
 Lines 454-460    Link Here 
454
    (const Ipv6Header & header, Ptr<const Packet> packet,
454
    (const Ipv6Header & header, Ptr<const Packet> packet,
455
     DropReason reason, Ptr<Ipv6> ipv6,
455
     DropReason reason, Ptr<Ipv6> ipv6,
456
     uint32_t interface);
456
     uint32_t interface);
457
   
457
458
  /**
459
   * Adds a multicast address to the list of addresses to pass to local deliver.
460
   * \param address the address.
461
   */
462
  void AddMulticastAddress (Ipv6Address address);
463
464
  /**
465
   * Adds a multicast address to the list of addresses to pass to local deliver.
466
   * \param address the address.
467
   * \param interface the incoming interface.
468
   */
469
  void AddMulticastAddress (Ipv6Address address, uint32_t interface);
470
471
  /**
472
   * Removes a multicast address from the list of addresses to pass to local deliver.
473
   * \param address the address.
474
   */
475
  void RemoveMulticastAddress (Ipv6Address address);
476
477
  /**
478
   * Removes a multicast address from the list of addresses to pass to local deliver.
479
   * \param address the address.
480
   * \param interface the incoming interface.
481
   */
482
  void RemoveMulticastAddress (Ipv6Address address, uint32_t interface);
483
484
  /**
485
   * Checks if the address has been registered.
486
   * \param address the address.
487
   * \return true if the address is registered.
488
   */
489
  bool IsRegisteredMulticastAddress (Ipv6Address address) const;
490
491
  /**
492
   * Checks if the address has been registered for a specific interface.
493
   * \param address the address.
494
   * \param interface the incoming interface.
495
   * \return true if the address is registered.
496
   */
497
  bool IsRegisteredMulticastAddress (Ipv6Address address, uint32_t interface) const;
498
458
protected:
499
protected:
459
  /**
500
  /**
460
   * \brief Dispose object.
501
   * \brief Dispose object.
 Lines 718-723    Link Here 
718
   * \brief Allow ICMPv6 Redirect sending state
759
   * \brief Allow ICMPv6 Redirect sending state
719
   */
760
   */
720
  bool m_sendIcmpv6Redirect;
761
  bool m_sendIcmpv6Redirect;
762
763
  /**
764
   * \brief IPv6 multicast addresses / interface key.
765
   */
766
  typedef std::pair<Ipv6Address, uint64_t> Ipv6RegisteredMulticastAddressKey_t;
767
768
  /**
769
   * \brief Container of the IPv6 multicast addresses.
770
   */
771
  typedef std::map<Ipv6RegisteredMulticastAddressKey_t, bool> Ipv6RegisteredMulticastAddress_t;
772
773
  /**
774
   * \brief Container Iterator of the IPv6 multicast addresses.
775
   */
776
  typedef std::map<Ipv6RegisteredMulticastAddressKey_t, bool>::iterator Ipv6RegisteredMulticastAddressIter_t;
777
778
  /**
779
   * \brief Container Const Iterator of the IPv6 multicast addresses.
780
   */
781
  typedef std::map<Ipv6RegisteredMulticastAddressKey_t, bool>::const_iterator Ipv6RegisteredMulticastAddressCIter_t;
782
783
  /**
784
   * \brief Container of the IPv6 multicast addresses.
785
   */
786
  typedef std::map<Ipv6Address, bool> Ipv6RegisteredMulticastAddressNoInterface_t;
787
788
  /**
789
   * \brief Container Iterator of the IPv6 multicast addresses.
790
   */
791
  typedef std::map<Ipv6Address, bool>::iterator Ipv6RegisteredMulticastAddressNoInterfaceIter_t;
792
793
  /**
794
   * \brief Container Const Iterator of the IPv6 multicast addresses.
795
   */
796
  typedef std::map<Ipv6Address, bool>::const_iterator Ipv6RegisteredMulticastAddressNoInterfaceCIter_t;
797
798
  /**
799
   * \brief List of multicast IP addresses of interest, divided per interface.
800
   */
801
  Ipv6RegisteredMulticastAddress_t m_multicastAddresses;
802
803
  /**
804
   * \brief List of multicast IP addresses of interest for all the interfaces.
805
   */
806
  Ipv6RegisteredMulticastAddressNoInterface_t m_multicastAddressesNoInterface;
721
};
807
};
722
808
723
} /* namespace ns3 */
809
} /* namespace ns3 */
(-)a/src/internet/model/ipv6-raw-socket-impl.cc (+45 lines)
 Lines 139-144    Link Here 
139
  NS_LOG_FUNCTION_NOARGS ();
139
  NS_LOG_FUNCTION_NOARGS ();
140
  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
140
  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
141
141
142
  Ipv6LeaveGroup ();
142
  if (ipv6)
143
  if (ipv6)
143
    {
144
    {
144
      ipv6->DeleteRawSocket (this);
145
      ipv6->DeleteRawSocket (this);
 Lines 297-302    Link Here 
297
  return data.packet;
298
  return data.packet;
298
}
299
}
299
300
301
void
302
Ipv6RawSocketImpl::Ipv6JoinGroup (Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses)
303
{
304
  NS_LOG_FUNCTION (this << address << &filterMode << &sourceAddresses);
305
306
  // We can join only one multicast group (or change its params)
307
  NS_ASSERT_MSG ((m_ipv6MulticastGroupAddress == address || m_ipv6MulticastGroupAddress.IsAny ()), "Can join only one IPv6 multicast group.");
308
309
  m_ipv6MulticastGroupAddress = address;
310
311
  Ptr<Ipv6L3Protocol> ipv6l3 = m_node->GetObject <Ipv6L3Protocol> ();
312
  if (ipv6l3)
313
    {
314
      if (filterMode == INCLUDE && sourceAddresses.empty ())
315
        {
316
          // it is a leave
317
          if (m_boundnetdevice)
318
            {
319
              int32_t index = ipv6l3->GetInterfaceForDevice (m_boundnetdevice);
320
              NS_ASSERT_MSG (index >= 0, "Interface without a valid index");
321
              ipv6l3->RemoveMulticastAddress (address, index);
322
            }
323
          else
324
            {
325
              ipv6l3->RemoveMulticastAddress (address);
326
            }
327
        }
328
      else
329
        {
330
          // it is a join or a modification
331
          if (m_boundnetdevice)
332
            {
333
              int32_t index = ipv6l3->GetInterfaceForDevice (m_boundnetdevice);
334
              NS_ASSERT_MSG (index >= 0, "Interface without a valid index");
335
              ipv6l3->AddMulticastAddress (address, index);
336
            }
337
          else
338
            {
339
              ipv6l3->AddMulticastAddress (address);
340
            }
341
        }
342
    }
343
}
344
300
uint32_t Ipv6RawSocketImpl::GetTxAvailable () const
345
uint32_t Ipv6RawSocketImpl::GetTxAvailable () const
301
{
346
{
302
  NS_LOG_FUNCTION_NOARGS ();
347
  NS_LOG_FUNCTION_NOARGS ();
(-)a/src/internet/model/ipv6-raw-socket-impl.h (+1 lines)
 Lines 107-112    Link Here 
107
  virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address& toAddress);
107
  virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address& toAddress);
108
  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
108
  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
109
  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, Address& fromAddress);
109
  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, Address& fromAddress);
110
  virtual void Ipv6JoinGroup (Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses);
110
111
111
  /**
112
  /**
112
   * \brief Set protocol field.
113
   * \brief Set protocol field.
(-)a/src/internet/model/ripng.cc (+2 lines)
 Lines 119-124    Link Here 
119
      if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
119
      if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
120
        {
120
        {
121
          activeInterface = true;
121
          activeInterface = true;
122
          m_ipv6->SetForwarding (i, true);
122
        }
123
        }
123
124
124
      for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
125
      for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
 Lines 290-295    Link Here 
290
  if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
291
  if (m_interfaceExclusions.find (i) == m_interfaceExclusions.end ())
291
    {
292
    {
292
      activeInterface = true;
293
      activeInterface = true;
294
      m_ipv6->SetForwarding (i, true);
293
    }
295
    }
294
296
295
  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
297
  for (uint32_t j = 0; j < m_ipv6->GetNAddresses (i); j++)
(-)a/src/internet/model/udp-socket-impl.cc (+65 lines)
 Lines 26-31    Link Here 
26
#include "ns3/ipv6-route.h"
26
#include "ns3/ipv6-route.h"
27
#include "ns3/ipv4.h"
27
#include "ns3/ipv4.h"
28
#include "ns3/ipv6.h"
28
#include "ns3/ipv6.h"
29
#include "ns3/ipv6-l3-protocol.h"
29
#include "ns3/ipv4-header.h"
30
#include "ns3/ipv4-header.h"
30
#include "ns3/ipv4-routing-protocol.h"
31
#include "ns3/ipv4-routing-protocol.h"
31
#include "ns3/ipv6-routing-protocol.h"
32
#include "ns3/ipv6-routing-protocol.h"
 Lines 305-310    Link Here 
305
          m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
306
          m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
306
          return -1;
307
          return -1;
307
        }
308
        }
309
      if (ipv6.IsMulticast ())
310
        {
311
          Ptr<Ipv6L3Protocol> ipv6l3 = m_node->GetObject <Ipv6L3Protocol> ();
312
          if (ipv6l3)
313
            {
314
              ipv6l3->AddMulticastAddress (ipv6);
315
            }
316
        }
308
    }
317
    }
309
  else
318
  else
310
    {
319
    {
 Lines 349-354    Link Here 
349
      m_errno = Socket::ERROR_BADF;
358
      m_errno = Socket::ERROR_BADF;
350
      return -1;
359
      return -1;
351
    }
360
    }
361
  Ipv6LeaveGroup ();
352
  m_shutdownRecv = true;
362
  m_shutdownRecv = true;
353
  m_shutdownSend = true;
363
  m_shutdownSend = true;
354
  DeallocateEndPoint ();
364
  DeallocateEndPoint ();
 Lines 955-960    Link Here 
955
      NS_ASSERT (m_endPoint6 != 0);
965
      NS_ASSERT (m_endPoint6 != 0);
956
    }
966
    }
957
  m_endPoint6->BindToNetDevice (netdevice);
967
  m_endPoint6->BindToNetDevice (netdevice);
968
969
  if (m_endPoint6->GetLocalAddress ().IsMulticast ())
970
    {
971
      Ptr<Ipv6L3Protocol> ipv6l3 = m_node->GetObject <Ipv6L3Protocol> ();
972
      if (ipv6l3)
973
        {
974
          uint32_t index = ipv6l3->GetInterfaceForDevice (netdevice);
975
          ipv6l3->RemoveMulticastAddress (m_endPoint6->GetLocalAddress ());
976
          ipv6l3->AddMulticastAddress (m_endPoint6->GetLocalAddress (), index);
977
        }
978
    }
979
958
  return;
980
  return;
959
}
981
}
960
982
 Lines 1169-1173    Link Here 
1169
  return m_allowBroadcast;
1191
  return m_allowBroadcast;
1170
}
1192
}
1171
1193
1194
void
1195
UdpSocketImpl::Ipv6JoinGroup (Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses)
1196
{
1197
  NS_LOG_FUNCTION (this << address << &filterMode << &sourceAddresses);
1198
1199
  // We can join only one multicast group (or change its params)
1200
  NS_ASSERT_MSG ((m_ipv6MulticastGroupAddress == address || m_ipv6MulticastGroupAddress.IsAny ()), "Can join only one IPv6 multicast group.");
1201
1202
  m_ipv6MulticastGroupAddress = address;
1203
1204
  Ptr<Ipv6L3Protocol> ipv6l3 = m_node->GetObject <Ipv6L3Protocol> ();
1205
  if (ipv6l3)
1206
    {
1207
      if (filterMode == INCLUDE && sourceAddresses.empty ())
1208
        {
1209
          // it is a leave
1210
          if (m_boundnetdevice)
1211
            {
1212
              int32_t index = ipv6l3->GetInterfaceForDevice (m_boundnetdevice);
1213
              NS_ASSERT_MSG (index >= 0, "Interface without a valid index");
1214
              ipv6l3->RemoveMulticastAddress (address, index);
1215
            }
1216
          else
1217
            {
1218
              ipv6l3->RemoveMulticastAddress (address);
1219
            }
1220
        }
1221
      else
1222
        {
1223
          // it is a join or a modification
1224
          if (m_boundnetdevice)
1225
            {
1226
              int32_t index = ipv6l3->GetInterfaceForDevice (m_boundnetdevice);
1227
              NS_ASSERT_MSG (index >= 0, "Interface without a valid index");
1228
              ipv6l3->AddMulticastAddress (address, index);
1229
            }
1230
          else
1231
            {
1232
              ipv6l3->AddMulticastAddress (address);
1233
            }
1234
        }
1235
    }
1236
}
1172
1237
1173
} // namespace ns3
1238
} // namespace ns3
(-)a/src/internet/model/udp-socket-impl.h (+1 lines)
 Lines 98-103    Link Here 
98
  virtual void BindToNetDevice (Ptr<NetDevice> netdevice);
98
  virtual void BindToNetDevice (Ptr<NetDevice> netdevice);
99
  virtual bool SetAllowBroadcast (bool allowBroadcast);
99
  virtual bool SetAllowBroadcast (bool allowBroadcast);
100
  virtual bool GetAllowBroadcast () const;
100
  virtual bool GetAllowBroadcast () const;
101
  virtual void Ipv6JoinGroup (Ipv6Address address, Socket::Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses);
101
102
102
private:
103
private:
103
  // Attributes set through UdpSocket base class 
104
  // Attributes set through UdpSocket base class 
(-)a/src/internet/test/ipv6-ripng-test.cc (+1 lines)
 Lines 613-618    Link Here 
613
  Ptr<SocketFactory> rxSocketFactory = listener->GetObject<UdpSocketFactory> ();
613
  Ptr<SocketFactory> rxSocketFactory = listener->GetObject<UdpSocketFactory> ();
614
  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
614
  Ptr<Socket> rxSocket = rxSocketFactory->CreateSocket ();
615
  NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("ff02::9"), 521)), 0, "trivial");
615
  NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("ff02::9"), 521)), 0, "trivial");
616
  rxSocket->BindToNetDevice (listenerDev);
616
  rxSocket->SetRecvCallback (MakeCallback (&Ipv6RipngSplitHorizonStrategyTest::ReceivePktProbe, this));
617
  rxSocket->SetRecvCallback (MakeCallback (&Ipv6RipngSplitHorizonStrategyTest::ReceivePktProbe, this));
617
618
618
  // ------ Now the tests ------------
619
  // ------ Now the tests ------------
(-)a/src/network/model/socket.cc (+32 lines)
 Lines 510-515    Link Here 
510
  return m_ipv6RecvHopLimit;
510
  return m_ipv6RecvHopLimit;
511
}
511
}
512
512
513
void
514
Socket::Ipv6JoinGroup (Ipv6Address address, Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses)
515
{
516
  NS_LOG_FUNCTION (this<<address<<&filterMode<<&sourceAddresses);
517
  NS_ASSERT_MSG (false,"Ipv6JoinGroup not implemented on this socket");
518
}
519
520
void
521
Socket::Ipv6JoinGroup (Ipv6Address address)
522
{
523
  NS_LOG_FUNCTION (this<<address);
524
525
  // Join Group. Note that joining a group with no sources means joining without source restrictions.
526
  std::vector<Ipv6Address> sourceAddresses;
527
  Ipv6JoinGroup (address, EXCLUDE, sourceAddresses);
528
}
529
530
void
531
Socket::Ipv6LeaveGroup (void)
532
{
533
  NS_LOG_FUNCTION (this);
534
  if(m_ipv6MulticastGroupAddress.IsAny () )
535
    {
536
      NS_LOG_INFO (" The socket was not bound to any group.");
537
      return;
538
    }
539
  // Leave Group. Note that joining a group with no sources means leaving it.
540
  std::vector<Ipv6Address> sourceAddresses;
541
  Ipv6JoinGroup (m_ipv6MulticastGroupAddress, INCLUDE, sourceAddresses);
542
  m_ipv6MulticastGroupAddress = Ipv6Address::GetAny ();
543
}
544
513
/***************************************************************
545
/***************************************************************
514
 *           Socket Tags
546
 *           Socket Tags
515
 ***************************************************************/
547
 ***************************************************************/
(-)a/src/network/model/socket.h (+34 lines)
 Lines 109-114    Link Here 
109
  };
109
  };
110
110
111
  /**
111
  /**
112
   * \enum Ipv6MulticastFilterMode
113
   * \brief Enumeration of the possible filter of a socket.
114
   */
115
  enum Ipv6MulticastFilterMode
116
  {
117
    INCLUDE=1,
118
    EXCLUDE
119
  };
120
121
  /**
112
   * This method wraps the creation of sockets that is performed
122
   * This method wraps the creation of sockets that is performed
113
   * on a given node by a SocketFactory specified by TypeId.
123
   * on a given node by a SocketFactory specified by TypeId.
114
   * 
124
   * 
 Lines 817-822    Link Here 
817
   */
827
   */
818
  bool IsIpv6RecvHopLimit (void) const;
828
  bool IsIpv6RecvHopLimit (void) const;
819
 
829
 
830
  /**
831
   * \brief Joins a IPv6 multicast group.
832
   *
833
   * Based on the filter mode and source addresses this can be interpreted as a
834
   * join, leave, or modification to source filtering on a multicast group.
835
   *
836
   * \param address Requested multicast address.
837
   * \param filterMode Socket filtering mode (INCLUDE | EXCLUDE).
838
   * \param sourceAddresses All the source addresses on which socket is interested or not interested.
839
   */
840
  virtual void Ipv6JoinGroup (Ipv6Address address, Ipv6MulticastFilterMode filterMode, std::vector<Ipv6Address> sourceAddresses);
841
842
  /**
843
   * \brief Joins a IPv6 multicast group without filters.
844
   * \param address Group address on which socket wants to join.
845
   */
846
  virtual void Ipv6JoinGroup (Ipv6Address address);
847
848
  /**
849
   * \brief Leaves IPv6 multicast group.
850
   */
851
  virtual void Ipv6LeaveGroup (void);
852
820
protected:
853
protected:
821
  /**
854
  /**
822
   * \brief Notify through the callback (if set) that the connection has been
855
   * \brief Notify through the callback (if set) that the connection has been
 Lines 913-918    Link Here 
913
946
914
  Ptr<NetDevice> m_boundnetdevice; //!< the device this socket is bound to (might be null).
947
  Ptr<NetDevice> m_boundnetdevice; //!< the device this socket is bound to (might be null).
915
  bool m_recvPktInfo; //!< if the socket should add packet info tags to the packet forwarded to L4.
948
  bool m_recvPktInfo; //!< if the socket should add packet info tags to the packet forwarded to L4.
949
  Ipv6Address m_ipv6MulticastGroupAddress; //!< IPv6 multicast group address.
916
950
917
private:
951
private:
918
  Callback<void, Ptr<Socket> >                   m_connectionSucceeded;  //!< connection succeeded callback
952
  Callback<void, Ptr<Socket> >                   m_connectionSucceeded;  //!< connection succeeded callback

Return to bug 2234