xref: /openbsd-src/sys/net/if_etherip.c (revision d59bb9942320b767f2a19aaa7690c8c6e30b724c)
1 /*	$OpenBSD: if_etherip.c,v 1.14 2017/01/29 19:58:47 bluhm Exp $	*/
2 /*
3  * Copyright (c) 2015 Kazuya GODA <goda@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "bpfilter.h"
19 #include "pf.h"
20 #include "gif.h"
21 
22 #include <sys/param.h>
23 #include <sys/systm.h>
24 #include <sys/mbuf.h>
25 #include <sys/socket.h>
26 #include <sys/ioctl.h>
27 #include <sys/device.h>
28 #include <sys/sysctl.h>
29 
30 #include <net/if.h>
31 #include <net/if_var.h>
32 #include <net/if_dl.h>
33 #include <net/if_media.h>
34 
35 #include <netinet/in.h>
36 #include <netinet/ip.h>
37 #include <netinet/ip_var.h>
38 #include <netinet/if_ether.h>
39 #include <netinet/ip_ether.h>
40 
41 #ifdef INET6
42 #include <netinet/ip6.h>
43 #include <netinet6/ip6_var.h>
44 #endif
45 
46 #if NBPFILTER > 0
47 #include <net/bpf.h>
48 #endif
49 
50 #if NPF > 0
51 #include <net/pfvar.h>
52 #endif
53 
54 #include <net/if_etherip.h>
55 
56 struct etherip_softc {
57 	struct arpcom sc_ac;
58 	struct ifmedia sc_media;
59 	unsigned int sc_rdomain;
60 	struct sockaddr_storage sc_src;
61 	struct sockaddr_storage sc_dst;
62 	LIST_ENTRY(etherip_softc) sc_entry;
63 };
64 
65 LIST_HEAD(, etherip_softc) etherip_softc_list;
66 
67 #if 0
68 /*
69  * TODO:
70  *   At this stage, etherip_allow and etheripstat are defined
71  *   at netinet/ip_ether.c. When implementation of etherip is
72  *   removed from gif(4), there are moved here.
73  */
74 
75 /*
76  * We can control the acceptance of EtherIP packets by altering the sysctl
77  * net.inet.etherip.allow value. Zero means drop them, all else is acceptance.
78  */
79 int etherip_allow = 0;
80 
81 struct etheripstat etheripstat;
82 #endif
83 
84 void etheripattach(int);
85 int etherip_clone_create(struct if_clone *, int);
86 int etherip_clone_destroy(struct ifnet *);
87 int etherip_ioctl(struct ifnet *, u_long, caddr_t);
88 void etherip_start(struct ifnet *);
89 int etherip_media_change(struct ifnet *);
90 void etherip_media_status(struct ifnet *, struct ifmediareq *);
91 int etherip_set_tunnel_addr(struct ifnet *, struct sockaddr_storage *,
92    struct sockaddr_storage *);
93 
94 struct if_clone	etherip_cloner = IF_CLONE_INITIALIZER("etherip",
95     etherip_clone_create, etherip_clone_destroy);
96 
97 
98 void
99 etheripattach(int count)
100 {
101 	if_clone_attach(&etherip_cloner);
102 }
103 
104 int
105 etherip_clone_create(struct if_clone *ifc, int unit)
106 {
107 	struct ifnet *ifp;
108 	struct etherip_softc *sc;
109 
110 	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
111 		return ENOMEM;
112 
113 	ifp = &sc->sc_ac.ac_if;
114 	snprintf(ifp->if_xname, sizeof ifp->if_xname, "etherip%d", unit);
115 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
116 	ether_fakeaddr(ifp);
117 
118 	ifp->if_softc = sc;
119 	ifp->if_ioctl = etherip_ioctl;
120 	ifp->if_start = etherip_start;
121 	ifp->if_xflags = IFXF_CLONED;
122 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
123 
124 	ifp->if_capabilities = IFCAP_VLAN_MTU;
125 
126 	ifmedia_init(&sc->sc_media, 0, etherip_media_change,
127 	    etherip_media_status);
128 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
129 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
130 
131 	if_attach(ifp);
132 	ether_ifattach(ifp);
133 
134 	LIST_INSERT_HEAD(&etherip_softc_list, sc, sc_entry);
135 
136 	return 0;
137 }
138 
139 int
140 etherip_clone_destroy(struct ifnet *ifp)
141 {
142 	struct etherip_softc *sc = ifp->if_softc;
143 
144 	LIST_REMOVE(sc, sc_entry);
145 
146 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
147 	ether_ifdetach(ifp);
148 	if_detach(ifp);
149 	free(sc, M_DEVBUF, sizeof(*sc));
150 
151 	return 0;
152 }
153 
154 int
155 etherip_media_change(struct ifnet *ifp)
156 {
157 	return 0;
158 }
159 
160 void
161 etherip_media_status(struct ifnet *ifp, struct ifmediareq *imr)
162 {
163 	imr->ifm_active = IFM_ETHER | IFM_AUTO;
164 	imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
165 }
166 
167 void
168 etherip_start(struct ifnet *ifp)
169 {
170 	struct etherip_softc *sc = ifp->if_softc;
171 	struct mbuf *m;
172 	int error;
173 
174 	for (;;) {
175 		IFQ_DEQUEUE(&ifp->if_snd, m);
176 		if (m == NULL)
177 			break;
178 
179 #if NBPFILTER > 0
180 		if (ifp->if_bpf)
181 			bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
182 #endif
183 		if (sc->sc_src.ss_family == AF_UNSPEC ||
184 		    sc->sc_dst.ss_family == AF_UNSPEC) {
185 			m_freem(m);
186 			continue;
187 		}
188 
189 		switch (sc->sc_src.ss_family) {
190 		case AF_INET:
191 			error = ip_etherip_output(ifp, m);
192 			break;
193 #ifdef INET6
194 		case AF_INET6:
195 			error = ip6_etherip_output(ifp, m);
196 			break;
197 #endif
198 		default:
199 			unhandled_af(sc->sc_src.ss_family);
200 		}
201 
202 		if (error)
203 			ifp->if_oerrors++;
204 	}
205 
206 }
207 
208 
209 int
210 etherip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
211 {
212 	struct etherip_softc *sc = ifp->if_softc;
213 	struct if_laddrreq *lifr = (struct if_laddrreq *)data;
214 	struct ifreq *ifr = (struct ifreq *)data;
215 	struct sockaddr_storage *src, *dst;
216 	struct proc *p = curproc;
217 	int error = 0;
218 
219 	switch (cmd) {
220 	case SIOCSIFADDR:
221 		ifp->if_flags |= IFF_UP;
222 		/* FALLTHROUGH */
223 
224 	case SIOCSIFFLAGS:
225 		if (ifp->if_flags & IFF_UP)
226 			ifp->if_flags |= IFF_RUNNING;
227 		else
228 			ifp->if_flags &= ~IFF_RUNNING;
229 
230 		break;
231 
232 	case SIOCSLIFPHYRTABLE:
233 		if ((error = suser(p, 0)) != 0)
234 			break;
235 
236 		if (ifr->ifr_rdomainid < 0 ||
237 		    ifr->ifr_rdomainid > RT_TABLEID_MAX ||
238 		    !rtable_exists(ifr->ifr_rdomainid)) {
239 			error = EINVAL;
240 			break;
241 		}
242 		sc->sc_rdomain = ifr->ifr_rdomainid;
243 		break;
244 
245 	case SIOCGLIFPHYRTABLE:
246 		ifr->ifr_rdomainid = sc->sc_rdomain;
247 		break;
248 
249 	case SIOCSLIFPHYADDR:
250 		if ((error = suser(p, 0)) != 0)
251 			break;
252 
253 		src = &lifr->addr;
254 		dst = &lifr->dstaddr;
255 		if (src->ss_family == AF_UNSPEC || dst->ss_family == AF_UNSPEC)
256 			return EADDRNOTAVAIL;
257 
258 		switch (src->ss_family) {
259 		case AF_INET:
260 			if (src->ss_len != sizeof(struct sockaddr_in) ||
261 			    dst->ss_len != sizeof(struct sockaddr_in))
262 				return EINVAL;
263 			break;
264 #ifdef INET6
265 		case AF_INET6:
266 			if (src->ss_len != sizeof(struct sockaddr_in6) ||
267 			    dst->ss_len != sizeof(struct sockaddr_in6))
268 				return EINVAL;
269 			break;
270 #endif
271 		default:
272 			return EAFNOSUPPORT;
273 		}
274 
275 		error = etherip_set_tunnel_addr(ifp, src, dst);
276 		break;
277 
278 	case SIOCDIFPHYADDR:
279 		if ((error = suser(p, 0)) != 0)
280 			break;
281 
282 		ifp->if_flags &= ~IFF_RUNNING;
283 		memset(&sc->sc_src, 0, sizeof(sc->sc_src));
284 		memset(&sc->sc_dst, 0, sizeof(sc->sc_dst));
285 		break;
286 
287 	case SIOCGLIFPHYADDR:
288 		if (sc->sc_dst.ss_family == AF_UNSPEC)
289 			return EADDRNOTAVAIL;
290 
291 		memset(&lifr->addr, 0, sizeof(lifr->addr));
292 		memset(&lifr->dstaddr, 0, sizeof(lifr->dstaddr));
293 		memcpy(&lifr->addr, &sc->sc_src, sc->sc_src.ss_len);
294 		memcpy(&lifr->dstaddr, &sc->sc_dst, sc->sc_dst.ss_len);
295 
296 		break;
297 
298 	case SIOCSIFMEDIA:
299 	case SIOCGIFMEDIA:
300 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
301 		break;
302 
303 	default:
304 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
305 		break;
306 	}
307 
308 	return error;
309 }
310 
311 int
312 etherip_set_tunnel_addr(struct ifnet *ifp, struct sockaddr_storage *src,
313     struct sockaddr_storage *dst)
314 {
315 	struct etherip_softc *sc, *tsc;
316 	int error = 0;
317 
318 	sc  = ifp->if_softc;
319 
320 	LIST_FOREACH(tsc, &etherip_softc_list, sc_entry) {
321 		if (tsc == sc)
322 			continue;
323 
324 		if (tsc->sc_src.ss_family != src->ss_family ||
325 		    tsc->sc_dst.ss_family != dst->ss_family ||
326 		    tsc->sc_src.ss_len != src->ss_len ||
327 		    tsc->sc_dst.ss_len != dst->ss_len)
328 			continue;
329 
330 		if (tsc->sc_rdomain == sc->sc_rdomain &&
331 		    memcmp(&tsc->sc_dst, dst, dst->ss_len) == 0 &&
332 		    memcmp(&tsc->sc_src, src, src->ss_len) == 0) {
333 			error = EADDRNOTAVAIL;
334 			goto out;
335 		}
336 	}
337 
338 	memcpy(&sc->sc_src, src, src->ss_len);
339 	memcpy(&sc->sc_dst, dst, dst->ss_len);
340 out:
341 	return error;
342 }
343 
344 int
345 ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
346 {
347 	struct etherip_softc *sc = (struct etherip_softc *)ifp->if_softc;
348 	struct sockaddr_in *src, *dst;
349 	struct etherip_header *eip;
350 	struct ip *ip;
351 
352 	src = (struct sockaddr_in *)&sc->sc_src;
353 	dst = (struct sockaddr_in *)&sc->sc_dst;
354 
355 	if (src == NULL || dst == NULL ||
356 	    src->sin_family != AF_INET || dst->sin_family != AF_INET) {
357 		m_freem(m);
358 		return EAFNOSUPPORT;
359 	}
360 	if (dst->sin_addr.s_addr == INADDR_ANY) {
361 		m_freem(m);
362 		return ENETUNREACH;
363 	}
364 
365 	m->m_flags &= ~(M_BCAST|M_MCAST);
366 
367 	M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
368 	if (m == NULL) {
369 		etheripstat.etherip_adrops++;
370 		return ENOBUFS;
371 	}
372 	eip = mtod(m, struct etherip_header *);
373 	eip->eip_ver = ETHERIP_VERSION;
374 	eip->eip_res = 0;
375 	eip->eip_pad = 0;
376 
377 	M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
378 	if (m == NULL) {
379 		etheripstat.etherip_adrops++;
380 		return ENOBUFS;
381 	}
382 	ip = mtod(m, struct ip *);
383 	memset(ip, 0, sizeof(struct ip));
384 
385 	ip->ip_v = IPVERSION;
386 	ip->ip_hl = sizeof(struct ip) >> 2;
387 	ip->ip_id = htons(ip_randomid());
388 	ip->ip_tos = IPTOS_LOWDELAY;
389 	ip->ip_p = IPPROTO_ETHERIP;
390 	ip->ip_len = htons(m->m_pkthdr.len);
391 	ip->ip_ttl = IPDEFTTL;
392 	ip->ip_src = src->sin_addr;
393 	ip->ip_dst = dst->sin_addr;
394 
395 	m->m_pkthdr.ph_rtableid = sc->sc_rdomain;
396 
397 #if NPF > 0
398 	pf_pkt_addr_changed(m);
399 #endif
400 	etheripstat.etherip_opackets++;
401 	etheripstat.etherip_obytes += (m->m_pkthdr.len -
402 	    (sizeof(struct ip) + sizeof(struct etherip_header)));
403 
404 	return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL, 0);
405 }
406 
407 int
408 ip_etherip_input(struct mbuf **mp, int *offp, int proto)
409 {
410 	struct mbuf *m = *mp;
411 	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
412 	struct etherip_softc *sc;
413 	const struct ip *ip;
414 	struct etherip_header *eip;
415 	struct sockaddr_in *src, *dst;
416 	struct ifnet *ifp = NULL;
417 
418 	ip = mtod(m, struct ip *);
419 
420 	if (ip->ip_p != IPPROTO_ETHERIP) {
421 		m_freem(m);
422 		ipstat_inc(ips_noproto);
423 		return IPPROTO_DONE;
424 	}
425 
426 	if (!etherip_allow) {
427 		m_freem(m);
428 		etheripstat.etherip_pdrops++;
429 		return IPPROTO_DONE;
430 	}
431 
432 	LIST_FOREACH(sc, &etherip_softc_list, sc_entry) {
433 		if (sc->sc_src.ss_family != AF_INET ||
434 		    sc->sc_dst.ss_family != AF_INET)
435 			continue;
436 
437 		src = (struct sockaddr_in *)&sc->sc_src;
438 		dst = (struct sockaddr_in *)&sc->sc_dst;
439 
440 		if (sc->sc_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid) ||
441 		    src->sin_addr.s_addr != ip->ip_dst.s_addr ||
442 		    dst->sin_addr.s_addr != ip->ip_src.s_addr)
443 			continue;
444 
445 		ifp = &sc->sc_ac.ac_if;
446 		break;
447 	}
448 
449 	if (ifp == NULL) {
450 #if NGIF > 0
451 		/*
452 		 * This path is nessesary for gif(4) and etherip(4) coexistence.
453 		 * This is tricky but the path will be removed soon when
454 		 * implementation of etherip is removed from gif(4).
455 		 */
456 		return etherip_input(mp, offp, proto);
457 #else
458 		etheripstat.etherip_noifdrops++;
459 		m_freem(m);
460 		return IPPROTO_DONE;
461 #endif /* NGIF */
462 	}
463 
464 	m_adj(m, *offp);
465 	m = m_pullup(m, sizeof(struct etherip_header));
466 	if (m == NULL) {
467 		etheripstat.etherip_adrops++;
468 		return IPPROTO_DONE;
469 	}
470 
471 	eip = mtod(m, struct etherip_header *);
472 	if (eip->eip_ver != ETHERIP_VERSION || eip->eip_pad) {
473 		etheripstat.etherip_adrops++;
474 		m_freem(m);
475 		return IPPROTO_DONE;
476 	}
477 
478 	etheripstat.etherip_ipackets++;
479 	etheripstat.etherip_ibytes += (m->m_pkthdr.len -
480 	    sizeof(struct etherip_header));
481 
482 	m_adj(m, sizeof(struct etherip_header));
483 	m = m_pullup(m, sizeof(struct ether_header));
484 	if (m == NULL) {
485 		etheripstat.etherip_adrops++;
486 		return IPPROTO_DONE;
487 	}
488 	m->m_flags &= ~(M_BCAST|M_MCAST);
489 
490 #if NPF > 0
491 	pf_pkt_addr_changed(m);
492 #endif
493 
494 	ml_enqueue(&ml, m);
495 	if_input(ifp, &ml);
496 	return IPPROTO_DONE;
497 }
498 
499 #ifdef INET6
500 int
501 ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
502 {
503 	struct etherip_softc *sc = (struct etherip_softc *)ifp->if_softc;
504 	struct sockaddr_in6 *src, *dst;
505 	struct etherip_header *eip;
506 	struct ip6_hdr *ip6;
507 	int error;
508 
509 	src = (struct sockaddr_in6 *)&sc->sc_src;
510 	dst = (struct sockaddr_in6 *)&sc->sc_dst;
511 
512 	if (src == NULL || dst == NULL ||
513 	    src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6) {
514 		error = EAFNOSUPPORT;
515 		goto drop;
516 	}
517 	if (IN6_IS_ADDR_UNSPECIFIED(&dst->sin6_addr)) {
518 		error = ENETUNREACH;
519 		goto drop;
520 	}
521 
522 	m->m_flags &= ~(M_BCAST|M_MCAST);
523 
524 	M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
525 	if (m == NULL) {
526 		etheripstat.etherip_adrops++;
527 		return ENOBUFS;
528 	}
529 	eip = mtod(m, struct etherip_header *);
530 	eip->eip_ver = ETHERIP_VERSION;
531 	eip->eip_res = 0;
532 	eip->eip_pad = 0;
533 
534 	M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
535 	if (m == NULL) {
536 		etheripstat.etherip_adrops++;
537 		return ENOBUFS;
538 	}
539 	ip6 = mtod(m, struct ip6_hdr *);
540 	ip6->ip6_flow = 0;
541 	ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
542 	ip6->ip6_vfc |= IPV6_VERSION;
543 	ip6->ip6_nxt  = IPPROTO_ETHERIP;
544 	ip6->ip6_hlim = ip6_defhlim;
545 	ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
546 	error = in6_embedscope(&ip6->ip6_src, src, NULL);
547 	if (error != 0)
548 		goto drop;
549 	error = in6_embedscope(&ip6->ip6_dst, dst, NULL);
550 	if (error != 0)
551 		goto drop;
552 
553 	m->m_pkthdr.ph_rtableid = sc->sc_rdomain;
554 
555 #if NPF > 0
556 	pf_pkt_addr_changed(m);
557 #endif
558 	etheripstat.etherip_opackets++;
559 	etheripstat.etherip_obytes += (m->m_pkthdr.len -
560 	    (sizeof(struct ip6_hdr) + sizeof(struct etherip_header)));
561 
562 	return ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL);
563 
564 drop:
565 	m_freem(m);
566 	return (error);
567 }
568 
569 int
570 ip6_etherip_input(struct mbuf **mp, int *offp, int proto)
571 {
572 	struct mbuf *m = *mp;
573 	struct mbuf_list ml = MBUF_LIST_INITIALIZER();
574 	struct etherip_softc *sc;
575 	const struct ip6_hdr *ip6;
576 	struct etherip_header *eip;
577 	struct sockaddr_in6 ipsrc, ipdst;
578 	struct sockaddr_in6 *src6, *dst6;
579 	struct ifnet *ifp = NULL;
580 
581 
582 	if (!etherip_allow) {
583 		m_freem(m);
584 		etheripstat.etherip_pdrops++;
585 		return IPPROTO_NONE;
586 	}
587 
588 	ip6 = mtod(m, const struct ip6_hdr *);
589 	in6_recoverscope(&ipsrc, &ip6->ip6_src);
590 	in6_recoverscope(&ipdst, &ip6->ip6_dst);
591 
592 	LIST_FOREACH(sc, &etherip_softc_list, sc_entry) {
593 		if (sc->sc_src.ss_family != AF_INET6 ||
594 		    sc->sc_dst.ss_family != AF_INET6)
595 			continue;
596 
597 		src6 = (struct sockaddr_in6 *)&sc->sc_src;
598 		dst6 = (struct sockaddr_in6 *)&sc->sc_dst;
599 
600 		if (IN6_ARE_ADDR_EQUAL(&src6->sin6_addr, &ipdst.sin6_addr) &&
601 		    src6->sin6_scope_id == ipdst.sin6_scope_id &&
602 		    IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, &ipsrc.sin6_addr) &&
603 		    dst6->sin6_scope_id == ipsrc.sin6_scope_id) {
604 			ifp = &sc->sc_ac.ac_if;
605 			break;
606 		}
607 	}
608 
609 	if (ifp == NULL) {
610 #if NGIF > 0
611 		/*
612 		 * This path is nessesary for gif(4) and etherip(4) coexistence.
613 		 * This is tricky but the path will be removed soon when
614 		 * implementation of etherip is removed from gif(4).
615 		 */
616 		return etherip_input(mp, offp, proto);
617 #else
618 		etheripstat.etherip_noifdrops++;
619 		m_freem(m);
620 		return IPPROTO_DONE;
621 #endif /* NGIF */
622 	}
623 
624 	m_adj(m, *offp);
625 	m = m_pullup(m, sizeof(struct etherip_header));
626 	if (m == NULL) {
627 		etheripstat.etherip_adrops++;
628 		return IPPROTO_DONE;
629 	}
630 
631 	eip = mtod(m, struct etherip_header *);
632 	if ((eip->eip_ver != ETHERIP_VERSION) || eip->eip_pad) {
633 		etheripstat.etherip_adrops++;
634 		m_freem(m);
635 		return IPPROTO_DONE;
636 	}
637 	etheripstat.etherip_ipackets++;
638 	etheripstat.etherip_ibytes += (m->m_pkthdr.len -
639 	    sizeof(struct etherip_header));
640 
641 	m_adj(m, sizeof(struct etherip_header));
642 	m = m_pullup(m, sizeof(struct ether_header));
643 	if (m == NULL) {
644 		etheripstat.etherip_adrops++;
645 		return IPPROTO_DONE;
646 	}
647 
648 	m->m_flags &= ~(M_BCAST|M_MCAST);
649 
650 #if NPF > 0
651 	pf_pkt_addr_changed(m);
652 #endif
653 
654 	ml_enqueue(&ml, m);
655 	if_input(ifp, &ml);
656 	return IPPROTO_DONE;
657 }
658 #endif /* INET6 */
659 
660 int
661 ip_etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
662     void *newp, size_t newlen)
663 {
664 	/* All sysctl names at this level are terminal. */
665 	if (namelen != 1)
666 		return ENOTDIR;
667 
668 	switch (name[0]) {
669 	case ETHERIPCTL_ALLOW:
670 		return sysctl_int(oldp, oldlenp, newp, newlen, &etherip_allow);
671 	case ETHERIPCTL_STATS:
672 		if (newp != NULL)
673 			return EPERM;
674 		return sysctl_struct(oldp, oldlenp, newp, newlen,
675 		    &etheripstat, sizeof(etheripstat));
676 	default:
677 		break;
678 	}
679 
680 	return ENOPROTOOPT;
681 }
682