/*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#include <netinet/in_var.h>
#include <netinet/in_tclass.h>
#include <netinet/ip_var.h>
+#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
SYSCTL_INT(_net_link_generic_system, OID_AUTO, if_verbose,
CTLFLAG_RW | CTLFLAG_LOCKED, &if_verbose, 0, "");
+boolean_t intcoproc_unrestricted;
+
/* Eventhandler context for interface events */
struct eventhandler_lists_ctxt ifnet_evhdlr_ctxt;
lck_mtx_init(&ifma_trash_lock, ifa_mtx_grp, ifa_mtx_attr);
TAILQ_INIT(&ifma_trash_head);
+
+ PE_parse_boot_argn("intcoproc_unrestricted", &intcoproc_unrestricted,
+ sizeof (intcoproc_unrestricted));
}
/*
if (ifa->ifa_attached != NULL)
(*ifa->ifa_attached)(ifa);
+
}
__private_extern__ void
if (unit > ifc->ifc_maxunit)
return (ENXIO);
+ lck_mtx_lock(&ifc->ifc_mutex);
err = (*ifc->ifc_create)(ifc, unit, params);
- if (err != 0)
+ if (err != 0) {
+ lck_mtx_unlock(&ifc->ifc_mutex);
return (err);
+ }
if (!wildcard) {
bytoff = unit >> 3;
}
}
+ lck_mtx_unlock(&ifc->ifc_mutex);
return (0);
}
static int
if_clone_destroy(const char *name)
{
- struct if_clone *ifc;
- struct ifnet *ifp;
+ struct if_clone *ifc = NULL;
+ struct ifnet *ifp = NULL;
int bytoff, bitoff;
u_int32_t unit;
+ int error = 0;
ifc = if_clone_lookup(name, &unit);
- if (ifc == NULL)
- return (EINVAL);
- if (unit < ifc->ifc_minifs)
- return (EINVAL);
+ if (ifc == NULL) {
+ error = EINVAL;
+ goto done;
+ }
- ifp = ifunit(name);
- if (ifp == NULL)
- return (ENXIO);
+ if (unit < ifc->ifc_minifs) {
+ error = EINVAL;
+ goto done;
+ }
- if (ifc->ifc_destroy == NULL)
- return (EOPNOTSUPP);
+ ifp = ifunit_ref(name);
+ if (ifp == NULL) {
+ error = ENXIO;
+ goto done;
+ }
- (*ifc->ifc_destroy)(ifp);
+ if (ifc->ifc_destroy == NULL) {
+ error = EOPNOTSUPP;
+ goto done;
+ }
- /*
- * Compute offset in the bitmap and deallocate the unit.
- */
+ lck_mtx_lock(&ifc->ifc_mutex);
+ error = (*ifc->ifc_destroy)(ifp);
+
+ if (error) {
+ lck_mtx_unlock(&ifc->ifc_mutex);
+ goto done;
+ }
+
+ /* Compute offset in the bitmap and deallocate the unit. */
bytoff = unit >> 3;
bitoff = unit - (bytoff << 3);
KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
("%s: bit is already cleared", __func__));
ifc->ifc_units[bytoff] &= ~(1 << bitoff);
- return (0);
+ lck_mtx_unlock(&ifc->ifc_mutex);
+
+done:
+ if (ifp != NULL)
+ ifnet_decr_iorefcnt(ifp);
+ return (error);
}
/*
return (ifc);
}
+void *
+if_clone_softc_allocate(const struct if_clone *ifc)
+{
+ void *p_clone = NULL;
+
+ VERIFY(ifc != NULL);
+
+ p_clone = zalloc(ifc->ifc_zone);
+ if (p_clone != NULL)
+ bzero(p_clone, ifc->ifc_softc_size);
+
+ return (p_clone);
+}
+
+void
+if_clone_softc_deallocate(const struct if_clone *ifc, void *p_softc)
+{
+ VERIFY(ifc != NULL && p_softc != NULL);
+ bzero(p_softc, ifc->ifc_softc_size);
+ zfree(ifc->ifc_zone, p_softc);
+}
+
/*
* Register a network interface cloner.
*/
if (ifc->ifc_units == NULL)
return (ENOBUFS);
ifc->ifc_bmlen = len;
+ 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);
+ }
LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
if_cloners_count++;
{
LIST_REMOVE(ifc, ifc_list);
FREE(ifc->ifc_units, M_CLONE);
+ if (ifc->ifc_softc_size != 0)
+ zdestroy(ifc->ifc_zone);
+
+ lck_mtx_destroy(&ifc->ifc_mutex, ifnet_lock_group);
if_cloners_count--;
}
for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
bzero(outbuf, sizeof(outbuf));
- strlcpy(outbuf, ifc->ifc_name,
- min(strlen(ifc->ifc_name), IFNAMSIZ));
+ strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
error = copyout(outbuf, dst, IFNAMSIZ);
if (error)
break;
ret = IFRTYPE_FUNCTIONAL_INTCOPROC;
} else if ((exclude_delegate &&
(ifp->if_family == IFNET_FAMILY_ETHERNET ||
+ ifp->if_family == IFNET_FAMILY_BOND ||
+ ifp->if_family == IFNET_FAMILY_VLAN ||
ifp->if_family == IFNET_FAMILY_FIREWIRE)) ||
(!exclude_delegate && IFNET_IS_WIRED(ifp))) {
ret = IFRTYPE_FUNCTIONAL_WIRED;
/*
* Find an interface address specific to an interface best matching
- * a given address.
+ * a given address applying same source address selection rules
+ * as done in the kernel for implicit source address binding
+ */
+struct ifaddr *
+ifaof_ifpforaddr_select(const struct sockaddr *addr, struct ifnet *ifp)
+{
+ u_int af = addr->sa_family;
+
+ if (af == AF_INET6)
+ return (in6_selectsrc_core_ifa(__DECONST(struct sockaddr_in6 *, addr), ifp, 0));
+
+ return (ifaof_ifpforaddr(addr, ifp));
+}
+
+/*
+ * Find an interface address specific to an interface best matching
+ * a given address without regards to source address selection.
+ *
+ * This is appropriate for use-cases where we just want to update/init
+ * some data structure like routing table entries.
*/
struct ifaddr *
ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp)
}
ifnet_touch_lastchange(ifp);
+ ifnet_touch_lastupdown(ifp);
/* Drop the lock to notify addresses and route */
ifnet_lock_done(ifp);
struct tb_profile tb = { 0, 0, 0 };
if ((error = proc_suser(p)) != 0)
- break;
+ break;
+
IFCQ_LOCK(ifq);
if (!IFCQ_IS_READY(ifq)) {
return (error);
}
+boolean_t
+if_check_netagent(struct ifnet *ifp, uuid_t find_agent_uuid)
+{
+ boolean_t found = FALSE;
+
+ if (!ifp || uuid_is_null(find_agent_uuid))
+ return FALSE;
+
+ ifnet_lock_shared(ifp);
+
+ if (ifp->if_agentids != NULL) {
+ for (uint32_t index = 0; index < ifp->if_agentcount; index++) {
+ if (uuid_compare(ifp->if_agentids[index], find_agent_uuid) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ ifnet_lock_done(ifp);
+
+ return found;
+}
+
static __attribute__((noinline)) int
ifioctl_netagent(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
{
int error = 0;
ifnet_head_lock_exclusive();
-
+ for (u_int32_t order_index = 0; order_index < count; order_index++) {
+ if (ordered_indices[order_index] == IFSCOPE_NONE ||
+ ordered_indices[order_index] > (uint32_t)if_index) {
+ error = EINVAL;
+ ifnet_head_done();
+ return (error);
+ }
+ }
// Flush current ordered list
for (ifp = TAILQ_FIRST(&ifnet_ordered_head); ifp != NULL;
ifp = TAILQ_FIRST(&ifnet_ordered_head)) {
for (u_int32_t order_index = 0; order_index < count; order_index++) {
u_int32_t interface_index = ordered_indices[order_index];
- if (interface_index == IFSCOPE_NONE ||
- interface_index > (uint32_t)if_index) {
- break;
- }
ifp = ifindex2ifnet[interface_index];
if (ifp == NULL) {
continue;
{
int error = 0;
u_int32_t *ordered_indices = NULL;
-
if (data == NULL) {
return (EINVAL);
}
if (error != 0) {
break;
}
- }
-
- error = ifnet_reset_order(ordered_indices, ifo->ifo_count);
- break;
- }
- case SIOCGIFORDER: { /* struct if_order */
- struct if_order *ifo = (struct if_order *)(void *)data;
-
- u_int32_t ordered_count = if_ordered_count;
-
- if (ifo->ifo_count == 0 ||
- ordered_count == 0) {
- ifo->ifo_count = ordered_count;
- } else if (ifo->ifo_ordered_indices != USER_ADDR_NULL) {
- u_int32_t count_to_copy =
- MIN(ordered_count, ifo->ifo_count);
- size_t length = (count_to_copy * sizeof(u_int32_t));
- struct ifnet *ifp = NULL;
- u_int32_t cursor = 0;
-
- ordered_indices = _MALLOC(length, M_NECP, M_WAITOK);
- if (ordered_indices == NULL) {
- error = ENOMEM;
+ /* ordered_indices should not contain duplicates */
+ bool found_duplicate = FALSE;
+ for (uint32_t i = 0; i < (ifo->ifo_count - 1) && !found_duplicate ; i++){
+ for (uint32_t j = i + 1; j < ifo->ifo_count && !found_duplicate ; j++){
+ if (ordered_indices[j] == ordered_indices[i]){
+ error = EINVAL;
+ found_duplicate = TRUE;
+ break;
+ }
+ }
+ }
+ if (found_duplicate) {
break;
}
+ }
- ifnet_head_lock_shared();
- TAILQ_FOREACH(ifp, &ifnet_ordered_head, if_ordered_link) {
- if (cursor >= count_to_copy) {
- break;
- }
- ordered_indices[cursor] = ifp->if_index;
- cursor++;
- }
- ifnet_head_done();
+ error = ifnet_reset_order(ordered_indices, ifo->ifo_count);
- ifo->ifo_count = count_to_copy;
- error = copyout(ordered_indices,
- ifo->ifo_ordered_indices, length);
- } else {
- error = EINVAL;
- }
break;
}
switch (cmd) {
case SIOCSIFNAT64PREFIX: /* struct if_nat64req */
error = ifnet_set_nat64prefix(ifp, ifnat64->ifnat64_prefixes);
+ if (error != 0)
+ ip6stat.ip6s_clat464_plat64_pfx_setfail++;
break;
case SIOCGIFNAT64PREFIX: /* struct if_nat64req */
error = ifnet_get_nat64prefix(ifp, ifnat64->ifnat64_prefixes);
+ if (error != 0)
+ ip6stat.ip6s_clat464_plat64_pfx_getfail++;
break;
default:
return (error);
}
+
+static __attribute__((noinline)) int
+ifioctl_clat46addr(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ struct if_clat46req *ifclat46 = (struct if_clat46req *)(void *)data;
+ struct in6_ifaddr *ia6_clat = NULL;
+ int error = 0;
+
+ VERIFY(ifp != NULL);
+
+ switch (cmd) {
+ case SIOCGIFCLAT46ADDR:
+ ia6_clat = in6ifa_ifpwithflag(ifp, IN6_IFF_CLAT46);
+ if (ia6_clat == NULL) {
+ error = ENOENT;
+ break;
+ }
+
+ bcopy(&ia6_clat->ia_addr.sin6_addr, &ifclat46->ifclat46_addr.v6_address,
+ sizeof(ifclat46->ifclat46_addr.v6_address));
+ ifclat46->ifclat46_addr.v6_prefixlen = ia6_clat->ia_plen;
+ IFA_REMREF(&ia6_clat->ia_ifa);
+ break;
+ default:
+ VERIFY(0);
+ /* NOTREACHED */
+ }
+
+ return (error);
+}
#endif
+static int
+ifioctl_get_protolist(struct ifnet *ifp, u_int32_t * ret_count,
+ user_addr_t ifpl)
+{
+ u_int32_t actual_count;
+ u_int32_t count;
+ int error = 0;
+ u_int32_t *list = NULL;
+
+ /* find out how many */
+ count = if_get_protolist(ifp, NULL, 0);
+ if (ifpl == USER_ADDR_NULL) {
+ goto done;
+ }
+
+ /* copy out how many there's space for */
+ if (*ret_count < count) {
+ count = *ret_count;
+ }
+ if (count == 0) {
+ goto done;
+ }
+ list = _MALLOC(count * sizeof(*list), M_TEMP, M_WAITOK | M_ZERO);
+ if (list == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ actual_count = if_get_protolist(ifp, list, count);
+ if (actual_count < count) {
+ count = actual_count;
+ }
+ if (count != 0) {
+ error = copyout((caddr_t)list, ifpl, count * sizeof(*list));
+ }
+
+ done:
+ if (list != NULL) {
+ if_free_protolist(list);
+ }
+ *ret_count = count;
+ return (error);
+}
+
+static __attribute__((noinline)) int
+ifioctl_protolist(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ int error = 0;
+
+ switch (cmd) {
+ case SIOCGIFPROTOLIST32: { /* struct if_protolistreq32 */
+ struct if_protolistreq32 ifpl;
+
+ bcopy(data, &ifpl, sizeof(ifpl));
+ if (ifpl.ifpl_reserved != 0) {
+ error = EINVAL;
+ break;
+ }
+ error = ifioctl_get_protolist(ifp, &ifpl.ifpl_count,
+ CAST_USER_ADDR_T(ifpl.ifpl_list));
+ bcopy(&ifpl, data, sizeof(ifpl));
+ break;
+ }
+ case SIOCGIFPROTOLIST64: { /* struct if_protolistreq64 */
+ struct if_protolistreq64 ifpl;
+
+ bcopy(data, &ifpl, sizeof(ifpl));
+ if (ifpl.ifpl_reserved != 0) {
+ error = EINVAL;
+ break;
+ }
+ error = ifioctl_get_protolist(ifp, &ifpl.ifpl_count,
+ ifpl.ifpl_list);
+ bcopy(&ifpl, data, sizeof(ifpl));
+ break;
+ }
+ default:
+ VERIFY(0);
+ /* NOTREACHED */
+ }
+
+ return (error);
+}
+
+/*
+ * List the ioctl()s we can perform on restricted INTCOPROC interfaces.
+ */
+static bool
+ifioctl_restrict_intcoproc(unsigned long cmd, const char *ifname,
+ struct ifnet *ifp, struct proc *p)
+{
+
+ if (intcoproc_unrestricted == TRUE) {
+ return (false);
+ }
+ if (proc_pid(p) == 0) {
+ return (false);
+ }
+ if (ifname) {
+ ifp = ifunit(ifname);
+ }
+ if (ifp == NULL) {
+ return (false);
+ }
+ if (!IFNET_IS_INTCOPROC(ifp)) {
+ return (false);
+ }
+ switch (cmd) {
+ case SIOCGIFBRDADDR:
+ case SIOCGIFCONF32:
+ case SIOCGIFCONF64:
+ case SIOCGIFFLAGS:
+ case SIOCGIFEFLAGS:
+ case SIOCGIFCAP:
+ case SIOCGIFMAC:
+ case SIOCGIFMETRIC:
+ case SIOCGIFMTU:
+ case SIOCGIFPHYS:
+ case SIOCGIFTYPE:
+ case SIOCGIFFUNCTIONALTYPE:
+ case SIOCGIFPSRCADDR:
+ case SIOCGIFPDSTADDR:
+ case SIOCGIFGENERIC:
+ case SIOCGIFDEVMTU:
+ case SIOCGIFVLAN:
+ case SIOCGIFBOND:
+ case SIOCGIFWAKEFLAGS:
+ case SIOCGIFGETRTREFCNT:
+ case SIOCGIFOPPORTUNISTIC:
+ case SIOCGIFLINKQUALITYMETRIC:
+ case SIOCGIFLOG:
+ case SIOCGIFDELEGATE:
+ case SIOCGIFEXPENSIVE:
+ case SIOCGIFINTERFACESTATE:
+ case SIOCGIFPROBECONNECTIVITY:
+ case SIOCGIFTIMESTAMPENABLED:
+ case SIOCGECNMODE:
+ case SIOCGQOSMARKINGMODE:
+ case SIOCGQOSMARKINGENABLED:
+ case SIOCGIFLOWINTERNET:
+ case SIOCGIFSTATUS:
+ case SIOCGIFMEDIA32:
+ case SIOCGIFMEDIA64:
+ case SIOCGIFDESC:
+ case SIOCGIFLINKPARAMS:
+ case SIOCGIFQUEUESTATS:
+ case SIOCGIFTHROTTLE:
+ case SIOCGIFAGENTIDS32:
+ case SIOCGIFAGENTIDS64:
+ case SIOCGIFNETSIGNATURE:
+ case SIOCGIFINFO_IN6:
+ case SIOCGIFAFLAG_IN6:
+ case SIOCGNBRINFO_IN6:
+ case SIOCGIFALIFETIME_IN6:
+ case SIOCGIFNETMASK_IN6:
+ case SIOCGIFPROTOLIST32:
+ case SIOCGIFPROTOLIST64:
+ return (false);
+ default:
+#if (DEBUG || DEVELOPMENT)
+ printf("%s: cmd 0x%lx not allowed (pid %u)\n",
+ __func__, cmd, proc_pid(p));
+#endif
+ return (true);
+ }
+ return (false);
+}
+
/*
* Interface ioctls.
*
goto done;
case SIOCSIFORDER: /* struct if_order */
- case SIOCGIFORDER: /* struct if_order */
error = ifioctl_iforder(cmd, data);
goto done;
case SIOCGQOSMARKINGENABLED: /* struct ifreq */
case SIOCSIFLOWINTERNET: /* struct ifreq */
case SIOCGIFLOWINTERNET: /* struct ifreq */
+ case SIOCGIFLOWPOWER: /* struct ifreq */
+ case SIOCSIFLOWPOWER: /* struct ifreq */
{ /* struct ifreq */
struct ifreq ifr;
bcopy(data, &ifr, sizeof (ifr));
ifr.ifr_name[IFNAMSIZ - 1] = '\0';
bcopy(&ifr.ifr_name, ifname, IFNAMSIZ);
+ if (ifioctl_restrict_intcoproc(cmd, ifname, NULL, p) == true) {
+ error = EPERM;
+ goto done;
+ }
error = ifioctl_ifreq(so, cmd, &ifr, p);
bcopy(&ifr, data, sizeof (ifr));
goto done;
ifp = ifunit(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);
+ break;
default:
/*
* This is a bad assumption, but the code seems to
goto done;
}
+ if (ifioctl_restrict_intcoproc(cmd, NULL, ifp, p) == true) {
+ error = EPERM;
+ goto done;
+ }
switch (cmd) {
case SIOCSIFPHYADDR: /* struct {if,in_}aliasreq */
#if INET6
break;
#if INET6
- case SIOCSIFNAT64PREFIX: /* struct if_nsreq */
- case SIOCGIFNAT64PREFIX: /* struct if_nsreq */
+ case SIOCSIFNAT64PREFIX: /* struct if_nat64req */
+ case SIOCGIFNAT64PREFIX: /* struct if_nat64req */
error = ifioctl_nat64prefix(ifp, cmd, data);
break;
+
+ case SIOCGIFCLAT46ADDR: /* struct if_clat46req */
+ error = ifioctl_clat46addr(ifp, cmd, data);
+ break;
#endif
+
+ case SIOCGIFPROTOLIST32: /* struct if_protolistreq32 */
+ case SIOCGIFPROTOLIST64: /* struct if_protolistreq64 */
+ error = ifioctl_protolist(ifp, cmd, data);
+ break;
+
default:
if (so->so_proto == NULL) {
error = EOPNOTSUPP;
* Send the event even upon error from the driver because
* we changed the flags.
*/
- ev_msg.vendor_code = KEV_VENDOR_APPLE;
- ev_msg.kev_class = KEV_NETWORK_CLASS;
- ev_msg.kev_subclass = KEV_DL_SUBCLASS;
-
- ev_msg.event_code = KEV_DL_SIFFLAGS;
- strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
- ev_data.if_family = ifp->if_family;
- ev_data.if_unit = (u_int32_t) ifp->if_unit;
- ev_msg.dv[0].data_length = sizeof(struct net_event_data);
- ev_msg.dv[0].data_ptr = &ev_data;
- ev_msg.dv[1].data_length = 0;
- dlil_post_complete_msg(ifp, &ev_msg);
+ dlil_post_sifflags_msg(ifp);
ifnet_touch_lastchange(ifp);
break;
IFRTYPE_LOW_INTERNET_ENABLE_DL;
ifnet_lock_done(ifp);
break;
+ case SIOCGIFLOWPOWER:
+ ifr->ifr_low_power_mode =
+ !!(ifp->if_xflags & IFXF_LOW_POWER);
+ break;
+ case SIOCSIFLOWPOWER:
+#if (DEVELOPMENT || DEBUG)
+ error = if_set_low_power(ifp, !!(ifr->ifr_low_power_mode));
+#else /* DEVELOPMENT || DEBUG */
+ error = EOPNOTSUPP;
+#endif /* DEVELOPMENT || DEBUG */
+ break;
default:
VERIFY(0);
/* NOTREACHED */
* has not been locked (RTV_MTU is not set) and
* if it was non-zero to begin with.
*/
- if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu)
+ if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu) {
rt->rt_rmx.rmx_mtu = ifp->if_mtu;
+ if (rt_key(rt)->sa_family == AF_INET &&
+ INTF_ADJUST_MTU_FOR_CLAT46(ifp)) {
+ rt->rt_rmx.rmx_mtu = IN6_LINKMTU(ifp);
+ /* Further adjust the size for CLAT46 expansion */
+ rt->rt_rmx.rmx_mtu -= CLAT46_HDR_EXPANSION_OVERHD;
+ }
+ }
}
RT_UNLOCK(rt);
case SIOCGIFAGENTIDS64:
case SIOCGIFAGENTDATA32:
case SIOCGIFAGENTDATA64:
- case SIOCGIFAGENTLIST32:
- case SIOCGIFAGENTLIST64:
-
case SIOCSIFINTERFACESTATE:
case SIOCGIFINTERFACESTATE:
case SIOCGECNMODE:
case SIOCSECNMODE:
+ case SIOCSIFORDER:
+
case SIOCSQOSMARKINGMODE:
case SIOCSQOSMARKINGENABLED:
case SIOCGQOSMARKINGMODE:
case SIOCGQOSMARKINGENABLED:
+
+ case SIOCSIFTIMESTAMPENABLE:
+ case SIOCSIFTIMESTAMPDISABLE:
+ case SIOCGIFTIMESTAMPENABLED:
+
+ case SIOCSIFDISABLEOUTPUT:
+
+ case SIOCGIFAGENTLIST32:
+ case SIOCGIFAGENTLIST64:
+
+ case SIOCSIFLOWINTERNET:
+ case SIOCGIFLOWINTERNET:
+
+#if INET6
+ case SIOCGIFNAT64PREFIX:
+ case SIOCSIFNAT64PREFIX:
+
+ case SIOCGIFCLAT46ADDR:
+#endif /* INET6 */
+
+ case SIOCGIFPROTOLIST32:
+ case SIOCGIFPROTOLIST64:
+
+ case SIOCGIFLOWPOWER:
+ case SIOCSIFLOWPOWER:
;
}
}
-/*
- * XXX: This API is only used by BSD stack and for now will always return 0.
- * For Skywalk native drivers, preamble space need not be allocated in mbuf
- * as the preamble will be reserved in the translated skywalk packet
- * which is transmitted to the driver.
- * For Skywalk compat drivers currently headroom is always set to zero.
- */
uint32_t
ifnet_mbuf_packetpreamblelen(struct ifnet *ifp)
{