Sat Jan 23 02:58:13 2016 UTC ()
fix compilation


(christos)
diff -r1.71 -r1.72 src/sys/netinet/in_gif.c

cvs diff -r1.71 -r1.72 src/sys/netinet/in_gif.c (switch to unified diff)

--- src/sys/netinet/in_gif.c 2016/01/22 23:27:12 1.71
+++ src/sys/netinet/in_gif.c 2016/01/23 02:58:13 1.72
@@ -1,413 +1,415 @@ @@ -1,413 +1,415 @@
1/* $NetBSD: in_gif.c,v 1.71 2016/01/22 23:27:12 riastradh Exp $ */ 1/* $NetBSD: in_gif.c,v 1.72 2016/01/23 02:58:13 christos Exp $ */
2/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */ 2/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
3 3
4/* 4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors 16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software 17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission. 18 * without specific prior written permission.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE. 30 * SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.71 2016/01/22 23:27:12 riastradh Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.72 2016/01/23 02:58:13 christos Exp $");
35 35
36#ifdef _KERNEL_OPT 36#ifdef _KERNEL_OPT
37#include "opt_inet.h" 37#include "opt_inet.h"
38#endif 38#endif
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/socket.h> 42#include <sys/socket.h>
43#include <sys/sockio.h> 43#include <sys/sockio.h>
44#include <sys/mbuf.h> 44#include <sys/mbuf.h>
45#include <sys/errno.h> 45#include <sys/errno.h>
46#include <sys/ioctl.h> 46#include <sys/ioctl.h>
47#include <sys/syslog.h> 47#include <sys/syslog.h>
48#include <sys/protosw.h> 48#include <sys/protosw.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50 50
51#include <net/if.h> 51#include <net/if.h>
52#include <net/route.h> 52#include <net/route.h>
53 53
54#include <netinet/in.h> 54#include <netinet/in.h>
55#include <netinet/in_systm.h> 55#include <netinet/in_systm.h>
56#include <netinet/ip.h> 56#include <netinet/ip.h>
57#include <netinet/ip_var.h> 57#include <netinet/ip_var.h>
58#include <netinet/in_gif.h> 58#include <netinet/in_gif.h>
59#include <netinet/in_var.h> 59#include <netinet/in_var.h>
60#include <netinet/ip_encap.h> 60#include <netinet/ip_encap.h>
61#include <netinet/ip_ecn.h> 61#include <netinet/ip_ecn.h>
62 62
63#ifdef INET6 63#ifdef INET6
64#include <netinet/ip6.h> 64#include <netinet/ip6.h>
65#endif 65#endif
66 66
67#include <net/if_gif.h> 67#include <net/if_gif.h>
68 68
69#include "gif.h" 69#include "gif.h"
70 70
71#include <net/net_osdep.h> 71#include <net/net_osdep.h>
72 72
73static int gif_validate4(const struct ip *, struct gif_softc *, 73static int gif_validate4(const struct ip *, struct gif_softc *,
74 struct ifnet *); 74 struct ifnet *);
75 75
76#if NGIF > 0 76#if NGIF > 0
77int ip_gif_ttl = GIF_TTL; 77int ip_gif_ttl = GIF_TTL;
78#else 78#else
79int ip_gif_ttl = 0; 79int ip_gif_ttl = 0;
80#endif 80#endif
81 81
82static const struct protosw in_gif_protosw = { 82static const struct protosw in_gif_protosw = {
83 .pr_type = SOCK_RAW, 83 .pr_type = SOCK_RAW,
84 .pr_domain = &inetdomain, 84 .pr_domain = &inetdomain,
85 .pr_protocol = 0 /* IPPROTO_IPV[46] */, 85 .pr_protocol = 0 /* IPPROTO_IPV[46] */,
86 .pr_flags = PR_ATOMIC|PR_ADDR, 86 .pr_flags = PR_ATOMIC|PR_ADDR,
87 .pr_input = in_gif_input, 87 .pr_input = in_gif_input,
88 .pr_ctlinput = NULL, 88 .pr_ctlinput = NULL,
89 .pr_ctloutput = rip_ctloutput, 89 .pr_ctloutput = rip_ctloutput,
90 .pr_usrreqs = &rip_usrreqs, 90 .pr_usrreqs = &rip_usrreqs,
91}; 91};
92 92
93int 93int
94in_gif_output(struct ifnet *ifp, int family, struct mbuf *m) 94in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
95{ 95{
96 struct rtentry *rt; 96 struct rtentry *rt;
97 struct gif_softc *sc = ifp->if_softc; 97 struct gif_softc *sc = ifp->if_softc;
98 struct sockaddr_in *sin_src = satosin(sc->gif_psrc); 98 struct sockaddr_in *sin_src = satosin(sc->gif_psrc);
99 struct sockaddr_in *sin_dst = satosin(sc->gif_pdst); 99 struct sockaddr_in *sin_dst = satosin(sc->gif_pdst);
100 struct ip iphdr; /* capsule IP header, host byte ordered */ 100 struct ip iphdr; /* capsule IP header, host byte ordered */
101 int proto, error; 101 int proto, error;
102 u_int8_t tos; 102 u_int8_t tos;
103 union { 103 union {
104 struct sockaddr dst; 104 struct sockaddr dst;
105 struct sockaddr_in dst4; 105 struct sockaddr_in dst4;
106 } u; 106 } u;
107 107
108 if (sin_src == NULL || sin_dst == NULL || 108 if (sin_src == NULL || sin_dst == NULL ||
109 sin_src->sin_family != AF_INET || 109 sin_src->sin_family != AF_INET ||
110 sin_dst->sin_family != AF_INET) { 110 sin_dst->sin_family != AF_INET) {
111 m_freem(m); 111 m_freem(m);
112 return EAFNOSUPPORT; 112 return EAFNOSUPPORT;
113 } 113 }
114 114
115 switch (family) { 115 switch (family) {
116#ifdef INET 116#ifdef INET
117 case AF_INET: 117 case AF_INET:
118 { 118 {
119 const struct ip *ip; 119 const struct ip *ip;
120 120
121 proto = IPPROTO_IPV4; 121 proto = IPPROTO_IPV4;
122 if (m->m_len < sizeof(*ip)) { 122 if (m->m_len < sizeof(*ip)) {
123 m = m_pullup(m, sizeof(*ip)); 123 m = m_pullup(m, sizeof(*ip));
124 if (m == NULL) 124 if (m == NULL)
125 return ENOBUFS; 125 return ENOBUFS;
126 } 126 }
127 ip = mtod(m, const struct ip *); 127 ip = mtod(m, const struct ip *);
128 tos = ip->ip_tos; 128 tos = ip->ip_tos;
129 break; 129 break;
130 } 130 }
131#endif /* INET */ 131#endif /* INET */
132#ifdef INET6 132#ifdef INET6
133 case AF_INET6: 133 case AF_INET6:
134 { 134 {
135 const struct ip6_hdr *ip6; 135 const struct ip6_hdr *ip6;
136 proto = IPPROTO_IPV6; 136 proto = IPPROTO_IPV6;
137 if (m->m_len < sizeof(*ip6)) { 137 if (m->m_len < sizeof(*ip6)) {
138 m = m_pullup(m, sizeof(*ip6)); 138 m = m_pullup(m, sizeof(*ip6));
139 if (m == NULL) 139 if (m == NULL)
140 return ENOBUFS; 140 return ENOBUFS;
141 } 141 }
142 ip6 = mtod(m, const struct ip6_hdr *); 142 ip6 = mtod(m, const struct ip6_hdr *);
143 tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 143 tos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
144 break; 144 break;
145 } 145 }
146#endif /* INET6 */ 146#endif /* INET6 */
147 default: 147 default:
148#ifdef DEBUG 148#ifdef DEBUG
149 printf("in_gif_output: warning: unknown family %d passed\n", 149 printf("in_gif_output: warning: unknown family %d passed\n",
150 family); 150 family);
151#endif 151#endif
152 m_freem(m); 152 m_freem(m);
153 return EAFNOSUPPORT; 153 return EAFNOSUPPORT;
154 } 154 }
155 155
156 memset(&iphdr, 0, sizeof(iphdr)); 156 memset(&iphdr, 0, sizeof(iphdr));
157 iphdr.ip_src = sin_src->sin_addr; 157 iphdr.ip_src = sin_src->sin_addr;
158 /* bidirectional configured tunnel mode */ 158 /* bidirectional configured tunnel mode */
159 if (sin_dst->sin_addr.s_addr != INADDR_ANY) 159 if (sin_dst->sin_addr.s_addr != INADDR_ANY)
160 iphdr.ip_dst = sin_dst->sin_addr; 160 iphdr.ip_dst = sin_dst->sin_addr;
161 else { 161 else {
162 m_freem(m); 162 m_freem(m);
163 return ENETUNREACH; 163 return ENETUNREACH;
164 } 164 }
165 iphdr.ip_p = proto; 165 iphdr.ip_p = proto;
166 /* version will be set in ip_output() */ 166 /* version will be set in ip_output() */
167 iphdr.ip_ttl = ip_gif_ttl; 167 iphdr.ip_ttl = ip_gif_ttl;
168 iphdr.ip_len = htons(m->m_pkthdr.len + sizeof(struct ip)); 168 iphdr.ip_len = htons(m->m_pkthdr.len + sizeof(struct ip));
169 if (ifp->if_flags & IFF_LINK1) 169 if (ifp->if_flags & IFF_LINK1)
170 ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos); 170 ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos);
171 else 171 else
172 ip_ecn_ingress(ECN_NOCARE, &iphdr.ip_tos, &tos); 172 ip_ecn_ingress(ECN_NOCARE, &iphdr.ip_tos, &tos);
173 173
174 /* prepend new IP header */ 174 /* prepend new IP header */
175 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 175 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
176 /* XXX Is m_pullup really necessary after M_PREPEND? */ 176 /* XXX Is m_pullup really necessary after M_PREPEND? */
177 if (m != NULL && M_UNWRITABLE(m, sizeof(struct ip))) 177 if (m != NULL && M_UNWRITABLE(m, sizeof(struct ip)))
178 m = m_pullup(m, sizeof(struct ip)); 178 m = m_pullup(m, sizeof(struct ip));
179 if (m == NULL) 179 if (m == NULL)
180 return ENOBUFS; 180 return ENOBUFS;
181 bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip)); 181 bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
182 182
183 sockaddr_in_init(&u.dst4, &sin_dst->sin_addr, 0); 183 sockaddr_in_init(&u.dst4, &sin_dst->sin_addr, 0);
184 if ((rt = rtcache_lookup(&sc->gif_ro, &u.dst)) == NULL) { 184 if ((rt = rtcache_lookup(&sc->gif_ro, &u.dst)) == NULL) {
185 m_freem(m); 185 m_freem(m);
186 return ENETUNREACH; 186 return ENETUNREACH;
187 } 187 }
188 188
189 /* If the route constitutes infinite encapsulation, punt. */ 189 /* If the route constitutes infinite encapsulation, punt. */
190 if (rt->rt_ifp == ifp) { 190 if (rt->rt_ifp == ifp) {
191 rtcache_free(&sc->gif_ro); 191 rtcache_free(&sc->gif_ro);
192 m_freem(m); 192 m_freem(m);
193 return ENETUNREACH; /*XXX*/ 193 return ENETUNREACH; /*XXX*/
194 } 194 }
195 195
196 error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL); 196 error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL);
197 return (error); 197 return (error);
198} 198}
199 199
200void 200void
201in_gif_input(struct mbuf *m, ...) 201in_gif_input(struct mbuf *m, ...)
202{ 202{
203 int off, proto; 203 int off, proto;
204 struct ifnet *gifp = NULL; 204 struct ifnet *gifp = NULL;
205 const struct ip *ip; 205 const struct ip *ip;
206 va_list ap; 206 va_list ap;
207 int af; 207 int af;
208 u_int8_t otos; 208 u_int8_t otos;
209 209
210 va_start(ap, m); 210 va_start(ap, m);
211 off = va_arg(ap, int); 211 off = va_arg(ap, int);
212 proto = va_arg(ap, int); 212 proto = va_arg(ap, int);
213 va_end(ap); 213 va_end(ap);
214 214
215 ip = mtod(m, const struct ip *); 215 ip = mtod(m, const struct ip *);
216 216
217 gifp = (struct ifnet *)encap_getarg(m); 217 gifp = (struct ifnet *)encap_getarg(m);
218 218
219 if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) { 219 if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) {
220 m_freem(m); 220 m_freem(m);
221 ip_statinc(IP_STAT_NOGIF); 221 ip_statinc(IP_STAT_NOGIF);
222 return; 222 return;
223 } 223 }
224#ifndef GIF_ENCAPCHECK 224#ifndef GIF_ENCAPCHECK
225 struct gif_softc *sc = (struct gif_softc *)gifp->if_softc; 225 struct gif_softc *sc = (struct gif_softc *)gifp->if_softc;
226 /* other CPU do delete_tunnel */ 226 /* other CPU do delete_tunnel */
227 if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) { 227 if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
228 m_freem(m); 228 m_freem(m);
229 ip_statinc(IP_STAT_NOGIF); 229 ip_statinc(IP_STAT_NOGIF);
230 return; 230 return;
231 } 231 }
232 232
233 if (!gif_validate4(ip, sc, m->m_pkthdr.rcvif)) { 233 if (!gif_validate4(ip, sc, m->m_pkthdr.rcvif)) {
234 m_freem(m); 234 m_freem(m);
235 ip_statinc(IP_STAT_NOGIF); 235 ip_statinc(IP_STAT_NOGIF);
236 return; 236 return;
237 } 237 }
238#endif 238#endif
239 otos = ip->ip_tos; 239 otos = ip->ip_tos;
240 m_adj(m, off); 240 m_adj(m, off);
241 241
242 switch (proto) { 242 switch (proto) {
243#ifdef INET 243#ifdef INET
244 case IPPROTO_IPV4: 244 case IPPROTO_IPV4:
245 { 245 {
246 struct ip *xip; 246 struct ip *xip;
247 af = AF_INET; 247 af = AF_INET;
248 if (M_UNWRITABLE(m, sizeof(*xip))) { 248 if (M_UNWRITABLE(m, sizeof(*xip))) {
249 if ((m = m_pullup(m, sizeof(*xip))) == NULL) 249 if ((m = m_pullup(m, sizeof(*xip))) == NULL)
250 return; 250 return;
251 } 251 }
252 xip = mtod(m, struct ip *); 252 xip = mtod(m, struct ip *);
253 if (gifp->if_flags & IFF_LINK1) 253 if (gifp->if_flags & IFF_LINK1)
254 ip_ecn_egress(ECN_ALLOWED, &otos, &xip->ip_tos); 254 ip_ecn_egress(ECN_ALLOWED, &otos, &xip->ip_tos);
255 else 255 else
256 ip_ecn_egress(ECN_NOCARE, &otos, &xip->ip_tos); 256 ip_ecn_egress(ECN_NOCARE, &otos, &xip->ip_tos);
257 break; 257 break;
258 } 258 }
259#endif 259#endif
260#ifdef INET6 260#ifdef INET6
261 case IPPROTO_IPV6: 261 case IPPROTO_IPV6:
262 { 262 {
263 struct ip6_hdr *ip6; 263 struct ip6_hdr *ip6;
264 u_int8_t itos; 264 u_int8_t itos;
265 af = AF_INET6; 265 af = AF_INET6;
266 if (M_UNWRITABLE(m, sizeof(*ip6))) { 266 if (M_UNWRITABLE(m, sizeof(*ip6))) {
267 if ((m = m_pullup(m, sizeof(*ip6))) == NULL) 267 if ((m = m_pullup(m, sizeof(*ip6))) == NULL)
268 return; 268 return;
269 } 269 }
270 ip6 = mtod(m, struct ip6_hdr *); 270 ip6 = mtod(m, struct ip6_hdr *);
271 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 271 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
272 if (gifp->if_flags & IFF_LINK1) 272 if (gifp->if_flags & IFF_LINK1)
273 ip_ecn_egress(ECN_ALLOWED, &otos, &itos); 273 ip_ecn_egress(ECN_ALLOWED, &otos, &itos);
274 else 274 else
275 ip_ecn_egress(ECN_NOCARE, &otos, &itos); 275 ip_ecn_egress(ECN_NOCARE, &otos, &itos);
276 ip6->ip6_flow &= ~htonl(0xff << 20); 276 ip6->ip6_flow &= ~htonl(0xff << 20);
277 ip6->ip6_flow |= htonl((u_int32_t)itos << 20); 277 ip6->ip6_flow |= htonl((u_int32_t)itos << 20);
278 break; 278 break;
279 } 279 }
280#endif /* INET6 */ 280#endif /* INET6 */
281 default: 281 default:
282 ip_statinc(IP_STAT_NOGIF); 282 ip_statinc(IP_STAT_NOGIF);
283 m_freem(m); 283 m_freem(m);
284 return; 284 return;
285 } 285 }
286 gif_input(m, af, gifp); 286 gif_input(m, af, gifp);
287 return; 287 return;
288} 288}
289 289
290/* 290/*
291 * validate outer address. 291 * validate outer address.
292 */ 292 */
293static int 293static int
294gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) 294gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp)
295{ 295{
296 struct sockaddr_in *src, *dst; 296 struct sockaddr_in *src, *dst;
297 struct in_ifaddr *ia4; 297 struct in_ifaddr *ia4;
298 298
299 src = satosin(sc->gif_psrc); 299 src = satosin(sc->gif_psrc);
300 dst = satosin(sc->gif_pdst); 300 dst = satosin(sc->gif_pdst);
301 301
302 /* check for address match */ 302 /* check for address match */
303 if (src->sin_addr.s_addr != ip->ip_dst.s_addr || 303 if (src->sin_addr.s_addr != ip->ip_dst.s_addr ||
304 dst->sin_addr.s_addr != ip->ip_src.s_addr) 304 dst->sin_addr.s_addr != ip->ip_src.s_addr)
305 return 0; 305 return 0;
306 306
307 /* martian filters on outer source - NOT done in ip_input! */ 307 /* martian filters on outer source - NOT done in ip_input! */
308 if (IN_MULTICAST(ip->ip_src.s_addr)) 308 if (IN_MULTICAST(ip->ip_src.s_addr))
309 return 0; 309 return 0;
310 switch ((ntohl(ip->ip_src.s_addr) & 0xff000000) >> 24) { 310 switch ((ntohl(ip->ip_src.s_addr) & 0xff000000) >> 24) {
311 case 0: case 127: case 255: 311 case 0: case 127: case 255:
312 return 0; 312 return 0;
313 } 313 }
314 /* reject packets with broadcast on source */ 314 /* reject packets with broadcast on source */
315 TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_list) { 315 TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_list) {
316 if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0) 316 if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0)
317 continue; 317 continue;
318 if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr) 318 if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr)
319 return 0; 319 return 0;
320 } 320 }
321 321
322 /* ingress filters on outer source */ 322 /* ingress filters on outer source */
323 if ((sc->gif_if.if_flags & IFF_LINK2) == 0 && ifp) { 323 if ((sc->gif_if.if_flags & IFF_LINK2) == 0 && ifp) {
324 union { 324 union {
325 struct sockaddr sa; 325 struct sockaddr sa;
326 struct sockaddr_in sin; 326 struct sockaddr_in sin;
327 } u; 327 } u;
328 struct rtentry *rt; 328 struct rtentry *rt;
329 329
330 sockaddr_in_init(&u.sin, &ip->ip_src, 0); 330 sockaddr_in_init(&u.sin, &ip->ip_src, 0);
331 rt = rtalloc1(&u.sa, 0); 331 rt = rtalloc1(&u.sa, 0);
332 if (rt == NULL || rt->rt_ifp != ifp) { 332 if (rt == NULL || rt->rt_ifp != ifp) {
333#if 0 333#if 0
334 log(LOG_WARNING, "%s: packet from 0x%x dropped " 334 log(LOG_WARNING, "%s: packet from 0x%x dropped "
335 "due to ingress filter\n", if_name(&sc->gif_if), 335 "due to ingress filter\n", if_name(&sc->gif_if),
336 (u_int32_t)ntohl(u.sin.sin_addr.s_addr)); 336 (u_int32_t)ntohl(u.sin.sin_addr.s_addr));
337#endif 337#endif
338 if (rt != NULL) 338 if (rt != NULL)
339 rtfree(rt); 339 rtfree(rt);
340 return 0; 340 return 0;
341 } 341 }
342 rtfree(rt); 342 rtfree(rt);
343 } 343 }
344 344
345 return 32 * 2; 345 return 32 * 2;
346} 346}
347 347
348#ifdef GIF_ENCAPCHECK 348#ifdef GIF_ENCAPCHECK
349/* 349/*
350 * we know that we are in IFF_UP, outer address available, and outer family 350 * we know that we are in IFF_UP, outer address available, and outer family
351 * matched the physical addr family. see gif_encapcheck(). 351 * matched the physical addr family. see gif_encapcheck().
352 */ 352 */
353int 353int
354gif_encapcheck4(struct mbuf *m, int off, int proto, void *arg) 354gif_encapcheck4(struct mbuf *m, int off, int proto, void *arg)
355{ 355{
356 struct ip ip; 356 struct ip ip;
357 struct gif_softc *sc; 357 struct gif_softc *sc;
358 struct ifnet *ifp; 358 struct ifnet *ifp;
359 359
360 /* sanity check done in caller */ 360 /* sanity check done in caller */
361 sc = arg; 361 sc = arg;
362 362
363 m_copydata(m, 0, sizeof(ip), &ip); 363 m_copydata(m, 0, sizeof(ip), &ip);
364 ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL; 364 ifp = ((m->m_flags & M_PKTHDR) != 0) ? m->m_pkthdr.rcvif : NULL;
365 365
366 return gif_validate4(&ip, sc, ifp); 366 return gif_validate4(&ip, sc, ifp);
367} 367}
368#endif 368#endif
369 369
370int 370int
371in_gif_attach(struct gif_softc *sc) 371in_gif_attach(struct gif_softc *sc)
372{ 372{
373#ifndef GIF_ENCAPCHECK 373#ifndef GIF_ENCAPCHECK
374 struct sockaddr_in mask4; 374 struct sockaddr_in mask4;
375 375
376 memset(&mask4, 0, sizeof(mask4)); 376 memset(&mask4, 0, sizeof(mask4));
377 mask4.sin_len = sizeof(struct sockaddr_in); 377 mask4.sin_len = sizeof(struct sockaddr_in);
378 mask4.sin_addr.s_addr = ~0; 378 mask4.sin_addr.s_addr = ~0;
379 379
380 if (!sc->gif_psrc || !sc->gif_pdst) 380 if (!sc->gif_psrc || !sc->gif_pdst)
381 return EINVAL; 381 return EINVAL;
382 sc->encap_cookie4 = encap_attach(AF_INET, -1, sc->gif_psrc, 382 sc->encap_cookie4 = encap_attach(AF_INET, -1, sc->gif_psrc,
383 (struct sockaddr *)&mask4, sc->gif_pdst, (struct sockaddr *)&mask4, 383 (struct sockaddr *)&mask4, sc->gif_pdst, (struct sockaddr *)&mask4,
384 (const struct protosw *)&in_gif_protosw, sc); 384 (const struct protosw *)&in_gif_protosw, sc);
385#else 385#else
386 sc->encap_cookie4 = encap_attach_func(AF_INET, -1, gif_encapcheck, 386 sc->encap_cookie4 = encap_attach_func(AF_INET, -1, gif_encapcheck,
387 &in_gif_protosw, sc); 387 &in_gif_protosw, sc);
388#endif 388#endif
389 if (sc->encap_cookie4 == NULL) 389 if (sc->encap_cookie4 == NULL)
390 return EEXIST; 390 return EEXIST;
391 return 0; 391 return 0;
392} 392}
393 393
 394#ifdef notdef
394int 395int
395in_gif_pause(struct gif_softc *sc) 396in_gif_pause(struct gif_softc *sc)
396{ 397{
397 int error; 398 int error;
398 399
399 error = encap_detach(sc->encap_cookie4); 400 error = encap_detach(sc->encap_cookie4);
400 if (error == 0) 401 if (error == 0)
401 sc->encap_cookie4 = NULL; 402 sc->encap_cookie4 = NULL;
402 403
403 return error; 404 return error;
404} 405}
 406#endif
405 407
406int 408int
407in_gif_detach(struct gif_softc *sc) 409in_gif_detach(struct gif_softc *sc)
408{ 410{
409 411
410 rtcache_free(&sc->gif_ro); 412 rtcache_free(&sc->gif_ro);
411 413
412 return 0; 414 return 0;
413} 415}