source: rtems-libbsd/freebsd/sys/net/if_faith.c @ 3d1e767

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 3d1e767 was 3d1e767, checked in by Sebastian Huber <sebastian.huber@…>, on 04/27/16 at 08:25:22

Directly use <sys/types.h> provided by Newlib

  • Property mode set to 100644
File size: 7.5 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*      $KAME: if_faith.c,v 1.23 2001/12/17 13:55:29 sumikawa Exp $     */
4
5/*-
6 * Copyright (c) 1982, 1986, 1993
7 *      The Regents of the University of California.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD$
34 */
35/*
36 * derived from
37 *      @(#)if_loop.c   8.1 (Berkeley) 6/10/93
38 * Id: if_loop.c,v 1.22 1996/06/19 16:24:10 wollman Exp
39 */
40
41/*
42 * Loopback interface driver for protocol testing and timing.
43 */
44#include <rtems/bsd/local/opt_inet.h>
45#include <rtems/bsd/local/opt_inet6.h>
46
47#include <rtems/bsd/sys/param.h>
48#include <sys/systm.h>
49#include <sys/kernel.h>
50#include <sys/mbuf.h>
51#include <sys/module.h>
52#include <sys/socket.h>
53#include <rtems/bsd/sys/errno.h>
54#include <sys/sockio.h>
55#include <sys/time.h>
56#include <sys/queue.h>
57#include <sys/types.h>
58#include <sys/malloc.h>
59
60#include <net/if.h>
61#include <net/if_clone.h>
62#include <net/if_types.h>
63#include <net/netisr.h>
64#include <net/route.h>
65#include <net/bpf.h>
66#include <net/vnet.h>
67
68#ifdef  INET
69#include <netinet/in.h>
70#include <netinet/in_systm.h>
71#include <netinet/in_var.h>
72#include <netinet/ip.h>
73#endif
74
75#ifdef INET6
76#ifndef INET
77#include <netinet/in.h>
78#endif
79#include <netinet6/in6_var.h>
80#include <netinet/ip6.h>
81#include <netinet6/ip6_var.h>
82#endif
83
84#define FAITHNAME       "faith"
85
86struct faith_softc {
87        struct ifnet *sc_ifp;
88};
89
90static int faithioctl(struct ifnet *, u_long, caddr_t);
91int faithoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
92        struct route *);
93static void faithrtrequest(int, struct rtentry *, struct rt_addrinfo *);
94#ifdef INET6
95static int faithprefix(struct in6_addr *);
96#endif
97
98static int faithmodevent(module_t, int, void *);
99
100static MALLOC_DEFINE(M_FAITH, FAITHNAME, "Firewall Assisted Tunnel Interface");
101
102static int      faith_clone_create(struct if_clone *, int, caddr_t);
103static void     faith_clone_destroy(struct ifnet *);
104
105IFC_SIMPLE_DECLARE(faith, 0);
106
107#define FAITHMTU        1500
108
109static int
110faithmodevent(mod, type, data)
111        module_t mod;
112        int type;
113        void *data;
114{
115
116        switch (type) {
117        case MOD_LOAD:
118                if_clone_attach(&faith_cloner);
119
120#ifdef INET6
121                faithprefix_p = faithprefix;
122#endif
123
124                break;
125        case MOD_UNLOAD:
126#ifdef INET6
127                faithprefix_p = NULL;
128#endif
129
130                if_clone_detach(&faith_cloner);
131                break;
132        default:
133                return EOPNOTSUPP;
134        }
135        return 0;
136}
137
138static moduledata_t faith_mod = {
139        "if_faith",
140        faithmodevent,
141        0
142};
143
144DECLARE_MODULE(if_faith, faith_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
145MODULE_VERSION(if_faith, 1);
146
147static int
148faith_clone_create(ifc, unit, params)
149        struct if_clone *ifc;
150        int unit;
151        caddr_t params;
152{
153        struct ifnet *ifp;
154        struct faith_softc *sc;
155
156        sc = malloc(sizeof(struct faith_softc), M_FAITH, M_WAITOK | M_ZERO);
157        ifp = sc->sc_ifp = if_alloc(IFT_FAITH);
158        if (ifp == NULL) {
159                free(sc, M_FAITH);
160                return (ENOSPC);
161        }
162
163        ifp->if_softc = sc;
164        if_initname(sc->sc_ifp, ifc->ifc_name, unit);
165
166        ifp->if_mtu = FAITHMTU;
167        /* Change to BROADCAST experimentaly to announce its prefix. */
168        ifp->if_flags = /* IFF_LOOPBACK */ IFF_BROADCAST | IFF_MULTICAST;
169        ifp->if_ioctl = faithioctl;
170        ifp->if_output = faithoutput;
171        ifp->if_hdrlen = 0;
172        ifp->if_addrlen = 0;
173        ifp->if_snd.ifq_maxlen = ifqmaxlen;
174        if_attach(ifp);
175        bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
176        return (0);
177}
178
179static void
180faith_clone_destroy(ifp)
181        struct ifnet *ifp;
182{
183        struct faith_softc *sc = ifp->if_softc;
184
185        bpfdetach(ifp);
186        if_detach(ifp);
187        if_free(ifp);
188        free(sc, M_FAITH);
189}
190
191int
192faithoutput(ifp, m, dst, ro)
193        struct ifnet *ifp;
194        struct mbuf *m;
195        struct sockaddr *dst;
196        struct route *ro;
197{
198        int isr;
199        u_int32_t af;
200        struct rtentry *rt = NULL;
201
202        M_ASSERTPKTHDR(m);
203
204        if (ro != NULL)
205                rt = ro->ro_rt;
206        /* BPF writes need to be handled specially. */
207        if (dst->sa_family == AF_UNSPEC) {
208                bcopy(dst->sa_data, &af, sizeof(af));
209                dst->sa_family = af;
210        }
211
212        if (bpf_peers_present(ifp->if_bpf)) {
213                af = dst->sa_family;
214                bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m);
215        }
216
217        if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
218                m_freem(m);
219                return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
220                        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
221        }
222        ifp->if_opackets++;
223        ifp->if_obytes += m->m_pkthdr.len;
224        switch (dst->sa_family) {
225#ifdef INET
226        case AF_INET:
227                isr = NETISR_IP;
228                break;
229#endif
230#ifdef INET6
231        case AF_INET6:
232                isr = NETISR_IPV6;
233                break;
234#endif
235        default:
236                m_freem(m);
237                return EAFNOSUPPORT;
238        }
239
240        /* XXX do we need more sanity checks? */
241
242        m->m_pkthdr.rcvif = ifp;
243        ifp->if_ipackets++;
244        ifp->if_ibytes += m->m_pkthdr.len;
245        netisr_dispatch(isr, m);
246        return (0);
247}
248
249/* ARGSUSED */
250static void
251faithrtrequest(cmd, rt, info)
252        int cmd;
253        struct rtentry *rt;
254        struct rt_addrinfo *info;
255{
256        RT_LOCK_ASSERT(rt);
257        rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
258}
259
260/*
261 * Process an ioctl request.
262 */
263/* ARGSUSED */
264static int
265faithioctl(ifp, cmd, data)
266        struct ifnet *ifp;
267        u_long cmd;
268        caddr_t data;
269{
270        struct ifaddr *ifa;
271        struct ifreq *ifr = (struct ifreq *)data;
272        int error = 0;
273
274        switch (cmd) {
275
276        case SIOCSIFADDR:
277                ifp->if_flags |= IFF_UP;
278                ifp->if_drv_flags |= IFF_DRV_RUNNING;
279                ifa = (struct ifaddr *)data;
280                ifa->ifa_rtrequest = faithrtrequest;
281                /*
282                 * Everything else is done at a higher level.
283                 */
284                break;
285
286        case SIOCADDMULTI:
287        case SIOCDELMULTI:
288                if (ifr == 0) {
289                        error = EAFNOSUPPORT;           /* XXX */
290                        break;
291                }
292                switch (ifr->ifr_addr.sa_family) {
293#ifdef INET
294                case AF_INET:
295                        break;
296#endif
297#ifdef INET6
298                case AF_INET6:
299                        break;
300#endif
301
302                default:
303                        error = EAFNOSUPPORT;
304                        break;
305                }
306                break;
307
308#ifdef SIOCSIFMTU
309        case SIOCSIFMTU:
310                ifp->if_mtu = ifr->ifr_mtu;
311                break;
312#endif
313
314        case SIOCSIFFLAGS:
315                break;
316
317        default:
318                error = EINVAL;
319        }
320        return (error);
321}
322
323#ifdef INET6
324/*
325 * XXX could be slow
326 * XXX could be layer violation to call sys/net from sys/netinet6
327 */
328static int
329faithprefix(in6)
330        struct in6_addr *in6;
331{
332        struct rtentry *rt;
333        struct sockaddr_in6 sin6;
334        int ret;
335
336        if (V_ip6_keepfaith == 0)
337                return 0;
338
339        bzero(&sin6, sizeof(sin6));
340        sin6.sin6_family = AF_INET6;
341        sin6.sin6_len = sizeof(struct sockaddr_in6);
342        sin6.sin6_addr = *in6;
343        rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB);
344        if (rt && rt->rt_ifp && rt->rt_ifp->if_type == IFT_FAITH &&
345            (rt->rt_ifp->if_flags & IFF_UP) != 0)
346                ret = 1;
347        else
348                ret = 0;
349        if (rt)
350                RTFREE_LOCKED(rt);
351        return ret;
352}
353#endif
Note: See TracBrowser for help on using the repository browser.