Subject: (IPng 6697) discovery-v2-03 questions (neighbor cache handling)

From: Jun-ichiro itojun Itoh <[email-masked]>
Date: Thu, 05 Nov 1998 21:08:33 +0900

I got several questions related to ND6 protocol spec, namely
	discovery-v2-03.  In the following, "lladdr" means "link-layer
	address", such as ethernet MAC address.

	I would like to know opinions from implementers, how UNH interop
	test understands the spec, and so forth.  Thanks,

[email-masked]
[email-masked]
jun-ichiro itoh

1. neighbor cache processing rule when no lladdr is attached.
=============================================================
ND6 specification defines the following conditions for src/dst lladdr option,
for each ND6 packet type:
	RS: medium w/o lladdr: not needed (can't attach)
	    medium with lladdr: source lladdr option SHOULD be included,
		    if lladdr is known
	RA: medium w/o lladdr: not needed (can't attach)
	    medium with lladdr: router MAY attach source lladdr option,
		    MAY omit it for load balancing
	NS: medium w/o lladdr: not needed (can't attach)
	    medium with lladdr:
		    source lladdr option MUST be attached for multicast
		    solicitation, SHOULD be attached for unicast solicitation
	redirect:
	    medium w/o lladdr: not needed (can't attach)
	    medium with lladdr:
		target lladdr option SHOULD be included if known.
		(ATM) MUST be included on some medium.

As seen in the above list, it is not rare to see RS/RA/NS/redirect
packet, WITHOUT source/target lladdr option.

However, the following sections in discovery-v2-03 assume that source/target
lladdr is attached to ND packet:
	6.2.6(RS)
	6.3.4(RA)
	7.2.3(NS)
	8.3(redirect)
	appendix C, second state transition chart (p87 to p88) must be
		clarified for the following 3 cases:
			medium without lladdr
			medium with lladdr, packet with lladdr
			medium with lladdr, packet without lladdr
This should be fixed.  Also, 6.2.6, 6.3.4, 7.2.3 and 8.3 has almost
the same textual description for neighbor cache updates.  I believe
these duplicates should be merged into one section somewhere.

It is not very trivial to clarify.  Choices might be:
	1. do not make neighbor cache if there's no lladdr, or
	2. make neighbor cache with some state.
However, these ways do not work very well.

1. If you do not make neighbor cache entry:
	You cannot record IsRouter flag, and you will have chances for
	stale entry on default router list.
	For example, the following list of event will create a stale entry:
		router X transmits RA without lladdr.
			Host Y will install default router list entry for X.
			No neighbor cache entry created.
		router X becomes host.
		host X (previously router X) transmits NS with lladr.
			Default router list entry for X remains on the host Y.
			Neighbor cache entry will be created, with IsRouter 0,
			based on NS processing rule.
	Now, you got a problem.  If you try to send a packet to off-link
	destination, you will be sending packet to host X.

	If host Y ignores "RA without lladdr", there will be no stale default
	router list entry.  However, in this case, router X can never achieve
	load balancing among the routers by sending "RA without lladdr"
	from routers.

	The source of the problem is recaped in the second question,
	"neighbor cache entry and default router list".  See the last
	part of the email.

	What should on medium without lladdr?  It is still unclear for us.

2a. If you make neighbor cache entry with INCOMPLETE state:
	INCOMPLETE state does not really fit this situation.  INCOMPLETE is
	defined as:
		Address resolution is in progress and the link-layer
		address of the neighbor has not yet been determined.
	However, we have never performed address resolution for this entry.

	It is not good to require address resolution for every "RA without
	lladdr".

2b. If you make neighbor cache entry with some state other than INCOMPLETE
	If there is an entry with non-INCOMLETE state, it is assumed
	that the entry once has lladdr for the target in the past.
	Therefore, it is not very suitable for this situation.
	If you set the state to STALE you have a big problem --- DELAY state
	will defer your future address resolution.

Here are solutions we came up with.
Solution 1: (from [email-masked])
	If a node receives ND packet without lladdr, do not make neighbor
	cache.

	If node is about to send a pacet to off-link destination, and router X 
	is chosen from default router list, and there is no neighbor cache
	entry for router X, node should perform the following.
	- make neighbor cache entry
	- set it INCOMPLETE
	- set IsRouter bit for the entry
	- perform neighbor discovery
	- transmit packet if ND completed

	/*
	 * new entry: neighbor cache entrys is created
	 * olladdr: neighbor cache entry got old lladdr
	 * lladdr: packet contains lladdr option
	 * llchange: olladdr != lladdr
	 *
	 * newentry olladdr  lladdr  llchange	(*=record lladdr)
	 *	0	n	n	--	(1)
	 *	0	y	n	--	(2)
	 *	0	n	y	--	(3) * set state to STALE
	 *	0	y	y	n	(4) *
	 *	0	y	y	y	(5) * set state to STALE
	 *	1	--	n	--	(6)   (don't create entry)
	 *	1	--	y	--	(7) * set state to STALE
	 */

Solution 2: (from [email-masked])
	Define a new neighbor cache state, PASSIVE.  PASSIVE entry will be
	made when a node received ND packets without lladdr.
	If a node received RA/RS/NS/redirect without lladdr option,
	1. create neighbor cache entry,
	2. make it PASSIVE state, and
	3. set IsRouter flag properly.
	You MUST NOT remove neighbor cache entry for node A, if node A is
	listed in default router list.

	The above rule still works if there's no lladdr defined for the medium.

	/*
	 * new entry: neighbor cache entrys is created
	 * olladdr: neighbor cache entry got old lladdr
	 * lladdr: packet contains lladdr option
	 * llchange: olladdr != lladdr
	 *
	 * newentry olladdr  lladdr  llchange	(*=record lladdr)
	 *	0	n	n	--	(1)
	 *	0	y	n	--	(2)
	 *	0	n	y	--	(3) * set state to STALE
	 *	0	y	y	n	(4) *
	 *	0	y	y	y	(5) * set state to STALE
	 *	1	--	n	--	(6)   set state to PASSIVE
	 *	1	--	y	--	(7) * set state to STALE
	 */
	/*
	 * ICMP6 type dependent behavior.
	 *
	 * NS: clear IsRouter if new entry
	 * RS: clear IsRouter
	 * RA: set IsRouter if there's lladdr
	 * redir: clear IsRouter if new entry
	 *
	 * newentry olladdr  lladdr  llchange	    NS  RS  RA	redir
	 *	0	n	n	--	(1)	c   s?
	 *	0	y	n	--	(2)	c   s
	 *	0	n	y	--	(3)	c   s
	 *	0	y	y	n	(4)	c   s
	 *	0	y	y	y	(5)	c   s
	 *	1	--	n	--	(6) c	c   s?  c
	 *	1	--	y	--	(7) c	c   s	c
	 *
	 *					(c=clear s=set)
	 */

Clarification 1:
	To make implementations easy, rules for source/target lladdr option
	for ND packets should be:
	- on medium with lladdr: MUST attach one
	- on medium w/o lladdr: not needed (and cannot attach)

2. neighbor cache entry and default router list
===============================================
Rules for IsRouter bit is "edge trigger" in nature.  Therefore, IsRouter
rule works only if the following statement is satisfied:

	For a node that is listed onto default router list,
	there always be a neighbor cache entry.

This must be clearly stated somewhere in document.  (What happens on medium 
ithout lladdr??  We still need to make neighbor cache entry just for
IsRouter bit)

IsRouter bit must be revisited, really.
--------------------------------------------------------------------
IETF IPng Working Group Mailing List
IPng Home Page:                      http://playground.sun.com/ipng
FTP archive:                      ftp://playground.sun.com/pub/ipng
Direct all administrative requests to [email-masked]
--------------------------------------------------------------------