This source file includes following definitions.
- in6_gif_output
- in6_gif_input
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 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/socket.h>
36 #include <sys/sockio.h>
37 #include <sys/mbuf.h>
38 #include <sys/errno.h>
39 #include <sys/ioctl.h>
40 #include <sys/protosw.h>
41
42 #include <net/if.h>
43 #include <net/route.h>
44
45 #include <netinet/in.h>
46 #include <netinet/in_systm.h>
47 #include <netinet/ip_ipsp.h>
48
49 #ifdef INET
50 #include <netinet/ip.h>
51 #endif
52
53 #include <netinet/ip6.h>
54 #include <netinet6/ip6_var.h>
55 #include <netinet6/in6_gif.h>
56
57 #ifdef INET6
58 #include <netinet/ip6.h>
59 #endif
60
61 #include <netinet/ip_ecn.h>
62
63 #include <net/if_gif.h>
64
65 #include "bridge.h"
66
67 #ifndef offsetof
68 #define offsetof(s, e) ((int)&((s *)0)->e)
69 #endif
70
71 int
72 in6_gif_output(ifp, family, m)
73 struct ifnet *ifp;
74 int family;
75 struct mbuf *m;
76 {
77 struct gif_softc *sc = (struct gif_softc*)ifp;
78 struct sockaddr_in6 *dst = (struct sockaddr_in6 *)&sc->gif_ro6.ro_dst;
79 struct sockaddr_in6 *sin6_src = (struct sockaddr_in6 *)sc->gif_psrc;
80 struct sockaddr_in6 *sin6_dst = (struct sockaddr_in6 *)sc->gif_pdst;
81 struct tdb tdb;
82 struct xformsw xfs;
83 int error;
84 struct mbuf *mp;
85
86 if (sin6_src == NULL || sin6_dst == NULL ||
87 sin6_src->sin6_family != AF_INET6 ||
88 sin6_dst->sin6_family != AF_INET6) {
89 m_freem(m);
90 return EAFNOSUPPORT;
91 }
92
93
94 bzero(&tdb, sizeof(tdb));
95 bzero(&xfs, sizeof(xfs));
96 tdb.tdb_src.sin6.sin6_family = AF_INET6;
97 tdb.tdb_src.sin6.sin6_len = sizeof(struct sockaddr_in6);
98 tdb.tdb_src.sin6.sin6_addr = sin6_src->sin6_addr;
99 tdb.tdb_dst.sin6.sin6_family = AF_INET6;
100 tdb.tdb_dst.sin6.sin6_len = sizeof(struct sockaddr_in6);
101 tdb.tdb_dst.sin6.sin6_addr = sin6_dst->sin6_addr;
102 tdb.tdb_xform = &xfs;
103 xfs.xf_type = -1;
104
105 switch (family) {
106 #ifdef INET
107 case AF_INET:
108 break;
109 #endif
110 #ifdef INET6
111 case AF_INET6:
112 break;
113 #endif
114 #if NBRIDGE > 0
115 case AF_LINK:
116 break;
117 #endif
118 default:
119 #ifdef DEBUG
120 printf("in6_gif_output: warning: unknown family %d passed\n",
121 family);
122 #endif
123 m_freem(m);
124 return EAFNOSUPPORT;
125 }
126
127
128 mp = NULL;
129 #if NBRIDGE > 0
130 if (family == AF_LINK)
131 error = etherip_output(m, &tdb, &mp, 0, 0);
132 else
133 #endif
134 error = ipip_output(m, &tdb, &mp, 0, 0);
135 if (error)
136 return error;
137 else if (mp == NULL)
138 return EFAULT;
139
140 m = mp;
141
142
143 if (dst->sin6_family != sin6_dst->sin6_family ||
144 !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) {
145
146 bzero(dst, sizeof(*dst));
147 dst->sin6_family = sin6_dst->sin6_family;
148 dst->sin6_len = sizeof(struct sockaddr_in6);
149 dst->sin6_addr = sin6_dst->sin6_addr;
150 if (sc->gif_ro6.ro_rt) {
151 RTFREE(sc->gif_ro6.ro_rt);
152 sc->gif_ro6.ro_rt = NULL;
153 }
154 }
155
156 if (sc->gif_ro6.ro_rt == NULL) {
157 rtalloc((struct route *)&sc->gif_ro6);
158 if (sc->gif_ro6.ro_rt == NULL) {
159 m_freem(m);
160 return ENETUNREACH;
161 }
162 }
163
164
165
166
167
168
169 error = ip6_output(m, 0, &sc->gif_ro6, IPV6_MINMTU, 0, NULL, NULL);
170
171 return error;
172 }
173
174 int in6_gif_input(mp, offp, proto)
175 struct mbuf **mp;
176 int *offp, proto;
177 {
178 struct mbuf *m = *mp;
179 struct gif_softc *sc;
180 struct ifnet *gifp = NULL;
181 struct ip6_hdr *ip6;
182
183
184 if (m->m_flags & (M_AUTH | M_CONF))
185 goto inject;
186
187 ip6 = mtod(m, struct ip6_hdr *);
188
189 #define satoin6(sa) (((struct sockaddr_in6 *)(sa))->sin6_addr)
190 LIST_FOREACH(sc, &gif_softc_list, gif_list) {
191 if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
192 sc->gif_psrc->sa_family != AF_INET6 ||
193 sc->gif_pdst->sa_family != AF_INET6) {
194 continue;
195 }
196
197 if ((sc->gif_if.if_flags & IFF_UP) == 0)
198 continue;
199
200 if (IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_psrc), &ip6->ip6_dst) &&
201 IN6_ARE_ADDR_EQUAL(&satoin6(sc->gif_pdst), &ip6->ip6_src)) {
202 gifp = &sc->gif_if;
203 break;
204 }
205 }
206
207 if (gifp) {
208 m->m_pkthdr.rcvif = gifp;
209 gifp->if_ipackets++;
210 gifp->if_ibytes += m->m_pkthdr.len;
211 ipip_input(m, *offp, gifp);
212 return IPPROTO_DONE;
213 }
214
215 inject:
216
217 ip4_input6(&m, offp, 0);
218 return IPPROTO_DONE;
219 }