if_stf.c (78701) | if_stf.c (79106) |
---|---|
1/* $FreeBSD: head/sys/net/if_stf.c 78701 2001-06-24 14:52:55Z ume $ */ | 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> | 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> |
|
101#include <netinet/ip_var.h> 102#include <netinet/in_var.h> 103 104#include <netinet/ip6.h> 105#include <netinet6/ip6_var.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> |
106#include <netinet6/in6_gif.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 | 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 "bpf.h" 117#define NBPFILTER NBPF 118#include "stf.h" 119#include "gif.h" /*XXX*/ 120 121#if NBPFILTER > 0 | |
122#include <net/bpf.h> | 116#include <net/bpf.h> |
123#endif | |
124 | 117 |
125#if NGIF > 0 126#include <net/if_gif.h> 127#endif 128 129#if NSTF > 0 130#if NSTF != 1 131# error only single stf interface allowed 132#endif 133 | |
134#define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) == 0x2002) 135#define GET_V4(x) ((struct in_addr *)(&(x)->s6_addr16[1])) 136 137struct stf_softc { 138 struct ifnet sc_if; /* common area */ 139 union { 140 struct route __sc_ro4; 141 struct route_in6 __sc_ro6; /* just for safety */ 142 } __sc_ro46; 143#define sc_ro __sc_ro46.__sc_ro4 144 const struct encaptab *encap_cookie; 145}; 146 147static struct stf_softc *stf; | 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; |
148static int nstf; | |
149 | 132 |
150#if NGIF > 0 151extern int ip_gif_ttl; /*XXX*/ 152#else 153static int ip_gif_ttl = 40; /*XXX*/ 154#endif | 133static MALLOC_DEFINE(M_STF, "stf", "6to4 Tunnel Interface"); 134static int ip_stf_ttl = 40; |
155 | 135 |
156extern struct protosw in_stf_protosw; | 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}; |
157 | 144 |
158void stfattach __P((void *)); | 145static int stfmodevent __P((module_t, int, void *)); |
159static int stf_encapcheck __P((const struct mbuf *, int, int, void *)); 160static struct in6_ifaddr *stf_getsrcifa6 __P((struct ifnet *)); 161static int stf_output __P((struct ifnet *, struct mbuf *, struct sockaddr *, 162 struct rtentry *)); 163static int stf_checkaddr4 __P((struct stf_softc *, struct in_addr *, 164 struct ifnet *)); 165static int stf_checkaddr6 __P((struct stf_softc *, struct in6_addr *, 166 struct ifnet *)); 167static void stf_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 168static int stf_ioctl __P((struct ifnet *, u_long, caddr_t)); 169 | 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 |
170void 171stfattach(dummy) 172 void *dummy; | 157static int 158stfmodevent(mod, type, data) 159 module_t mod; 160 int type; 161 void *data; |
173{ 174 struct stf_softc *sc; | 162{ 163 struct stf_softc *sc; |
175 int i; | 164 int err; |
176 const struct encaptab *p; 177 | 165 const struct encaptab *p; 166 |
178 nstf = NSTF; 179 stf = malloc(nstf * sizeof(struct stf_softc), M_DEVBUF, M_WAITOK); 180 bzero(stf, nstf * sizeof(struct stf_softc)); 181 sc = stf; | 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; |
182 | 172 |
183 /* XXX just in case... */ 184 for (i = 0; i < nstf; i++) { 185 sc = &stf[i]; | |
186 bzero(sc, sizeof(*sc)); 187 sc->sc_if.if_name = "stf"; | 173 bzero(sc, sizeof(*sc)); 174 sc->sc_if.if_name = "stf"; |
188 sc->sc_if.if_unit = i; | 175 sc->sc_if.if_unit = 0; |
189 190 p = encap_attach_func(AF_INET, IPPROTO_IPV6, stf_encapcheck, 191 &in_stf_protosw, sc); 192 if (p == NULL) { 193 printf("%s: attach failed\n", if_name(&sc->sc_if)); | 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)); |
194 continue; | 181 return (ENOMEM); |
195 } 196 sc->encap_cookie = p; 197 198 sc->sc_if.if_mtu = IPV6_MMTU; 199 sc->sc_if.if_flags = 0; 200 sc->sc_if.if_ioctl = stf_ioctl; 201 sc->sc_if.if_output = stf_output; 202 sc->sc_if.if_type = IFT_STF; 203#if 0 204 /* turn off ingress filter */ 205 sc->sc_if.if_flags |= IFF_LINK2; 206#endif 207 sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; 208 if_attach(&sc->sc_if); | 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); |
209#if NBPFILTER > 0 | |
210#ifdef HAVE_OLD_BPF 211 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); 212#else 213 bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_NULL, sizeof(u_int)); 214#endif | 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 |
215#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; |
216 } | 210 } |
211 212 return (0); |
|
217} 218 | 213} 214 |
219PSEUDO_SET(stfattach, if_stf); | 215static moduledata_t stf_mod = { 216 "if_stf", 217 stfmodevent, 218 0 219}; |
220 | 220 |
221DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 222 |
|
221static int 222stf_encapcheck(m, off, proto, arg) 223 const struct mbuf *m; 224 int off; 225 int proto; 226 void *arg; 227{ 228 struct ip ip; --- 179 unchanged lines hidden (view full) --- 408 ip = mtod(m, struct ip *); 409 410 bzero(ip, sizeof(*ip)); 411 412 bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), 413 &ip->ip_src, sizeof(ip->ip_src)); 414 bcopy(in4, &ip->ip_dst, sizeof(ip->ip_dst)); 415 ip->ip_p = IPPROTO_IPV6; | 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; |
416 ip->ip_ttl = ip_gif_ttl; /*XXX*/ | 418 ip->ip_ttl = ip_stf_ttl; |
417 ip->ip_len = m->m_pkthdr.len; /*host order*/ 418 if (ifp->if_flags & IFF_LINK1) 419 ip_ecn_ingress(ECN_ALLOWED, &ip->ip_tos, &tos); 420 else 421 ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); 422 423 dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; 424 if (dst4->sin_family != AF_INET || --- 177 unchanged lines hidden (view full) --- 602 ip_ecn_egress(ECN_ALLOWED, &otos, &itos); 603 else 604 ip_ecn_egress(ECN_NOCARE, &otos, &itos); 605 ip6->ip6_flow &= ~htonl(0xff << 20); 606 ip6->ip6_flow |= htonl((u_int32_t)itos << 20); 607 608 m->m_pkthdr.rcvif = ifp; 609 | 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 |
610#if NBPFILTER > 0 | |
611 if (ifp->if_bpf) { 612 /* 613 * We need to prepend the address family as 614 * a four byte field. Cons up a dummy header 615 * to pacify bpf. This is safe because bpf 616 * will only read from the mbuf (i.e., it won't 617 * try to free it or keep a pointer a to it). 618 */ --- 5 unchanged lines hidden (view full) --- 624 m0.m_data = (char *)⁡ 625 626#ifdef HAVE_OLD_BPF 627 bpf_mtap(ifp, &m0); 628#else 629 bpf_mtap(ifp->if_bpf, &m0); 630#endif 631 } | 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 } |
632#endif /*NBPFILTER > 0*/ | |
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} | 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} |
706 707#endif /* NSTF > 0 */ | |