Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if.c
Show First 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sockio.h> | #include <sys/sockio.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/taskqueue.h> | #include <sys/taskqueue.h> | ||||
#include <sys/domain.h> | #include <sys/domain.h> | ||||
#include <sys/jail.h> | #include <sys/jail.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/eventhandler.h> | |||||
#include <machine/stdarg.h> | #include <machine/stdarg.h> | ||||
#include <vm/uma.h> | #include <vm/uma.h> | ||||
#include <net/bpf.h> | #include <net/bpf.h> | ||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_arp.h> | #include <net/if_arp.h> | ||||
▲ Show 20 Lines • Show All 2,143 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Mark an interface down and notify protocols of | * Mark an interface down and notify protocols of | ||||
* the transition. | * the transition. | ||||
*/ | */ | ||||
void | void | ||||
if_down(struct ifnet *ifp) | if_down(struct ifnet *ifp) | ||||
{ | { | ||||
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_DOWN); | |||||
if_unroute(ifp, IFF_UP, AF_UNSPEC); | if_unroute(ifp, IFF_UP, AF_UNSPEC); | ||||
} | } | ||||
/* | /* | ||||
* Mark an interface up and notify protocols of | * Mark an interface up and notify protocols of | ||||
* the transition. | * the transition. | ||||
*/ | */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) | ||||
int error = 0; | int error = 0; | ||||
int new_flags, temp_flags; | int new_flags, temp_flags; | ||||
size_t namelen, onamelen; | size_t namelen, onamelen; | ||||
size_t descrlen; | size_t descrlen; | ||||
char *descrbuf, *odescrbuf; | char *descrbuf, *odescrbuf; | ||||
char new_name[IFNAMSIZ]; | char new_name[IFNAMSIZ]; | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
struct sockaddr_dl *sdl; | struct sockaddr_dl *sdl; | ||||
bool if_up_done; | |||||
ifr = (struct ifreq *)data; | ifr = (struct ifreq *)data; | ||||
switch (cmd) { | switch (cmd) { | ||||
case SIOCGIFINDEX: | case SIOCGIFINDEX: | ||||
ifr->ifr_index = ifp->if_index; | ifr->ifr_index = ifp->if_index; | ||||
break; | break; | ||||
case SIOCGIFFLAGS: | case SIOCGIFFLAGS: | ||||
temp_flags = ifp->if_flags | ifp->if_drv_flags; | temp_flags = ifp->if_flags | ifp->if_drv_flags; | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (error) | ||||
return (error); | return (error); | ||||
if (ifr->ifr_fib >= rt_numfibs) | if (ifr->ifr_fib >= rt_numfibs) | ||||
return (EINVAL); | return (EINVAL); | ||||
ifp->if_fib = ifr->ifr_fib; | ifp->if_fib = ifr->ifr_fib; | ||||
break; | break; | ||||
case SIOCSIFFLAGS: | case SIOCSIFFLAGS: | ||||
if_up_done = false; | |||||
error = priv_check(td, PRIV_NET_SETIFFLAGS); | error = priv_check(td, PRIV_NET_SETIFFLAGS); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Currently, no driver owned flags pass the IFF_CANTCHANGE | * Currently, no driver owned flags pass the IFF_CANTCHANGE | ||||
* check, so we don't need special handling here yet. | * check, so we don't need special handling here yet. | ||||
*/ | */ | ||||
new_flags = (ifr->ifr_flags & 0xffff) | | new_flags = (ifr->ifr_flags & 0xffff) | | ||||
(ifr->ifr_flagshigh << 16); | (ifr->ifr_flagshigh << 16); | ||||
if (ifp->if_flags & IFF_UP && | if (ifp->if_flags & IFF_UP && | ||||
(new_flags & IFF_UP) == 0) { | (new_flags & IFF_UP) == 0) { | ||||
if_down(ifp); | if_down(ifp); | ||||
} else if (new_flags & IFF_UP && | } else if (new_flags & IFF_UP && | ||||
(ifp->if_flags & IFF_UP) == 0) { | (ifp->if_flags & IFF_UP) == 0) { | ||||
if_up(ifp); | if_up(ifp); | ||||
if_up_done = true; | |||||
} | } | ||||
/* See if permanently promiscuous mode bit is about to flip */ | /* See if permanently promiscuous mode bit is about to flip */ | ||||
if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { | if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { | ||||
if (new_flags & IFF_PPROMISC) | if (new_flags & IFF_PPROMISC) | ||||
ifp->if_flags |= IFF_PROMISC; | ifp->if_flags |= IFF_PROMISC; | ||||
else if (ifp->if_pcount == 0) | else if (ifp->if_pcount == 0) | ||||
ifp->if_flags &= ~IFF_PROMISC; | ifp->if_flags &= ~IFF_PROMISC; | ||||
if (log_promisc_mode_change) | if (log_promisc_mode_change) | ||||
log(LOG_INFO, "%s: permanently promiscuous mode %s\n", | log(LOG_INFO, "%s: permanently promiscuous mode %s\n", | ||||
ifp->if_xname, | ifp->if_xname, | ||||
((new_flags & IFF_PPROMISC) ? | ((new_flags & IFF_PPROMISC) ? | ||||
"enabled" : "disabled")); | "enabled" : "disabled")); | ||||
} | } | ||||
ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | | ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | | ||||
(new_flags &~ IFF_CANTCHANGE); | (new_flags &~ IFF_CANTCHANGE); | ||||
if (ifp->if_ioctl) { | if (ifp->if_ioctl) { | ||||
(void) (*ifp->if_ioctl)(ifp, cmd, data); | (void) (*ifp->if_ioctl)(ifp, cmd, data); | ||||
} | } | ||||
if (if_up_done) | |||||
EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_UP); | |||||
getmicrotime(&ifp->if_lastchange); | getmicrotime(&ifp->if_lastchange); | ||||
break; | break; | ||||
case SIOCSIFCAP: | case SIOCSIFCAP: | ||||
error = priv_check(td, PRIV_NET_SETIFCAP); | error = priv_check(td, PRIV_NET_SETIFCAP); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
if (ifp->if_ioctl == NULL) | if (ifp->if_ioctl == NULL) | ||||
▲ Show 20 Lines • Show All 1,708 Lines • Show Last 20 Lines |