+ 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) {
+ 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)
+{
+ 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) {
+ lck_mtx_unlock(proto_family_mutex);
+ return ENXIO;
+ }
+
+ ret = proto_family->attach_proto(ifp, protocol_family);
+
+ lck_mtx_unlock(proto_family_mutex);
+ return ret;
+}
+
+
+__private_extern__ errno_t
+proto_unplumb(
+ 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 && 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;