X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..36401178fd6817c043cc00b0c00c7f723e58efae:/bsd/net/if_loop.c diff --git a/bsd/net/if_loop.c b/bsd/net/if_loop.c index ee62c35a1..67e5f1f81 100644 --- a/bsd/net/if_loop.c +++ b/bsd/net/if_loop.c @@ -1,31 +1,29 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. The rights granted to you under the - * License may not be used to create, or enable the creation or - * redistribution of, unlawful or unlicensed copies of an Apple operating - * system, or to circumvent, violate, or enable the circumvention or - * violation of, any terms of an Apple operating system software license - * agreement. - * - * Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and * limitations under the License. - * - * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1982, 1986, 1993 @@ -62,6 +60,12 @@ * @(#)if_loop.c 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/net/if_loop.c,v 1.47.2.5 2001/07/03 11:01:41 ume Exp $ */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2006 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* * Loopback interface driver for protocol testing and timing. @@ -87,13 +91,8 @@ #include #endif -#if IPX -#include -#include -#endif - #if INET6 -#ifndef INET +#if !INET #include #endif #include @@ -112,6 +111,10 @@ extern struct ifqueue atalkintrq; #include #endif +#if CONFIG_MACF_NET +#include +#endif + #define NLOOP_ATTACHMENTS (NLOOP * 12) struct lo_statics_str { @@ -119,7 +122,7 @@ struct lo_statics_str { bpf_packet_func bpf_callback; }; -void loopattach(void *dummy); +void loopattach(void); static struct lo_statics_str lo_statics[NLOOP]; int loopattach_done = 0; /* used to sync ip6_init2 loopback configuration */ @@ -130,14 +133,13 @@ int loopattach_done = 0; /* used to sync ip6_init2 loopback configuration */ #define LOMTU 16384 #endif -struct ifnet loif[NLOOP]; -struct ifnet *lo_ifp = &loif[0]; +ifnet_t lo_ifp = NULL; struct loopback_header { - u_long protocol; + protocol_family_t protocol; }; -void lo_reg_if_mods(void); +static void lo_reg_if_mods(void); /* Local forward declerations */ @@ -174,9 +176,10 @@ lo_framer( static errno_t lo_add_proto( - __unused struct ifnet *ifp, - __unused u_long protocol_family, - __unused struct ddesc_head_str *demux_desc_head) + __unused ifnet_t interface, + __unused protocol_family_t protocol_family, + __unused const struct ifnet_demux_desc *demux_array, + __unused u_int32_t demux_count) { return 0; } @@ -192,59 +195,48 @@ lo_del_proto( static int lo_output( - struct ifnet *ifp, - struct mbuf *m) + ifnet_t ifp, + mbuf_t m_list) { + mbuf_t m; + + for (m = m_list; m; m = m->m_nextpkt) { + if ((m->m_flags & M_PKTHDR) == 0) + panic("lo_output: no HDR"); - if ((m->m_flags & M_PKTHDR) == 0) - panic("lo_output: no HDR"); - - /* - * Don't overwrite the rcvif field if it is in use. - * This is used to match multicast packets, sent looping - * back, with the appropriate group record on input. - */ - if (m->m_pkthdr.rcvif == NULL) - m->m_pkthdr.rcvif = ifp; - - ifp->if_ibytes += m->m_pkthdr.len; - ifp->if_obytes += m->m_pkthdr.len; + /* + * Don't overwrite the rcvif field if it is in use. + * This is used to match multicast packets, sent looping + * back, with the appropriate group record on input. + */ + if (m->m_pkthdr.rcvif == NULL) + m->m_pkthdr.rcvif = ifp; - ifp->if_opackets++; - ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + ifp->if_obytes += m->m_pkthdr.len; - m->m_pkthdr.header = mtod(m, char *); - m->m_pkthdr.csum_data = 0xffff; /* loopback checksums are always OK */ - m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR | - CSUM_IP_CHECKED | CSUM_IP_VALID; - m_adj(m, sizeof(struct loopback_header)); + ifp->if_opackets++; + ifp->if_ipackets++; -#if NBPFILTER > 0 - if (lo_statics[ifp->if_unit].bpf_mode != BPF_TAP_DISABLE) { - struct mbuf m0, *n; - - n = m; - if (ifp->if_bpf->bif_dlt == DLT_NULL) { - struct loopback_header *header; - /* - * We need to prepend the address family as - * a four byte field. Cons up a dummy header - * to pacify bpf. This is safe because bpf - * will only read from the mbuf (i.e., it won't - * try to free it or keep a pointer a to it). - */ - header = (struct loopback_header*)m->m_pkthdr.header; - m0.m_next = m; - m0.m_len = 4; - m0.m_data = (char *)&header->protocol; - n = &m0; + m->m_pkthdr.header = mtod(m, char *); + if (apple_hwcksum_tx != 0) { + /* loopback checksums are always OK */ + m->m_pkthdr.csum_data = 0xffff; + m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_PSEUDO_HDR | + CSUM_IP_CHECKED | CSUM_IP_VALID; + } + m_adj(m, sizeof(struct loopback_header)); + + { + /* We need to prepend the address family as a four byte field. */ + u_int32_t protocol_family = + ((struct loopback_header*)m->m_pkthdr.header)->protocol; + + bpf_tap_out(ifp, DLT_NULL, m, &protocol_family, sizeof(protocol_family)); } - - lo_statics[ifp->if_unit].bpf_callback(ifp, n); } -#endif - return dlil_input(ifp, m, m); + return ifnet_input(ifp, m_list, NULL); } @@ -253,18 +245,20 @@ lo_output( * (should?) be split into separate pre-output routines for each protocol. */ -static int +static errno_t lo_pre_output( - __unused struct ifnet *ifp, - u_long protocol_family, - struct mbuf **m, + __unused ifnet_t ifp, + protocol_family_t protocol_family, + mbuf_t *m, __unused const struct sockaddr *dst, - caddr_t route, - char *frame_type, - __unused char *dst_addr) + void *route, + char *frame_type, + __unused char *dst_addr) { - register struct rtentry *rt = (struct rtentry *) route; + register struct rtentry *rt = route; + + (*m)->m_flags |= M_LOOP; if (((*m)->m_flags & M_PKTHDR) == 0) panic("looutput no HDR"); @@ -278,7 +272,7 @@ lo_pre_output( return ((rt->rt_flags & RTF_HOST) ? EHOSTUNREACH : ENETUNREACH); } - *(u_long *)frame_type = protocol_family; + *(protocol_family_t*)frame_type = protocol_family; return 0; } @@ -287,13 +281,11 @@ lo_pre_output( * lo_input - This should work for all attached protocols that use the * ifq/schednetisr input mechanism. */ -static int +static errno_t lo_input( - struct mbuf *m, - __unused char *fh, - __unused struct ifnet *ifp, - __unused u_long protocol_family, - __unused int sync_ok) + __unused ifnet_t ifp, + __unused protocol_family_t protocol_family, + mbuf_t m) { if (proto_input(protocol_family, m) != 0) m_freem(m); @@ -385,39 +377,35 @@ loioctl( #endif /* NLOOP > 0 */ -static int lo_attach_proto(struct ifnet *ifp, u_long protocol_family) +static errno_t lo_attach_proto(ifnet_t ifp, protocol_family_t protocol_family) { - struct dlil_proto_reg_str reg; - int stat =0 ; + struct ifnet_attach_proto_param_v2 proto; + errno_t result = 0; - bzero(®, sizeof(reg)); - TAILQ_INIT(®.demux_desc_head); - reg.interface_family = ifp->if_family; - reg.unit_number = ifp->if_unit; - reg.input = lo_input; - reg.pre_output = lo_pre_output; - reg.protocol_family = protocol_family; + bzero(&proto, sizeof(proto)); + proto.input = lo_input; + proto.pre_output = lo_pre_output; - stat = dlil_attach_protocol(®); + result = ifnet_attach_protocol_v2(ifp, protocol_family, &proto); - if (stat && stat != EEXIST) { - printf("lo_attach_proto: dlil_attach_protocol for %d returned=%d\n", - protocol_family, stat); + if (result && result != EEXIST) { + printf("lo_attach_proto: ifnet_attach_protocol for %u returned=%d\n", + protocol_family, result); } - return stat; + return result; } -void lo_reg_if_mods() +static void lo_reg_if_mods(void) { int error; /* Register protocol registration functions */ - if ((error = dlil_reg_proto_module(PF_INET, APPLE_IF_FAM_LOOPBACK, lo_attach_proto, NULL)) != 0) - printf("dlil_reg_proto_module failed for AF_INET error=%d\n", error); + if ((error = proto_register_plumber(PF_INET, APPLE_IF_FAM_LOOPBACK, lo_attach_proto, NULL)) != 0) + printf("proto_register_plumber failed for AF_INET error=%d\n", error); - if ((error = dlil_reg_proto_module(PF_INET6, APPLE_IF_FAM_LOOPBACK, lo_attach_proto, NULL)) != 0) - printf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error); + if ((error = proto_register_plumber(PF_INET6, APPLE_IF_FAM_LOOPBACK, lo_attach_proto, NULL)) != 0) + printf("proto_register_plumber failed for AF_INET6 error=%d\n", error); } static errno_t @@ -445,38 +433,55 @@ lo_set_bpf_tap( /* ARGSUSED */ void -loopattach( - __unused void *dummy) +loopattach(void) { - struct ifnet *ifp; - int i = 0; + struct ifnet_init_params lo_init; + errno_t result = 0; - lo_reg_if_mods(); +#if NLOOP != 1 +More than one loopback interface is not supported. +#endif - for (ifp = loif; i < NLOOP; ifp++) { - lo_statics[i].bpf_callback = 0; - lo_statics[i].bpf_mode = BPF_TAP_DISABLE; - bzero(ifp, sizeof(struct ifnet)); - ifp->if_name = "lo"; - ifp->if_family = APPLE_IF_FAM_LOOPBACK; - ifp->if_unit = i++; - ifp->if_mtu = LOMTU; - ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; - ifp->if_ioctl = loioctl; - ifp->if_demux = lo_demux; - ifp->if_framer = lo_framer; - ifp->if_add_proto = lo_add_proto; - ifp->if_del_proto = lo_del_proto; - ifp->if_set_bpf_tap = lo_set_bpf_tap; - ifp->if_output = lo_output; - ifp->if_type = IFT_LOOP; - ifp->if_hwassist = IF_HWASSIST_CSUM_IP | IF_HWASSIST_CSUM_TCP | IF_HWASSIST_CSUM_UDP; - ifp->if_hdrlen = sizeof(struct loopback_header); - lo_ifp = ifp; - dlil_if_attach(ifp); -#if NBPFILTER > 0 - bpfattach(ifp, DLT_NULL, sizeof(u_int)); + lo_reg_if_mods(); + + lo_statics[0].bpf_callback = 0; + lo_statics[0].bpf_mode = BPF_TAP_DISABLE; + + bzero(&lo_init, sizeof(lo_init)); + lo_init.name = "lo"; + lo_init.unit = 0; + lo_init.family = IFNET_FAMILY_LOOPBACK; + lo_init.type = IFT_LOOP; + lo_init.output = lo_output; + lo_init.demux = lo_demux; + lo_init.add_proto = lo_add_proto; + lo_init.del_proto = lo_del_proto; + lo_init.framer = lo_framer; + lo_init.softc = &lo_statics[0]; + lo_init.ioctl = loioctl; + lo_init.set_bpf_tap = lo_set_bpf_tap; + result = ifnet_allocate(&lo_init, &lo_ifp); + if (result != 0) { + printf("ifnet_allocate for lo0 failed - %d\n", result); + return; + } + + ifnet_set_mtu(lo_ifp, LOMTU); + ifnet_set_flags(lo_ifp, IFF_LOOPBACK | IFF_MULTICAST, IFF_LOOPBACK | IFF_MULTICAST); + ifnet_set_offload(lo_ifp, IFNET_CSUM_IP | IFNET_CSUM_TCP | IFNET_CSUM_UDP | IFNET_CSUM_FRAGMENT | IFNET_IP_FRAGMENT | IFNET_MULTIPAGES); + ifnet_set_hdrlen(lo_ifp, sizeof(struct loopback_header)); + ifnet_set_eflags(lo_ifp, IFEF_SENDLIST, IFEF_SENDLIST); + +#if CONFIG_MACF_NET + mac_ifnet_label_init(ifp); #endif + + result = ifnet_attach(lo_ifp, NULL); + if (result != 0) { + printf("ifnet_attach lo0 failed - %d\n", result); + return; } + bpfattach(lo_ifp, DLT_NULL, sizeof(u_int)); + loopattach_done = 1; }