1/* $FreeBSD: head/sys/net/if_stf.c 79106 2001-07-02 21:02:09Z brooks $ */ |
2/* $KAME: if_stf.c,v 1.62 2001/06/07 22:32:16 itojun 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 --- 83 unchanged lines hidden (view full) --- 93#include <net/route.h> 94#include <net/netisr.h> 95#include <net/if_types.h> 96#include <net/if_stf.h> 97 98#include <netinet/in.h> 99#include <netinet/in_systm.h> 100#include <netinet/ip.h> |
101#include <netinet/ipprotosw.h> |
102#include <netinet/ip_var.h> 103#include <netinet/in_var.h> 104 105#include <netinet/ip6.h> 106#include <netinet6/ip6_var.h> |
107#include <netinet6/in6_var.h> 108#include <netinet/ip_ecn.h> 109 110#include <netinet/ip_encap.h> 111 112#include <machine/stdarg.h> 113 114#include <net/net_osdep.h> 115 |
116#include <net/bpf.h> |
117 |
118#define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) == 0x2002) 119#define GET_V4(x) ((struct in_addr *)(&(x)->s6_addr16[1])) 120 121struct stf_softc { 122 struct ifnet sc_if; /* common area */ 123 union { 124 struct route __sc_ro4; 125 struct route_in6 __sc_ro6; /* just for safety */ 126 } __sc_ro46; 127#define sc_ro __sc_ro46.__sc_ro4 128 const struct encaptab *encap_cookie; 129}; 130 131static struct stf_softc *stf; |
132 |
133static MALLOC_DEFINE(M_STF, "stf", "6to4 Tunnel Interface"); 134static int ip_stf_ttl = 40; |
135 |
136extern struct domain inetdomain; 137struct ipprotosw in_stf_protosw = 138{ SOCK_RAW, &inetdomain, IPPROTO_IPV6, PR_ATOMIC|PR_ADDR, 139 in_stf_input, rip_output, 0, rip_ctloutput, 140 0, 141 0, 0, 0, 0, 142 &rip_usrreqs 143}; |
144 |
145static int stfmodevent __P((module_t, int, void *)); |
146static int stf_encapcheck __P((const struct mbuf *, int, int, void *)); 147static struct in6_ifaddr *stf_getsrcifa6 __P((struct ifnet *)); 148static int stf_output __P((struct ifnet *, struct mbuf *, struct sockaddr *, 149 struct rtentry *)); 150static int stf_checkaddr4 __P((struct stf_softc *, struct in_addr *, 151 struct ifnet *)); 152static int stf_checkaddr6 __P((struct stf_softc *, struct in6_addr *, 153 struct ifnet *)); 154static void stf_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 155static int stf_ioctl __P((struct ifnet *, u_long, caddr_t)); 156 |
157static int 158stfmodevent(mod, type, data) 159 module_t mod; 160 int type; 161 void *data; |
162{ 163 struct stf_softc *sc; |
164 int err; |
165 const struct encaptab *p; 166 |
167 switch (type) { 168 case MOD_LOAD: 169 stf = malloc(sizeof(struct stf_softc), M_STF, M_WAITOK); 170 bzero(stf, sizeof(struct stf_softc)); 171 sc = stf; |
172 |
173 bzero(sc, sizeof(*sc)); 174 sc->sc_if.if_name = "stf"; |
175 sc->sc_if.if_unit = 0; |
176 177 p = encap_attach_func(AF_INET, IPPROTO_IPV6, stf_encapcheck, 178 &in_stf_protosw, sc); 179 if (p == NULL) { 180 printf("%s: attach failed\n", if_name(&sc->sc_if)); |
181 return (ENOMEM); |
182 } 183 sc->encap_cookie = p; 184 185 sc->sc_if.if_mtu = IPV6_MMTU; 186 sc->sc_if.if_flags = 0; 187 sc->sc_if.if_ioctl = stf_ioctl; 188 sc->sc_if.if_output = stf_output; 189 sc->sc_if.if_type = IFT_STF; 190#if 0 191 /* turn off ingress filter */ 192 sc->sc_if.if_flags |= IFF_LINK2; 193#endif 194 sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; 195 if_attach(&sc->sc_if); |
196#ifdef HAVE_OLD_BPF 197 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); 198#else 199 bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_NULL, sizeof(u_int)); 200#endif |
201 break; 202 case MOD_UNLOAD: 203 sc = stf; 204 bpfdetach(&sc->sc_if); 205 if_detach(&sc->sc_if); 206 err = encap_detach(sc->encap_cookie); 207 KASSERT(err == 0, ("Unexpected error detaching encap_cookie")); 208 free(sc, M_STF); 209 break; |
210 } |
211 212 return (0); |
213} 214 |
215static moduledata_t stf_mod = { 216 "if_stf", 217 stfmodevent, 218 0 219}; |
220 |
221DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 222 |
223static int 224stf_encapcheck(m, off, proto, arg) 225 const struct mbuf *m; 226 int off; 227 int proto; 228 void *arg; 229{ 230 struct ip ip; --- 179 unchanged lines hidden (view full) --- 410 ip = mtod(m, struct ip *); 411 412 bzero(ip, sizeof(*ip)); 413 414 bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), 415 &ip->ip_src, sizeof(ip->ip_src)); 416 bcopy(in4, &ip->ip_dst, sizeof(ip->ip_dst)); 417 ip->ip_p = IPPROTO_IPV6; |
418 ip->ip_ttl = ip_stf_ttl; |
419 ip->ip_len = m->m_pkthdr.len; /*host order*/ 420 if (ifp->if_flags & IFF_LINK1) 421 ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos); 422 else 423 ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); 424 425 dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; 426 if (dst4->sin_family != AF_INET || --- 177 unchanged lines hidden (view full) --- 604 ip_ecn_egress(ECN_ALLOWED, &otos, &itos); 605 else 606 ip_ecn_egress(ECN_NOCARE, &otos, &itos); 607 ip6->ip6_flow &= ~htonl(0xff << 20); 608 ip6->ip6_flow |= htonl((u_int32_t)itos << 20); 609 610 m->m_pkthdr.rcvif = ifp; 611 |
612 if (ifp->if_bpf) { 613 /* 614 * We need to prepend the address family as 615 * a four byte field. Cons up a dummy header 616 * to pacify bpf. This is safe because bpf 617 * will only read from the mbuf (i.e., it won't 618 * try to free it or keep a pointer a to it). 619 */ --- 5 unchanged lines hidden (view full) --- 625 m0.m_data = (char *)⁡ 626 627#ifdef HAVE_OLD_BPF 628 bpf_mtap(ifp, &m0); 629#else 630 bpf_mtap(ifp->if_bpf, &m0); 631#endif 632 } |
633 634 /* 635 * Put the packet to the network layer input queue according to the 636 * specified address family. 637 * See net/if_gif.c for possible issues with packet processing 638 * reorder due to extra queueing. 639 */ 640 ifq = &ip6intrq; --- 57 unchanged lines hidden (view full) --- 698 699 default: 700 error = EINVAL; 701 break; 702 } 703 704 return error; 705} |