xref: /openbsd/sys/net/if_ethersubr.c (revision a4cc1f24)
1 /*	$OpenBSD: if_ethersubr.c,v 1.296 2025/01/15 06:15:44 dlg Exp $	*/
2 /*	$NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
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
18  *    without specific prior written permission.
19  *
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
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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
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
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1982, 1989, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)if_ethersubr.c	8.1 (Berkeley) 6/10/93
62  */
63 
64 /*
65 %%% portions-copyright-nrl-95
66 Portions of this software are Copyright 1995-1998 by Randall Atkinson,
67 Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
68 Reserved. All rights under this copyright have been assigned to the US
69 Naval Research Laboratory (NRL). The NRL Copyright Notice and License
70 Agreement Version 1.1 (January 17, 1995) applies to these portions of the
71 software.
72 You should have received a copy of the license with this software. If you
73 didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
74 */
75 
76 #include "bpfilter.h"
77 
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/mbuf.h>
83 #include <sys/socket.h>
84 #include <sys/ioctl.h>
85 #include <sys/errno.h>
86 #include <sys/syslog.h>
87 #include <sys/timeout.h>
88 #include <sys/smr.h>
89 
90 #include <net/if.h>
91 #include <net/netisr.h>
92 #include <net/route.h>
93 #include <net/if_llc.h>
94 #include <net/if_dl.h>
95 #include <net/if_media.h>
96 #include <net/if_types.h>
97 
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #include <netinet/ip_ipsp.h>
101 #include <netinet/ip.h>
102 #include <netinet/ip6.h>
103 #include <netinet/tcp.h>
104 #include <netinet/udp.h>
105 
106 #if NBPFILTER > 0
107 #include <net/bpf.h>
108 #endif
109 
110 #include "vlan.h"
111 #if NVLAN > 0
112 #include <net/if_vlan_var.h>
113 #endif
114 
115 #include "carp.h"
116 #if NCARP > 0
117 #include <netinet/ip_carp.h>
118 #endif
119 
120 #include "pppoe.h"
121 #if NPPPOE > 0
122 #include <net/if_pppoe.h>
123 #endif
124 
125 #include "bpe.h"
126 #if NBPE > 0
127 #include <net/if_bpe.h>
128 #endif
129 
130 #ifdef INET6
131 #include <netinet6/in6_var.h>
132 #include <netinet6/nd6.h>
133 #endif
134 
135 #ifdef PIPEX
136 #include <net/pipex.h>
137 #endif
138 
139 #ifdef MPLS
140 #include <netmpls/mpls.h>
141 #endif /* MPLS */
142 
143 #include "af_frame.h"
144 #if NAF_FRAME > 0
145 #include <net/frame.h>
146 
147 static struct mbuf *
148 	ether_frm_input(struct ifnet *, struct mbuf *, uint64_t, uint16_t);
149 #endif
150 
151 /* #define ETHERDEBUG 1 */
152 #ifdef ETHERDEBUG
153 int etherdebug = ETHERDEBUG;
154 #define DNPRINTF(level, fmt, args...)					\
155 	do {								\
156 		if (etherdebug >= level)				\
157 			printf("%s: " fmt "\n", __func__, ## args);	\
158 	} while (0)
159 #else
160 #define DNPRINTF(level, fmt, args...)					\
161 	do { } while (0)
162 #endif
163 #define DPRINTF(fmt, args...)	DNPRINTF(1, fmt, args)
164 
165 u_int8_t etherbroadcastaddr[ETHER_ADDR_LEN] =
166     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
167 u_int8_t etheranyaddr[ETHER_ADDR_LEN] =
168     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
169 #define senderr(e) { error = (e); goto bad;}
170 
171 int
ether_ioctl(struct ifnet * ifp,struct arpcom * arp,u_long cmd,caddr_t data)172 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
173 {
174 	struct ifreq *ifr = (struct ifreq *)data;
175 	int error = 0;
176 
177 	switch (cmd) {
178 	case SIOCSIFADDR:
179 		break;
180 
181 	case SIOCSIFMTU:
182 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
183 			error = EINVAL;
184 		else
185 			ifp->if_mtu = ifr->ifr_mtu;
186 		break;
187 
188 	case SIOCADDMULTI:
189 	case SIOCDELMULTI:
190 		if (ifp->if_flags & IFF_MULTICAST) {
191 			error = (cmd == SIOCADDMULTI) ?
192 			    ether_addmulti(ifr, arp) :
193 			    ether_delmulti(ifr, arp);
194 		} else
195 			error = ENOTTY;
196 		break;
197 
198 	default:
199 		error = ENOTTY;
200 	}
201 
202 	return (error);
203 }
204 
205 
206 void
ether_rtrequest(struct ifnet * ifp,int req,struct rtentry * rt)207 ether_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
208 {
209 	if (rt == NULL)
210 		return;
211 
212 	switch (rt_key(rt)->sa_family) {
213 	case AF_INET:
214 		arp_rtrequest(ifp, req, rt);
215 		break;
216 #ifdef INET6
217 	case AF_INET6:
218 		nd6_rtrequest(ifp, req, rt);
219 		break;
220 #endif
221 	default:
222 		break;
223 	}
224 }
225 
226 int
ether_resolve(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt,struct ether_header * eh)227 ether_resolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
228     struct rtentry *rt, struct ether_header *eh)
229 {
230 	struct arpcom *ac = (struct arpcom *)ifp;
231 	sa_family_t af = dst->sa_family;
232 	int error = 0;
233 
234 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
235 		senderr(ENETDOWN);
236 
237 	KASSERT(rt != NULL || ISSET(m->m_flags, M_MCAST|M_BCAST) ||
238 		af == AF_UNSPEC || af == pseudo_AF_HDRCMPLT);
239 
240 #ifdef DIAGNOSTIC
241 	if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
242 		printf("%s: trying to send packet on wrong domain. "
243 		    "if %d vs. mbuf %d\n", ifp->if_xname,
244 		    ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid));
245 	}
246 #endif
247 
248 	switch (af) {
249 	case AF_INET:
250 		error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
251 		if (error)
252 			return (error);
253 		eh->ether_type = htons(ETHERTYPE_IP);
254 
255 		/*
256 		 * If broadcasting on a simplex interface, loopback a copy.
257 		 * The checksum must be calculated in software.  Keep the
258 		 * condition in sync with in_ifcap_cksum().
259 		 */
260 		if (ISSET(m->m_flags, M_BCAST) &&
261 		    ISSET(ifp->if_flags, IFF_SIMPLEX) &&
262 		    !m->m_pkthdr.pf.routed) {
263 			struct mbuf *mcopy;
264 
265 			/* XXX Should we input an unencrypted IPsec packet? */
266 			mcopy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
267 			if (mcopy != NULL)
268 				if_input_local(ifp, mcopy, af);
269 		}
270 		break;
271 #ifdef INET6
272 	case AF_INET6:
273 		error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
274 		if (error)
275 			return (error);
276 		eh->ether_type = htons(ETHERTYPE_IPV6);
277 		break;
278 #endif
279 #ifdef MPLS
280 	case AF_MPLS:
281 		if (rt == NULL)
282 			senderr(EHOSTUNREACH);
283 
284 		if (!ISSET(ifp->if_xflags, IFXF_MPLS))
285 			senderr(ENETUNREACH);
286 
287 		dst = ISSET(rt->rt_flags, RTF_GATEWAY) ?
288 		    rt->rt_gateway : rt_key(rt);
289 
290 		switch (dst->sa_family) {
291 		case AF_LINK:
292 			if (satosdl(dst)->sdl_alen < sizeof(eh->ether_dhost))
293 				senderr(EHOSTUNREACH);
294 			memcpy(eh->ether_dhost, LLADDR(satosdl(dst)),
295 			    sizeof(eh->ether_dhost));
296 			break;
297 #ifdef INET6
298 		case AF_INET6:
299 			error = nd6_resolve(ifp, rt, m, dst, eh->ether_dhost);
300 			if (error)
301 				return (error);
302 			break;
303 #endif
304 		case AF_INET:
305 			error = arpresolve(ifp, rt, m, dst, eh->ether_dhost);
306 			if (error)
307 				return (error);
308 			break;
309 		default:
310 			senderr(EHOSTUNREACH);
311 		}
312 		/* XXX handling for simplex devices in case of M/BCAST ?? */
313 		if (m->m_flags & (M_BCAST | M_MCAST))
314 			eh->ether_type = htons(ETHERTYPE_MPLS_MCAST);
315 		else
316 			eh->ether_type = htons(ETHERTYPE_MPLS);
317 		break;
318 #endif /* MPLS */
319 	case pseudo_AF_HDRCMPLT:
320 		/* take the whole header from the sa */
321 		memcpy(eh, dst->sa_data, sizeof(*eh));
322 		return (0);
323 
324 	case AF_UNSPEC:
325 		/* take the dst and type from the sa, but get src below */
326 		memcpy(eh, dst->sa_data, sizeof(*eh));
327 		break;
328 
329 	default:
330 		printf("%s: can't handle af%d\n", ifp->if_xname, af);
331 		senderr(EAFNOSUPPORT);
332 	}
333 
334 	memcpy(eh->ether_shost, ac->ac_enaddr, sizeof(eh->ether_shost));
335 
336 	return (0);
337 
338 bad:
339 	m_freem(m);
340 	return (error);
341 }
342 
343 struct mbuf*
ether_encap(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt,int * errorp)344 ether_encap(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
345     struct rtentry *rt, int *errorp)
346 {
347 	struct ether_header eh;
348 	int error;
349 
350 	error = ether_resolve(ifp, m, dst, rt, &eh);
351 	switch (error) {
352 	case 0:
353 		break;
354 	case EAGAIN:
355 		error = 0;
356 	default:
357 		*errorp = error;
358 		return (NULL);
359 	}
360 
361 	m = m_prepend(m, ETHER_ALIGN + sizeof(eh), M_DONTWAIT);
362 	if (m == NULL) {
363 		*errorp = ENOBUFS;
364 		return (NULL);
365 	}
366 
367 	m_adj(m, ETHER_ALIGN);
368 	memcpy(mtod(m, struct ether_header *), &eh, sizeof(eh));
369 
370 	return (m);
371 }
372 
373 int
ether_output(struct ifnet * ifp,struct mbuf * m,struct sockaddr * dst,struct rtentry * rt)374 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
375     struct rtentry *rt)
376 {
377 	int error;
378 
379 	m = ether_encap(ifp, m, dst, rt, &error);
380 	if (m == NULL)
381 		return (error);
382 
383 	return (if_enqueue(ifp, m));
384 }
385 
386 /*
387  * Process a received Ethernet packet.
388  *
389  * Ethernet input has several "phases" of filtering packets to
390  * support virtual/pseudo interfaces before actual layer 3 protocol
391  * handling.
392  *
393  * First phase:
394  *
395  * The first phase supports drivers that aggregate multiple Ethernet
396  * ports into a single logical interface, ie, aggr(4) and trunk(4).
397  * These drivers intercept packets by swapping out the if_input handler
398  * on the "port" interfaces to steal the packets before they get here
399  * to ether_input().
400  */
401 void
ether_input(struct ifnet * ifp,struct mbuf * m)402 ether_input(struct ifnet *ifp, struct mbuf *m)
403 {
404 	struct ether_header *eh;
405 	void (*input)(struct ifnet *, struct mbuf *);
406 	u_int16_t etype;
407 	struct arpcom *ac;
408 	const struct ether_brport *eb;
409 	unsigned int sdelim = 0;
410 	uint64_t dst, self;
411 
412 	/* Drop short frames */
413 	if (m->m_len < ETHER_HDR_LEN)
414 		goto dropanyway;
415 
416 	/*
417 	 * Second phase: service delimited packet filtering.
418 	 *
419 	 * Let vlan(4) and svlan(4) look at "service delimited"
420 	 * packets. If a virtual interface does not exist to take
421 	 * those packets, they're returned to ether_input() so a
422 	 * bridge can have a go at forwarding them.
423 	 */
424 
425 	eh = mtod(m, struct ether_header *);
426 	dst = ether_addr_to_e64((struct ether_addr *)eh->ether_dhost);
427 	etype = ntohs(eh->ether_type);
428 
429 	if (ISSET(m->m_flags, M_VLANTAG) ||
430 	    etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) {
431 #if NVLAN > 0
432 		m = vlan_input(ifp, m, &sdelim);
433 		if (m == NULL)
434 			return;
435 #else
436 		sdelim = 1;
437 #endif
438 	}
439 
440 	/*
441 	 * Third phase: bridge processing.
442 	 *
443 	 * Give the packet to a bridge interface, ie, bridge(4),
444 	 * veb(4), or tpmr(4), if it is configured. A bridge
445 	 * may take the packet and forward it to another port, or it
446 	 * may return it here to ether_input() to support local
447 	 * delivery to this port.
448 	 */
449 
450 	ac = (struct arpcom *)ifp;
451 
452 	smr_read_enter();
453 	eb = SMR_PTR_GET(&ac->ac_brport);
454 	if (eb != NULL)
455 		eb->eb_port_take(eb->eb_port);
456 	smr_read_leave();
457 	if (eb != NULL) {
458 		m = (*eb->eb_input)(ifp, m, dst, eb->eb_port);
459 		eb->eb_port_rele(eb->eb_port);
460 		if (m == NULL) {
461 			return;
462 		}
463 	}
464 
465 	/*
466 	 * Fourth phase: drop service delimited packets.
467 	 *
468 	 * If the packet has a tag, and a bridge didn't want it,
469 	 * it's not for this port.
470 	 */
471 
472 	if (sdelim)
473 		goto dropanyway;
474 
475 	/*
476 	 * Fifth phase: destination address check.
477 	 *
478 	 * Is the packet specifically addressed to this port?
479 	 */
480 
481 	eh = mtod(m, struct ether_header *);
482 	self = ether_addr_to_e64((struct ether_addr *)ac->ac_enaddr);
483 	if (dst != self) {
484 #if NCARP > 0
485 		/*
486 		 * If it's not for this port, it could be for carp(4).
487 		 */
488 		if (ifp->if_type != IFT_CARP &&
489 		    !SRPL_EMPTY_LOCKED(&ifp->if_carp)) {
490 			m = carp_input(ifp, m, dst);
491 			if (m == NULL)
492 				return;
493 
494 			eh = mtod(m, struct ether_header *);
495 		}
496 #endif
497 
498 		/*
499 		 * If not, it must be multicast or broadcast to go further.
500 		 */
501 		if (!ETH64_IS_MULTICAST(dst))
502 			goto dropanyway;
503 
504 		/*
505 		 * If this is not a simplex interface, drop the packet
506 		 * if it came from us.
507 		 */
508 		if ((ifp->if_flags & IFF_SIMPLEX) == 0) {
509 			uint64_t src = ether_addr_to_e64(
510 			    (struct ether_addr *)eh->ether_shost);
511 			if (self == src)
512 				goto dropanyway;
513 		}
514 
515 		SET(m->m_flags, ETH64_IS_BROADCAST(dst) ? M_BCAST : M_MCAST);
516 		ifp->if_imcasts++;
517 	}
518 
519 	/*
520 	 * Sixth phase: protocol demux.
521 	 *
522 	 * At this point it is known that the packet is destined
523 	 * for layer 3 protocol handling on the local port.
524 	 */
525 	etype = ntohs(eh->ether_type);
526 
527 	switch (etype) {
528 	case ETHERTYPE_IP:
529 		input = ipv4_input;
530 		break;
531 
532 	case ETHERTYPE_ARP:
533 		if (ifp->if_flags & IFF_NOARP)
534 			goto dropanyway;
535 		input = arpinput;
536 		break;
537 
538 	case ETHERTYPE_REVARP:
539 		if (ifp->if_flags & IFF_NOARP)
540 			goto dropanyway;
541 		input = revarpinput;
542 		break;
543 
544 #ifdef INET6
545 	/*
546 	 * Schedule IPv6 software interrupt for incoming IPv6 packet.
547 	 */
548 	case ETHERTYPE_IPV6:
549 		input = ipv6_input;
550 		break;
551 #endif /* INET6 */
552 #if NPPPOE > 0 || defined(PIPEX)
553 	case ETHERTYPE_PPPOEDISC:
554 	case ETHERTYPE_PPPOE:
555 		if (m->m_flags & (M_MCAST | M_BCAST))
556 			goto dropanyway;
557 #ifdef PIPEX
558 		if (pipex_enable) {
559 			struct pipex_session *session;
560 
561 			if ((session = pipex_pppoe_lookup_session(m)) != NULL) {
562 				pipex_pppoe_input(m, session);
563 				pipex_rele_session(session);
564 				return;
565 			}
566 		}
567 #endif
568 		if (etype == ETHERTYPE_PPPOEDISC) {
569 			if (mq_enqueue(&pppoediscinq, m) == 0)
570 				schednetisr(NETISR_PPPOE);
571 		} else {
572 			m = pppoe_vinput(ifp, m);
573 			if (m != NULL && mq_enqueue(&pppoeinq, m) == 0)
574 				schednetisr(NETISR_PPPOE);
575 		}
576 		return;
577 #endif
578 #ifdef MPLS
579 	case ETHERTYPE_MPLS:
580 	case ETHERTYPE_MPLS_MCAST:
581 		input = mpls_input;
582 		break;
583 #endif
584 #if NBPE > 0
585 	case ETHERTYPE_PBB:
586 		bpe_input(ifp, m);
587 		return;
588 #endif
589 	default:
590 #if NAF_FRAME > 0
591 		m = ether_frm_input(ifp, m, dst, etype);
592 #endif
593 		goto dropanyway;
594 	}
595 
596 	m_adj(m, sizeof(*eh));
597 	(*input)(ifp, m);
598 	return;
599 dropanyway:
600 	m_freem(m);
601 	return;
602 }
603 
604 int
ether_brport_isset(struct ifnet * ifp)605 ether_brport_isset(struct ifnet *ifp)
606 {
607 	struct arpcom *ac = (struct arpcom *)ifp;
608 
609 	KERNEL_ASSERT_LOCKED();
610 	if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL)
611 		return (EBUSY);
612 
613 	return (0);
614 }
615 
616 void
ether_brport_set(struct ifnet * ifp,const struct ether_brport * eb)617 ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb)
618 {
619 	struct arpcom *ac = (struct arpcom *)ifp;
620 
621 	KERNEL_ASSERT_LOCKED();
622 	KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL,
623 	    "%s setting an already set brport", ifp->if_xname);
624 
625 	SMR_PTR_SET_LOCKED(&ac->ac_brport, eb);
626 }
627 
628 void
ether_brport_clr(struct ifnet * ifp)629 ether_brport_clr(struct ifnet *ifp)
630 {
631 	struct arpcom *ac = (struct arpcom *)ifp;
632 
633 	KERNEL_ASSERT_LOCKED();
634 	KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL,
635 	    "%s clearing an already clear brport", ifp->if_xname);
636 
637 	SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL);
638 }
639 
640 const struct ether_brport *
ether_brport_get(struct ifnet * ifp)641 ether_brport_get(struct ifnet *ifp)
642 {
643 	struct arpcom *ac = (struct arpcom *)ifp;
644 	SMR_ASSERT_CRITICAL();
645 	return (SMR_PTR_GET(&ac->ac_brport));
646 }
647 
648 const struct ether_brport *
ether_brport_get_locked(struct ifnet * ifp)649 ether_brport_get_locked(struct ifnet *ifp)
650 {
651 	struct arpcom *ac = (struct arpcom *)ifp;
652 	KERNEL_ASSERT_LOCKED();
653 	return (SMR_PTR_GET_LOCKED(&ac->ac_brport));
654 }
655 
656 /*
657  * Convert Ethernet address to printable (loggable) representation.
658  */
659 static char digits[] = "0123456789abcdef";
660 char *
ether_sprintf(u_char * ap)661 ether_sprintf(u_char *ap)
662 {
663 	int i;
664 	static char etherbuf[ETHER_ADDR_LEN * 3];
665 	char *cp = etherbuf;
666 
667 	for (i = 0; i < ETHER_ADDR_LEN; i++) {
668 		*cp++ = digits[*ap >> 4];
669 		*cp++ = digits[*ap++ & 0xf];
670 		*cp++ = ':';
671 	}
672 	*--cp = 0;
673 	return (etherbuf);
674 }
675 
676 /*
677  * Generate a (hopefully) acceptable MAC address, if asked.
678  */
679 void
ether_fakeaddr(struct ifnet * ifp)680 ether_fakeaddr(struct ifnet *ifp)
681 {
682 	static int unit;
683 	int rng = arc4random();
684 
685 	/* Non-multicast; locally administered address */
686 	((struct arpcom *)ifp)->ac_enaddr[0] = 0xfe;
687 	((struct arpcom *)ifp)->ac_enaddr[1] = 0xe1;
688 	((struct arpcom *)ifp)->ac_enaddr[2] = 0xba;
689 	((struct arpcom *)ifp)->ac_enaddr[3] = 0xd0 | (unit++ & 0xf);
690 	((struct arpcom *)ifp)->ac_enaddr[4] = rng;
691 	((struct arpcom *)ifp)->ac_enaddr[5] = rng >> 8;
692 }
693 
694 /*
695  * Perform common duties while attaching to interface list
696  */
697 void
ether_ifattach(struct ifnet * ifp)698 ether_ifattach(struct ifnet *ifp)
699 {
700 	struct arpcom *ac = (struct arpcom *)ifp;
701 
702 	/*
703 	 * Any interface which provides a MAC address which is obviously
704 	 * invalid gets whacked, so that users will notice.
705 	 */
706 	if (ETHER_IS_MULTICAST(((struct arpcom *)ifp)->ac_enaddr))
707 		ether_fakeaddr(ifp);
708 
709 	ifp->if_type = IFT_ETHER;
710 	ifp->if_addrlen = ETHER_ADDR_LEN;
711 	ifp->if_hdrlen = ETHER_HDR_LEN;
712 	ifp->if_mtu = ETHERMTU;
713 	ifp->if_input = ether_input;
714 	if (ifp->if_output == NULL)
715 		ifp->if_output = ether_output;
716 	ifp->if_rtrequest = ether_rtrequest;
717 
718 	if (ifp->if_hardmtu == 0)
719 		ifp->if_hardmtu = ETHERMTU;
720 
721 	if_alloc_sadl(ifp);
722 	memcpy(LLADDR(ifp->if_sadl), ac->ac_enaddr, ifp->if_addrlen);
723 	LIST_INIT(&ac->ac_multiaddrs);
724 #if NBPFILTER > 0
725 	bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN);
726 #endif
727 }
728 
729 void
ether_ifdetach(struct ifnet * ifp)730 ether_ifdetach(struct ifnet *ifp)
731 {
732 	struct arpcom *ac = (struct arpcom *)ifp;
733 	struct ether_multi *enm;
734 
735 	/* Undo pseudo-driver changes. */
736 	if_deactivate(ifp);
737 
738 	while (!LIST_EMPTY(&ac->ac_multiaddrs)) {
739 		enm = LIST_FIRST(&ac->ac_multiaddrs);
740 		LIST_REMOVE(enm, enm_list);
741 		free(enm, M_IFMADDR, sizeof *enm);
742 	}
743 }
744 
745 #if 0
746 /*
747  * This is for reference.  We have table-driven versions of the
748  * crc32 generators, which are faster than the double-loop.
749  */
750 u_int32_t __pure
751 ether_crc32_le_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
752 {
753 	u_int32_t c, carry;
754 	size_t i, j;
755 
756 	for (i = 0; i < len; i++) {
757 		c = buf[i];
758 		for (j = 0; j < 8; j++) {
759 			carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01);
760 			crc >>= 1;
761 			c >>= 1;
762 			if (carry)
763 				crc = (crc ^ ETHER_CRC_POLY_LE);
764 		}
765 	}
766 
767 	return (crc);
768 }
769 
770 u_int32_t __pure
771 ether_crc32_be_update(u_int_32_t crc, const u_int8_t *buf, size_t len)
772 {
773 	u_int32_t c, carry;
774 	size_t i, j;
775 
776 	for (i = 0; i < len; i++) {
777 		c = buf[i];
778 		for (j = 0; j < 8; j++) {
779 			carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01);
780 			crc <<= 1;
781 			c >>= 1;
782 			if (carry)
783 				crc = (crc ^ ETHER_CRC_POLY_BE) | carry;
784 		}
785 	}
786 
787 	return (crc);
788 }
789 #else
790 u_int32_t __pure
ether_crc32_le_update(u_int32_t crc,const u_int8_t * buf,size_t len)791 ether_crc32_le_update(u_int32_t crc, const u_int8_t *buf, size_t len)
792 {
793 	static const u_int32_t crctab[] = {
794 		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
795 		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
796 		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
797 		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
798 	};
799 	size_t i;
800 
801 	for (i = 0; i < len; i++) {
802 		crc ^= buf[i];
803 		crc = (crc >> 4) ^ crctab[crc & 0xf];
804 		crc = (crc >> 4) ^ crctab[crc & 0xf];
805 	}
806 
807 	return (crc);
808 }
809 
810 u_int32_t __pure
ether_crc32_be_update(u_int32_t crc,const u_int8_t * buf,size_t len)811 ether_crc32_be_update(u_int32_t crc, const u_int8_t *buf, size_t len)
812 {
813 	static const u_int8_t rev[] = {
814 		0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
815 		0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
816 	};
817 	static const u_int32_t crctab[] = {
818 		0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
819 		0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
820 		0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
821 		0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd
822 	};
823 	size_t i;
824 	u_int8_t data;
825 
826 	for (i = 0; i < len; i++) {
827 		data = buf[i];
828 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data & 0xf]];
829 		crc = (crc << 4) ^ crctab[(crc >> 28) ^ rev[data >> 4]];
830 	}
831 
832 	return (crc);
833 }
834 #endif
835 
836 u_int32_t
ether_crc32_le(const u_int8_t * buf,size_t len)837 ether_crc32_le(const u_int8_t *buf, size_t len)
838 {
839 	return ether_crc32_le_update(0xffffffff, buf, len);
840 }
841 
842 u_int32_t
ether_crc32_be(const u_int8_t * buf,size_t len)843 ether_crc32_be(const u_int8_t *buf, size_t len)
844 {
845 	return ether_crc32_be_update(0xffffffff, buf, len);
846 }
847 
848 u_char	ether_ipmulticast_min[ETHER_ADDR_LEN] =
849     { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
850 u_char	ether_ipmulticast_max[ETHER_ADDR_LEN] =
851     { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
852 
853 #ifdef INET6
854 u_char	ether_ip6multicast_min[ETHER_ADDR_LEN] =
855     { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
856 u_char	ether_ip6multicast_max[ETHER_ADDR_LEN] =
857     { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
858 #endif
859 
860 /*
861  * Convert a sockaddr into an Ethernet address or range of Ethernet
862  * addresses.
863  */
864 int
ether_multiaddr(struct sockaddr * sa,u_int8_t addrlo[ETHER_ADDR_LEN],u_int8_t addrhi[ETHER_ADDR_LEN])865 ether_multiaddr(struct sockaddr *sa, u_int8_t addrlo[ETHER_ADDR_LEN],
866     u_int8_t addrhi[ETHER_ADDR_LEN])
867 {
868 	struct sockaddr_in *sin;
869 #ifdef INET6
870 	struct sockaddr_in6 *sin6;
871 #endif /* INET6 */
872 
873 	switch (sa->sa_family) {
874 
875 	case AF_UNSPEC:
876 		memcpy(addrlo, sa->sa_data, ETHER_ADDR_LEN);
877 		memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
878 		break;
879 
880 	case AF_INET:
881 		sin = satosin(sa);
882 		if (sin->sin_addr.s_addr == INADDR_ANY) {
883 			/*
884 			 * An IP address of INADDR_ANY means listen to
885 			 * or stop listening to all of the Ethernet
886 			 * multicast addresses used for IP.
887 			 * (This is for the sake of IP multicast routers.)
888 			 */
889 			memcpy(addrlo, ether_ipmulticast_min, ETHER_ADDR_LEN);
890 			memcpy(addrhi, ether_ipmulticast_max, ETHER_ADDR_LEN);
891 		} else {
892 			ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
893 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
894 		}
895 		break;
896 #ifdef INET6
897 	case AF_INET6:
898 		sin6 = satosin6(sa);
899 		if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
900 			/*
901 			 * An IP6 address of 0 means listen to or stop
902 			 * listening to all of the Ethernet multicast
903 			 * address used for IP6.
904 			 *
905 			 * (This might not be healthy, given IPv6's reliance on
906 			 * multicast for things like neighbor discovery.
907 			 * Perhaps initializing all-nodes, solicited nodes, and
908 			 * possibly all-routers for this interface afterwards
909 			 * is not a bad idea.)
910 			 */
911 
912 			memcpy(addrlo, ether_ip6multicast_min, ETHER_ADDR_LEN);
913 			memcpy(addrhi, ether_ip6multicast_max, ETHER_ADDR_LEN);
914 		} else {
915 			ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, addrlo);
916 			memcpy(addrhi, addrlo, ETHER_ADDR_LEN);
917 		}
918 		break;
919 #endif
920 
921 	default:
922 		return (EAFNOSUPPORT);
923 	}
924 	return (0);
925 }
926 
927 /*
928  * Add an Ethernet multicast address or range of addresses to the list for a
929  * given interface.
930  */
931 int
ether_addmulti(struct ifreq * ifr,struct arpcom * ac)932 ether_addmulti(struct ifreq *ifr, struct arpcom *ac)
933 {
934 	struct ether_multi *enm;
935 	u_char addrlo[ETHER_ADDR_LEN];
936 	u_char addrhi[ETHER_ADDR_LEN];
937 	int s = splnet(), error;
938 
939 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
940 	if (error != 0) {
941 		splx(s);
942 		return (error);
943 	}
944 
945 	/*
946 	 * Verify that we have valid Ethernet multicast addresses.
947 	 */
948 	if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
949 		splx(s);
950 		return (EINVAL);
951 	}
952 	/*
953 	 * See if the address range is already in the list.
954 	 */
955 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
956 	if (enm != NULL) {
957 		/*
958 		 * Found it; just increment the reference count.
959 		 */
960 		refcnt_take(&enm->enm_refcnt);
961 		splx(s);
962 		return (0);
963 	}
964 	/*
965 	 * New address or range; malloc a new multicast record
966 	 * and link it into the interface's multicast list.
967 	 */
968 	enm = malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
969 	if (enm == NULL) {
970 		splx(s);
971 		return (ENOBUFS);
972 	}
973 	memcpy(enm->enm_addrlo, addrlo, ETHER_ADDR_LEN);
974 	memcpy(enm->enm_addrhi, addrhi, ETHER_ADDR_LEN);
975 	refcnt_init_trace(&enm->enm_refcnt, DT_REFCNT_IDX_ETHMULTI);
976 	LIST_INSERT_HEAD(&ac->ac_multiaddrs, enm, enm_list);
977 	ac->ac_multicnt++;
978 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
979 		ac->ac_multirangecnt++;
980 	splx(s);
981 	/*
982 	 * Return ENETRESET to inform the driver that the list has changed
983 	 * and its reception filter should be adjusted accordingly.
984 	 */
985 	return (ENETRESET);
986 }
987 
988 /*
989  * Delete a multicast address record.
990  */
991 int
ether_delmulti(struct ifreq * ifr,struct arpcom * ac)992 ether_delmulti(struct ifreq *ifr, struct arpcom *ac)
993 {
994 	struct ether_multi *enm;
995 	u_char addrlo[ETHER_ADDR_LEN];
996 	u_char addrhi[ETHER_ADDR_LEN];
997 	int s = splnet(), error;
998 
999 	error = ether_multiaddr(&ifr->ifr_addr, addrlo, addrhi);
1000 	if (error != 0) {
1001 		splx(s);
1002 		return (error);
1003 	}
1004 
1005 	/*
1006 	 * Look up the address in our list.
1007 	 */
1008 	ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
1009 	if (enm == NULL) {
1010 		splx(s);
1011 		return (ENXIO);
1012 	}
1013 	if (refcnt_rele(&enm->enm_refcnt) == 0) {
1014 		/*
1015 		 * Still some claims to this record.
1016 		 */
1017 		splx(s);
1018 		return (0);
1019 	}
1020 	/*
1021 	 * No remaining claims to this record; unlink and free it.
1022 	 */
1023 	LIST_REMOVE(enm, enm_list);
1024 	free(enm, M_IFMADDR, sizeof *enm);
1025 	ac->ac_multicnt--;
1026 	if (memcmp(addrlo, addrhi, ETHER_ADDR_LEN) != 0)
1027 		ac->ac_multirangecnt--;
1028 	splx(s);
1029 	/*
1030 	 * Return ENETRESET to inform the driver that the list has changed
1031 	 * and its reception filter should be adjusted accordingly.
1032 	 */
1033 	return (ENETRESET);
1034 }
1035 
1036 uint64_t
ether_addr_to_e64(const struct ether_addr * ea)1037 ether_addr_to_e64(const struct ether_addr *ea)
1038 {
1039 	uint64_t e64 = 0;
1040 	size_t i;
1041 
1042 	for (i = 0; i < nitems(ea->ether_addr_octet); i++) {
1043 		e64 <<= 8;
1044 		e64 |= ea->ether_addr_octet[i];
1045 	}
1046 
1047 	return (e64);
1048 }
1049 
1050 void
ether_e64_to_addr(struct ether_addr * ea,uint64_t e64)1051 ether_e64_to_addr(struct ether_addr *ea, uint64_t e64)
1052 {
1053 	size_t i = nitems(ea->ether_addr_octet);
1054 
1055 	do {
1056 		ea->ether_addr_octet[--i] = e64;
1057 		e64 >>= 8;
1058 	} while (i > 0);
1059 }
1060 
1061 /* Parse different TCP/IP protocol headers for a quick view inside an mbuf. */
1062 void
ether_extract_headers(struct mbuf * m0,struct ether_extracted * ext)1063 ether_extract_headers(struct mbuf *m0, struct ether_extracted *ext)
1064 {
1065 	struct mbuf	*m;
1066 	size_t		 hlen, iplen;
1067 	int		 hoff;
1068 	uint8_t		 ipproto;
1069 	uint16_t	 ether_type;
1070 	/* gcc 4.2.1 on sparc64 may create 32 bit loads on unaligned mbuf */
1071 	union {
1072 		u_char	hc_data;
1073 #if _BYTE_ORDER == _LITTLE_ENDIAN
1074 		struct {
1075 			u_int	hl:4,	/* header length */
1076 				v:4;	/* version */
1077 		} hc_ip;
1078 		struct {
1079 			u_int	x2:4,	/* (unused) */
1080 				off:4;	/* data offset */
1081 		} hc_th;
1082 #endif
1083 #if _BYTE_ORDER == _BIG_ENDIAN
1084 		struct {
1085 			u_int	v:4,	/* version */
1086 				hl:4;	/* header length */
1087 		} hc_ip;
1088 		struct {
1089 			u_int	off:4,	/* data offset */
1090 				x2:4;	/* (unused) */
1091 		} hc_th;
1092 #endif
1093 	} hdrcpy;
1094 
1095 	/* Return NULL if header was not recognized. */
1096 	memset(ext, 0, sizeof(*ext));
1097 
1098 	KASSERT(ISSET(m0->m_flags, M_PKTHDR));
1099 	ext->paylen = m0->m_pkthdr.len;
1100 
1101 	if (m0->m_len < sizeof(*ext->eh)) {
1102 		DPRINTF("m_len %d, eh %zu", m0->m_len, sizeof(*ext->eh));
1103 		return;
1104 	}
1105 	ext->eh = mtod(m0, struct ether_header *);
1106 	ether_type = ntohs(ext->eh->ether_type);
1107 	hlen = sizeof(*ext->eh);
1108 	if (ext->paylen < hlen) {
1109 		DPRINTF("paylen %u, ehlen %zu", ext->paylen, hlen);
1110 		ext->eh = NULL;
1111 		return;
1112 	}
1113 	ext->paylen -= hlen;
1114 
1115 #if NVLAN > 0
1116 	if (ether_type == ETHERTYPE_VLAN) {
1117 		if (m0->m_len < sizeof(*ext->evh)) {
1118 			DPRINTF("m_len %d, evh %zu",
1119 			    m0->m_len, sizeof(*ext->evh));
1120 			return;
1121 		}
1122 		ext->evh = mtod(m0, struct ether_vlan_header *);
1123 		ether_type = ntohs(ext->evh->evl_proto);
1124 		hlen = sizeof(*ext->evh);
1125 		if (sizeof(*ext->eh) + ext->paylen < hlen) {
1126 			DPRINTF("paylen %zu, evhlen %zu",
1127 			    sizeof(*ext->eh) + ext->paylen, hlen);
1128 			ext->evh = NULL;
1129 			return;
1130 		}
1131 		ext->paylen = sizeof(*ext->eh) + ext->paylen - hlen;
1132 	}
1133 #endif
1134 
1135 	switch (ether_type) {
1136 	case ETHERTYPE_IP:
1137 		m = m_getptr(m0, hlen, &hoff);
1138 		if (m == NULL || m->m_len - hoff < sizeof(*ext->ip4)) {
1139 			DPRINTF("m_len %d, hoff %d, ip4 %zu",
1140 			    m ? m->m_len : -1, hoff, sizeof(*ext->ip4));
1141 			return;
1142 		}
1143 		ext->ip4 = (struct ip *)(mtod(m, caddr_t) + hoff);
1144 
1145 		memcpy(&hdrcpy.hc_data, ext->ip4, 1);
1146 		hlen = hdrcpy.hc_ip.hl << 2;
1147 		if (m->m_len - hoff < hlen) {
1148 			DPRINTF("m_len %d, hoff %d, iphl %zu",
1149 			    m ? m->m_len : -1, hoff, hlen);
1150 			ext->ip4 = NULL;
1151 			return;
1152 		}
1153 		if (ext->paylen < hlen) {
1154 			DPRINTF("paylen %u, ip4hlen %zu", ext->paylen, hlen);
1155 			ext->ip4 = NULL;
1156 			return;
1157 		}
1158 		iplen = ntohs(ext->ip4->ip_len);
1159 		if (ext->paylen < iplen) {
1160 			DPRINTF("paylen %u, ip4len %zu", ext->paylen, iplen);
1161 			ext->ip4 = NULL;
1162 			return;
1163 		}
1164 		if (iplen < hlen) {
1165 			DPRINTF("ip4len %zu, ip4hlen %zu", iplen, hlen);
1166 			ext->ip4 = NULL;
1167 			return;
1168 		}
1169 		ext->iplen = iplen;
1170 		ext->iphlen = hlen;
1171 		ext->paylen -= hlen;
1172 		ipproto = ext->ip4->ip_p;
1173 
1174 		if (ISSET(ntohs(ext->ip4->ip_off), IP_MF|IP_OFFMASK))
1175 			return;
1176 		break;
1177 #ifdef INET6
1178 	case ETHERTYPE_IPV6:
1179 		m = m_getptr(m0, hlen, &hoff);
1180 		if (m == NULL || m->m_len - hoff < sizeof(*ext->ip6)) {
1181 			DPRINTF("m_len %d, hoff %d, ip6 %zu",
1182 			    m ? m->m_len : -1, hoff, sizeof(*ext->ip6));
1183 			return;
1184 		}
1185 		ext->ip6 = (struct ip6_hdr *)(mtod(m, caddr_t) + hoff);
1186 
1187 		hlen = sizeof(*ext->ip6);
1188 		if (ext->paylen < hlen) {
1189 			DPRINTF("paylen %u, ip6hlen %zu", ext->paylen, hlen);
1190 			ext->ip6 = NULL;
1191 			return;
1192 		}
1193 		iplen = hlen + ntohs(ext->ip6->ip6_plen);
1194 		if (ext->paylen < iplen) {
1195 			DPRINTF("paylen %u, ip6len %zu", ext->paylen, iplen);
1196 			ext->ip6 = NULL;
1197 			return;
1198 		}
1199 		ext->iplen = iplen;
1200 		ext->iphlen = hlen;
1201 		ext->paylen -= hlen;
1202 		ipproto = ext->ip6->ip6_nxt;
1203 		break;
1204 #endif
1205 	default:
1206 		return;
1207 	}
1208 
1209 	switch (ipproto) {
1210 	case IPPROTO_TCP:
1211 		m = m_getptr(m, hoff + hlen, &hoff);
1212 		if (m == NULL || m->m_len - hoff < sizeof(*ext->tcp)) {
1213 			DPRINTF("m_len %d, hoff %d, tcp %zu",
1214 			    m ? m->m_len : -1, hoff, sizeof(*ext->tcp));
1215 			return;
1216 		}
1217 		ext->tcp = (struct tcphdr *)(mtod(m, caddr_t) + hoff);
1218 
1219 		memcpy(&hdrcpy.hc_data, &ext->tcp->th_flags - 1, 1);
1220 		hlen = hdrcpy.hc_th.off << 2;
1221 		if (m->m_len - hoff < hlen) {
1222 			DPRINTF("m_len %d, hoff %d, thoff %zu",
1223 			    m ? m->m_len : -1, hoff, hlen);
1224 			ext->tcp = NULL;
1225 			return;
1226 		}
1227 		if (ext->iplen - ext->iphlen < hlen) {
1228 			DPRINTF("iplen %u, iphlen %u, tcphlen %zu",
1229 			    ext->iplen, ext->iphlen, hlen);
1230 			ext->tcp = NULL;
1231 			return;
1232 		}
1233 		ext->tcphlen = hlen;
1234 		ext->paylen -= hlen;
1235 		break;
1236 
1237 	case IPPROTO_UDP:
1238 		m = m_getptr(m, hoff + hlen, &hoff);
1239 		if (m == NULL || m->m_len - hoff < sizeof(*ext->udp)) {
1240 			DPRINTF("m_len %d, hoff %d, tcp %zu",
1241 			    m ? m->m_len : -1, hoff, sizeof(*ext->tcp));
1242 			return;
1243 		}
1244 		ext->udp = (struct udphdr *)(mtod(m, caddr_t) + hoff);
1245 
1246 		hlen = sizeof(*ext->udp);
1247 		if (ext->iplen - ext->iphlen < hlen) {
1248 			DPRINTF("iplen %u, iphlen %u, udphlen %zu",
1249 			    ext->iplen, ext->iphlen, hlen);
1250 			ext->udp = NULL;
1251 			return;
1252 		}
1253 		break;
1254 	}
1255 
1256 	DNPRINTF(2, "%s%s%s%s%s%s ip %u, iph %u, tcph %u, payl %u",
1257 	    ext->eh ? "eh," : "", ext->evh ? "evh," : "",
1258 	    ext->ip4 ? "ip4," : "", ext->ip6 ? "ip6," : "",
1259 	    ext->tcp ? "tcp," : "", ext->udp ? "udp," : "",
1260 	    ext->iplen, ext->iphlen, ext->tcphlen, ext->paylen);
1261 }
1262 
1263 #if NAF_FRAME > 0
1264 
1265 #include <sys/socket.h>
1266 #include <sys/protosw.h>
1267 #include <sys/domain.h>
1268 
1269 /*
1270  * lock order is:
1271  *
1272  * - socket lock
1273  * - ether_pcb_lock
1274  * - socket buffer mtx
1275  */
1276 
1277 struct ether_pcb;
1278 
1279 struct ether_pcb_group {
1280 	TAILQ_ENTRY(ether_pcb_group)
1281 			 epg_entry;
1282 	struct ether_pcb *
1283 			 epg_pcb;
1284 	unsigned int	 epg_ifindex;
1285 	uint8_t		 epg_addr[ETHER_ADDR_LEN];
1286 	struct task	 epg_hook;
1287 };
1288 
1289 TAILQ_HEAD(ether_pcb_groups, ether_pcb_group);
1290 
1291 struct ether_pcb {
1292 	TAILQ_ENTRY(ether_pcb)
1293 			 ep_entry;
1294 	struct rwlock	 ep_lock;
1295 
1296 	struct socket	*ep_socket;
1297 
1298 	uint64_t	 ep_laddr;
1299 	uint64_t	 ep_faddr;
1300 	unsigned int	 ep_ifindex;
1301 	uint16_t	 ep_etype;
1302 
1303 	uint64_t	 ep_options;
1304 	int		 ep_txprio;
1305 
1306 	struct ether_pcb_groups
1307 			 ep_groups;
1308 };
1309 
1310 TAILQ_HEAD(ether_pcb_list, ether_pcb);
1311 
1312 static int	ether_frm_attach(struct socket *, int, int);
1313 static int	ether_frm_detach(struct socket *);
1314 static int	ether_frm_bind(struct socket *, struct mbuf *, struct proc *);
1315 static int	ether_frm_connect(struct socket *, struct mbuf *);
1316 static int	ether_frm_disconnect(struct socket *);
1317 static int	ether_frm_shutdown(struct socket *);
1318 static int	ether_frm_send(struct socket *, struct mbuf *, struct mbuf *,
1319 		    struct mbuf *);
1320 static int	ether_frm_sockaddr(struct socket *, struct mbuf *);
1321 static int	ether_frm_peeraddr(struct socket *, struct mbuf *);
1322 
1323 const struct pr_usrreqs ether_frm_usrreqs = {
1324 	.pru_attach	= ether_frm_attach,
1325 	.pru_detach	= ether_frm_detach,
1326 	.pru_bind	= ether_frm_bind,
1327 	.pru_connect	= ether_frm_connect,
1328 	.pru_disconnect	= ether_frm_disconnect,
1329 	.pru_shutdown	= ether_frm_shutdown,
1330 	.pru_send	= ether_frm_send,
1331 	.pru_sockaddr	= ether_frm_sockaddr,
1332 	.pru_peeraddr	= ether_frm_peeraddr,
1333 };
1334 
1335 static struct rwlock ether_pcb_lock = RWLOCK_INITIALIZER("ethsocks");
1336 static struct ether_pcb_list ether_pcbs = TAILQ_HEAD_INITIALIZER(ether_pcbs);
1337 
1338 static int
ether_frm_valid_etype(uint16_t etype)1339 ether_frm_valid_etype(uint16_t etype)
1340 {
1341 	switch (etype) {
1342 	case ETHERTYPE_LLDP:
1343 	case ETHERTYPE_EAPOL:
1344 		return (1);
1345 	}
1346 
1347 	return (0);
1348 }
1349 
1350 static int
ether_frm_nam2sfrm(struct sockaddr_frame ** sfrmp,const struct mbuf * nam)1351 ether_frm_nam2sfrm(struct sockaddr_frame **sfrmp, const struct mbuf *nam)
1352 {
1353 	struct sockaddr_frame *sfrm;
1354 
1355 	if (nam->m_len != sizeof(*sfrm))
1356 		return (EINVAL);
1357 
1358 	sfrm = mtod(nam, struct sockaddr_frame *);
1359 	if (sfrm->sfrm_family != AF_FRAME)
1360 		return (EAFNOSUPPORT);
1361 	*sfrmp = sfrm;
1362 	return (0);
1363 }
1364 
1365 static int
ether_frm_ifp(struct ifnet ** ifpp,const struct sockaddr_frame * sfrm)1366 ether_frm_ifp(struct ifnet **ifpp, const struct sockaddr_frame *sfrm)
1367 {
1368 	struct ifnet *ifp;
1369 
1370 	if (sfrm->sfrm_ifindex != 0)
1371 		ifp = if_get(sfrm->sfrm_ifindex);
1372 	else if (sfrm->sfrm_ifname[0] != '\0') {
1373 		KERNEL_LOCK();
1374 		ifp = if_unit(sfrm->sfrm_ifname);
1375 		KERNEL_UNLOCK();
1376 	} else {
1377 		*ifpp = NULL;
1378 		return (0);
1379 	}
1380 
1381 	if (ifp == NULL)
1382 		return (ENXIO);
1383 
1384 	if (ifp->if_type != IFT_ETHER) {
1385 		if_put(ifp);
1386 		return (EAFNOSUPPORT);
1387 	}
1388 
1389 	*ifpp = ifp;
1390 	return (0);
1391 }
1392 
1393 static int
ether_frm_attach(struct socket * so,int proto,int wait)1394 ether_frm_attach(struct socket *so, int proto, int wait)
1395 {
1396 	struct ether_pcb *ep;
1397 	int error;
1398 
1399 	if (so->so_pcb != NULL)
1400 		return (EINVAL);
1401 
1402 	error = suser(curproc);
1403 	if (error != 0)
1404 		return (error);
1405 
1406 	error = soreserve(so, MCLBYTES, MCLBYTES);
1407 	if (error != 0)
1408 		return (error);
1409 
1410 	ep = malloc(sizeof(*ep), M_PCB, (wait ? M_WAITOK : M_NOWAIT) | M_ZERO);
1411 	if (ep == NULL)
1412 		return (ENOMEM);
1413 
1414 	rw_init(&ep->ep_lock, "ethsock");
1415 
1416 	so->so_pcb = ep;
1417 	ep->ep_socket = so; /* shares a ref with the list */
1418 
1419 	ep->ep_txprio = IF_HDRPRIO_PACKET;
1420 	TAILQ_INIT(&ep->ep_groups);
1421 
1422 	/* give the ref to the list */
1423 	rw_enter_write(&ether_pcb_lock);
1424 	TAILQ_INSERT_TAIL(&ether_pcbs, ep, ep_entry);
1425 	rw_exit_write(&ether_pcb_lock);
1426 
1427 	return (0);
1428 }
1429 
1430 static int
ether_frm_detach(struct socket * so)1431 ether_frm_detach(struct socket *so)
1432 {
1433 	struct ether_pcb *ep;
1434 	struct ether_pcb_group *epg, *nepg;
1435 	struct ifnet *ifp;
1436 
1437 	soassertlocked(so);
1438 
1439 	ep = so->so_pcb;
1440 
1441 	/* take the ref from the list */
1442 	rw_enter_write(&ether_pcb_lock);
1443 	TAILQ_REMOVE(&ether_pcbs, ep, ep_entry);
1444 	rw_exit_write(&ether_pcb_lock);
1445 
1446 	so->so_pcb = NULL; /* shares a ref with the list */
1447 
1448 	/* XXX locking */
1449 	TAILQ_FOREACH_SAFE(epg, &ep->ep_groups, epg_entry, nepg) {
1450 		ifp = if_get(epg->epg_ifindex);
1451 		if (ifp != NULL) {
1452 			struct ifreq ifr;
1453 			struct sockaddr *sa;
1454 
1455 			if_detachhook_del(ifp, &epg->epg_hook);
1456 
1457 			memset(&ifr, 0, sizeof(ifr));
1458 			strlcpy(ifr.ifr_name, ifp->if_xname,
1459 			    sizeof(ifr.ifr_name));
1460 			sa = &ifr.ifr_addr;
1461 			sa->sa_family = AF_UNSPEC;
1462 			memcpy(sa->sa_data, &epg->epg_addr, ETHER_ADDR_LEN);
1463 
1464 			(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr);
1465 		}
1466 		if_put(ifp);
1467 
1468 		TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1469 		free(epg, M_PCB, sizeof(*epg));
1470 	}
1471 
1472 	free(ep, M_PCB, sizeof(*ep));
1473 
1474 	return (0);
1475 }
1476 
1477 static int
ether_frm_bind(struct socket * so,struct mbuf * nam,struct proc * p)1478 ether_frm_bind(struct socket *so, struct mbuf *nam, struct proc *p)
1479 {
1480 	struct sockaddr_frame *sfrm;
1481 	struct ether_pcb *ep;
1482 	struct ether_pcb *epe;
1483 	struct ifnet *ifp = NULL;
1484 	unsigned int ifindex = 0;
1485 	uint16_t etype;
1486 	uint64_t laddr;
1487 	int error;
1488 
1489 	soassertlocked(so);
1490 
1491 	error = ether_frm_nam2sfrm(&sfrm, nam);
1492 	if (error != 0)
1493 		return (error);
1494 
1495 	etype = ntohs(sfrm->sfrm_proto);
1496 	if (!ether_frm_valid_etype(etype))
1497 		return (EADDRNOTAVAIL);
1498 
1499 	ep = so->so_pcb;
1500 	if (ep->ep_etype != 0)
1501 		return (EINVAL);
1502 
1503 	error = ether_frm_ifp(&ifp, sfrm);
1504 	if (error != 0)
1505 		return (error);
1506 	if (ifp != NULL)
1507 		ifindex = ifp->if_index;
1508 
1509 	laddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1510 
1511 	rw_enter_write(&ether_pcb_lock);
1512 	TAILQ_FOREACH(epe, &ether_pcbs, ep_entry) {
1513 		if (ep == epe)
1514 			continue;
1515 
1516 		/* XXX check stuff */
1517 	}
1518 
1519 	if (error == 0) {
1520 		/* serialised by the socket lock */
1521 		ep->ep_etype = etype;
1522 		ep->ep_ifindex = ifindex;
1523 		ep->ep_laddr = laddr;
1524 	}
1525 	rw_exit_write(&ether_pcb_lock);
1526 
1527 	if_put(ifp);
1528 	return (error);
1529 }
1530 
1531 static int
ether_frm_connect(struct socket * so,struct mbuf * nam)1532 ether_frm_connect(struct socket *so, struct mbuf *nam)
1533 {
1534 	struct sockaddr_frame *sfrm;
1535 	struct ether_pcb *ep;
1536 	struct ether_pcb *epe;
1537 	struct ifnet *ifp = NULL;
1538 	uint64_t faddr;
1539 	uint16_t etype;
1540 	int error;
1541 
1542 	soassertlocked(so);
1543 
1544 	error = ether_frm_nam2sfrm(&sfrm, nam);
1545 	if (error != 0)
1546 		return (error);
1547 
1548 	etype = ntohs(sfrm->sfrm_proto);
1549 	if (!ether_frm_valid_etype(etype))
1550 		return (EADDRNOTAVAIL);
1551 
1552 	faddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1553 	if (faddr == 0)
1554 		return (EADDRNOTAVAIL);
1555 
1556 	error = ether_frm_ifp(&ifp, sfrm);
1557 	if (error != 0)
1558 		return (error);
1559 	if (ifp == NULL)
1560 		return (EADDRNOTAVAIL);
1561 
1562 	ep = so->so_pcb;
1563 	if (ep->ep_etype != 0) {
1564 		if (ep->ep_faddr != 0 ||
1565 		    ep->ep_etype != etype) {
1566 			error = EISCONN;
1567 			goto put;
1568 		}
1569 	}
1570 	if (ep->ep_ifindex != 0) {
1571 		if (ep->ep_ifindex != ifp->if_index) {
1572 			error = EADDRNOTAVAIL;
1573 			goto put;
1574 		}
1575 	}
1576 
1577 	rw_enter_write(&ether_pcb_lock);
1578 	TAILQ_FOREACH(epe, &ether_pcbs, ep_entry) {
1579 		if (ep == epe)
1580 			continue;
1581 		/* XXX check stuff */
1582 	}
1583 
1584 	if (error == 0) {
1585 		/* serialised by the socket lock */
1586 		ep->ep_etype = etype;
1587 		ep->ep_ifindex = ifp->if_index;
1588 		ep->ep_faddr = faddr;
1589 	}
1590 	rw_exit_write(&ether_pcb_lock);
1591 
1592 put:
1593 	if_put(ifp);
1594 	return (error);
1595 }
1596 
1597 static int
ether_frm_disconnect(struct socket * so)1598 ether_frm_disconnect(struct socket *so)
1599 {
1600 	struct ether_pcb *ep;
1601 
1602 	soassertlocked(so);
1603 
1604 	ep = so->so_pcb;
1605 	if (ep->ep_faddr == 0)
1606 		return (ENOTCONN);
1607 
1608 	rw_enter_write(&ether_pcb_lock);
1609 	ep->ep_ifindex = 0;
1610 	ep->ep_etype = 0;
1611 	ep->ep_laddr = 0;
1612 	ep->ep_faddr = 0;
1613 	rw_exit_write(&ether_pcb_lock);
1614 
1615 	return (0);
1616 }
1617 
1618 static int
ether_frm_shutdown(struct socket * so)1619 ether_frm_shutdown(struct socket *so)
1620 {
1621 	soassertlocked(so);
1622 	socantsendmore(so);
1623 	return (0);
1624 }
1625 
1626 static int
ether_frm_send(struct socket * so,struct mbuf * m,struct mbuf * nam,struct mbuf * control)1627 ether_frm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
1628     struct mbuf *control)
1629 {
1630 	struct ether_pcb *ep;
1631 	int error;
1632 	uint16_t etype;
1633 	uint64_t laddr;
1634 	uint64_t faddr;
1635 	struct ifnet *ifp = NULL;
1636 	struct arpcom *ac;
1637 	struct ether_header *eh;
1638 	int txprio;
1639 
1640 	soassertlocked_readonly(so);
1641 
1642 	ep = so->so_pcb;
1643 	KASSERTMSG(ep != NULL, "%s: NULL pcb on socket %p", __func__, so);
1644 	txprio = ep->ep_txprio;
1645 
1646 	/* XXX get prio out of a cmsg */
1647 	m_freem(control);
1648 
1649 	if (nam != NULL) {
1650 		struct sockaddr_frame *sfrm;
1651 
1652 		error = ether_frm_nam2sfrm(&sfrm, nam);
1653 		if (error != 0)
1654 			goto drop;
1655 
1656 		etype = ntohs(sfrm->sfrm_proto);
1657 		if (!ether_frm_valid_etype(etype)) {
1658 			error = EADDRNOTAVAIL;
1659 			goto drop;
1660 		}
1661 
1662 		if (ep->ep_faddr != 0) {
1663 			error = EISCONN;
1664 			goto drop;
1665 		}
1666 		faddr = ether_addr_to_e64((struct ether_addr *)sfrm->sfrm_addr);
1667 		if (faddr == 0) {
1668 			error = EADDRNOTAVAIL;
1669 			goto drop;
1670 		}
1671 
1672 		error = ether_frm_ifp(&ifp, sfrm);
1673 		if (error != 0)
1674 			goto drop;
1675 		if (ifp == NULL) {
1676 			ifp = if_get(ep->ep_ifindex);
1677 			if (ifp == NULL) {
1678 				error = EADDRNOTAVAIL;
1679 				goto drop;
1680 			}
1681 		} else {
1682 			if (ep->ep_ifindex != 0 &&
1683 			    ep->ep_ifindex != ifp->if_index) {
1684 				error = EADDRNOTAVAIL;
1685 				goto drop;
1686 			}
1687 		}
1688 
1689 		if (ep->ep_etype != etype) {
1690 			if (ep->ep_etype == 0) {
1691 				/* this is cheeky */
1692 				rw_enter_write(&ether_pcb_lock);
1693 				ep->ep_etype = etype;
1694 				rw_exit_write(&ether_pcb_lock);
1695 			} else {
1696 				error = EADDRNOTAVAIL;
1697 				goto drop;
1698 			}
1699 		}
1700 	} else {
1701 		faddr = ep->ep_faddr;
1702 		if (faddr == 0) {
1703 			error = ENOTCONN;
1704 			goto drop;
1705 		}
1706 
1707 		ifp = if_get(ep->ep_ifindex);
1708 		if (ifp == NULL) {
1709 			error = ENXIO;
1710 			goto drop;
1711 		}
1712 
1713 		etype = ep->ep_etype;
1714 	}
1715 
1716 	if (ifp->if_type != IFT_ETHER) {
1717 		error = EAFNOSUPPORT;
1718 		goto drop;
1719 	}
1720 
1721 	ac = (struct arpcom *)ifp;
1722 
1723 	laddr = ether_addr_to_e64((struct ether_addr *)ac->ac_enaddr);
1724 	if (ep->ep_laddr != laddr) {
1725 		if (ep->ep_laddr != 0) {
1726 			error = EADDRNOTAVAIL;
1727 			goto drop;
1728 		}
1729 	}
1730 
1731 	m = m_prepend(m, ETHER_ALIGN + sizeof(*eh), M_NOWAIT);
1732 	if (m == NULL)
1733 		goto drop;
1734 	m_adj(m, ETHER_ALIGN);
1735 
1736 	if (txprio != IF_HDRPRIO_PACKET)
1737 		m->m_pkthdr.pf.prio = txprio;
1738 
1739 	eh = mtod(m, struct ether_header *);
1740 	ether_e64_to_addr((struct ether_addr *)eh->ether_dhost, faddr);
1741 	ether_e64_to_addr((struct ether_addr *)eh->ether_shost, laddr);
1742 	eh->ether_type = htons(etype);
1743 
1744 	error = if_enqueue(ifp, m);
1745 	m = NULL;
1746 
1747 drop:
1748 	if_put(ifp);
1749 	m_freem(m);
1750 	return (error);
1751 }
1752 
1753 static int
ether_frm_sockaddr_frame(struct ether_pcb * ep,struct mbuf * nam,uint64_t addr)1754 ether_frm_sockaddr_frame(struct ether_pcb *ep, struct mbuf *nam, uint64_t addr)
1755 {
1756 	struct sockaddr_frame *sfrm;
1757 	struct ifnet *ifp;
1758 
1759 	nam->m_len = sizeof(*sfrm);
1760 	sfrm = mtod(nam, struct sockaddr_frame *);
1761 	memset(sfrm, 0, sizeof(*sfrm));
1762 	sfrm->sfrm_len = sizeof(*sfrm);
1763 	sfrm->sfrm_family = AF_FRAME;
1764 
1765 	ether_e64_to_addr((struct ether_addr *)sfrm->sfrm_addr, addr);
1766 
1767 	if (ep->ep_etype) {
1768 		sfrm->sfrm_proto = htons(ep->ep_etype);
1769 		sfrm->sfrm_ifindex = ep->ep_ifindex;
1770 
1771 		ifp = if_get(ep->ep_ifindex);
1772 		if (ifp != NULL) {
1773 			strlcpy(sfrm->sfrm_ifname, ifp->if_xname,
1774 			    sizeof(sfrm->sfrm_ifname));
1775 		}
1776 		if_put(ifp);
1777 	}
1778 
1779 	return (0);
1780 }
1781 
1782 static int
ether_frm_sockaddr(struct socket * so,struct mbuf * nam)1783 ether_frm_sockaddr(struct socket *so, struct mbuf *nam)
1784 {
1785 	struct ether_pcb *ep = so->so_pcb;
1786 
1787 	return (ether_frm_sockaddr_frame(ep, nam, ep->ep_laddr));
1788 }
1789 
1790 static int
ether_frm_peeraddr(struct socket * so,struct mbuf * nam)1791 ether_frm_peeraddr(struct socket *so, struct mbuf *nam)
1792 {
1793 	struct ether_pcb *ep = so->so_pcb;
1794 
1795 	return (ether_frm_sockaddr_frame(ep, nam, ep->ep_faddr));
1796 }
1797 
1798 static void
ether_frm_group_detach(void * arg)1799 ether_frm_group_detach(void *arg)
1800 {
1801 	struct ether_pcb_group *epg = arg;
1802 	struct ether_pcb *ep = epg->epg_pcb;
1803 	struct socket *so = ep->ep_socket;
1804 	struct ifnet *ifp;
1805 
1806 	ifp = if_get(epg->epg_ifindex);
1807 
1808 	/* XXX locking^Wreference counts */
1809 	solock(so);
1810 	if (ifp != NULL)
1811 		if_detachhook_del(ifp, &epg->epg_hook);
1812 	TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1813 	sounlock(so);
1814 
1815 	if_put(ifp);
1816 	free(epg, M_PCB, sizeof(*epg));
1817 }
1818 
1819 static int
ether_frm_group(struct socket * so,int optname,struct mbuf * m)1820 ether_frm_group(struct socket *so, int optname, struct mbuf *m)
1821 {
1822 	struct frame_mreq *fmr;
1823 	struct ifreq ifr;
1824 	struct sockaddr *sa;
1825 	struct ifnet *ifp;
1826 	struct ether_pcb *ep;
1827 	struct ether_pcb_group *epg;
1828 	u_long cmd;
1829 	int error;
1830 
1831 	soassertlocked(so);
1832 
1833 	if (m->m_len != sizeof(*fmr))
1834 		return (EINVAL);
1835 
1836 	fmr = mtod(m, struct frame_mreq *);
1837 	if (!ETHER_IS_MULTICAST(fmr->fmr_addr))
1838 		return (EADDRNOTAVAIL);
1839 
1840 	if (fmr->fmr_ifindex == 0) {
1841 		KERNEL_LOCK();
1842 		ifp = if_unit(fmr->fmr_ifname);
1843 		KERNEL_UNLOCK();
1844 	} else
1845 		ifp = if_get(fmr->fmr_ifindex);
1846 	if (ifp == NULL)
1847 		return (ENXIO);
1848 
1849 	if (ifp->if_type != IFT_ETHER) {
1850 		error = EADDRNOTAVAIL;
1851 		goto put;
1852 	}
1853 
1854 	if (ETHER_IS_BROADCAST(fmr->fmr_addr)) {
1855 		error = 0;
1856 		goto put;
1857 	}
1858 
1859 	ep = so->so_pcb;
1860 	TAILQ_FOREACH(epg, &ep->ep_groups, epg_entry) {
1861 		if (epg->epg_ifindex != ifp->if_index)
1862 			continue;
1863 		if (!ETHER_IS_EQ(epg->epg_addr, fmr->fmr_addr))
1864 			continue;
1865 
1866 		break;
1867 	}
1868 
1869 	switch (optname) {
1870 	case FRAME_ADD_MEMBERSHIP:
1871 		if (epg != NULL) {
1872 			error = EISCONN;
1873 			goto put;
1874 		}
1875 		epg = malloc(sizeof(*epg), M_PCB, M_DONTWAIT);
1876 		if (epg == NULL) {
1877 			error = ENOMEM;
1878 			goto put;
1879 		}
1880 
1881 		epg->epg_pcb = ep;
1882 		epg->epg_ifindex = ifp->if_index;
1883 		memcpy(&epg->epg_addr, fmr->fmr_addr, sizeof(epg->epg_addr));
1884 		task_set(&epg->epg_hook, ether_frm_group_detach, epg);
1885 
1886 		cmd = SIOCADDMULTI;
1887 		break;
1888 	case FRAME_DEL_MEMBERSHIP:
1889 		if (epg == NULL) {
1890 			error = ENOTCONN;
1891 			goto put;
1892 		}
1893 		cmd = SIOCDELMULTI;
1894 		break;
1895 	default:
1896 		panic("%s: unexpected optname %d", __func__, optname);
1897 		/* NOTREACHED */
1898 	}
1899 
1900 	memset(&ifr, 0, sizeof(ifr));
1901 	strlcpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name));
1902 	sa = &ifr.ifr_addr;
1903 	sa->sa_family = AF_UNSPEC;
1904 	memcpy(sa->sa_data, fmr->fmr_addr, ETHER_ADDR_LEN);
1905 
1906 	/* XXX soref? */
1907 	/* this could lead to multiple epgs for the same if/group */
1908 	sounlock(so);
1909 	KERNEL_LOCK();
1910 	NET_LOCK();
1911 	error = (*ifp->if_ioctl)(ifp, cmd, (caddr_t)&ifr);
1912 	NET_UNLOCK();
1913 	KERNEL_UNLOCK();
1914 	solock(so);
1915 
1916 	switch (optname) {
1917 	case FRAME_ADD_MEMBERSHIP:
1918 		if (error != 0) {
1919 			free(epg, M_PCB, sizeof(*epg));
1920 			break;
1921 		}
1922 
1923 		TAILQ_INSERT_TAIL(&ep->ep_groups, epg, epg_entry);
1924 		if_detachhook_add(ifp, &epg->epg_hook);
1925 		break;
1926 	case FRAME_DEL_MEMBERSHIP:
1927 		if (error != 0)
1928 			break;
1929 
1930 		if_detachhook_del(ifp, &epg->epg_hook);
1931 		TAILQ_REMOVE(&ep->ep_groups, epg, epg_entry);
1932 		free(epg, M_PCB, sizeof(*epg));
1933 		break;
1934 	}
1935 put:
1936 	if_put(ifp);
1937 
1938 	return (error);
1939 }
1940 
1941 #define ETHER_PCB_OPTM(_v)	(1ULL << (_v))
1942 
1943 #define ETHER_PCB_OPTS				\
1944 	ETHER_PCB_OPTM(FRAME_RECVDSTADDR) |	\
1945 	ETHER_PCB_OPTM(FRAME_RECVPRIO)
1946 
1947 static int
ether_frm_setopt(struct ether_pcb * ep,int optname,struct mbuf * m)1948 ether_frm_setopt(struct ether_pcb *ep, int optname, struct mbuf *m)
1949 {
1950 	uint64_t optm = ETHER_PCB_OPTM(optname);
1951 	int opt;
1952 
1953 	if (!ISSET(ETHER_PCB_OPTS, optm))
1954 		return (ENOPROTOOPT);
1955 
1956 	if (m->m_len != sizeof(opt))
1957 		return (EINVAL);
1958 
1959 	opt = *mtod(m, int *);
1960 	if (opt)
1961 		SET(ep->ep_options, optm);
1962 	else
1963 		CLR(ep->ep_options, optm);
1964 
1965 	return (0);
1966 }
1967 
1968 static int
ether_frm_setsockopt(struct socket * so,int optname,struct mbuf * m)1969 ether_frm_setsockopt(struct socket *so, int optname, struct mbuf *m)
1970 {
1971 	struct ether_pcb *ep = so->so_pcb;
1972 	int error = ENOPROTOOPT;
1973 	int v;
1974 
1975 	if (optname >= 0 && optname < 64)
1976 		return (ether_frm_setopt(ep, optname, m));
1977 
1978 	switch (optname) {
1979 	case FRAME_ADD_MEMBERSHIP:
1980 	case FRAME_DEL_MEMBERSHIP:
1981 		error = ether_frm_group(so, optname, m);
1982 		break;
1983 	case FRAME_SENDPRIO:
1984 		if (m->m_len != sizeof(v)) {
1985 			error = EINVAL;
1986 			break;
1987 		}
1988 		v = *mtod(m, int *);
1989 		error = if_txhprio_l2_check(v);
1990 		if (error != 0)
1991 			break;
1992 		ep->ep_txprio = v;
1993 		break;
1994 
1995 	default:
1996 		break;
1997 	}
1998 
1999 	return (error);
2000 }
2001 
2002 static int
ether_frm_getopt(struct ether_pcb * ep,int optname,struct mbuf * m)2003 ether_frm_getopt(struct ether_pcb *ep, int optname, struct mbuf *m)
2004 {
2005 	uint64_t optm = ETHER_PCB_OPTM(optname);
2006 	int opt;
2007 
2008 	if (!ISSET(ETHER_PCB_OPTS, optm))
2009 		return (ENOPROTOOPT);
2010 
2011 	opt = !!ISSET(ep->ep_options, optm);
2012 
2013 	m->m_len = sizeof(opt);
2014 	*mtod(m, int *) = opt;
2015 
2016 	return (0);
2017 }
2018 
2019 static int
ether_frm_getsockopt(struct socket * so,int optname,struct mbuf * m)2020 ether_frm_getsockopt(struct socket *so, int optname, struct mbuf *m)
2021 {
2022 	struct ether_pcb *ep = so->so_pcb;
2023 	int error = ENOPROTOOPT;
2024 
2025 	if (optname >= 0 && optname < 64)
2026 		return (ether_frm_getopt(ep, optname, m));
2027 
2028 	switch (optname) {
2029 	default:
2030 		break;
2031 	}
2032 
2033 	return (error);
2034 }
2035 
2036 int
ether_frm_ctloutput(int op,struct socket * so,int level,int optname,struct mbuf * m)2037 ether_frm_ctloutput(int op, struct socket *so, int level, int optname,
2038     struct mbuf *m)
2039 {
2040 	int error = 0;
2041 
2042 	if (level != IFT_ETHER)
2043 		return (EINVAL);
2044 
2045 	switch (op) {
2046 	case PRCO_SETOPT:
2047 		error = ether_frm_setsockopt(so, optname, m);
2048 		break;
2049 	case PRCO_GETOPT:
2050 		error = ether_frm_getsockopt(so, optname, m);
2051 		break;
2052 	}
2053 
2054 	return (error);
2055 }
2056 
2057 static struct mbuf *
ether_frm_cmsg(struct mbuf * cmsgs,const void * data,size_t datalen,int type,int level)2058 ether_frm_cmsg(struct mbuf *cmsgs, const void *data, size_t datalen,
2059     int type, int level)
2060 {
2061 	struct mbuf *cm;
2062 
2063 	cm = sbcreatecontrol(data, datalen, type, level);
2064 	if (cm != NULL) {
2065 		cm->m_next = cmsgs;
2066 		cmsgs = cm;
2067 	}
2068 
2069 	return (cmsgs);
2070 }
2071 
2072 static void
ether_frm_recv(struct socket * so,struct mbuf * m0,const struct sockaddr_frame * sfrm)2073 ether_frm_recv(struct socket *so, struct mbuf *m0,
2074     const struct sockaddr_frame *sfrm)
2075 {
2076 	struct ether_pcb *ep = so->so_pcb;
2077 	struct mbuf *m;
2078 	struct mbuf *cmsgs = NULL;
2079 	int ok;
2080 
2081 	/* offset 0 and m_adj cos sbappendaddr needs m_pkthdr.len */
2082 	m = m_copym(m0, 0, M_COPYALL, M_DONTWAIT);
2083 	if (m == NULL)
2084 		return;
2085 	m_adj(m, sizeof(struct ether_header));
2086 
2087 	if (ISSET(ep->ep_options, ETHER_PCB_OPTM(FRAME_RECVPRIO))) {
2088 		int rxprio = m0->m_pkthdr.pf.prio;
2089 		cmsgs = ether_frm_cmsg(cmsgs, &rxprio, sizeof(rxprio),
2090 		    FRAME_RECVPRIO, IFT_ETHER);
2091 	}
2092 
2093 	if (ISSET(ep->ep_options, ETHER_PCB_OPTM(FRAME_RECVDSTADDR))) {
2094 		struct ether_header *eh = mtod(m0, struct ether_header *);
2095 		cmsgs = ether_frm_cmsg(cmsgs, eh->ether_dhost, ETHER_ADDR_LEN,
2096 		    FRAME_RECVDSTADDR, IFT_ETHER);
2097 	}
2098 
2099 	if (ISSET(so->so_options, SO_TIMESTAMP)) {
2100 		struct timeval tv;
2101 		m_microtime(m0, &tv);
2102 		cmsgs = ether_frm_cmsg(cmsgs, &tv, sizeof(tv),
2103 		    SCM_TIMESTAMP, SOL_SOCKET);
2104 	}
2105 
2106 	mtx_enter(&so->so_rcv.sb_mtx);
2107 	ok = sbappendaddr(so, &so->so_rcv, (struct sockaddr *)sfrm, m, cmsgs);
2108 	mtx_leave(&so->so_rcv.sb_mtx);
2109 
2110 	if (!ok) {
2111 		m_freem(m);
2112 		m_freem(cmsgs);
2113 		return;
2114 	}
2115 
2116 	sorwakeup(so);
2117 }
2118 
2119 static struct mbuf *
ether_frm_input(struct ifnet * ifp,struct mbuf * m,uint64_t dst,uint16_t etype)2120 ether_frm_input(struct ifnet *ifp, struct mbuf *m, uint64_t dst, uint16_t etype)
2121 {
2122 	struct sockaddr_frame sfrm = { .sfrm_family = AF_UNSPEC };
2123 	struct ether_pcb *ep;
2124 	struct ether_header *eh;
2125 	uint64_t src;
2126 
2127 	if (TAILQ_EMPTY(&ether_pcbs))
2128 		return (m);
2129 
2130 	eh = mtod(m, struct ether_header *);
2131 	src = ether_addr_to_e64((struct ether_addr *)eh->ether_shost);
2132 	if (src == 0)
2133 		return (m);
2134 
2135 	rw_enter_read(&ether_pcb_lock);
2136 	TAILQ_FOREACH(ep, &ether_pcbs, ep_entry) {
2137 		if (ep->ep_etype == 0) /* bound? */
2138 			continue;
2139 		if (ep->ep_etype != etype)
2140 			continue;
2141 		if (ep->ep_ifindex != 0) {
2142 			if (ep->ep_ifindex != ifp->if_index)
2143 				continue;
2144 		}
2145 
2146 		if (ep->ep_laddr != 0) {
2147 			if (ep->ep_laddr != dst)
2148 				continue;
2149 		}
2150 		/* ether_input says dst is valid for local delivery */
2151 
2152 		if (ep->ep_faddr != 0) { /* connected? */
2153 			if (ep->ep_faddr != src)
2154 				continue;
2155 		}
2156 
2157 		if (sfrm.sfrm_family == AF_UNSPEC) {
2158 			sfrm.sfrm_len = sizeof(sfrm);
2159 			sfrm.sfrm_family = AF_FRAME;
2160 			sfrm.sfrm_proto = htons(etype);
2161 			sfrm.sfrm_ifindex = ifp->if_index;
2162 			ether_e64_to_addr((struct ether_addr *)sfrm.sfrm_addr,
2163 			    src);
2164 			strlcpy(sfrm.sfrm_ifname, ifp->if_xname,
2165 			    sizeof(sfrm.sfrm_ifname));
2166 		}
2167 
2168 		ether_frm_recv(ep->ep_socket, m, &sfrm);
2169 	}
2170 	rw_exit_read(&ether_pcb_lock);
2171 
2172 	return (m);
2173 }
2174 
2175 #endif /* NAF_FRAME */
2176