/*
- * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <net/if_ppp.h>
#include <net/ethernet.h>
#include <net/network_agent.h>
+#include <net/pktsched/pktsched_netem.h>
#include <net/radix.h>
#include <net/route.h>
#include <net/dlil.h>
#include <sys/domain.h>
#include <libkern/OSAtomic.h>
-#if INET || INET6
+#if INET
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/in_tclass.h>
#include <netinet/tcp_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
-#if INET6
#include <netinet6/in6_var.h>
#include <netinet6/in6_ifattach.h>
#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
-#endif /* INET6 */
-#endif /* INET || INET6 */
+#endif /* INET */
-#if CONFIG_MACF_NET
-#include <security/mac_framework.h>
-#endif
#include <os/log.h>
#define IFMA_ZONE_MAX 64 /* maximum elements in zone */
#define IFMA_ZONE_NAME "ifmultiaddr" /* zone name */
-#if INET6
/*
* XXX: declare here to avoid to include many inet6 related files..
* should be more generalized?
*/
extern void nd6_setmtu(struct ifnet *);
extern lck_mtx_t *nd6_mutex;
-#endif
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Link layers");
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
SYSCTL_INT(_net_link_generic_system, OID_AUTO, if_verbose,
CTLFLAG_RW | CTLFLAG_LOCKED, &if_verbose, 0, "");
+#if (DEBUG || DEVELOPMENT)
+static uint32_t default_tcp_kao_max = 0;
+SYSCTL_INT(_net_link_generic_system, OID_AUTO, default_tcp_kao_max,
+ CTLFLAG_RW | CTLFLAG_LOCKED, &default_tcp_kao_max, 0, "");
+#else
+static const uint32_t default_tcp_kao_max = 0;
+#endif /* (DEBUG || DEVELOPMENT) */
+
+u_int32_t companion_link_sock_buffer_limit = 0;
+
+static int
+sysctl_set_companion_link_sock_buf_limit SYSCTL_HANDLER_ARGS
+{
+#pragma unused(arg1, arg2)
+ int error, tmp = companion_link_sock_buffer_limit;
+ error = sysctl_handle_int(oidp, &tmp, 0, req);
+ if (tmp < 0) {
+ return EINVAL;
+ }
+ if ((error = priv_check_cred(kauth_cred_get(),
+ PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
+ return error;
+ }
+
+ u_int32_t new_limit = tmp;
+ if (new_limit == companion_link_sock_buffer_limit) {
+ return 0;
+ }
+
+ bool recover = new_limit == 0 ? true : false;
+ if (recover) {
+ error = inp_recover_companion_link(&tcbinfo);
+ } else {
+ error = inp_limit_companion_link(&tcbinfo, new_limit);
+ }
+ if (!error) {
+ companion_link_sock_buffer_limit = new_limit;
+ }
+ return error;
+}
+
+SYSCTL_PROC(_net_link_generic_system, OID_AUTO, companion_sndbuf_limit,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_ANYBODY,
+ &companion_link_sock_buffer_limit, 0, sysctl_set_companion_link_sock_buf_limit,
+ "I", "set sock send buffer limit of connections using companion links");
+
boolean_t intcoproc_unrestricted;
/* Eventhandler context for interface events */
ifma_size = (ifma_debug == 0) ? sizeof(struct ifmultiaddr) :
sizeof(struct ifmultiaddr_dbg);
- ifma_zone = zinit(ifma_size, IFMA_ZONE_MAX * ifma_size, 0,
- IFMA_ZONE_NAME);
- if (ifma_zone == NULL) {
- panic("%s: failed allocating %s", __func__, IFMA_ZONE_NAME);
- /* NOTREACHED */
- }
- zone_change(ifma_zone, Z_EXPAND, TRUE);
- zone_change(ifma_zone, Z_CALLERACCT, FALSE);
-
+ ifma_zone = zone_create(IFMA_ZONE_NAME, ifma_size, ZC_NONE);
lck_mtx_init(&ifma_trash_lock, ifa_mtx_grp, ifa_mtx_attr);
TAILQ_INIT(&ifma_trash_head);
panic("%s: unexpected (missing) refcnt ifa=%p", __func__, ifa);
/* NOTREACHED */
}
- ifa->ifa_debug &= ~(IFD_ATTACHED | IFD_DETACHING);
+ ifa->ifa_debug &= ~IFD_ATTACHED;
if (ifa->ifa_detached != NULL) {
(*ifa->ifa_detached)(ifa);
lck_mtx_init(&ifc->ifc_mutex, ifnet_lock_group, ifnet_lock_attr);
if (ifc->ifc_softc_size != 0) {
- ifc->ifc_zone = zinit(ifc->ifc_softc_size,
- ifc->ifc_zone_max_elem * ifc->ifc_softc_size, 0, ifc->ifc_name);
- if (ifc->ifc_zone == NULL) {
- FREE(ifc->ifc_units, M_CLONE);
- return ENOBUFS;
- }
- zone_change(ifc->ifc_zone, Z_EXPAND, TRUE);
- zone_change(ifc->ifc_zone, Z_CALLERACCT, FALSE);
+ ifc->ifc_zone = zone_create(ifc->ifc_name, ifc->ifc_softc_size,
+ ZC_DESTRUCTIBLE);
}
LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
if_functional_type(struct ifnet *ifp, bool exclude_delegate)
{
u_int32_t ret = IFRTYPE_FUNCTIONAL_UNKNOWN;
+
if (ifp != NULL) {
if (ifp->if_flags & IFF_LOOPBACK) {
ret = IFRTYPE_FUNCTIONAL_LOOPBACK;
+ } else if (IFNET_IS_COMPANION_LINK(ifp)) {
+ ret = IFRTYPE_FUNCTIONAL_COMPANIONLINK;
} else if ((exclude_delegate &&
- (ifp->if_subfamily == IFNET_SUBFAMILY_WIFI)) ||
+ (ifp->if_family == IFNET_FAMILY_ETHERNET &&
+ ifp->if_subfamily == IFNET_SUBFAMILY_WIFI)) ||
(!exclude_delegate && IFNET_IS_WIFI(ifp))) {
if (ifp->if_eflags & IFEF_AWDL) {
ret = IFRTYPE_FUNCTIONAL_WIFI_AWDL;
return ia;
}
-#if INET6
/*
* Similar to ifa_foraddr, except that this for IPv6.
*/
struct in6_ifaddr *ia = NULL;
lck_rw_lock_shared(&in6_ifaddr_rwlock);
- for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
+ TAILQ_FOREACH(ia, IN6ADDR_HASH(addr6), ia6_hash) {
IFA_LOCK(&ia->ia_ifa);
if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, addr6) &&
(scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope)) {
return ia;
}
-#endif /* INET6 */
/*
* Return the first (primary) address of a given family on an interface.
u_int af = addr->sa_family;
const char *addr_data = addr->sa_data, *cplim;
-#if INET6
if (af != AF_INET && af != AF_INET6) {
-#else
- if (af != AF_INET) {
-#endif /* !INET6 */
ifscope = IFSCOPE_NONE;
}
__private_extern__ void
if_updown( struct ifnet *ifp, int up)
{
+ u_int32_t eflags;
int i;
struct ifaddr **ifa;
struct timespec tv;
}
/* Indicate that the up/down state is changing */
- ifp->if_eflags |= IFEF_UPDOWNCHANGE;
+ eflags = if_set_eflags(ifp, IFEF_UPDOWNCHANGE);
+ ASSERT((eflags & IFEF_UPDOWNCHANGE) == 0);
/* Mark interface up or down */
if (up) {
/* Aquire the lock to clear the changing flag */
ifnet_lock_exclusive(ifp);
- ifp->if_eflags &= ~IFEF_UPDOWNCHANGE;
+ if_clear_eflags(ifp, IFEF_UPDOWNCHANGE);
wakeup(&ifp->if_eflags);
}
}
if (IFCQ_IS_ENABLED(ifq)) {
- IFCQ_PURGE(ifq);
+ fq_if_request_classq(ifq, CLASSQRQ_PURGE, NULL);
}
VERIFY(IFCQ_IS_EMPTY(ifq));
{
struct ifclassq *ifq = &ifp->if_snd;
u_int32_t cnt = 0, len = 0;
- u_int32_t a_cnt = 0, a_len = 0;
VERIFY(sc == MBUF_SC_UNSPEC || MBUF_VALID_SC(sc));
VERIFY(flow != 0);
}
if (IFCQ_IS_ENABLED(ifq)) {
- IFCQ_PURGE_SC(ifq, sc, flow, cnt, len);
+ cqrq_purge_sc_t req = { sc, flow, 0, 0 };
+
+ fq_if_request_classq(ifq, CLASSQRQ_PURGE_SC, &req);
+ cnt = req.packets;
+ len = req.bytes;
}
if (!ifq_locked) {
}
if (packets != NULL) {
- *packets = cnt + a_cnt;
+ *packets = cnt;
}
if (bytes != NULL) {
- *bytes = len + a_len;
+ *bytes = len;
}
}
switch (cmd) {
case SIOCSIFLINKPARAMS: { /* struct if_linkparamsreq */
- struct tb_profile tb = { 0, 0, 0 };
+ struct tb_profile tb = { .rate = 0, .percent = 0, .depth = 0 };
if ((error = proc_suser(p)) != 0) {
break;
}
+ char netem_name[32];
+ (void) snprintf(netem_name, sizeof(netem_name),
+ "if_output_netem_%s", if_name(ifp));
+ error = netem_config(&ifp->if_output_netem, netem_name,
+ &iflpr->iflpr_output_netem, (void *)ifp,
+ ifnet_enqueue_netem, NETEM_MAX_BATCH_SIZE);
+ if (error != 0) {
+ break;
+ }
+
IFCQ_LOCK(ifq);
if (!IFCQ_IS_READY(ifq)) {
error = ENXIO;
sizeof(iflpr->iflpr_output_lt));
bcopy(&ifp->if_input_lt, &iflpr->iflpr_input_lt,
sizeof(iflpr->iflpr_input_lt));
+
+ if (ifp->if_output_netem != NULL) {
+ netem_get_params(ifp->if_output_netem,
+ &iflpr->iflpr_output_netem);
+ }
+
break;
}
#define IF_MAXAGENTS 64
#define IF_AGENT_INCREMENT 8
-static int
+int
if_add_netagent_locked(struct ifnet *ifp, uuid_t new_agent_uuid)
{
+ VERIFY(ifp != NULL);
+
uuid_t *first_empty_slot = NULL;
u_int32_t index = 0;
bool already_added = FALSE;
switch (mode) {
case IFRTYPE_QOSMARKING_MODE_NONE:
ifp->if_qosmarking_mode = IFRTYPE_QOSMARKING_MODE_NONE;
- ifp->if_eflags &= ~IFEF_QOSMARKING_CAPABLE;
break;
case IFRTYPE_QOSMARKING_FASTLANE:
- ifp->if_qosmarking_mode = IFRTYPE_QOSMARKING_FASTLANE;
- ifp->if_eflags |= IFEF_QOSMARKING_CAPABLE;
- if (net_qos_policy_capable_enabled != 0) {
- ifp->if_eflags |= IFEF_QOSMARKING_ENABLED;
- }
+ case IFRTYPE_QOSMARKING_RFC4594:
+ ifp->if_qosmarking_mode = mode;
break;
default:
error = EINVAL;
}
if (error == 0 && old_mode != ifp->if_qosmarking_mode) {
dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_QOS_MODE_CHANGED,
- NULL, sizeof(struct kev_dl_rrc_state));
+ NULL, 0);
}
return error;
}
if (found_duplicate) {
break;
}
- }
-
- error = ifnet_reset_order(ordered_indices, ifo->ifo_count);
+ error = ifnet_reset_order(ordered_indices, ifo->ifo_count);
+ } else {
+ // Clear the list
+ error = ifnet_reset_order(NULL, 0);
+ }
break;
}
return error;
}
+static __attribute__((noinline)) int
+ifioctl_networkid(struct ifnet *ifp, caddr_t data)
+{
+ struct if_netidreq *ifnetidr = (struct if_netidreq *)(void *)data;
+ int error = 0;
+ int len = ifnetidr->ifnetid_len;
+
+ VERIFY(ifp != NULL);
+
+ if (len > sizeof(ifnetidr->ifnetid)) {
+ error = EINVAL;
+ goto end;
+ }
+
+ if (len == 0) {
+ bzero(&ifp->network_id, sizeof(ifp->network_id));
+ } else if (len > sizeof(ifp->network_id)) {
+ error = EINVAL;
+ goto end;
+ }
+
+ ifp->network_id_len = len;
+ bcopy(data, ifp->network_id, len);
+end:
+ return error;
+}
+
static __attribute__((noinline)) int
ifioctl_netsignature(struct ifnet *ifp, u_long cmd, caddr_t data)
{
return error;
}
-#if INET6
static __attribute__((noinline)) int
ifioctl_nat64prefix(struct ifnet *ifp, u_long cmd, caddr_t data)
{
return error;
}
-#endif
static int
case SIOCGIFFLAGS:
case SIOCGIFEFLAGS:
case SIOCGIFCAP:
- case SIOCGIFMAC:
case SIOCGIFMETRIC:
case SIOCGIFMTU:
case SIOCGIFPHYS:
case SIOCGIFNETMASK_IN6:
case SIOCGIFPROTOLIST32:
case SIOCGIFPROTOLIST64:
+ case SIOCGIFXFLAGS:
return false;
default:
#if (DEBUG || DEVELOPMENT)
error = EOPNOTSUPP;
goto done;
}
- /* FALLTHRU */
+ OS_FALLTHROUGH;
case SIOCIFCREATE: /* struct ifreq */
case SIOCIFCREATE2: /* struct ifreq */
case SIOCIFDESTROY: /* struct ifreq */
case SIOCGIFFLAGS: /* struct ifreq */
case SIOCGIFEFLAGS: /* struct ifreq */
case SIOCGIFCAP: /* struct ifreq */
-#if CONFIG_MACF_NET
- case SIOCGIFMAC: /* struct ifreq */
- case SIOCSIFMAC: /* struct ifreq */
-#endif /* CONFIG_MACF_NET */
case SIOCGIFMETRIC: /* struct ifreq */
case SIOCGIFMTU: /* struct ifreq */
case SIOCGIFPHYS: /* struct ifreq */
case SIOCGIFLOWINTERNET: /* struct ifreq */
case SIOCGIFLOWPOWER: /* struct ifreq */
case SIOCSIFLOWPOWER: /* struct ifreq */
+ case SIOCSIF6LOWPAN: /* struct ifreq */
+ case SIOCGIF6LOWPAN: /* struct ifreq */
+ case SIOCGIFMPKLOG: /* struct ifreq */
+ case SIOCSIFMPKLOG: /* struct ifreq */
+ case SIOCGIFCONSTRAINED: /* struct ifreq */
+ case SIOCSIFCONSTRAINED: /* struct ifreq */
+ case SIOCGIFXFLAGS: /* struct ifreq */
+ case SIOCGIFNOACKPRIO: /* struct ifreq */
+ case SIOCSIFNOACKPRIO: /* struct ifreq */
{ /* struct ifreq */
struct ifreq ifr;
bcopy(data, &ifr, sizeof(ifr));
case SIOCSIFPHYADDR: /* struct {if,in_}aliasreq */
bcopy(((struct in_aliasreq *)(void *)data)->ifra_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
-#if INET6
case SIOCSIFPHYADDR_IN6_32: /* struct in6_aliasreq_32 */
bcopy(((struct in6_aliasreq_32 *)(void *)data)->ifra_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCSIFPHYADDR_IN6_64: /* struct in6_aliasreq_64 */
bcopy(((struct in6_aliasreq_64 *)(void *)data)->ifra_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
-#endif /* INET6 */
case SIOCGIFSTATUS: /* struct ifstat */
ifs = _MALLOC(sizeof(*ifs), M_DEVBUF, M_WAITOK);
bcopy(data, ifs, sizeof(*ifs));
ifs->ifs_name[IFNAMSIZ - 1] = '\0';
bcopy(ifs->ifs_name, ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCGIFMEDIA32: /* struct ifmediareq32 */
case SIOCGIFXMEDIA32: /* struct ifmediareq32 */
bcopy(((struct ifmediareq32 *)(void *)data)->ifm_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCGIFMEDIA64: /* struct ifmediareq64 */
case SIOCGIFXMEDIA64: /* struct ifmediareq64 */
bcopy(((struct ifmediareq64 *)(void *)data)->ifm_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCSIFDESC: /* struct if_descreq */
case SIOCGIFDESC: /* struct if_descreq */
bcopy(((struct if_descreq *)(void *)data)->ifdr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCSIFLINKPARAMS: /* struct if_linkparamsreq */
case SIOCGIFLINKPARAMS: /* struct if_linkparamsreq */
bcopy(((struct if_linkparamsreq *)(void *)data)->iflpr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCGIFQUEUESTATS: /* struct if_qstatsreq */
bcopy(((struct if_qstatsreq *)(void *)data)->ifqr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCSIFTHROTTLE: /* struct if_throttlereq */
case SIOCGIFTHROTTLE: /* struct if_throttlereq */
bcopy(((struct if_throttlereq *)(void *)data)->ifthr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCAIFAGENTID: /* struct if_agentidreq */
case SIOCGIFAGENTIDS64: /* struct if_agentidsreq64 */
bcopy(((struct if_agentidreq *)(void *)data)->ifar_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
case SIOCSIFNETSIGNATURE: /* struct if_nsreq */
case SIOCGIFNETSIGNATURE: /* struct if_nsreq */
bcopy(((struct if_nsreq *)(void *)data)->ifnsr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
+ case SIOCSIFNETWORKID: /* struct if_netidreq */
+ bcopy(((struct if_netidreq *)(void *)data)->ifnetid_name,
+ ifname, IFNAMSIZ);
+ ifp = ifunit_ref(ifname);
+ break;
case SIOCGIFPROTOLIST32: /* struct if_protolistreq32 */
case SIOCGIFPROTOLIST64: /* struct if_protolistreq64 */
bcopy(((struct if_protolistreq *)(void *)data)->ifpl_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
default:
/*
*/
bcopy(((struct ifreq *)(void *)data)->ifr_name,
ifname, IFNAMSIZ);
- ifp = ifunit(ifname);
+ ifp = ifunit_ref(ifname);
break;
}
dlil_if_unlock();
}
switch (cmd) {
case SIOCSIFPHYADDR: /* struct {if,in_}aliasreq */
-#if INET6
case SIOCSIFPHYADDR_IN6_32: /* struct in6_aliasreq_32 */
case SIOCSIFPHYADDR_IN6_64: /* struct in6_aliasreq_64 */
-#endif /* INET6 */
error = proc_suser(p);
if (error != 0) {
break;
bcopy(ifs, data, sizeof(*ifs));
break;
- case SIOCGIFMEDIA32: /* struct ifmediareq32 */
- case SIOCGIFMEDIA64: /* struct ifmediareq64 */
+ case SIOCGIFMEDIA32: /* struct ifmediareq32 */
+ case SIOCGIFMEDIA64: /* struct ifmediareq64 */
case SIOCGIFXMEDIA32: /* struct ifmediareq32 */
case SIOCGIFXMEDIA64: /* struct ifmediareq64 */
error = ifioctl_get_media(ifp, so, cmd, data);
error = ifioctl_netsignature(ifp, cmd, data);
break;
-#if INET6
+ case SIOCSIFNETWORKID: /* struct if_netidreq */
+ error = ifioctl_networkid(ifp, data);
+ break;
case SIOCSIFNAT64PREFIX: /* struct if_nat64req */
case SIOCGIFNAT64PREFIX: /* struct if_nat64req */
error = ifioctl_nat64prefix(ifp, cmd, data);
case SIOCGIFCLAT46ADDR: /* struct if_clat46req */
error = ifioctl_clat46addr(ifp, cmd, data);
break;
-#endif
case SIOCGIFPROTOLIST32: /* struct if_protolistreq32 */
case SIOCGIFPROTOLIST64: /* struct if_protolistreq64 */
}
}
+ if (ifp != NULL) {
+ ifnet_decr_iorefcnt(ifp);
+ }
return error;
}
ifnet_lock_done(ifp);
break;
+ case SIOCGIFXFLAGS:
+ ifnet_lock_shared(ifp);
+ ifr->ifr_xflags = ifp->if_xflags;
+ ifnet_lock_done(ifp);
+ break;
+
case SIOCGIFCAP:
ifnet_lock_shared(ifp);
ifr->ifr_reqcap = ifp->if_capabilities;
ifnet_lock_done(ifp);
break;
-#if CONFIG_MACF_NET
- case SIOCGIFMAC:
- error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp);
- break;
-
- case SIOCSIFMAC:
- error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp);
- break;
-#endif /* CONFIG_MACF_NET */
-
case SIOCGIFMETRIC:
ifnet_lock_shared(ifp);
ifr->ifr_metric = ifp->if_metric;
*/
if (ifp->if_mtu != oldmtu) {
if_rtmtu_update(ifp);
-#if INET6
nd6_setmtu(ifp);
-#endif /* INET6 */
/* Inform all transmit queues about the new MTU */
IFCQ_LOCK(ifq);
ifnet_update_sndq(ifq, CLASSQ_EV_LINK_MTU);
error = EINVAL;
break;
}
+ if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
+ ifr->ifr_addr.sa_len = sizeof(struct sockaddr);
+ }
/*
* User is permitted to anonymously join a particular link
case SIOCSIFALTMTU:
case SIOCSIFVLAN:
case SIOCSIFBOND:
+ case SIOCSIF6LOWPAN:
error = proc_suser(p);
if (error != 0) {
break;
case SIOCGIFDEVMTU:
case SIOCGIFVLAN:
case SIOCGIFBOND:
+ case SIOCGIF6LOWPAN:
error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
break;
PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
return error;
}
- ifnet_lock_exclusive(ifp);
if (ifr->ifr_expensive) {
- ifp->if_eflags |= IFEF_EXPENSIVE;
+ if_set_eflags(ifp, IFEF_EXPENSIVE);
} else {
- ifp->if_eflags &= ~IFEF_EXPENSIVE;
+ if_clear_eflags(ifp, IFEF_EXPENSIVE);
}
- ifnet_lock_done(ifp);
+ ifnet_increment_generation(ifp);
+
/*
* Update the expensive bit in the delegated interface
* structure.
if (difp->if_delegated.ifp == ifp) {
difp->if_delegated.expensive =
ifp->if_eflags & IFEF_EXPENSIVE ? 1 : 0;
+ ifnet_increment_generation(difp);
}
ifnet_lock_done(difp);
}
ifnet_head_done();
+ necp_update_all_clients();
+ break;
+ }
+
+ case SIOCGIFCONSTRAINED:
+ if ((ifp->if_xflags & IFXF_CONSTRAINED) != 0) {
+ ifr->ifr_constrained = 1;
+ } else {
+ ifr->ifr_constrained = 0;
+ }
+ break;
+
+ case SIOCSIFCONSTRAINED:
+ {
+ struct ifnet *difp;
+
+ if ((error = priv_check_cred(kauth_cred_get(),
+ PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
+ return error;
+ }
+ if (ifr->ifr_constrained) {
+ if_set_xflags(ifp, IFXF_CONSTRAINED);
+ } else {
+ if_clear_xflags(ifp, IFXF_CONSTRAINED);
+ }
+ ifnet_increment_generation(ifp);
+ /*
+ * Update the constrained bit in the delegated interface
+ * structure.
+ */
+ ifnet_head_lock_shared();
+ TAILQ_FOREACH(difp, &ifnet_head, if_link) {
+ ifnet_lock_exclusive(difp);
+ if (difp->if_delegated.ifp == ifp) {
+ difp->if_delegated.constrained =
+ ((ifp->if_xflags & IFXF_CONSTRAINED) != 0) ? 1 : 0;
+ ifnet_increment_generation(difp);
+ }
+ ifnet_lock_done(difp);
+ }
+ ifnet_head_done();
+ necp_update_all_clients();
break;
}
PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
return error;
}
- ifnet_lock_exclusive(ifp);
if (ifr->ifr_2kcl) {
- ifp->if_eflags |= IFEF_2KCL;
+ if_set_eflags(ifp, IFEF_2KCL);
} else {
- ifp->if_eflags &= ~IFEF_2KCL;
+ if_clear_eflags(ifp, IFEF_2KCL);
}
- ifnet_lock_done(ifp);
break;
case SIOCGSTARTDELAY:
ifnet_lock_shared(ifp);
case SIOCGIFINTERFACESTATE:
if_get_state(ifp, &ifr->ifr_interface_state);
-
break;
+
case SIOCSIFINTERFACESTATE:
if ((error = priv_check_cred(kauth_cred_get(),
PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
return error;
}
if (ifr->ifr_ecn_mode == IFRTYPE_ECN_DEFAULT) {
- ifp->if_eflags &= ~(IFEF_ECN_ENABLE | IFEF_ECN_DISABLE);
+ if_clear_eflags(ifp, IFEF_ECN_ENABLE | IFEF_ECN_DISABLE);
} else if (ifr->ifr_ecn_mode == IFRTYPE_ECN_ENABLE) {
- ifp->if_eflags |= IFEF_ECN_ENABLE;
- ifp->if_eflags &= ~IFEF_ECN_DISABLE;
+ if_set_eflags(ifp, IFEF_ECN_ENABLE);
+ if_clear_eflags(ifp, IFEF_ECN_DISABLE);
} else if (ifr->ifr_ecn_mode == IFRTYPE_ECN_DISABLE) {
- ifp->if_eflags |= IFEF_ECN_DISABLE;
- ifp->if_eflags &= ~IFEF_ECN_ENABLE;
+ if_set_eflags(ifp, IFEF_ECN_DISABLE);
+ if_clear_eflags(ifp, IFEF_ECN_ENABLE);
} else {
error = EINVAL;
}
break;
+
case SIOCSIFTIMESTAMPENABLE:
case SIOCSIFTIMESTAMPDISABLE:
error = proc_suser(p);
break;
}
- ifnet_lock_exclusive(ifp);
if ((cmd == SIOCSIFTIMESTAMPENABLE &&
(ifp->if_xflags & IFXF_TIMESTAMP_ENABLED) != 0) ||
(cmd == SIOCSIFTIMESTAMPDISABLE &&
(ifp->if_xflags & IFXF_TIMESTAMP_ENABLED) == 0)) {
- ifnet_lock_done(ifp);
break;
}
if (cmd == SIOCSIFTIMESTAMPENABLE) {
- ifp->if_xflags |= IFXF_TIMESTAMP_ENABLED;
+ if_set_xflags(ifp, IFXF_TIMESTAMP_ENABLED);
} else {
- ifp->if_xflags &= ~IFXF_TIMESTAMP_ENABLED;
+ if_clear_xflags(ifp, IFXF_TIMESTAMP_ENABLED);
}
- ifnet_lock_done(ifp);
/*
* Pass the setting to the interface if it supports either
* software or hardware time stamping
return error;
}
if (ifr->ifr_qosmarking_enabled != 0) {
- ifp->if_eflags |= IFEF_QOSMARKING_ENABLED;
+ if_set_eflags(ifp, IFEF_QOSMARKING_ENABLED);
} else {
- ifp->if_eflags &= ~IFEF_QOSMARKING_ENABLED;
+ if_clear_eflags(ifp, IFEF_QOSMARKING_ENABLED);
}
break;
case SIOCGQOSMARKINGENABLED:
ifr->ifr_qosmarking_enabled =
- (ifp->if_eflags & IFEF_QOSMARKING_ENABLED) ? 1 : 0;
+ ((ifp->if_eflags & IFEF_QOSMARKING_ENABLED) != 0) ? 1 : 0;
break;
case SIOCSIFDISABLEOUTPUT:
error = EINVAL;
#endif /* (DEBUG || DEVELOPMENT) */
break;
+
+ case SIOCSIFSUBFAMILY:
+ if ((error = priv_check_cred(kauth_cred_get(),
+ PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
+ return error;
+ }
+ error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
+ break;
+
case SIOCSIFLOWINTERNET:
if ((error = priv_check_cred(kauth_cred_get(),
PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
return error;
}
- ifnet_lock_exclusive(ifp);
if (ifr->ifr_low_internet & IFRTYPE_LOW_INTERNET_ENABLE_UL) {
- ifp->if_xflags |= IFXF_LOW_INTERNET_UL;
+ if_set_xflags(ifp, IFXF_LOW_INTERNET_UL);
} else {
- ifp->if_xflags &= ~(IFXF_LOW_INTERNET_UL);
+ if_clear_xflags(ifp, IFXF_LOW_INTERNET_UL);
}
if (ifr->ifr_low_internet & IFRTYPE_LOW_INTERNET_ENABLE_DL) {
- ifp->if_xflags |= IFXF_LOW_INTERNET_DL;
+ if_set_xflags(ifp, IFXF_LOW_INTERNET_DL);
} else {
- ifp->if_xflags &= ~(IFXF_LOW_INTERNET_DL);
+ if_clear_xflags(ifp, IFXF_LOW_INTERNET_DL);
}
- ifnet_lock_done(ifp);
break;
case SIOCGIFLOWINTERNET:
ifnet_lock_shared(ifp);
ifr->ifr_low_internet = 0;
- if (ifp->if_xflags & IFXF_LOW_INTERNET_UL) {
+ if ((ifp->if_xflags & IFXF_LOW_INTERNET_UL) != 0) {
ifr->ifr_low_internet |=
IFRTYPE_LOW_INTERNET_ENABLE_UL;
}
- if (ifp->if_xflags & IFXF_LOW_INTERNET_DL) {
+ if ((ifp->if_xflags & IFXF_LOW_INTERNET_DL) != 0) {
ifr->ifr_low_internet |=
IFRTYPE_LOW_INTERNET_ENABLE_DL;
}
break;
case SIOCGIFLOWPOWER:
ifr->ifr_low_power_mode =
- !!(ifp->if_xflags & IFXF_LOW_POWER);
+ ((ifp->if_xflags & IFXF_LOW_POWER) != 0);
break;
case SIOCSIFLOWPOWER:
#if (DEVELOPMENT || DEBUG)
- error = if_set_low_power(ifp, !!(ifr->ifr_low_power_mode));
+ error = if_set_low_power(ifp, (ifr->ifr_low_power_mode != 0));
#else /* DEVELOPMENT || DEBUG */
error = EOPNOTSUPP;
#endif /* DEVELOPMENT || DEBUG */
break;
+
+ case SIOCGIFMPKLOG:
+ ifr->ifr_mpk_log = ((ifp->if_xflags & IFXF_MPK_LOG) != 0);
+ break;
+ case SIOCSIFMPKLOG:
+ if (ifr->ifr_mpk_log) {
+ if_set_xflags(ifp, IFXF_MPK_LOG);
+ } else {
+ if_clear_xflags(ifp, IFXF_MPK_LOG);
+ }
+ break;
+ case SIOCGIFNOACKPRIO:
+ if ((ifp->if_eflags & IFEF_NOACKPRI) != 0) {
+ ifr->ifr_noack_prio = 1;
+ } else {
+ ifr->ifr_noack_prio = 0;
+ }
+ break;
+
+ case SIOCSIFNOACKPRIO:
+ if ((error = priv_check_cred(kauth_cred_get(),
+ PRIV_NET_INTERFACE_CONTROL, 0)) != 0) {
+ return error;
+ }
+ if (ifr->ifr_noack_prio) {
+ if_set_eflags(ifp, IFEF_NOACKPRI);
+ } else {
+ if_clear_eflags(ifp, IFEF_NOACKPRI);
+ }
+ break;
+
default:
VERIFY(0);
/* NOTREACHED */
if (!(ifp->if_eflags & IFEF_RXPOLL) || !ifnet_is_attached(ifp, 1)) {
return;
}
-
- /* by now, ifnet will stay attached so if_inp must be valid */
- VERIFY(ifp->if_inp != NULL);
- bcopy(&ifp->if_inp->pstats, if_rs, sizeof(*if_rs));
-
+ bcopy(&ifp->if_poll_pstats, if_rs, sizeof(*if_rs));
/* Release the IO refcnt */
ifnet_decr_iorefcnt(ifp);
}
+void
+if_copy_netif_stats(struct ifnet *ifp, struct if_netif_stats *if_ns)
+{
+ bzero(if_ns, sizeof(*if_ns));
+#pragma unused(ifp)
+}
+
struct ifaddr *
ifa_remref(struct ifaddr *ifa, int locked)
{
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
-#if INET6
/* bsd/netinet6/in6_var.h */
case SIOCSIFADDR_IN6:
case SIOCGIFADDR_IN6:
case SIOCAUTOCONF_START:
case SIOCAUTOCONF_STOP:
case SIOCSETROUTERMODE_IN6:
+ case SIOCGETROUTERMODE_IN6:
case SIOCLL_CGASTART_32:
case SIOCLL_CGASTART_64:
case SIOCGIFCGAPREP_IN6:
case SIOCSIFCGAPREP_IN6:
-#endif /* INET6 */
/* bsd/sys/sockio.h */
case SIOCSIFADDR:
case SIOCGIFASYNCMAP:
case SIOCSIFASYNCMAP:
-#if CONFIG_MACF_NET
- case SIOCGIFMAC:
- case SIOCSIFMAC:
-#endif /* CONFIG_MACF_NET */
case SIOCSIFKPI:
case SIOCGIFKPI:
case SIOCGIFLINKQUALITYMETRIC:
case SIOCSIFOPPORTUNISTIC:
case SIOCGIFOPPORTUNISTIC:
+ case SIOCGETROUTERMODE:
case SIOCSETROUTERMODE:
case SIOCGIFEFLAGS:
case SIOCSIFDESC:
case SIOCSIFNETSIGNATURE:
case SIOCGIFNETSIGNATURE:
+ case SIOCSIFNETWORKID:
case SIOCGECNMODE:
case SIOCSECNMODE:
case SIOCSIFDISABLEOUTPUT:
+ case SIOCSIFSUBFAMILY:
+
case SIOCGIFAGENTLIST32:
case SIOCGIFAGENTLIST64:
case SIOCSIFLOWINTERNET:
case SIOCGIFLOWINTERNET:
-#if INET6
case SIOCGIFNAT64PREFIX:
case SIOCSIFNAT64PREFIX:
case SIOCGIFCLAT46ADDR:
-#endif /* INET6 */
case SIOCGIFPROTOLIST32:
case SIOCGIFPROTOLIST64:
+ case SIOCSIF6LOWPAN:
+ case SIOCGIF6LOWPAN:
+
case SIOCGIFLOWPOWER:
case SIOCSIFLOWPOWER:
+
+ case SIOCGIFMPKLOG:
+ case SIOCSIFMPKLOG:
+
+ case SIOCGIFCONSTRAINED:
+ case SIOCSIFCONSTRAINED:
+
+ case SIOCGIFXFLAGS:
+
+ case SIOCGIFNOACKPRIO:
+ case SIOCSIFNOACKPRIO:
;
}
}
p_intf_ev->nwk_wqe.arg = &p_intf_ev->intf_ev_arg;
nwk_wq_enqueue((struct nwk_wq_entry*)p_intf_ev);
}
+
+int
+if_get_tcp_kao_max(struct ifnet *ifp)
+{
+ int error = 0;
+
+ if (ifp->if_tcp_kao_max == 0) {
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ error = ifnet_ioctl(ifp, 0, SIOCGIFTCPKAOMAX, &ifr);
+
+ ifnet_lock_exclusive(ifp);
+ if (error == 0) {
+ ifp->if_tcp_kao_max = ifr.ifr_tcp_kao_max;
+ } else if (error == EOPNOTSUPP) {
+ ifp->if_tcp_kao_max = default_tcp_kao_max;
+ }
+ ifnet_lock_done(ifp);
+ }
+ return error;
+}