X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..d9a64523371fa019c4575bb400cbbc3a50ac9903:/bsd/net/kpi_protocol.c diff --git a/bsd/net/kpi_protocol.c b/bsd/net/kpi_protocol.c index 6c3043c94..6265a4b4b 100644 --- a/bsd/net/kpi_protocol.c +++ b/bsd/net/kpi_protocol.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2004-2010 Apple Inc. All rights reserved. + * Copyright (c) 2004-2013 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_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 @@ -11,10 +11,10 @@ * 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, @@ -22,7 +22,7 @@ * 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_OSREFERENCE_LICENSE_HEADER_END@ */ @@ -44,167 +44,141 @@ typedef int (*attach_t)(struct ifnet *ifp, uint32_t protocol_family); typedef int (*detach_t)(struct ifnet *ifp, uint32_t protocol_family); struct proto_input_entry { - struct proto_input_entry *next; - int detach; - struct domain *domain; - int hash; - int chain; - - protocol_family_t protocol; - proto_input_handler input; + struct proto_input_entry *next; + int detach; + struct domain *domain; + int hash; + int chain; + + protocol_family_t protocol; + proto_input_handler input; proto_input_detached_handler detached; - - mbuf_t inject_first; - mbuf_t inject_last; - - struct proto_input_entry *input_next; - mbuf_t input_first; - mbuf_t input_last; + + mbuf_t inject_first; + mbuf_t inject_last; + + struct proto_input_entry *input_next; + mbuf_t input_first; + mbuf_t input_last; }; struct proto_family_str { TAILQ_ENTRY(proto_family_str) proto_fam_next; - protocol_family_t proto_family; - ifnet_family_t if_family; - proto_plumb_handler attach_proto; - proto_unplumb_handler detach_proto; + protocol_family_t proto_family; + ifnet_family_t if_family; + proto_plumb_handler attach_proto; + proto_unplumb_handler detach_proto; }; -#define PROTO_HASH_SLOTS 5 - -static struct proto_input_entry *proto_hash[PROTO_HASH_SLOTS]; -static int proto_total_waiting = 0; -static struct proto_input_entry *proto_input_add_list = NULL; -static lck_mtx_t *proto_family_mutex = 0; -static TAILQ_HEAD(, proto_family_str) proto_family_head = - TAILQ_HEAD_INITIALIZER(proto_family_head); - -extern lck_mtx_t *domain_proto_mtx; -extern struct dlil_threading_info *dlil_lo_thread_ptr; - -static int -proto_hash_value( - protocol_family_t protocol) -{ - switch(protocol) { - case PF_INET: - return 0; - case PF_INET6: - return 1; - case PF_APPLETALK: - return 2; - case PF_VLAN: - return 3; - } - return 4; -} +static struct proto_input_entry *proto_hash[PROTO_HASH_SLOTS]; +static int proto_total_waiting = 0; +static struct proto_input_entry *proto_input_add_list = NULL; +decl_lck_mtx_data(static, proto_family_mutex_data); +static lck_mtx_t *proto_family_mutex = &proto_family_mutex_data; +static TAILQ_HEAD(, proto_family_str) proto_family_head = + TAILQ_HEAD_INITIALIZER(proto_family_head); __private_extern__ void proto_kpi_init(void) { - lck_grp_attr_t *grp_attrib = 0; - lck_attr_t *lck_attrib = 0; - lck_grp_t *lck_group = 0; - + lck_grp_attr_t *grp_attrib = NULL; + lck_attr_t *lck_attrib = NULL; + lck_grp_t *lck_group = NULL; + /* Allocate a mtx lock */ grp_attrib = lck_grp_attr_alloc_init(); lck_group = lck_grp_alloc_init("protocol kpi", grp_attrib); lck_grp_attr_free(grp_attrib); lck_attrib = lck_attr_alloc_init(); - proto_family_mutex = lck_mtx_alloc_init(lck_group, lck_attrib); + lck_mtx_init(proto_family_mutex, lck_group, lck_attrib); lck_grp_free(lck_group); lck_attr_free(lck_attrib); - - bzero(proto_hash, sizeof(proto_hash)); + + bzero(proto_hash, sizeof (proto_hash)); } __private_extern__ errno_t -proto_register_input( - protocol_family_t protocol, - proto_input_handler input, - proto_input_detached_handler detached, - int chains) +proto_register_input(protocol_family_t protocol, proto_input_handler input, + proto_input_detached_handler detached, int chains) { - struct proto_input_entry *entry; - struct dlil_threading_info *thread = dlil_lo_thread_ptr; - - entry = _MALLOC(sizeof(*entry), M_IFADDR, M_WAITOK); - + struct dlil_threading_info *inp = dlil_main_input_thread; + struct domain *dp; + domain_guard_t guard; + + entry = _MALLOC(sizeof (*entry), M_IFADDR, M_WAITOK | M_ZERO); if (entry == NULL) - return ENOMEM; - - bzero(entry, sizeof(*entry)); + return (ENOMEM); + entry->protocol = protocol; entry->input = input; entry->detached = detached; entry->hash = proto_hash_value(protocol); entry->chain = chains; - - { - struct domain *dp = domains; - - lck_mtx_assert(domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED); - lck_mtx_lock(domain_proto_mtx); - while (dp && (protocol_family_t)dp->dom_family != protocol) - dp = dp->dom_next; - entry->domain = dp; - lck_mtx_unlock(domain_proto_mtx); + + guard = domain_guard_deploy(); + TAILQ_FOREACH(dp, &domains, dom_entry) { + if (dp->dom_family == (int)protocol) + break; } + domain_guard_release(guard); + if (dp == NULL) + return (EINVAL); + + entry->domain = dp; - - lck_mtx_lock(&thread->input_lck); + lck_mtx_lock(&inp->input_lck); entry->next = proto_input_add_list; proto_input_add_list = entry; - - thread->input_waiting |= DLIL_PROTO_REGISTER; - if ((thread->input_waiting & DLIL_INPUT_RUNNING) == 0) - wakeup((caddr_t)&thread->input_waiting); - lck_mtx_unlock(&thread->input_lck); - - return 0; -} + inp->input_waiting |= DLIL_PROTO_REGISTER; + if ((inp->input_waiting & DLIL_INPUT_RUNNING) == 0) + wakeup((caddr_t)&inp->input_waiting); + lck_mtx_unlock(&inp->input_lck); + + return (0); +} __private_extern__ void -proto_unregister_input( - protocol_family_t protocol) +proto_unregister_input(protocol_family_t protocol) { struct proto_input_entry *entry = NULL; - - for (entry = proto_hash[proto_hash_value(protocol)]; entry; entry = entry->next) + + for (entry = proto_hash[proto_hash_value(protocol)]; entry != NULL; + entry = entry->next) { if (entry->protocol == protocol) break; - - if (entry) + } + + if (entry != NULL) entry->detach = 1; } - static void -proto_delayed_attach( - struct proto_input_entry *entry) +proto_delayed_attach(struct proto_input_entry *entry) { struct proto_input_entry *next_entry; - for (next_entry = entry->next; entry; entry = next_entry) { + + for (next_entry = entry->next; entry != NULL; entry = next_entry) { struct proto_input_entry *exist; int hash_slot; - + hash_slot = proto_hash_value(entry->protocol); next_entry = entry->next; - - for (exist = proto_hash[hash_slot]; exist; exist = exist->next) + + for (exist = proto_hash[hash_slot]; exist != NULL; + exist = exist->next) { if (exist->protocol == entry->protocol) break; - + } + /* If the entry already exists, call detached and dispose */ - if (exist) { + if (exist != NULL) { if (entry->detached) entry->detached(entry->protocol); FREE(entry, M_IFADDR); - } - else { + } else { entry->next = proto_hash[hash_slot]; proto_hash[hash_slot] = entry; } @@ -214,31 +188,32 @@ proto_delayed_attach( __private_extern__ void proto_input_run(void) { - struct proto_input_entry *entry; - struct dlil_threading_info *thread = dlil_lo_thread_ptr; + struct proto_input_entry *entry; + struct dlil_threading_info *inp = dlil_main_input_thread; mbuf_t packet_list; int i, locked = 0; - lck_mtx_assert(&thread->input_lck, LCK_MTX_ASSERT_NOTOWNED); + LCK_MTX_ASSERT(&inp->input_lck, LCK_MTX_ASSERT_NOTOWNED); - if ((thread->input_waiting & DLIL_PROTO_REGISTER) != 0) { - lck_mtx_lock_spin(&thread->input_lck); + if (inp->input_waiting & DLIL_PROTO_REGISTER) { + lck_mtx_lock_spin(&inp->input_lck); entry = proto_input_add_list; proto_input_add_list = NULL; - thread->input_waiting &= ~DLIL_PROTO_REGISTER; - lck_mtx_unlock(&thread->input_lck); + inp->input_waiting &= ~DLIL_PROTO_REGISTER; + lck_mtx_unlock(&inp->input_lck); proto_delayed_attach(entry); } + /* - Move everything from the lock protected list to the thread - specific list. + * Move everything from the lock protected list to the thread + * specific list. */ for (i = 0; proto_total_waiting != 0 && i < PROTO_HASH_SLOTS; i++) { - for (entry = proto_hash[i]; entry && proto_total_waiting; - entry = entry->next) { - if (entry->inject_first) { - lck_mtx_lock_spin(&thread->input_lck); - thread->input_waiting &= ~DLIL_PROTO_WAITING; + for (entry = proto_hash[i]; + entry != NULL && proto_total_waiting; entry = entry->next) { + if (entry->inject_first != NULL) { + lck_mtx_lock_spin(&inp->input_lck); + inp->input_waiting &= ~DLIL_PROTO_WAITING; packet_list = entry->inject_first; @@ -246,160 +221,159 @@ proto_input_run(void) entry->inject_last = NULL; proto_total_waiting--; - lck_mtx_unlock(&thread->input_lck); + lck_mtx_unlock(&inp->input_lck); - if (entry->domain && (entry->domain->dom_flags & DOM_REENTRANT) == 0) { + if (entry->domain != NULL && !(entry->domain-> + dom_flags & DOM_REENTRANT)) { lck_mtx_lock(entry->domain->dom_mtx); locked = 1; } - + if (entry->chain) { - entry->input(entry->protocol, packet_list); - } - else { + entry->input(entry->protocol, + packet_list); + } else { mbuf_t packet; - - for (packet = packet_list; packet; packet = packet_list) { - packet_list = mbuf_nextpkt(packet); + + for (packet = packet_list; + packet != NULL; + packet = packet_list) { + packet_list = + mbuf_nextpkt(packet); mbuf_setnextpkt(packet, NULL); - entry->input(entry->protocol, packet); + entry->input(entry->protocol, + packet); } } if (locked) { locked = 0; lck_mtx_unlock(entry->domain->dom_mtx); - } + } + } } } - } - } errno_t -proto_input( - protocol_family_t protocol, - mbuf_t packet_list) +proto_input(protocol_family_t protocol, mbuf_t packet_list) { - struct proto_input_entry *entry; - errno_t locked =0, result = 0; + struct proto_input_entry *entry; + errno_t locked = 0, result = 0; - for (entry = proto_hash[proto_hash_value(protocol)]; entry; - entry = entry->next) { + for (entry = proto_hash[proto_hash_value(protocol)]; entry != NULL; + entry = entry->next) { if (entry->protocol == protocol) break; } - if (entry->domain && (entry->domain->dom_flags & DOM_REENTRANT) == 0) { + if (entry == NULL) + return (-1); + + if (entry->domain && !(entry->domain->dom_flags & DOM_REENTRANT)) { lck_mtx_lock(entry->domain->dom_mtx); locked = 1; } - + if (entry->chain) { entry->input(entry->protocol, packet_list); - } - else { + } else { mbuf_t packet; - - for (packet = packet_list; packet; packet = packet_list) { + + for (packet = packet_list; packet != NULL; + packet = packet_list) { packet_list = mbuf_nextpkt(packet); mbuf_setnextpkt(packet, NULL); entry->input(entry->protocol, packet); } } - + if (locked) { lck_mtx_unlock(entry->domain->dom_mtx); - } - return result; + } + return (result); } errno_t -proto_inject( - protocol_family_t protocol, - mbuf_t packet_list) +proto_inject(protocol_family_t protocol, mbuf_t packet_list) { - struct proto_input_entry *entry; - mbuf_t last_packet; - int hash_slot = proto_hash_value(protocol); - struct dlil_threading_info *thread = dlil_lo_thread_ptr; - - for (last_packet = packet_list; mbuf_nextpkt(last_packet); - last_packet = mbuf_nextpkt(last_packet)) + struct proto_input_entry *entry; + mbuf_t last_packet; + int hash_slot = proto_hash_value(protocol); + struct dlil_threading_info *inp = dlil_main_input_thread; + + for (last_packet = packet_list; mbuf_nextpkt(last_packet) != NULL; + last_packet = mbuf_nextpkt(last_packet)) /* find the last packet */; - - for (entry = proto_hash[hash_slot]; entry; entry = entry->next) { + + for (entry = proto_hash[hash_slot]; entry != NULL; + entry = entry->next) { if (entry->protocol == protocol) break; } - - if (entry) { - lck_mtx_lock(&thread->input_lck); + + if (entry != NULL) { + lck_mtx_lock(&inp->input_lck); if (entry->inject_first == NULL) { proto_total_waiting++; - thread->input_waiting |= DLIL_PROTO_WAITING; + inp->input_waiting |= DLIL_PROTO_WAITING; entry->inject_first = packet_list; - } - else { + } else { mbuf_setnextpkt(entry->inject_last, packet_list); } entry->inject_last = last_packet; - if ((thread->input_waiting & DLIL_INPUT_RUNNING) == 0) { - wakeup((caddr_t)&thread->input_waiting); + if ((inp->input_waiting & DLIL_INPUT_RUNNING) == 0) { + wakeup((caddr_t)&inp->input_waiting); } - lck_mtx_unlock(&thread->input_lck); - } - else - { - return ENOENT; + lck_mtx_unlock(&inp->input_lck); + } else { + return (ENOENT); } - return 0; + return (0); } -static struct proto_family_str* -proto_plumber_find( - protocol_family_t proto_family, - ifnet_family_t if_family) +static struct proto_family_str * +proto_plumber_find(protocol_family_t proto_family, ifnet_family_t if_family) { struct proto_family_str *mod = NULL; TAILQ_FOREACH(mod, &proto_family_head, proto_fam_next) { - if ((mod->proto_family == (proto_family & 0xffff)) - && (mod->if_family == (if_family & 0xffff))) + if ((mod->proto_family == (proto_family & 0xffff)) && + (mod->if_family == (if_family & 0xffff))) break; - } + } - return mod; + return (mod); } errno_t -proto_register_plumber( - protocol_family_t protocol_family, - ifnet_family_t interface_family, - proto_plumb_handler attach, - proto_unplumb_handler detach) +proto_register_plumber(protocol_family_t protocol_family, + ifnet_family_t interface_family, proto_plumb_handler attach, + proto_unplumb_handler detach) { struct proto_family_str *proto_family; - if (attach == NULL) return EINVAL; + if (attach == NULL) + return (EINVAL); lck_mtx_lock(proto_family_mutex); - + TAILQ_FOREACH(proto_family, &proto_family_head, proto_fam_next) { if (proto_family->proto_family == protocol_family && - proto_family->if_family == interface_family) { + proto_family->if_family == interface_family) { lck_mtx_unlock(proto_family_mutex); - return EEXIST; + return (EEXIST); } } - proto_family = (struct proto_family_str *) _MALLOC(sizeof(struct proto_family_str), M_IFADDR, M_WAITOK); + proto_family = (struct proto_family_str *) + _MALLOC(sizeof (struct proto_family_str), M_IFADDR, + M_WAITOK | M_ZERO); if (!proto_family) { lck_mtx_unlock(proto_family_mutex); - return ENOMEM; + return (ENOMEM); } - bzero(proto_family, sizeof(struct proto_family_str)); proto_family->proto_family = protocol_family; proto_family->if_family = interface_family & 0xffff; proto_family->attach_proto = attach; @@ -407,57 +381,51 @@ proto_register_plumber( TAILQ_INSERT_TAIL(&proto_family_head, proto_family, proto_fam_next); lck_mtx_unlock(proto_family_mutex); - return 0; + return (0); } void -proto_unregister_plumber( - protocol_family_t protocol_family, - ifnet_family_t interface_family) +proto_unregister_plumber(protocol_family_t protocol_family, + ifnet_family_t interface_family) { struct proto_family_str *proto_family; lck_mtx_lock(proto_family_mutex); proto_family = proto_plumber_find(protocol_family, interface_family); - if (proto_family == 0) { + if (proto_family == NULL) { lck_mtx_unlock(proto_family_mutex); return; } TAILQ_REMOVE(&proto_family_head, proto_family, proto_fam_next); FREE(proto_family, M_IFADDR); - + lck_mtx_unlock(proto_family_mutex); - return; } __private_extern__ errno_t -proto_plumb( - protocol_family_t protocol_family, - ifnet_t ifp) +proto_plumb(protocol_family_t protocol_family, ifnet_t ifp) { struct proto_family_str *proto_family; int ret = 0; lck_mtx_lock(proto_family_mutex); proto_family = proto_plumber_find(protocol_family, ifp->if_family); - if (proto_family == 0) { + if (proto_family == NULL) { lck_mtx_unlock(proto_family_mutex); - return ENXIO; + return (ENXIO); } ret = proto_family->attach_proto(ifp, protocol_family); lck_mtx_unlock(proto_family_mutex); - return ret; + return (ret); } __private_extern__ errno_t -proto_unplumb( - protocol_family_t protocol_family, - ifnet_t ifp) +proto_unplumb(protocol_family_t protocol_family, ifnet_t ifp) { struct proto_family_str *proto_family; int ret = 0; @@ -465,11 +433,11 @@ proto_unplumb( lck_mtx_lock(proto_family_mutex); proto_family = proto_plumber_find(protocol_family, ifp->if_family); - if (proto_family && proto_family->detach_proto) + if (proto_family != NULL && proto_family->detach_proto) proto_family->detach_proto(ifp, protocol_family); else ret = ifnet_detach_protocol(ifp, protocol_family); - + lck_mtx_unlock(proto_family_mutex); - return ret; + return (ret); }