in_lltable_rtcheck

Juan Mojica jmojica at gmail.com
Thu May 2 14:20:17 UTC 2013


It looks like the same/similar problem is in sys/net/if.c

struct ifaddr *
ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)

...

			cp = addr->sa_data;
			cp2 = ifa->ifa_addr->sa_data;
			cp3 = ifa->ifa_netmask->sa_data;
			cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
			for (; cp3 < cplim; cp3++)
				if ((*cp++ ^ *cp2++) & *cp3)
					break;
			if (cp3 == cplim)
				goto done;

...

This is intended to be to be agnostic to the v3 protocol, but the
unintended consequence is that it compares the in_port_t field as
well.

-Juan



On Tue, Apr 30, 2013 at 9:22 AM, Juan Mojica <jmojica at gmail.com> wrote:

> Great!  Thanks Qing.  I'll come up with a patch and reply.
>
> -Juan
>
>
> On Mon, Apr 29, 2013 at 9:40 PM, Li, Qing <qing.li at bluecoat.com> wrote:
>
>> The problem you described here seemed familiar so I checked into the svn
>> history,
>> and found I have in fact fixed this issue in other parts of the code.
>>
>> Please see
>> http://svnweb.freebsd.org/base?view=revision&revision=186708
>>
>> So I think similar fix should be applied here as well.
>>
>> --Qing
>>
>>
>> ________________________________________
>> From: owner-freebsd-net at freebsd.org [owner-freebsd-net at freebsd.org] on
>> behalf of Juan Mojica [jmojica at gmail.com]
>> Sent: Monday, April 29, 2013 6:17 PM
>> To: FreeBSD Net
>> Subject: in_lltable_rtcheck
>>
>> Why is the code comparing the entire sockaddr structure instead of just
>> the
>> relevant fields?  We have a flood of the log message below when
>> transitioning an IP address from one port to another.  And this triggers
>> other behavior as well.
>>
>> Through GDB, we can see that the addresses are in the same subnet.  The
>> problem is that the sin_port port fields in the l3addr and in sa do not
>> match.
>>
>> Is there a reason sin_port should be compared here?
>>
>> I can come up with a patch, that's not an issue, but I wanted to confirm
>> with others first.
>>
>>
>>         if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
>>                 const char *sa, *mask, *addr, *lim;
>>                 int len;
>>
>>                 mask = (const char *)rt_mask(rt);
>>                 /*
>>                  * Just being extra cautious to avoid some custom
>>                  * code getting into trouble.
>>                  */
>>                 if (mask == NULL) {
>>                         RTFREE_LOCKED(rt);
>>                         return (EINVAL);
>>                 }
>>
>>                 sa = (const char *)rt_key(rt);
>>                 addr = (const char *)l3addr;
>>                 len = ((const struct sockaddr_in *)l3addr)->sin_len;
>>                 lim = addr + len;
>>
>>                 for ( ; addr < lim; sa++, mask++, addr++) {
>>                         if ((*sa ^ *addr) & *mask) {
>> #ifdef DIAGNOSTIC
>>                                 log(LOG_INFO, "IPv4 address: \"%s\" is
>> not on the network\n",
>>                                     inet_ntoa(((const struct sockaddr_in
>> *)l3addr)->sin_addr));
>> #endif
>>                                 RTFREE_LOCKED(rt);
>>                                 return (EINVAL);
>>                         }
>>                 }
>>         }
>>
>>
>> Regards
>>
>> --
>> Juan Mojica
>> Email: jmojica at gmail.com
>> _______________________________________________
>> freebsd-net at freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-net
>> To unsubscribe, send any mail to "freebsd-net-unsubscribe at freebsd.org"
>>
>
>
>
> --
> Juan Mojica
> Email: jmojica at gmail.com
>



-- 
Juan Mojica
Email: jmojica at gmail.com


More information about the freebsd-net mailing list