This source file includes following definitions.
- faithattach
- faith_clone_create
- faith_clone_destroy
- faithoutput
- faithrtrequest
- faithioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include "faith.h"
40
41 #if NFAITH > 0
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/mbuf.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48
49 #include <net/if.h>
50 #include <net/if_types.h>
51 #include <net/netisr.h>
52 #include <net/route.h>
53 #include <net/bpf.h>
54
55 #ifdef INET
56 #include <netinet/in.h>
57 #include <netinet/in_var.h>
58 #endif
59
60 #ifdef INET6
61 #ifndef INET
62 #include <netinet/in.h>
63 #endif
64 #include <netinet6/in6_var.h>
65 #endif
66
67 #include "bpfilter.h"
68
69 static int faithioctl(struct ifnet *, u_long, caddr_t);
70 int faithoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
71 struct rtentry *);
72 static void faithrtrequest(int, struct rtentry *, struct rt_addrinfo *);
73
74 void faithattach(int);
75 int faith_clone_create(struct if_clone *, int);
76 int faith_clone_destroy(struct ifnet *ifp);
77
78 struct if_clone faith_cloner =
79 IF_CLONE_INITIALIZER("faith", faith_clone_create, faith_clone_destroy);
80
81 #define FAITHMTU 1500
82
83
84 void
85 faithattach(faith)
86 int faith;
87 {
88 if_clone_attach(&faith_cloner);
89 }
90
91 int
92 faith_clone_create(ifc, unit)
93 struct if_clone *ifc;
94 int unit;
95 {
96 struct ifnet *ifp;
97
98 ifp = malloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT);
99 if (!ifp)
100 return (ENOMEM);
101 bzero(ifp, sizeof(*ifp));
102 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
103 unit);
104 ifp->if_mtu = FAITHMTU;
105
106 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
107 ifp->if_ioctl = faithioctl;
108 ifp->if_output = faithoutput;
109 ifp->if_type = IFT_FAITH;
110 ifp->if_hdrlen = 0;
111 ifp->if_addrlen = 0;
112 if_attach(ifp);
113 if_alloc_sadl(ifp);
114 #if NBPFILTER > 0
115 bpfattach(&ifp->if_bpf, ifp, DLT_NULL, sizeof(u_int));
116 #endif
117 return (0);
118 }
119
120 int
121 faith_clone_destroy(ifp)
122 struct ifnet *ifp;
123 {
124 if_detach(ifp);
125
126 free(ifp, M_DEVBUF);
127 return (0);
128 }
129
130 int
131 faithoutput(ifp, m, dst, rt)
132 struct ifnet *ifp;
133 struct mbuf *m;
134 struct sockaddr *dst;
135 struct rtentry *rt;
136 {
137 int s, isr;
138 struct ifqueue *ifq = 0;
139
140 if ((m->m_flags & M_PKTHDR) == 0)
141 panic("faithoutput no HDR");
142 #if NBPFILTER > 0
143
144 if (dst->sa_family == AF_UNSPEC) {
145 dst->sa_family = *(mtod(m, int *));
146 m->m_len -= sizeof(int);
147 m->m_pkthdr.len -= sizeof(int);
148 m->m_data += sizeof(int);
149 }
150
151 if (ifp->if_bpf)
152 bpf_mtap_af(ifp->if_bpf, dst->sa_family, m, BPF_DIRECTION_OUT);
153 #endif
154
155 if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
156 m_freem(m);
157 return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
158 rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
159 }
160 ifp->if_opackets++;
161 ifp->if_obytes += m->m_pkthdr.len;
162 switch (dst->sa_family) {
163 #ifdef INET
164 case AF_INET:
165 ifq = &ipintrq;
166 isr = NETISR_IP;
167 break;
168 #endif
169 #ifdef INET6
170 case AF_INET6:
171 ifq = &ip6intrq;
172 isr = NETISR_IPV6;
173 break;
174 #endif
175 default:
176 m_freem(m);
177 return EAFNOSUPPORT;
178 }
179
180
181
182 m->m_pkthdr.rcvif = ifp;
183 s = splnet();
184 if (IF_QFULL(ifq)) {
185 IF_DROP(ifq);
186 m_freem(m);
187 splx(s);
188 return (ENOBUFS);
189 }
190 IF_ENQUEUE(ifq, m);
191 schednetisr(isr);
192 ifp->if_ipackets++;
193 ifp->if_ibytes += m->m_pkthdr.len;
194 splx(s);
195 return (0);
196 }
197
198
199 static void
200 faithrtrequest(cmd, rt, info)
201 int cmd;
202 struct rtentry *rt;
203 struct rt_addrinfo *info;
204 {
205 if (rt)
206 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
207 }
208
209
210
211
212
213 static int
214 faithioctl(ifp, cmd, data)
215 struct ifnet *ifp;
216 u_long cmd;
217 caddr_t data;
218 {
219 struct ifaddr *ifa;
220 struct ifreq *ifr = (struct ifreq *)data;
221 int error = 0;
222
223 switch (cmd) {
224
225 case SIOCSIFADDR:
226 ifp->if_flags |= IFF_UP | IFF_RUNNING;
227 ifa = (struct ifaddr *)data;
228 ifa->ifa_rtrequest = faithrtrequest;
229
230
231
232 break;
233
234 case SIOCADDMULTI:
235 case SIOCDELMULTI:
236 if (ifr == 0) {
237 error = EAFNOSUPPORT;
238 break;
239 }
240 switch (ifr->ifr_addr.sa_family) {
241 #ifdef INET
242 case AF_INET:
243 break;
244 #endif
245 #ifdef INET6
246 case AF_INET6:
247 break;
248 #endif
249
250 default:
251 error = EAFNOSUPPORT;
252 break;
253 }
254 break;
255
256 case SIOCSIFFLAGS:
257 break;
258
259 default:
260 error = EINVAL;
261 }
262 return (error);
263 }
264 #endif