xref: /dflybsd-src/sys/net/stf/if_stf.c (revision 5f8e6ce5f120e62b36da3f8b1f077948c821e498)
1  /*	$FreeBSD: src/sys/net/if_stf.c,v 1.1.2.11 2003/01/23 21:06:44 sam Exp $	*/
2  /*	$KAME: if_stf.c,v 1.73 2001/12/03 11:08:30 keiichi Exp $	*/
3  
4  /*
5   * Copyright (C) 2000 WIDE Project.
6   * All rights reserved.
7   *
8   * Redistribution and use in source and binary forms, with or without
9   * modification, are permitted provided that the following conditions
10   * are met:
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer.
13   * 2. Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   * 3. Neither the name of the project nor the names of its contributors
17   *    may be used to endorse or promote products derived from this software
18   *    without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30   * SUCH DAMAGE.
31   */
32  
33  /*
34   * 6to4 interface, based on RFC3056.
35   *
36   * 6to4 interface is NOT capable of link-layer (I mean, IPv4) multicasting.
37   * There is no address mapping defined from IPv6 multicast address to IPv4
38   * address.  Therefore, we do not have IFF_MULTICAST on the interface.
39   *
40   * Due to the lack of address mapping for link-local addresses, we cannot
41   * throw packets toward link-local addresses (fe80::x).  Also, we cannot throw
42   * packets to link-local multicast addresses (ff02::x).
43   *
44   * Here are interesting symptoms due to the lack of link-local address:
45   *
46   * Unicast routing exchange:
47   * - RIPng: Impossible.  Uses link-local multicast packet toward ff02::9,
48   *   and link-local addresses as nexthop.
49   * - OSPFv6: Impossible.  OSPFv6 assumes that there's link-local address
50   *   assigned to the link, and makes use of them.  Also, HELLO packets use
51   *   link-local multicast addresses (ff02::5 and ff02::6).
52   * - BGP4+: Maybe.  You can only use global address as nexthop, and global
53   *   address as TCP endpoint address.
54   *
55   * Multicast routing protocols:
56   * - PIM: Hello packet cannot be used to discover adjacent PIM routers.
57   *   Adjacent PIM routers must be configured manually (is it really spec-wise
58   *   correct thing to do?).
59   *
60   * ICMPv6:
61   * - Redirects cannot be used due to the lack of link-local address.
62   *
63   * stf interface does not have, and will not need, a link-local address.
64   * It seems to have no real benefit and does not help the above symptoms much.
65   * Even if we assign link-locals to interface, we cannot really
66   * use link-local unicast/multicast on top of 6to4 cloud (since there's no
67   * encapsulation defined for link-local address), and the above analysis does
68   * not change.  RFC3056 does not mandate the assignment of link-local address
69   * either.
70   *
71   * 6to4 interface has security issues.  Refer to
72   * http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-00.txt
73   * for details.  The code tries to filter out some of malicious packets.
74   * Note that there is no way to be 100% secure.
75   */
76  
77  #include "opt_inet.h"
78  #include "opt_inet6.h"
79  
80  #include <sys/param.h>
81  #include <sys/systm.h>
82  #include <sys/socket.h>
83  #include <sys/sockio.h>
84  #include <sys/mbuf.h>
85  #include <sys/errno.h>
86  #include <sys/protosw.h>
87  #include <sys/kernel.h>
88  #include <machine/cpu.h>
89  
90  #include <sys/malloc.h>
91  
92  #include <net/if.h>
93  #include <net/route.h>
94  #include <net/netisr.h>
95  #include <net/if_types.h>
96  #include <net/ifq_var.h>
97  #include <net/netisr2.h>
98  #include "if_stf.h"
99  
100  #include <netinet/in.h>
101  #include <netinet/in_systm.h>
102  #include <netinet/ip.h>
103  #include <netinet/ip_var.h>
104  #include <netinet/in_var.h>
105  
106  #include <netinet/ip6.h>
107  #include <netinet6/ip6_var.h>
108  #include <netinet6/in6_var.h>
109  #include <netinet6/nd6.h>
110  #include <netinet/ip_ecn.h>
111  
112  #include <netinet/ip_encap.h>
113  
114  #include <machine/stdarg.h>
115  
116  #include <net/net_osdep.h>
117  
118  #include <net/bpf.h>
119  
120  #define IN6_IS_ADDR_6TO4(x)	(ntohs((x)->s6_addr16[0]) == 0x2002)
121  #define GET_V4(x)	((struct in_addr *)(&(x)->s6_addr16[1]))
122  
123  struct stf_softc {
124  	struct ifnet	sc_if;	   /* common area */
125  	struct route	*route_pcpu;
126  	const struct encaptab *encap_cookie;
127  };
128  
129  static struct stf_softc *stf;
130  
131  static MALLOC_DEFINE(M_STF, "stf", "6to4 Tunnel Interface");
132  static int ip_stf_ttl = 40;
133  
134  extern  struct domain inetdomain;
135  struct protosw in_stf_protosw =
136      {
137  	.pr_type = SOCK_RAW,
138  	.pr_domain = &inetdomain,
139  	.pr_protocol = IPPROTO_IPV6,
140  	.pr_flags = PR_ATOMIC|PR_ADDR,
141  
142  	.pr_input = in_stf_input,
143  	.pr_output = rip_output,
144  	.pr_ctlinput = NULL,
145  	.pr_ctloutput = rip_ctloutput,
146  
147  	.pr_usrreqs = &rip_usrreqs
148      };
149  
150  static int stfmodevent (module_t, int, void *);
151  static int stf_encapcheck (const struct mbuf *, int, int, void *);
152  static struct in6_ifaddr *stf_getsrcifa6 (struct ifnet *);
153  static int stf_output (struct ifnet *, struct mbuf *, struct sockaddr *,
154  	struct rtentry *);
155  static int stf_checkaddr4 (struct stf_softc *, struct in_addr *,
156  	struct ifnet *);
157  static int stf_checkaddr6 (struct stf_softc *, struct in6_addr *,
158  	struct ifnet *);
159  static void stf_rtrequest (int, struct rtentry *);
160  static int stf_ioctl (struct ifnet *, u_long, caddr_t, struct ucred *);
161  
162  static int
163  stfmodevent(module_t mod, int type, void *data)
164  {
165  	struct stf_softc *sc;
166  	int err, cpu;
167  	const struct encaptab *p;
168  
169  	switch (type) {
170  	case MOD_LOAD:
171  		stf = kmalloc(sizeof(struct stf_softc), M_STF,
172  		    M_WAITOK | M_ZERO);
173  		sc = stf;
174  
175  		bzero(sc, sizeof(*sc));
176  		if_initname(&(sc->sc_if), "stf", 0);
177  
178  		p = encap_attach_func(AF_INET, IPPROTO_IPV6, stf_encapcheck,
179  		    (void *)&in_stf_protosw, sc);
180  		if (p == NULL) {
181  			kprintf("%s: attach failed\n", if_name(&sc->sc_if));
182  			return (ENOMEM);
183  		}
184  		sc->encap_cookie = p;
185  		sc->route_pcpu = kmalloc(netisr_ncpus * sizeof(struct route),
186  		    M_STF, M_WAITOK | M_ZERO);
187  
188  		sc->sc_if.if_mtu    = IPV6_MMTU;
189  		sc->sc_if.if_flags  = 0;
190  		sc->sc_if.if_ioctl  = stf_ioctl;
191  		sc->sc_if.if_output = stf_output;
192  		sc->sc_if.if_type   = IFT_STF;
193  #if 0
194  		/* turn off ingress filter */
195  		sc->sc_if.if_flags  |= IFF_LINK2;
196  #endif
197  		ifq_set_maxlen(&sc->sc_if.if_snd, IFQ_MAXLEN);
198  		if_attach(&sc->sc_if, NULL);
199  		bpfattach(&sc->sc_if, DLT_NULL, sizeof(uint32_t));
200  		/*
201  		 * 6to4 interface is very special: no multicast, no linklocal.
202  		 * RFC2529 specifies how to make linklocals, but there's no
203  		 * use and it is rather harmful to have one.
204  		 *
205  		 * NOTE: ND_IFINFO() is only available after if_attach().
206  		 */
207  		ND_IFINFO(&sc->sc_if)->flags &= ~ND6_IFF_AUTO_LINKLOCAL;
208  		ND_IFINFO(&sc->sc_if)->flags |= ND6_IFF_NO_DAD;
209  		break;
210  	case MOD_UNLOAD:
211  		sc = stf;
212  		bpfdetach(&sc->sc_if);
213  		if_detach(&sc->sc_if);
214  		err = encap_detach(sc->encap_cookie);
215  		KASSERT(err == 0, ("Unexpected error detaching encap_cookie"));
216  		for (cpu = 0; cpu < netisr_ncpus; ++cpu) {
217  			if (sc->route_pcpu[cpu].ro_rt != NULL) {
218  				rtfree_async(sc->route_pcpu[cpu].ro_rt);
219  				sc->route_pcpu[cpu].ro_rt = NULL;
220  			}
221  		}
222  		kfree(sc->route_pcpu, M_STF);
223  		kfree(sc, M_STF);
224  		break;
225  	}
226  
227  	return (0);
228  }
229  
230  static moduledata_t stf_mod = {
231  	"if_stf",
232  	stfmodevent,
233  	0
234  };
235  
236  DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
237  
238  static int
239  stf_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
240  {
241  	struct ip ip;
242  	struct in6_ifaddr *ia6;
243  	struct stf_softc *sc;
244  	struct in_addr a, b;
245  
246  	sc = (struct stf_softc *)arg;
247  	if (sc == NULL)
248  		return 0;
249  
250  	if ((sc->sc_if.if_flags & IFF_UP) == 0)
251  		return 0;
252  
253  	/* IFF_LINK0 means "no decapsulation" */
254  	if ((sc->sc_if.if_flags & IFF_LINK0) != 0)
255  		return 0;
256  
257  	if (proto != IPPROTO_IPV6)
258  		return 0;
259  
260  	m_copydata(m, 0, sizeof(ip), &ip);
261  
262  	if (ip.ip_v != 4)
263  		return 0;
264  
265  	ia6 = stf_getsrcifa6(&sc->sc_if);
266  	if (ia6 == NULL)
267  		return 0;
268  
269  	/*
270  	 * check if IPv4 dst matches the IPv4 address derived from the
271  	 * local 6to4 address.
272  	 * success on: dst = 10.1.1.1, ia6->ia_addr = 2002:0a01:0101:...
273  	 */
274  	if (bcmp(GET_V4(&ia6->ia_addr.sin6_addr), &ip.ip_dst,
275  	    sizeof(ip.ip_dst)) != 0)
276  		return 0;
277  
278  	/*
279  	 * check if IPv4 src matches the IPv4 address derived from the
280  	 * local 6to4 address masked by prefixmask.
281  	 * success on: src = 10.1.1.1, ia6->ia_addr = 2002:0a00:.../24
282  	 * fail on: src = 10.1.1.1, ia6->ia_addr = 2002:0b00:.../24
283  	 */
284  	bzero(&a, sizeof(a));
285  	a.s_addr = GET_V4(&ia6->ia_addr.sin6_addr)->s_addr;
286  	a.s_addr &= GET_V4(&ia6->ia_prefixmask.sin6_addr)->s_addr;
287  	b = ip.ip_src;
288  	b.s_addr &= GET_V4(&ia6->ia_prefixmask.sin6_addr)->s_addr;
289  	if (a.s_addr != b.s_addr)
290  		return 0;
291  
292  	/* stf interface makes single side match only */
293  	return 32;
294  }
295  
296  static struct in6_ifaddr *
297  stf_getsrcifa6(struct ifnet *ifp)
298  {
299  	struct ifaddr_container *ifac;
300  	struct sockaddr_in6 *sin6;
301  	struct in_addr in;
302  
303  	TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) {
304  		struct ifaddr *ia = ifac->ifa;
305  		struct in_ifaddr_container *iac;
306  
307  		if (ia->ifa_addr == NULL)
308  			continue;
309  		if (ia->ifa_addr->sa_family != AF_INET6)
310  			continue;
311  		sin6 = (struct sockaddr_in6 *)ia->ifa_addr;
312  		if (!IN6_IS_ADDR_6TO4(&sin6->sin6_addr))
313  			continue;
314  
315  		bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in));
316  		LIST_FOREACH(iac, INADDR_HASH(in.s_addr), ia_hash) {
317  			if (iac->ia->ia_addr.sin_addr.s_addr == in.s_addr)
318  				break;
319  		}
320  		if (iac == NULL)
321  			continue;
322  
323  		return (struct in6_ifaddr *)ia;
324  	}
325  
326  	return NULL;
327  }
328  
329  static int
330  stf_output_serialized(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
331  		      struct rtentry *rt)
332  {
333  	struct stf_softc *sc;
334  	struct sockaddr_in6 *dst6;
335  	struct in_addr *in4;
336  	struct sockaddr_in *dst4;
337  	u_int8_t tos;
338  	struct ip *ip;
339  	struct ip6_hdr *ip6;
340  	struct in6_ifaddr *ia6;
341  	struct route *ro;
342  	static const uint32_t af = AF_INET6;
343  
344  	ASSERT_NETISR_NCPUS(mycpuid);
345  
346  	sc = (struct stf_softc*)ifp;
347  	dst6 = (struct sockaddr_in6 *)dst;
348  
349  	/* just in case */
350  	if ((ifp->if_flags & IFF_UP) == 0) {
351  		m_freem(m);
352  		return ENETDOWN;
353  	}
354  
355  	/*
356  	 * If we don't have an ip4 address that match my inner ip6 address,
357  	 * we shouldn't generate output.  Without this check, we'll end up
358  	 * using wrong IPv4 source.
359  	 */
360  	ia6 = stf_getsrcifa6(ifp);
361  	if (ia6 == NULL) {
362  		m_freem(m);
363  		return ENETDOWN;
364  	}
365  
366  	if (m->m_len < sizeof(*ip6)) {
367  		m = m_pullup(m, sizeof(*ip6));
368  		if (!m)
369  			return ENOBUFS;
370  	}
371  	ip6 = mtod(m, struct ip6_hdr *);
372  	tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
373  
374  	/*
375  	 * Pickup the right outer dst addr from the list of candidates.
376  	 * ip6_dst has priority as it may be able to give us shorter IPv4 hops.
377  	 */
378  	if (IN6_IS_ADDR_6TO4(&ip6->ip6_dst))
379  		in4 = GET_V4(&ip6->ip6_dst);
380  	else if (IN6_IS_ADDR_6TO4(&dst6->sin6_addr))
381  		in4 = GET_V4(&dst6->sin6_addr);
382  	else {
383  		m_freem(m);
384  		return ENETUNREACH;
385  	}
386  
387  	if (ifp->if_bpf) {
388  		bpf_gettoken();
389  		if (ifp->if_bpf)
390  			bpf_ptap(ifp->if_bpf, m, &af, sizeof(af));
391  		bpf_reltoken();
392  	}
393  
394  	M_PREPEND(m, sizeof(struct ip), M_NOWAIT);
395  	if (m && m->m_len < sizeof(struct ip))
396  		m = m_pullup(m, sizeof(struct ip));
397  	if (m == NULL)
398  		return ENOBUFS;
399  	ip = mtod(m, struct ip *);
400  
401  	bzero(ip, sizeof(*ip));
402  
403  	bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr),
404  	    &ip->ip_src, sizeof(ip->ip_src));
405  	bcopy(in4, &ip->ip_dst, sizeof(ip->ip_dst));
406  	ip->ip_p = IPPROTO_IPV6;
407  	ip->ip_ttl = ip_stf_ttl;
408  	ip->ip_len = htons(m->m_pkthdr.len);	/* network order */
409  	if (ifp->if_flags & IFF_LINK1)
410  		ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos);
411  	else
412  		ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos);
413  
414  	ro = &sc->route_pcpu[mycpuid];
415  	dst4 = (struct sockaddr_in *)&ro->ro_dst;
416  	if (dst4->sin_family != AF_INET ||
417  	    bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) {
418  		/* cache route doesn't match */
419  		dst4->sin_family = AF_INET;
420  		dst4->sin_len = sizeof(struct sockaddr_in);
421  		bcopy(&ip->ip_dst, &dst4->sin_addr, sizeof(dst4->sin_addr));
422  		if (ro->ro_rt) {
423  			RTFREE(ro->ro_rt);
424  			ro->ro_rt = NULL;
425  		}
426  	}
427  	if (ro->ro_rt != NULL && (ro->ro_rt->rt_flags & RTF_UP) == 0) {
428  		RTFREE(ro->ro_rt);
429  		ro->ro_rt = NULL;
430  	}
431  
432  	if (ro->ro_rt == NULL) {
433  		rtalloc(ro);
434  		if (ro->ro_rt == NULL) {
435  			m_freem(m);
436  			return ENETUNREACH;
437  		}
438  	}
439  
440  	return ip_output(m, NULL, ro, IP_DEBUGROUTE, NULL, NULL);
441  }
442  
443  static int
444  stf_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
445  	   struct rtentry *rt)
446  {
447  	struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
448  	int error;
449  
450  	ifsq_serialize_hw(ifsq);
451  	error = stf_output_serialized(ifp, m, dst, rt);
452  	ifsq_deserialize_hw(ifsq);
453  
454  	return error;
455  }
456  
457  /*
458   * Parameters:
459   *	inifp:	incoming interface
460   */
461  static int
462  stf_checkaddr4(struct stf_softc *sc, struct in_addr *in, struct ifnet *inifp)
463  {
464  	struct in_ifaddr_container *iac;
465  
466  	/*
467  	 * reject packets with the following address:
468  	 * 224.0.0.0/4 0.0.0.0/8 127.0.0.0/8 255.0.0.0/8
469  	 */
470  	if (IN_MULTICAST(ntohl(in->s_addr)))
471  		return -1;
472  	switch ((ntohl(in->s_addr) & 0xff000000) >> 24) {
473  	case 0: case 127: case 255:
474  		return -1;
475  	}
476  
477  	/*
478  	 * reject packets with broadcast
479  	 */
480  	TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) {
481  		struct in_ifaddr *ia4 = iac->ia;
482  
483  		if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
484  			continue;
485  		if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
486  			return -1;
487  	}
488  
489  	/*
490  	 * perform ingress filter
491  	 */
492  	if (sc && (sc->sc_if.if_flags & IFF_LINK2) == 0 && inifp) {
493  		struct sockaddr_in sin;
494  		struct rtentry *rt;
495  
496  		bzero(&sin, sizeof(sin));
497  		sin.sin_family = AF_INET;
498  		sin.sin_len = sizeof(struct sockaddr_in);
499  		sin.sin_addr = *in;
500  		rt = rtpurelookup((struct sockaddr *)&sin);
501  		if (!rt || rt->rt_ifp != inifp) {
502  #if 0
503  			log(LOG_WARNING, "%s: packet from 0x%x dropped "
504  			    "due to ingress filter\n", if_name(&sc->sc_if),
505  			    (u_int32_t)ntohl(sin.sin_addr.s_addr));
506  #endif
507  			if (rt)
508  				rtfree(rt);
509  			return -1;
510  		}
511  		rtfree(rt);
512  	}
513  
514  	return 0;
515  }
516  
517  /*
518   * Parameters:
519   *	inifp:	incoming interface
520   */
521  static int
522  stf_checkaddr6(struct stf_softc *sc, struct in6_addr *in6, struct ifnet *inifp)
523  {
524  	/*
525  	 * check 6to4 addresses
526  	 */
527  	if (IN6_IS_ADDR_6TO4(in6))
528  		return stf_checkaddr4(sc, GET_V4(in6), inifp);
529  
530  	/*
531  	 * reject anything that look suspicious.  the test is implemented
532  	 * in ip6_input too, but we check here as well to
533  	 * (1) reject bad packets earlier, and
534  	 * (2) to be safe against future ip6_input change.
535  	 */
536  	if (IN6_IS_ADDR_V4COMPAT(in6) || IN6_IS_ADDR_V4MAPPED(in6))
537  		return -1;
538  
539  	return 0;
540  }
541  
542  int
543  in_stf_input(struct mbuf **mp, int *offp, int proto)
544  {
545  	struct mbuf *m;
546  	struct stf_softc *sc;
547  	struct ip *ip;
548  	struct ip6_hdr *ip6;
549  	u_int8_t otos, itos;
550  	struct ifnet *ifp;
551  	int off;
552  	static const uint32_t af = AF_INET6;
553  
554  	m = *mp;
555  	off = *offp;
556  
557  	if (proto != IPPROTO_IPV6) {
558  		m_freem(m);
559  		return(IPPROTO_DONE);
560  	}
561  
562  	ip = mtod(m, struct ip *);
563  
564  	sc = (struct stf_softc *)encap_getarg(m);
565  
566  	if (sc == NULL || (sc->sc_if.if_flags & IFF_UP) == 0) {
567  		m_freem(m);
568  		return(IPPROTO_DONE);
569  	}
570  
571  	ifp = &sc->sc_if;
572  
573  	/*
574  	 * perform sanity check against outer src/dst.
575  	 * for source, perform ingress filter as well.
576  	 */
577  	if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 ||
578  	    stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) {
579  		m_freem(m);
580  		return(IPPROTO_DONE);
581  	}
582  
583  	otos = ip->ip_tos;
584  	m_adj(m, off);
585  
586  	if (m->m_len < sizeof(*ip6)) {
587  		m = m_pullup(m, sizeof(*ip6));
588  		if (!m)
589  			return(IPPROTO_DONE);
590  	}
591  	ip6 = mtod(m, struct ip6_hdr *);
592  
593  	/*
594  	 * perform sanity check against inner src/dst.
595  	 * for source, perform ingress filter as well.
596  	 */
597  	if (stf_checkaddr6(sc, &ip6->ip6_dst, NULL) < 0 ||
598  	    stf_checkaddr6(sc, &ip6->ip6_src, m->m_pkthdr.rcvif) < 0) {
599  		m_freem(m);
600  		return(IPPROTO_DONE);
601  	}
602  
603  	itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
604  	if ((ifp->if_flags & IFF_LINK1) != 0)
605  		ip_ecn_egress(ECN_ALLOWED, &otos, &itos);
606  	else
607  		ip_ecn_egress(ECN_NOCARE, &otos, &itos);
608  	ip6->ip6_flow &= ~htonl(0xff << 20);
609  	ip6->ip6_flow |= htonl((u_int32_t)itos << 20);
610  
611  	m->m_pkthdr.rcvif = ifp;
612  
613  	if (ifp->if_bpf) {
614  		bpf_gettoken();
615  		if (ifp->if_bpf)
616  			bpf_ptap(ifp->if_bpf, m, &af, sizeof(af));
617  		bpf_reltoken();
618  	}
619  
620  	/*
621  	 * Put the packet to the network layer input queue according to the
622  	 * specified address family.
623  	 * See net/if_gif.c for possible issues with packet processing
624  	 * reorder due to extra queueing.
625  	 */
626  	IFNET_STAT_INC(ifp, ipackets, 1);
627  	IFNET_STAT_INC(ifp, ibytes, m->m_pkthdr.len);
628  	m->m_flags &= ~M_HASH;
629  	netisr_queue(NETISR_IPV6, m);
630  	return(IPPROTO_DONE);
631  }
632  
633  /* ARGSUSED */
634  static void
635  stf_rtrequest(int cmd, struct rtentry *rt)
636  {
637  
638  	if (rt)
639  		rt->rt_rmx.rmx_mtu = IPV6_MMTU;
640  }
641  
642  static int
643  stf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
644  {
645  	struct ifaddr *ifa;
646  	struct ifreq *ifr;
647  	struct sockaddr_in6 *sin6;
648  	int error;
649  
650  	error = 0;
651  	switch (cmd) {
652  	case SIOCSIFADDR:
653  		ifa = (struct ifaddr *)data;
654  		if (ifa == NULL || ifa->ifa_addr->sa_family != AF_INET6) {
655  			error = EAFNOSUPPORT;
656  			break;
657  		}
658  		sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
659  		if (IN6_IS_ADDR_6TO4(&sin6->sin6_addr)) {
660  			ifa->ifa_rtrequest = stf_rtrequest;
661  			ifp->if_flags |= IFF_UP;
662  		} else
663  			error = EINVAL;
664  		break;
665  
666  	case SIOCADDMULTI:
667  	case SIOCDELMULTI:
668  		ifr = (struct ifreq *)data;
669  		if (ifr && ifr->ifr_addr.sa_family == AF_INET6)
670  			;
671  		else
672  			error = EAFNOSUPPORT;
673  		break;
674  
675  	default:
676  		error = EINVAL;
677  		break;
678  	}
679  
680  	return error;
681  }
682