/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2009 Robert N. M. Watson4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728/*29* When an interface has been detached but not yet freed, we set the various30* ifnet function pointers to "ifdead" versions. This prevents unexpected31* calls from the network stack into the device driver after if_detach() has32* returned.33*/3435#include <sys/param.h>36#include <sys/mbuf.h>37#include <sys/socket.h>3839#include <net/if.h>40#include <net/if_var.h>41#include <net/if_private.h>4243static int44ifdead_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,45struct route *ro)46{4748m_freem(m);49return (ENXIO);50}5152static void53ifdead_input(struct ifnet *ifp, struct mbuf *m)54{5556m_freem(m);57}5859static void60ifdead_start(struct ifnet *ifp)61{6263}6465static int66ifdead_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)67{6869return (ENXIO);70}7172static int73ifdead_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa,74struct sockaddr *sa)75{7677*llsa = NULL;78return (ENXIO);79}8081static void82ifdead_qflush(struct ifnet *ifp)83{8485}8687static int88ifdead_transmit(struct ifnet *ifp, struct mbuf *m)89{9091m_freem(m);92return (ENXIO);93}9495static uint64_t96ifdead_get_counter(struct ifnet *ifp, ift_counter cnt)97{9899return (0);100}101102static int103ifdead_snd_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params,104struct m_snd_tag **ppmt)105{106return (EOPNOTSUPP);107}108109static void110ifdead_ratelimit_query(struct ifnet *ifp __unused,111struct if_ratelimit_query_results *q)112{113/*114* This guy does not support115* this interface. Not sure116* why we would specify a117* flag on the interface118* that says we do.119*/120q->rate_table = NULL;121q->flags = RT_NOSUPPORT;122q->max_flows = 0;123q->number_of_rates = 0;124}125126void127if_dead(struct ifnet *ifp)128{129130ifp->if_output = ifdead_output;131ifp->if_input = ifdead_input;132ifp->if_start = ifdead_start;133ifp->if_ioctl = ifdead_ioctl;134ifp->if_resolvemulti = ifdead_resolvemulti;135ifp->if_qflush = ifdead_qflush;136ifp->if_transmit = ifdead_transmit;137ifp->if_get_counter = ifdead_get_counter;138ifp->if_snd_tag_alloc = ifdead_snd_tag_alloc;139ifp->if_ratelimit_query = ifdead_ratelimit_query;140}141142143