xref: /openbsd/sys/net/if_etherip.c (revision 02e922b0)
1 /*	$OpenBSD: if_etherip.c,v 1.56 2024/08/20 07:47:25 mvs 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 
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/mbuf.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include <sys/device.h>
27 #include <sys/sysctl.h>
28 #include <sys/tree.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 #include <net/route.h>
35 #include <net/rtable.h>
36 
37 #include <netinet/in.h>
38 #include <netinet/ip.h>
39 #include <netinet/ip_var.h>
40 #include <netinet/if_ether.h>
41 #include <netinet/ip_ether.h>
42 
43 #ifdef INET6
44 #include <netinet/ip6.h>
45 #include <netinet6/ip6_var.h>
46 #endif
47 
48 #if NBPFILTER > 0
49 #include <net/bpf.h>
50 #endif
51 
52 #if NPF > 0
53 #include <net/pfvar.h>
54 #endif
55 
56 #include <net/if_etherip.h>
57 
58 /*
59  * Locks used to protect data:
60  *	a	atomic
61  */
62 
63 union etherip_addr {
64 	struct in_addr	in4;
65 	struct in6_addr	in6;
66 };
67 
68 struct etherip_tunnel {
69 	union etherip_addr
70 			_t_src;
71 #define t_src4	_t_src.in4
72 #define t_src6	_t_src.in6
73 	union etherip_addr
74 			_t_dst;
75 #define t_dst4	_t_dst.in4
76 #define t_dst6	_t_dst.in6
77 
78 	unsigned int	t_rtableid;
79 	sa_family_t	t_af;
80 	uint8_t		t_tos;
81 
82 	TAILQ_ENTRY(etherip_tunnel)
83 			t_entry;
84 };
85 
86 TAILQ_HEAD(etherip_list, etherip_tunnel);
87 
88 static inline int etherip_cmp(const struct etherip_tunnel *,
89     const struct etherip_tunnel *);
90 
91 struct etherip_softc {
92 	struct etherip_tunnel	sc_tunnel; /* must be first */
93 	struct arpcom		sc_ac;
94 	struct ifmedia		sc_media;
95 	int			sc_txhprio;
96 	int			sc_rxhprio;
97 	uint16_t		sc_df;
98 	uint8_t			sc_ttl;
99 };
100 
101 /*
102  * We can control the acceptance of EtherIP packets by altering the sysctl
103  * net.inet.etherip.allow value. Zero means drop them, all else is acceptance.
104  */
105 int etherip_allow = 0;	/* [a] */
106 
107 struct cpumem *etheripcounters;
108 
109 void etheripattach(int);
110 int etherip_clone_create(struct if_clone *, int);
111 int etherip_clone_destroy(struct ifnet *);
112 int etherip_ioctl(struct ifnet *, u_long, caddr_t);
113 int etherip_output(struct ifnet *, struct mbuf *, struct sockaddr *,
114     struct rtentry *);
115 void etherip_start(struct ifnet *);
116 int etherip_media_change(struct ifnet *);
117 void etherip_media_status(struct ifnet *, struct ifmediareq *);
118 int etherip_set_tunnel(struct etherip_softc *, struct if_laddrreq *);
119 int etherip_get_tunnel(struct etherip_softc *, struct if_laddrreq *);
120 int etherip_del_tunnel(struct etherip_softc *);
121 int etherip_up(struct etherip_softc *);
122 int etherip_down(struct etherip_softc *);
123 struct etherip_softc *etherip_find(const struct etherip_tunnel *);
124 int etherip_input(struct etherip_tunnel *, struct mbuf *, uint8_t, int);
125 
126 struct if_clone	etherip_cloner = IF_CLONE_INITIALIZER("etherip",
127     etherip_clone_create, etherip_clone_destroy);
128 
129 struct etherip_list etherip_list = TAILQ_HEAD_INITIALIZER(etherip_list);
130 
131 void
etheripattach(int count)132 etheripattach(int count)
133 {
134 	if_clone_attach(&etherip_cloner);
135 	etheripcounters = counters_alloc(etherips_ncounters);
136 }
137 
138 int
etherip_clone_create(struct if_clone * ifc,int unit)139 etherip_clone_create(struct if_clone *ifc, int unit)
140 {
141 	struct ifnet *ifp;
142 	struct etherip_softc *sc;
143 
144 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
145 	ifp = &sc->sc_ac.ac_if;
146 
147 	snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d",
148 	    ifc->ifc_name, unit);
149 
150 	sc->sc_ttl = ip_defttl;
151 	sc->sc_txhprio = IFQ_TOS2PRIO(IPTOS_PREC_ROUTINE); /* 0 */
152 	sc->sc_rxhprio = IF_HDRPRIO_PACKET;
153 	sc->sc_df = htons(0);
154 
155 	ifp->if_softc = sc;
156 	ifp->if_hardmtu = ETHER_MAX_HARDMTU_LEN;
157 	ifp->if_ioctl = etherip_ioctl;
158 	ifp->if_output = etherip_output;
159 	ifp->if_start = etherip_start;
160 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
161 	ifp->if_xflags = IFXF_CLONED;
162 	ifp->if_capabilities = IFCAP_VLAN_MTU;
163 	ether_fakeaddr(ifp);
164 
165 	ifmedia_init(&sc->sc_media, 0, etherip_media_change,
166 	    etherip_media_status);
167 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
168 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
169 
170 	if_counters_alloc(ifp);
171 	if_attach(ifp);
172 	ether_ifattach(ifp);
173 
174 	NET_LOCK();
175 	TAILQ_INSERT_TAIL(&etherip_list, &sc->sc_tunnel, t_entry);
176 	NET_UNLOCK();
177 
178 	return (0);
179 }
180 
181 int
etherip_clone_destroy(struct ifnet * ifp)182 etherip_clone_destroy(struct ifnet *ifp)
183 {
184 	struct etherip_softc *sc = ifp->if_softc;
185 
186 	NET_LOCK();
187 	if (ISSET(ifp->if_flags, IFF_RUNNING))
188 		etherip_down(sc);
189 
190 	TAILQ_REMOVE(&etherip_list, &sc->sc_tunnel, t_entry);
191 	NET_UNLOCK();
192 
193 	ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
194 	ether_ifdetach(ifp);
195 	if_detach(ifp);
196 
197 	free(sc, M_DEVBUF, sizeof(*sc));
198 
199 	return (0);
200 }
201 
202 int
etherip_media_change(struct ifnet * ifp)203 etherip_media_change(struct ifnet *ifp)
204 {
205 	return 0;
206 }
207 
208 void
etherip_media_status(struct ifnet * ifp,struct ifmediareq * imr)209 etherip_media_status(struct ifnet *ifp, struct ifmediareq *imr)
210 {
211 	imr->ifm_active = IFM_ETHER | IFM_AUTO;
212 	imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
213 }
214 
215 int
etherip_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt)216 etherip_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
217     struct rtentry *rt)
218 {
219  	struct m_tag *mtag;
220 
221 	mtag = NULL;
222 	while ((mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) != NULL) {
223 		if (*(int *)(mtag + 1) == ifp->if_index) {
224 			m_freem(m);
225 			return (EIO);
226 		}
227 	}
228 
229 	return (ether_output(ifp, m, dst, rt));
230 }
231 
232 void
etherip_start(struct ifnet * ifp)233 etherip_start(struct ifnet *ifp)
234 {
235 	struct etherip_softc *sc = ifp->if_softc;
236 	struct mbuf *m;
237 	int error;
238 #if NBPFILTER > 0
239 	caddr_t if_bpf;
240 #endif
241 
242 	while ((m = ifq_dequeue(&ifp->if_snd)) != NULL) {
243 #if NBPFILTER > 0
244 		if_bpf = ifp->if_bpf;
245 		if (if_bpf)
246 			bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_OUT);
247 #endif
248 
249 		switch (sc->sc_tunnel.t_af) {
250 		case AF_INET:
251 			error = ip_etherip_output(ifp, m);
252 			break;
253 #ifdef INET6
254 		case AF_INET6:
255 			error = ip6_etherip_output(ifp, m);
256 			break;
257 #endif
258 		default:
259 			/* unhandled_af(sc->sc_tunnel.t_af); */
260 			m_freem(m);
261 			continue;
262 		}
263 
264 		if (error)
265 			ifp->if_oerrors++;
266 	}
267 }
268 
269 int
etherip_ioctl(struct ifnet * ifp,u_long cmd,caddr_t data)270 etherip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
271 {
272 	struct etherip_softc *sc = ifp->if_softc;
273 	struct ifreq *ifr = (struct ifreq *)data;
274 	int error = 0;
275 
276 	switch (cmd) {
277 	case SIOCSIFADDR:
278 		ifp->if_flags |= IFF_UP;
279 		/* FALLTHROUGH */
280 
281 	case SIOCSIFFLAGS:
282 		if (ISSET(ifp->if_flags, IFF_UP)) {
283 			if (!ISSET(ifp->if_flags, IFF_RUNNING))
284 				error = etherip_up(sc);
285 			else
286 				error = 0;
287 		} else {
288 			if (ISSET(ifp->if_flags, IFF_RUNNING))
289 				error = etherip_down(sc);
290 		}
291 		break;
292 
293 	case SIOCSLIFPHYRTABLE:
294 		if (ifr->ifr_rdomainid < 0 ||
295 		    ifr->ifr_rdomainid > RT_TABLEID_MAX ||
296 		    !rtable_exists(ifr->ifr_rdomainid)) {
297 			error = EINVAL;
298 			break;
299 		}
300 		sc->sc_tunnel.t_rtableid = ifr->ifr_rdomainid;
301 		break;
302 
303 	case SIOCGLIFPHYRTABLE:
304 		ifr->ifr_rdomainid = sc->sc_tunnel.t_rtableid;
305 		break;
306 
307 	case SIOCSLIFPHYADDR:
308 		error = etherip_set_tunnel(sc, (struct if_laddrreq *)data);
309 		break;
310 	case SIOCGLIFPHYADDR:
311 		error = etherip_get_tunnel(sc, (struct if_laddrreq *)data);
312 		break;
313 	case SIOCDIFPHYADDR:
314 		error = etherip_del_tunnel(sc);
315 		break;
316 
317 	case SIOCSTXHPRIO:
318 		error = if_txhprio_l2_check(ifr->ifr_hdrprio);
319 		if (error != 0)
320 			break;
321 
322 		sc->sc_txhprio = ifr->ifr_hdrprio;
323 		break;
324 	case SIOCGTXHPRIO:
325 		ifr->ifr_hdrprio = sc->sc_txhprio;
326                 break;
327 
328 	case SIOCSRXHPRIO:
329 		error = if_rxhprio_l2_check(ifr->ifr_hdrprio);
330 		if (error != 0)
331 			break;
332 
333 		sc->sc_rxhprio = ifr->ifr_hdrprio;
334 		break;
335 	case SIOCGRXHPRIO:
336 		ifr->ifr_hdrprio = sc->sc_rxhprio;
337                 break;
338 
339 	case SIOCSLIFPHYTTL:
340 		if (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff) {
341 			error = EINVAL;
342 			break;
343 		}
344 
345 		/* commit */
346 		sc->sc_ttl = (uint8_t)ifr->ifr_ttl;
347 		break;
348 	case SIOCGLIFPHYTTL:
349 		ifr->ifr_ttl = (int)sc->sc_ttl;
350 		break;
351 
352 	case SIOCSLIFPHYDF:
353 		/* commit */
354 		sc->sc_df = ifr->ifr_df ? htons(IP_DF) : htons(0);
355 		break;
356 	case SIOCGLIFPHYDF:
357 		ifr->ifr_df = sc->sc_df ? 1 : 0;
358 		break;
359 
360 	case SIOCSIFMEDIA:
361 	case SIOCGIFMEDIA:
362 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
363 		break;
364 
365 	case SIOCADDMULTI:
366 	case SIOCDELMULTI:
367 		break;
368 
369 	default:
370 		error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
371 		break;
372 	}
373 
374 	if (error == ENETRESET) {
375 		/* no hardware to program */
376 		error = 0;
377 	}
378 
379 	return (error);
380 }
381 
382 int
etherip_set_tunnel(struct etherip_softc * sc,struct if_laddrreq * req)383 etherip_set_tunnel(struct etherip_softc *sc, struct if_laddrreq *req)
384 {
385 	struct sockaddr *src = (struct sockaddr *)&req->addr;
386 	struct sockaddr *dst = (struct sockaddr *)&req->dstaddr;
387 	struct sockaddr_in *src4, *dst4;
388 #ifdef INET6
389 	struct sockaddr_in6 *src6, *dst6;
390 	int error;
391 #endif
392 
393 	/* sa_family and sa_len must be equal */
394 	if (src->sa_family != dst->sa_family || src->sa_len != dst->sa_len)
395 		return (EINVAL);
396 
397 	/* validate */
398 	switch (dst->sa_family) {
399 	case AF_INET:
400 		if (dst->sa_len != sizeof(*dst4))
401 			return (EINVAL);
402 
403 		src4 = (struct sockaddr_in *)src;
404 		if (in_nullhost(src4->sin_addr) ||
405 		    IN_MULTICAST(src4->sin_addr.s_addr))
406 			return (EINVAL);
407 
408 		dst4 = (struct sockaddr_in *)dst;
409 		if (in_nullhost(dst4->sin_addr) ||
410 		    IN_MULTICAST(dst4->sin_addr.s_addr))
411 			return (EINVAL);
412 
413 		sc->sc_tunnel.t_src4 = src4->sin_addr;
414 		sc->sc_tunnel.t_dst4 = dst4->sin_addr;
415 		break;
416 #ifdef INET6
417 	case AF_INET6:
418 		if (dst->sa_len != sizeof(*dst6))
419 			return (EINVAL);
420 
421 		src6 = (struct sockaddr_in6 *)src;
422 		if (IN6_IS_ADDR_UNSPECIFIED(&src6->sin6_addr) ||
423 		    IN6_IS_ADDR_MULTICAST(&src6->sin6_addr))
424 			return (EINVAL);
425 
426 		dst6 = (struct sockaddr_in6 *)dst;
427 		if (IN6_IS_ADDR_UNSPECIFIED(&dst6->sin6_addr) ||
428 		    IN6_IS_ADDR_MULTICAST(&dst6->sin6_addr))
429 			return (EINVAL);
430 
431 		error = in6_embedscope(&sc->sc_tunnel.t_src6, src6, NULL, NULL);
432 		if (error != 0)
433 			return (error);
434 
435 		error = in6_embedscope(&sc->sc_tunnel.t_dst6, dst6, NULL, NULL);
436 		if (error != 0)
437 			return (error);
438 
439 		break;
440 #endif
441 	default:
442 		return (EAFNOSUPPORT);
443 	}
444 
445 	/* commit */
446 	sc->sc_tunnel.t_af = dst->sa_family;
447 
448 	return (0);
449 }
450 
451 int
etherip_get_tunnel(struct etherip_softc * sc,struct if_laddrreq * req)452 etherip_get_tunnel(struct etherip_softc *sc, struct if_laddrreq *req)
453 {
454 	struct sockaddr *src = (struct sockaddr *)&req->addr;
455 	struct sockaddr *dst = (struct sockaddr *)&req->dstaddr;
456 	struct sockaddr_in *sin;
457 #ifdef INET6 /* ifconfig already embeds the scopeid */
458 	struct sockaddr_in6 *sin6;
459 #endif
460 
461 	switch (sc->sc_tunnel.t_af) {
462 	case AF_UNSPEC:
463 		return (EADDRNOTAVAIL);
464 	case AF_INET:
465 		sin = (struct sockaddr_in *)src;
466 		memset(sin, 0, sizeof(*sin));
467 		sin->sin_family = AF_INET;
468 		sin->sin_len = sizeof(*sin);
469 		sin->sin_addr = sc->sc_tunnel.t_src4;
470 
471 		sin = (struct sockaddr_in *)dst;
472 		memset(sin, 0, sizeof(*sin));
473 		sin->sin_family = AF_INET;
474 		sin->sin_len = sizeof(*sin);
475 		sin->sin_addr = sc->sc_tunnel.t_dst4;
476 
477 		break;
478 #ifdef INET6
479 	case AF_INET6:
480 		sin6 = (struct sockaddr_in6 *)src;
481 		memset(sin6, 0, sizeof(*sin6));
482 		sin6->sin6_family = AF_INET6;
483 		sin6->sin6_len = sizeof(*sin6);
484 		in6_recoverscope(sin6, &sc->sc_tunnel.t_src6);
485 
486 		sin6 = (struct sockaddr_in6 *)dst;
487 		memset(sin6, 0, sizeof(*sin6));
488 		sin6->sin6_family = AF_INET6;
489 		sin6->sin6_len = sizeof(*sin6);
490 		in6_recoverscope(sin6, &sc->sc_tunnel.t_dst6);
491 
492 		break;
493 #endif
494 	default:
495 		return (EAFNOSUPPORT);
496 	}
497 
498 	return (0);
499 }
500 
501 int
etherip_del_tunnel(struct etherip_softc * sc)502 etherip_del_tunnel(struct etherip_softc *sc)
503 {
504 	/* commit */
505 	sc->sc_tunnel.t_af = AF_UNSPEC;
506 
507 	return (0);
508 }
509 
510 int
etherip_up(struct etherip_softc * sc)511 etherip_up(struct etherip_softc *sc)
512 {
513 	struct ifnet *ifp = &sc->sc_ac.ac_if;
514 
515 	NET_ASSERT_LOCKED();
516 
517 	SET(ifp->if_flags, IFF_RUNNING);
518 
519 	return (0);
520 }
521 
522 int
etherip_down(struct etherip_softc * sc)523 etherip_down(struct etherip_softc *sc)
524 {
525 	struct ifnet *ifp = &sc->sc_ac.ac_if;
526 
527 	NET_ASSERT_LOCKED();
528 
529 	CLR(ifp->if_flags, IFF_RUNNING);
530 
531 	return (0);
532 }
533 
534 int
ip_etherip_output(struct ifnet * ifp,struct mbuf * m)535 ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
536 {
537 	struct etherip_softc *sc = (struct etherip_softc *)ifp->if_softc;
538 	struct m_tag *mtag;
539 	struct etherip_header *eip;
540 	struct ip *ip;
541 
542 	M_PREPEND(m, sizeof(*ip) + sizeof(*eip), M_DONTWAIT);
543 	if (m == NULL) {
544 		etheripstat_inc(etherips_adrops);
545 		return ENOBUFS;
546 	}
547 
548 	ip = mtod(m, struct ip *);
549 	memset(ip, 0, sizeof(struct ip));
550 
551 	ip->ip_v = IPVERSION;
552 	ip->ip_hl = sizeof(*ip) >> 2;
553 	ip->ip_tos = IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ?
554 	    m->m_pkthdr.pf.prio : sc->sc_txhprio);
555 	ip->ip_len = htons(m->m_pkthdr.len);
556 	ip->ip_id = htons(ip_randomid());
557 	ip->ip_off = sc->sc_df;
558 	ip->ip_ttl = sc->sc_ttl;
559 	ip->ip_p = IPPROTO_ETHERIP;
560 	ip->ip_src = sc->sc_tunnel.t_src4;
561 	ip->ip_dst = sc->sc_tunnel.t_dst4;
562 
563 	eip = (struct etherip_header *)(ip + 1);
564 	eip->eip_ver = ETHERIP_VERSION;
565 	eip->eip_res = 0;
566 	eip->eip_pad = 0;
567 
568 	mtag = m_tag_get(PACKET_TAG_GRE, sizeof(ifp->if_index), M_NOWAIT);
569 	if (mtag == NULL) {
570 		m_freem(m);
571 		return (ENOMEM);
572 	}
573 
574 	*(int *)(mtag + 1) = ifp->if_index;
575 	m_tag_prepend(m, mtag);
576 
577 	m->m_flags &= ~(M_BCAST|M_MCAST);
578 	m->m_pkthdr.ph_rtableid = sc->sc_tunnel.t_rtableid;
579 
580 #if NPF > 0
581 	pf_pkt_addr_changed(m);
582 #endif
583 	etheripstat_pkt(etherips_opackets, etherips_obytes, m->m_pkthdr.len -
584 	    (sizeof(struct ip) + sizeof(struct etherip_header)));
585 
586 	ip_send(m);
587 
588 	return (0);
589 }
590 
591 int
ip_etherip_input(struct mbuf ** mp,int * offp,int type,int af)592 ip_etherip_input(struct mbuf **mp, int *offp, int type, int af)
593 {
594 	struct mbuf *m = *mp;
595 	struct etherip_tunnel key;
596 	struct ip *ip;
597 
598 	ip = mtod(m, struct ip *);
599 
600 	key.t_af = AF_INET;
601 	key.t_src4 = ip->ip_dst;
602 	key.t_dst4 = ip->ip_src;
603 
604 	return (etherip_input(&key, m, ip->ip_tos, *offp));
605 }
606 
607 struct etherip_softc *
etherip_find(const struct etherip_tunnel * key)608 etherip_find(const struct etherip_tunnel *key)
609 {
610 	struct etherip_tunnel *t;
611 	struct etherip_softc *sc;
612 
613 	TAILQ_FOREACH(t, &etherip_list, t_entry) {
614 		if (etherip_cmp(key, t) != 0)
615 			continue;
616 
617 		sc = (struct etherip_softc *)t;
618 		if (!ISSET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING))
619 			continue;
620 
621 		return (sc);
622 	}
623 
624 	return (NULL);
625 }
626 
627 int
etherip_input(struct etherip_tunnel * key,struct mbuf * m,uint8_t tos,int hlen)628 etherip_input(struct etherip_tunnel *key, struct mbuf *m, uint8_t tos,
629     int hlen)
630 {
631 	struct etherip_softc *sc;
632 	struct ifnet *ifp;
633 	struct etherip_header *eip;
634 	int rxprio;
635 
636 	if (atomic_load_int(&etherip_allow) == 0 &&
637 	    (m->m_flags & (M_AUTH|M_CONF)) == 0) {
638 		etheripstat_inc(etherips_pdrops);
639 		goto drop;
640 	}
641 
642 	key->t_rtableid = m->m_pkthdr.ph_rtableid;
643 
644 	NET_ASSERT_LOCKED();
645 	sc = etherip_find(key);
646 	if (sc == NULL) {
647 		etheripstat_inc(etherips_noifdrops);
648 		goto drop;
649 	}
650 
651 	m_adj(m, hlen);
652 	m = m_pullup(m, sizeof(*eip));
653 	if (m == NULL) {
654 		etheripstat_inc(etherips_adrops);
655 		return IPPROTO_DONE;
656 	}
657 
658 	eip = mtod(m, struct etherip_header *);
659 	if (eip->eip_ver != ETHERIP_VERSION || eip->eip_pad) {
660 		etheripstat_inc(etherips_adrops);
661 		goto drop;
662 	}
663 
664 	m_adj(m, sizeof(struct etherip_header));
665 
666 	etheripstat_pkt(etherips_ipackets, etherips_ibytes, m->m_pkthdr.len);
667 
668 	m = m_pullup(m, sizeof(struct ether_header));
669 	if (m == NULL) {
670 		etheripstat_inc(etherips_adrops);
671 		return IPPROTO_DONE;
672 	}
673 
674 	rxprio = sc->sc_rxhprio;
675 	switch (rxprio) {
676 	case IF_HDRPRIO_PACKET:
677 		break;
678 	case IF_HDRPRIO_OUTER:
679 		m->m_pkthdr.pf.prio = IFQ_TOS2PRIO(tos);
680 		break;
681 	default:
682 		m->m_pkthdr.pf.prio = rxprio;
683 		break;
684 	}
685 
686 	ifp = &sc->sc_ac.ac_if;
687 
688 	m->m_flags &= ~(M_BCAST|M_MCAST);
689 	m->m_pkthdr.ph_ifidx = ifp->if_index;
690 	m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
691 
692 #if NPF > 0
693 	pf_pkt_addr_changed(m);
694 #endif
695 
696 	if_vinput(ifp, m);
697 	return IPPROTO_DONE;
698 
699 drop:
700 	m_freem(m);
701 	return (IPPROTO_DONE);
702 }
703 
704 #ifdef INET6
705 int
ip6_etherip_output(struct ifnet * ifp,struct mbuf * m)706 ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
707 {
708 	struct etherip_softc *sc = ifp->if_softc;
709 	struct m_tag *mtag;
710 	struct ip6_hdr *ip6;
711 	struct etherip_header *eip;
712 	uint16_t len;
713 	uint32_t flow;
714 
715 	if (IN6_IS_ADDR_UNSPECIFIED(&sc->sc_tunnel.t_dst6)) {
716 		m_freem(m);
717 		return (ENETUNREACH);
718 	}
719 
720 	len = m->m_pkthdr.len;
721 
722 	M_PREPEND(m, sizeof(*ip6) + sizeof(*eip), M_DONTWAIT);
723 	if (m == NULL) {
724 		etheripstat_inc(etherips_adrops);
725 		return ENOBUFS;
726 	}
727 
728 	flow = IPV6_VERSION << 24;
729 	flow |= IFQ_PRIO2TOS(sc->sc_txhprio == IF_HDRPRIO_PACKET ?
730 	     m->m_pkthdr.pf.prio : sc->sc_txhprio) << 20;
731 
732 	ip6 = mtod(m, struct ip6_hdr *);
733 	htobem32(&ip6->ip6_flow, flow);
734 	ip6->ip6_nxt  = IPPROTO_ETHERIP;
735 	ip6->ip6_hlim = sc->sc_ttl;
736 	ip6->ip6_plen = htons(len);
737 	memcpy(&ip6->ip6_src, &sc->sc_tunnel.t_src6, sizeof(ip6->ip6_src));
738 	memcpy(&ip6->ip6_dst, &sc->sc_tunnel.t_dst6, sizeof(ip6->ip6_dst));
739 
740 	eip = (struct etherip_header *)(ip6 + 1);
741 	eip->eip_ver = ETHERIP_VERSION;
742 	eip->eip_res = 0;
743 	eip->eip_pad = 0;
744 
745 	mtag = m_tag_get(PACKET_TAG_GRE, sizeof(ifp->if_index), M_NOWAIT);
746 	if (mtag == NULL) {
747 		m_freem(m);
748 		return (ENOMEM);
749 	}
750 
751 	*(int *)(mtag + 1) = ifp->if_index;
752 	m_tag_prepend(m, mtag);
753 
754 	if (sc->sc_df)
755 		SET(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT);
756 
757 	m->m_flags &= ~(M_BCAST|M_MCAST);
758 	m->m_pkthdr.ph_rtableid = sc->sc_tunnel.t_rtableid;
759 
760 #if NPF > 0
761 	pf_pkt_addr_changed(m);
762 #endif
763 
764 	etheripstat_pkt(etherips_opackets, etherips_obytes, len);
765 
766 	ip6_send(m);
767 	return (0);
768 }
769 
770 int
ip6_etherip_input(struct mbuf ** mp,int * offp,int proto,int af)771 ip6_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
772 {
773 	struct mbuf *m = *mp;
774 	struct etherip_tunnel key;
775 	const struct ip6_hdr *ip6;
776 	uint32_t flow;
777 
778 	ip6 = mtod(m, const struct ip6_hdr *);
779 
780 	key.t_af = AF_INET6;
781 	key.t_src6 = ip6->ip6_dst;
782 	key.t_dst6 = ip6->ip6_src;
783 
784 	flow = bemtoh32(&ip6->ip6_flow);
785 
786 	return (etherip_input(&key, m, flow >> 20, *offp));
787 }
788 #endif /* INET6 */
789 
790 int
etherip_sysctl_etheripstat(void * oldp,size_t * oldlenp,void * newp)791 etherip_sysctl_etheripstat(void *oldp, size_t *oldlenp, void *newp)
792 {
793 	struct etheripstat etheripstat;
794 
795 	CTASSERT(sizeof(etheripstat) == (etherips_ncounters *
796 	    sizeof(uint64_t)));
797 	memset(&etheripstat, 0, sizeof etheripstat);
798 	counters_read(etheripcounters, (uint64_t *)&etheripstat,
799 	    etherips_ncounters, NULL);
800 	return (sysctl_rdstruct(oldp, oldlenp, newp, &etheripstat,
801 	    sizeof(etheripstat)));
802 }
803 
804 int
etherip_sysctl(int * name,u_int namelen,void * oldp,size_t * oldlenp,void * newp,size_t newlen)805 etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
806     void *newp, size_t newlen)
807 {
808 	/* All sysctl names at this level are terminal. */
809 	if (namelen != 1)
810 		return ENOTDIR;
811 
812 	switch (name[0]) {
813 	case ETHERIPCTL_ALLOW:
814 		return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
815 		    &etherip_allow, 0, 1));
816 	case ETHERIPCTL_STATS:
817 		return (etherip_sysctl_etheripstat(oldp, oldlenp, newp));
818 	default:
819 		break;
820 	}
821 
822 	return ENOPROTOOPT;
823 }
824 
825 static inline int
etherip_ip_cmp(int af,const union etherip_addr * a,const union etherip_addr * b)826 etherip_ip_cmp(int af, const union etherip_addr *a, const union etherip_addr *b)
827 {
828 	switch (af) {
829 #ifdef INET6
830 	case AF_INET6:
831 		return (memcmp(&a->in6, &b->in6, sizeof(a->in6)));
832 		/* FALLTHROUGH */
833 #endif /* INET6 */
834 	case AF_INET:
835 		return (memcmp(&a->in4, &b->in4, sizeof(a->in4)));
836 		break;
837 	default:
838 		panic("%s: unsupported af %d", __func__, af);
839 	}
840 
841 	return (0);
842 }
843 
844 static inline int
etherip_cmp(const struct etherip_tunnel * a,const struct etherip_tunnel * b)845 etherip_cmp(const struct etherip_tunnel *a, const struct etherip_tunnel *b)
846 {
847 	int rv;
848 
849 	if (a->t_rtableid > b->t_rtableid)
850 		return (1);
851 	if (a->t_rtableid < b->t_rtableid)
852 		return (-1);
853 
854 	/* sort by address */
855 	if (a->t_af > b->t_af)
856 		return (1);
857 	if (a->t_af < b->t_af)
858 		return (-1);
859 
860 	rv = etherip_ip_cmp(a->t_af, &a->_t_dst, &b->_t_dst);
861 	if (rv != 0)
862 		return (rv);
863 
864 	rv = etherip_ip_cmp(a->t_af, &a->_t_src, &b->_t_src);
865 	if (rv != 0)
866 		return (rv);
867 
868 	return (0);
869 }
870