[Xorp-hackers] IGMPv3 patch & sources

leclanch@enst.fr leclanch@enst.fr
Sun, 4 Sep 2005 01:56:24 +0200 (CEST)


------=_20050904015624_60524
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: 8bit

Hello,

as promised, a little late yet, I provide the result of my humble coding
on xorp.

I've made XORP a little IGMPv3-compliant. What does the "a little"
mean ? Well, IGMPv3 RFC is implemented, and retrocompatibility seemed to
work. However, the black points are :
- MLDv2 is not implemented (yet a big part of code is shared with igmp)
- It can crash and can behave weirdly
- It has not been truely tested, since I didn't do tests with PIM, I
only tested if XORP maintained a coherent and legal internal state, what
it did in the end most of the time (show igmp groups is now
igmpv3-friendly)
- IT HAS BEEN CODED WITH JUNE 20th XORP SOURCES ! Therefore it does not
include any latter changes, including the Windows support.

So attached to this mail :
A file summarizing all the changes, also placed in the tar.gz

To get the igmpv3 mld6igmp source and the diff file for some other files
in XORP (libxorp/ip* and igmp template):
http://perso.enst.fr/~leclanch/mld6igmp-enst-igmpv3.tar.gz
http://perso.enst.fr/~leclanch/igmpv3-others-xorp.diff

Feel free to ask anything about this quite unfinished work, I'm sure I
forgot to say important things.

Guillaume.

------=_20050904015624_60524
Content-Type: text/plain; name="NOTES_igmpv3.txt"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="NOTES_igmpv3.txt"

Notes about the implementation of IGMPv3 in XORP.


Authors :
-------
Guillaume Leclanche

Student work for Télécom Paris (École Nationale Supérieure des Télécommunications).
http://www.enst.fr

Management by Jean-Louis Rougier, Associate Professor, GET/ENST/INFRES.


Contact :
-------
guillaume -a- leclanche -d- net


RFC used :
--------
- RFC 3376 (Cain, et al.; Oct 2002) for IGMPv3


Other software used for help :
----------------------------
igmprt (Abdelkader Lahmadi, Loria, 2001)
http://www.loria.fr/~lahmadi/igmpv3-router.html


BUGS SEEN IN XORP ELSEWHERE :
---------------------------
* XorpTimer::schedule_after is declared but not defined !


REAL NOTES START HERE
---------------------

Other files modified :
* added 224.0.0.22 and FF02::16 as multicast_all_routers_ssm
	- libxorp/ipv4.cc
	- libxorp/ipv4.hh
	- libxorp/ipv6.cc
	- libxorp/ipv6.hh	
	- libxorp/ipvx.cc
	- libxorp/ipvx.hh

* modified template for igmp version number allowed
	- etc/templates/igmp.tp


How Classes work :
----------------

Mld6igmpVif::_members
		list<GroupRecord *>

		GroupRecord::_sources
				SourceList
				
				SourceList : list<SourceRecord *>
						
						SourceRecord


GroupRecord -> 	_sources                        // The SourceList
		_mld6igmp_vif                   // The Interface
		_group                          // IPv4/6 address
		_state                          // Include or Exclude
		_group_compatibility_mode       // IGMP group version
		_last_reported_host             // The last host that
		                                // talked about the group
		
		_group_timer
		_last_member_query_timer
		_igmpv1_host_present_timer
		_igmpv2_host_present_timer

SourceList ->	_group                          // The Group Record
		_mld6igmp_vif                   // The Interface

SourceRecord ->	_group                          // The Group Record
		_mld6igmp_vif                   // The Interface
		_source_address                 // IPv4/6 address


In SourceList, operators + * - have been overloaded in order to make
the operations described in the RFC, that is :
+ => union
* => intersection
- => difference

operator = has also been overloaded in order to copy only source records.


Protocolary treatment :
---------------------

- A message arrives
	=> igmp_process()
		=>igmp_process_groups()
		
	- It's a query
		=> igmp_query_recv()

	- It's a report
		=> igmp_report_recv()

		- Groups incoming and their source list are compared
		  to the ones in memory.
		  If it's a new group, we create a INCLUDE{} group and
		  then we compare it.
		  * Reference: igmp_proto.cc:679
		- If queries need to be sent
			=> mld6igmp_query_send() (see below)

- The Group Timer expires
	=> GroupRecord::group_timer_timeout()
		Action depends on the state of the group
		- INCLUDE
			=> do nothing (timer is useless)
		- EXCLUDE
			=> if sources still have running timer
				switch to INCLUDE {those sources}
			=> else
				Destroy the source records and the group

- The Source Timer expires
	=> SourceRecord::source_timer_timeout()
		Whatever the state, disable the (S,G)
		Then if:
		- _group state is INCLUDE
			if there are no other sources
				destroy the source record and the group
			else
				destroy the source record only
		- _ group state is EXCLUDE
			There's nothing to do since the expired sources 
			are kept in this mode.

- On Startup
	- Variables are got from the configuration file or use commands
	- The vif subscribes locally to groups:
		- ALL_SYSTEMS (224.0.0.1)      // To send general queries
		- ALL_ROUTERS (224.0.0.2)      // IGMPv1/2 reports dest ip
		- ALL_ROUTERS_SSM (224.0.0.22) // IGMPv3 reports dest ip
	- A general query is sent (group = 0.0.0.0 and SourceList* = 0)
	- Another general query is scheduled to be sent after 
	  [startup_query_interval]. The timer is Query Timer. [_query_timer]

- The Query Timer expires
	- A general query is sent (group = 0.0.0.0 and SourceList* = 0)
	- Another general query is scheduled to be sent after 
	  [startup_query_interval]. The timer is Query Timer. [_query_timer]

- Sending a IGMP Membership Query
	=> mld6igmp_query_send()
		There are 3 versions of this function :
			- an IGMPv1/2 one, without S, QRV, QQIC, SourceList
			- a group-specific query one without SourceList
			- a group-and-source-specific query one
		You MUST give the protocol version to be used ! If you 
		don't know, just put 0, and the function will try to do
		its best to find the most suitable version



TO BE CHECKED OR TO BE DONE
---------------------------
* Not sure about how 1/10s and 1s values are put and got in messages.

* Retransmissions need to be scheduled for Group(-and-source) queries

* Xorp parses its own queries, should it be done or not ?

* Xorp does igmp treatment of special mcast adresses (e.g. .2 & .22), and there
  indications in the RFC that it shouldn't occur (to be checked)

* IT'S NOT STABLE, some crashes may occur, I guess mainly due to memory
  beeing freed for SourceRecord or GroupRecord when timeouts occur. The fact is
  that I don't manage to update timers correctly, see below.

* MLDv2 is not done at all, and MLDv1 is likely to be quite broken

* SourceRecord::update_timer doesn't really update the timer but only starts it
  or restarts it because I didn't find any way to change the expiry time of the
  timer without having xorp_igmp crash.
  
* States and timer expirations are not correctly tested and behavior may leave
  sources undeleted (or groups even).
------=_20050904015624_60524--