- int s, ret = 0;
- u_long tag;
- boolean_t funnel_state;
-
- funnel_state = thread_funnel_set(network_flock, TRUE);
- s = splnet();
-
- ret = dlil_find_dltag(ifp->if_family, ifp->if_unit, protocol_family, &tag);
-
- if (ret == 0) {
- proto_family = find_proto_module(protocol_family, ifp->if_family);
- if (proto_family && proto_family->detach_proto)
- ret = (*proto_family->detach_proto)(ifp, tag);
- else
- ret = dlil_detach_protocol(tag);
- }
-
- splx(s);
- thread_funnel_set(network_flock, funnel_state);
- return ret;
-}
-
-
-
-/*
- * Old if_attach no-op'ed function defined here for temporary backwards compatibility
- */
-
-void if_attach(ifp)
- struct ifnet *ifp;
-{
- dlil_if_attach(ifp);
-}
-
-
-
-int
-dlil_inject_if_input(struct mbuf *m, char *frame_header, u_long from_id)
-{
- struct ifnet *orig_ifp = 0;
- struct ifnet *ifp;
- struct if_proto *ifproto;
- struct if_proto *proto;
- struct dlil_filterq_entry *tmp;
- int retval = 0;
- struct dlil_filterq_head *fhead;
- int match_found;
-
- dlil_stats.inject_if_in1++;
-
- if (from_id >= dlil_filters_nb || dlil_filters[from_id].type != DLIL_IF_FILTER)
- return ENOENT;
-
- ifp = dlil_filters[from_id].ifp;
-
-/*
- * Let interface filters (if any) do their thing ...
- */
-
- fhead = (struct dlil_filterq_head *) &ifp->if_flt_head;
- match_found = 0;
-
- if (TAILQ_EMPTY(fhead) == 0) {
- while (orig_ifp != ifp) {
- orig_ifp = ifp;
- TAILQ_FOREACH_REVERSE(tmp, fhead, que, dlil_filterq_head) {
- if ((match_found) && (IFILT(tmp).filter_if_input)) {
- retval = (*IFILT(tmp).filter_if_input)(IFILT(tmp).cookie,
- &ifp,
- &m,
- &frame_header);
- if (retval) {
- if (retval == EJUSTRETURN)
- return 0;
- else {
- m_freem(m);
- return retval;
- }
- }
-
- }
-
- if (ifp != orig_ifp)
- break;
-
- if (from_id == tmp->filter_id)
- match_found = 1;
- }
- }
- }
-
- ifp->if_lastchange = time;
-
- /*
- * Call family demux module. If the demux module finds a match
- * for the frame it will fill-in the ifproto pointer.
- */
-
- retval = (*ifp->if_demux)(ifp, m, frame_header, &ifproto );
-
- if (m->m_flags & (M_BCAST|M_MCAST))
- ifp->if_imcasts++;
-
- if ((retval) && (ifp->offercnt)) {
- /*
- * No match was found, look for any offers.
- */
- struct dlil_proto_head *tmp = (struct dlil_proto_head *) &ifp->proto_head;
- TAILQ_FOREACH(proto, tmp, next) {
- if ((proto->dl_offer) && (proto->dl_offer(m, frame_header) == 0)) {
- ifproto = proto;
- retval = 0;
- break;
- }
- }
- }
-
- if (retval) {
- if (retval != EJUSTRETURN) {
- m_freem(m);
- return retval;
- }
- else
- return 0;
- }
- else
- if (ifproto == 0) {
- printf("ERROR - dlil_inject_if_input -- if_demux didn't return an if_proto pointer\n");
- m_freem(m);
- return 0;
- }
-
-/*
- * Call any attached protocol filters.
- */
- TAILQ_FOREACH_REVERSE(tmp, &ifproto->pr_flt_head, que, dlil_filterq_head) {
- if (PFILT(tmp).filter_dl_input) {
- retval = (*PFILT(tmp).filter_dl_input)(PFILT(tmp).cookie,
- &m,
- &frame_header,
- &ifp);
-
- if (retval) {
- if (retval == EJUSTRETURN)
- return 0;
- else {
- m_freem(m);
- return retval;
- }
- }
- }
- }
-
-
-
- retval = (*ifproto->dl_input)(m, frame_header,
- ifp, ifproto->dl_tag,
- FALSE);
-
- dlil_stats.inject_if_in2++;
- if (retval == EJUSTRETURN)
- retval = 0;
- else
- if (retval)
- m_freem(m);
-
- return retval;
-
-}
-
-
-
-
-
-int
-dlil_inject_pr_input(struct mbuf *m, char *frame_header, u_long from_id)
-{
- struct ifnet *orig_ifp = 0;
- struct dlil_filterq_entry *tmp;
- int retval;
- struct if_proto *ifproto = 0;
- int match_found;
- struct ifnet *ifp;
-
- dlil_stats.inject_pr_in1++;
- if (from_id >= dlil_filters_nb || dlil_filters[from_id].type != DLIL_PR_FILTER)
- return ENOENT;
-
- ifproto = dlil_filters[from_id].proto;
- ifp = dlil_filters[from_id].ifp;
-
-/*
- * Call any attached protocol filters.
- */
-
- match_found = 0;
- TAILQ_FOREACH_REVERSE(tmp, &ifproto->pr_flt_head, que, dlil_filterq_head) {
- if ((match_found) && (PFILT(tmp).filter_dl_input)) {
- retval = (*PFILT(tmp).filter_dl_input)(PFILT(tmp).cookie,
- &m,
- &frame_header,
- &ifp);
-
- if (retval) {
- if (retval == EJUSTRETURN)
- return 0;
- else {
- m_freem(m);
- return retval;
- }
- }
- }
-
- if (tmp->filter_id == from_id)
- match_found = 1;
- }
-
-
- retval = (*ifproto->dl_input)(m, frame_header,
- ifp, ifproto->dl_tag,
- FALSE);
-
- if (retval == EJUSTRETURN)
- retval = 0;
- else
- if (retval)
- m_freem(m);
-
- dlil_stats.inject_pr_in2++;
- return retval;
-}
-