Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Aug 1998 15:46:06 +0400 (MSD)
From:      Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   problem with ll cloned routes
Message-ID:  <199808181146.PAA06670@muffin.arcadia.spb.ru>

next in thread | raw e-mail | index | archive | help
Hello,

Please be patient to the things that I'm going to describe below,
I may be wrong (in fact I guess I'm wrong with the fix)
I've recently found an annoying feature of internal routing table
managing in FreeBSD 2.2.6-RELEASE (posted two lame problem reports
on this yet - #7578, wish someone will remove it from there).
First the problem itself: when interface is deleted (or alias
on an interface is deleted) a corresponding route to network that
was added for this interface is deleted also (it's quite reasonable
and what everyone expects when deleting an interface). Well, but
link layer cloned routes associated with this interface are not
deleted. They remain intact and what is worst apparently contain
pointer to the previous struct ifaddr, that itself contains
old interface information. So, when you delete an alias on interface
and for example set another (neighboring) ip address on it and
there is a route to some host cloned from the old alias, packets to
that host will go out with the old alias ip address of used interface.
Because when doing rt_alloc for ip_output, it will find the
old route matching and ip_output will happily retrieve an old
(non-existing so far) interface address from the pointer in
this rtentry and send packets with the old (non-existing)
ip address.
Well, now the technical details I've found. Please, if I'm wrong
could someone please explain me where I mistake.

Creating a route:
1. interface is being configured. On some step of this configuration
route to corresponding network is added (I'm now talking about
ether interface)
2. some packet is ready to be out on this interface. In ip_output
rtalloc_ign(ro, RTF_PRCLONING) is called to find route to the
destination
3. rtalloc_ign calls rtalloc1 that finds route to network created
when corresponding interface was created and then tries to allocate
route to destination
4. it calls rtrequest
5. rtrequest allocates a new rtentry and on some internal step
will call ifa->ifa_rtrequest for used interface (arp_rtrequest)
6. finally route is ready and has the flag RTF_WASCLONED (route
to network from which it was cloned has the flag RTF_CLONING on
it)
7. packet is out

Now deleting an alias or interface configuraion at all:
1. interface losts its address. On some step in_ifscrub is called
that will try to remove any route to the interface address that
is being deleted
2. in_ifscrub calls rtinit with RTM_DELETE parameter
3. rtinit on some step call rtrequest with cmd = RTM_DELETE
4. what happens in rtrequest_delete is a little bit strange -
it doesn't do anything that will delete routes cloned from
this route being deleted (not protocol-cloned). I.e. it apparently
doesn't even try to locate routing entries cloned from this
route.

Am I wrong and simply didn't notice such code? If so,
I'd appreciate it very much if you point me where is the
code that will try to remove cloned routing entries, I'm
very curious about it. Well, in fact I'm pretty sure that
such code must exist there but I didn't find it and
so didn't find why it doesn't work.
So the only thing that came to mind is the following:
in rtrequest_makeroute when checking if the route is
protocol-cloned check also if it's ll cloned and
create a link to parent route in this case also,
then in rtrequest_delete when checking for cloned routes
look also for any ll cloned routes if there is RTF_CLONING
flag on the route we are deleting.
This is the only trick I developed against that problem
and apparently it seems functional, also there comes
another problem that confuses me: netstat doesn't show
ll cloned entries with this fix and that's because it
assumes that having non-zero rt_parent pointer means
the route is _protocol_cloned_. Well, I'm a little bit
messed with that code and the only thing I definitely
want to know is - where is in fact the right code that
will clear ll cloned route entries and what is then
the right mechanism for keeping, creating and cleaning
such routes. I'll appreciate any comments on the above
posting because I got very curious about all this routing
implementation when started to look at the code.

Well, why do I think I'm wrong with the patch.
Because it makes ll cloned routes and protocol cloned
routes look similar (don't think netstat is wrong
not showing me routes with parent by default). Also,
route.c was not changed since 2.2.2-RELEASE and it
seems to me there was no such problem in 2.2.2,
unfortunately can't verify it right now.

Now the patched route.c

--- route.c	Tue Aug 18 13:32:27 1998
+++ route.c.orig	Tue Aug 18 13:30:29 1998
@@ -450,7 +450,7 @@
 		 * Now search what's left of the subtree for any cloned
 		 * routes which might have been formed from this node.
 		 */
-		if ((rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) && netmask) {
+		if ((rt->rt_flags & RTF_PRCLONING) && netmask) {
 			rnh->rnh_walktree_from(rnh, dst, netmask,
 					       rt_fixdelete, rt);
 		}
@@ -575,8 +575,7 @@
 
 		if (req == RTM_RESOLVE) {
 			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
-			if ((*ret_nrt)->rt_flags &
-			    (RTF_CLONING | RTF_PRCLONING)) {
+			if ((*ret_nrt)->rt_flags & RTF_PRCLONING) {
 				rt->rt_parent = (*ret_nrt);
 				(*ret_nrt)->rt_refcnt++;
 			}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808181146.PAA06670>