Subject: Re: fxp0: can't handle af118
To: Christos Zoulas <christos@zoulas.com>
From: Andreas Wrede <andreas@planix.com>
List: current-users
Date: 05/18/2004 17:27:15
This is a multi-part message in MIME format.
--------------080405070607010801040206
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
Christos Zoulas wrote:
> On May 18, 11:51am, erplefoo@gmail.com (Sean Davis) wrote:
> -- Subject: Re: fxp0: can't handle af118
>
> | I'm seeing the same thing with tl(4):
> | May 18 11:45:31 eros /netbsd: tl1: can't handle af8
> |
> | I am also using a catch-all return-rst rule...
> |
> | It appears to stem from sys/net/if_ethersubr.c (revision 1.114) line 462-465:
> | 462 default:
> | 463 printf("%s: can't handle af%d\n", ifp->if_xname,
> | 464 dst->sa_family);
> | 465 senderr(EAFNOSUPPORT);
> |
> | if the address family is broken, but different, for fxp, it sounds
> | like it's not getting set somewhere and a value from elsewhere is
> | leaking in, or something similar. I'll see if I can figure out what,
> | but it's been ages since I've looked through the ethernet code.
> |
> | -Sean
>
>
> I think the code that is broken is the code that prepares the dst packet
> somewhere in ip_nat or ip_fil.
The problem appears to have been introduced with the commit of rev 1.6
of src/sys/netinet/ip_fil_netbsd.c. I am running with the changes from
1.5, 1.7 and 1.8. The diff against the current head of p_fil_netbsd.c is
attached, it should be largely identical to changes from rev 1.6.
--
- aew
--------------080405070607010801040206
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
name="ipnat.diff1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ipnat.diff1"
Index: ip_fil_netbsd.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_fil_netbsd.c,v
retrieving revision 1.8
diff -u -r1.8 ip_fil_netbsd.c
--- ip_fil_netbsd.c 9 May 2004 08:29:30 -0000 1.8
+++ ip_fil_netbsd.c 18 May 2004 21:18:35 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_fil_netbsd.c,v 1.8 2004/05/09 08:29:30 taca Exp $ */
+/* $NetBSD: ip_fil_netbsd.c,v 1.5 2004/04/22 01:01:41 matt Exp $ */
/*
* Copyright (C) 1993-2003 by Darren Reed.
@@ -1001,10 +1001,6 @@
}
}
#endif
-#ifdef USE_INET6
- if (fin->fin_v == 6)
- return ipfr_fastroute6(m0, mpp, fin, fdp);
-#endif
hlen = fin->fin_hlen;
ip = mtod(m0, struct ip *);
@@ -1016,6 +1012,10 @@
m0->m_pkthdr.csuminfo = 0;
#endif /* __NetBSD__ && M_CSUM_IPv4 */
+#ifdef USE_INET6
+ if (fin->fin_v == 6)
+ return ipfr_fastroute6(m0, mpp, fin, fdp);
+#endif
/*
* Route packet.
*/
@@ -1023,13 +1023,14 @@
bzero((caddr_t)ro, sizeof (*ro));
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
- dst->sin_addr = ip->ip_dst;
fr = fin->fin_fr;
if (fdp)
ifp = fdp->fd_ifp;
- else
+ else {
ifp = fin->fin_ifp;
+ dst->sin_addr = ip->ip_dst;
+ }
if ((ifp == NULL) && (!fr || !(fr->fr_flags & FR_FASTROUTE))) {
error = -2;
@@ -1044,26 +1045,27 @@
if ((ifp != NULL) && (fdp == &fr->fr_tif))
return -1;
dst->sin_addr = ip->ip_dst;
- } else if (fdp != NULL) {
- if (fdp->fd_ip.s_addr != 0)
+ } else if (fdp) {
+ if (fdp->fd_ip.s_addr) {
dst->sin_addr = fdp->fd_ip;
+ ip->ip_dst = fdp->fd_ip;
+ } else
+ dst->sin_addr = ip->ip_dst;
}
dst->sin_len = sizeof(*dst);
rtalloc(ro);
-
- if ((ifp == NULL) && (ro->ro_rt != NULL))
- ifp = ro->ro_rt->rt_ifp;
-
- if ((ro->ro_rt == NULL) || (ifp == NULL)) {
- if (in_localaddr(ip->ip_dst))
- error = EHOSTUNREACH;
- else
- error = ENETUNREACH;
- goto bad;
+ if (!ifp) {
+ if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
+ if (in_localaddr(ip->ip_dst))
+ error = EHOSTUNREACH;
+ else
+ error = ENETUNREACH;
+ goto bad;
+ }
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
}
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
if (ro->ro_rt)
ro->ro_rt->rt_use++;
@@ -1072,9 +1074,8 @@
* go back through output filtering and miss their chance to get
* NAT'd and counted.
*/
+ fin->fin_ifp = ifp;
if (fin->fin_out == 0) {
- sifp = fin->fin_ifp;
- fin->fin_ifp = ifp;
fin->fin_out = 1;
(void) fr_acctpkt(fin, NULL);
fin->fin_fr = NULL;
@@ -1084,7 +1085,6 @@
(void) fr_checkstate(fin, &pass);
}
(void) fr_checknatout(fin, NULL);
- fin->fin_ifp = sifp;
} else
ip->ip_sum = 0;
/*
--------------080405070607010801040206--