iflib(9): Remove support for cloning pseudo interfaces
This code was used by the first incarnation of wg(4) and is dead ever sincef187d6dfbf
has removed the latter again. Moreover, this code matched iflib(4) like a square peg fits in a round hole, was incomplete and despite some hacks still tailored to VPC and wg(4) but not generic. In effect, this reverts the following:09f6ff4f1a
(w/ its "ancillary changes")9aeca21324
1f93e931d9
0f9544d03e
0dd691b412
Reviewed by: erj, kbowling Differential Revision: <https://reviews.freebsd.org/D41196>
This commit is contained in:
parent
eee6537665
commit
7ff9ae90f0
@ -52,6 +52,9 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20230803: Removal of support for cloning pseudo interfaces from iflib(9)
|
||||
OLD_FILES+=usr/include/net/iflib_private.h
|
||||
|
||||
# 20230802: Remove a copy of libdtrace.so installed to the wrong path
|
||||
OLD_FILES+=usr/lib/libdtrace.so.2
|
||||
|
||||
|
@ -325,7 +325,6 @@ rtnl_if_flags_to_linux(unsigned int if_flags)
|
||||
case IFF_STICKYARP:
|
||||
case IFF_DYING:
|
||||
case IFF_RENAMING:
|
||||
case IFF_NOGROUP:
|
||||
/* No Linux analogue */
|
||||
break;
|
||||
case IFF_MULTICAST:
|
||||
|
@ -4147,7 +4147,6 @@ net/if_vlan.c optional vlan
|
||||
net/if_vxlan.c optional vxlan inet | vxlan inet6
|
||||
net/ifdi_if.m optional ether pci iflib
|
||||
net/iflib.c optional ether pci iflib
|
||||
net/iflib_clone.c optional ether pci iflib
|
||||
net/mp_ring.c optional ether iflib
|
||||
net/mppcc.c optional netgraph_mppc_compression
|
||||
net/mppcd.c optional netgraph_mppc_compression
|
||||
|
@ -5,7 +5,6 @@
|
||||
KMOD= iflib
|
||||
SRCS= \
|
||||
iflib.c \
|
||||
iflib_clone.c \
|
||||
mp_ring.c
|
||||
SRCS+= ifdi_if.c
|
||||
SRCS+= device_if.h bus_if.h pci_if.h pci_iov_if.h ifdi_if.h
|
||||
|
@ -163,7 +163,7 @@ struct if_data {
|
||||
#define IFF_STICKYARP 0x100000 /* (n) sticky ARP */
|
||||
#define IFF_DYING 0x200000 /* (n) interface is winding down */
|
||||
#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */
|
||||
#define IFF_NOGROUP 0x800000 /* (n) interface is not part of any groups */
|
||||
#define IFF_SPARE 0x800000
|
||||
#define IFF_NETLINK_1 0x1000000 /* (n) used by netlink */
|
||||
|
||||
/*
|
||||
|
@ -308,7 +308,6 @@ void
|
||||
ifc_link_ifp(struct if_clone *ifc, struct ifnet *ifp)
|
||||
{
|
||||
|
||||
if ((ifc->ifc_flags & IFC_NOGROUP) == 0)
|
||||
if_addgroup(ifp, ifc->ifc_name);
|
||||
|
||||
IF_CLONE_LOCK(ifc);
|
||||
@ -336,7 +335,7 @@ ifc_unlink_ifp(struct if_clone *ifc, struct ifnet *ifp)
|
||||
}
|
||||
IF_CLONE_UNLOCK(ifc);
|
||||
|
||||
if (ifcifp != NULL && (ifc->ifc_flags & IFC_F_NOGROUP) == 0)
|
||||
if (ifcifp != NULL)
|
||||
if_delgroup(ifp, ifc->ifc_name);
|
||||
|
||||
return (ifcifp != NULL);
|
||||
@ -536,7 +535,7 @@ ifc_attach_cloner(const char *name, struct if_clone_addreq *req)
|
||||
ifc->ifc_match = req->match_f != NULL ? req->match_f : ifc_simple_match;
|
||||
ifc->ifc_create = req->create_f;
|
||||
ifc->ifc_destroy = req->destroy_f;
|
||||
ifc->ifc_flags = (req->flags & (IFC_F_AUTOUNIT | IFC_F_NOGROUP));
|
||||
ifc->ifc_flags = (req->flags & IFC_F_AUTOUNIT);
|
||||
|
||||
if (req->version == 2) {
|
||||
struct if_clone_addreq_v2 *req2 = (struct if_clone_addreq_v2 *)req;
|
||||
@ -782,8 +781,7 @@ if_clone_restoregroup(struct ifnet *ifp)
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
LIST_FOREACH(ifc, &V_if_cloners, ifc_list)
|
||||
if (strcmp(ifc->ifc_name, ifc_name) == 0 &&
|
||||
((ifc->ifc_flags & IFC_NOGROUP) == 0))
|
||||
if (strcmp(ifc->ifc_name, ifc_name) == 0)
|
||||
break;
|
||||
IF_CLONERS_UNLOCK();
|
||||
|
||||
@ -957,21 +955,3 @@ ifc_copyin(const struct ifc_data *ifd, void *target, size_t len)
|
||||
} else
|
||||
return (copyin(ifd->params, target, len));
|
||||
}
|
||||
|
||||
const char *
|
||||
ifc_name(struct if_clone *ifc)
|
||||
{
|
||||
return (ifc->ifc_name);
|
||||
}
|
||||
|
||||
void
|
||||
ifc_flags_set(struct if_clone *ifc, int flags)
|
||||
{
|
||||
ifc->ifc_flags = flags;
|
||||
}
|
||||
|
||||
int
|
||||
ifc_flags_get(struct if_clone *ifc)
|
||||
{
|
||||
return (ifc->ifc_flags);
|
||||
}
|
||||
|
@ -99,15 +99,12 @@ struct if_clone_addreq_v2 {
|
||||
ifc_dump_nl_f *dump_nl_f;
|
||||
};
|
||||
|
||||
|
||||
#define IFC_F_NOGROUP 0x01 /* Creation flag: don't add unit group */
|
||||
#define IFC_F_SPARE 0x01
|
||||
#define IFC_F_AUTOUNIT 0x02 /* Creation flag: automatically select unit */
|
||||
#define IFC_F_SYSSPACE 0x04 /* Cloner callback: params pointer is in kernel memory */
|
||||
#define IFC_F_FORCE 0x08 /* Deletion flag: force interface deletion */
|
||||
#define IFC_F_CREATE 0x10 /* Creation flag: indicate creation request */
|
||||
|
||||
#define IFC_NOGROUP IFC_F_NOGROUP
|
||||
|
||||
struct if_clone *ifc_attach_cloner(const char *name, struct if_clone_addreq *req);
|
||||
void ifc_detach_cloner(struct if_clone *ifc);
|
||||
int ifc_create_ifp(const char *name, struct ifc_data *ifd, struct ifnet **ifpp);
|
||||
@ -143,9 +140,6 @@ void if_clone_detach(struct if_clone *);
|
||||
int ifc_name2unit(const char *name, int *unit);
|
||||
int ifc_alloc_unit(struct if_clone *, int *);
|
||||
void ifc_free_unit(struct if_clone *, int);
|
||||
const char *ifc_name(struct if_clone *);
|
||||
void ifc_flags_set(struct if_clone *, int flags);
|
||||
int ifc_flags_get(struct if_clone *);
|
||||
|
||||
/* Interface clone event. */
|
||||
typedef void (*if_clone_event_handler_t)(void *, struct if_clone *);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014-2018, Matthew Macy (mmacy@mattmacy.io)
|
||||
# Copyright (c) 2014, Matthew Macy (mmacy@mattmacy.io)
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -39,10 +39,7 @@
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/iflib.h>
|
||||
#include <net/if_clone.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_private.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
INTERFACE ifdi;
|
||||
|
||||
@ -53,18 +50,6 @@ CODE {
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
null_knlist_add(if_ctx_t _ctx __unused, struct knote *_kn)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
null_knote_event(if_ctx_t _ctx __unused, struct knote *_kn, int _hint)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
null_timer_op(if_ctx_t _ctx __unused, uint16_t _qsidx __unused)
|
||||
{
|
||||
@ -76,12 +61,6 @@ CODE {
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
null_int_int_op(if_ctx_t _ctx __unused, int arg0 __unused)
|
||||
{
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
static int
|
||||
null_queue_intr_enable(if_ctx_t _ctx __unused, uint16_t _qid __unused)
|
||||
{
|
||||
@ -134,43 +113,6 @@ CODE {
|
||||
return (ENOTSUP);
|
||||
}
|
||||
|
||||
static void
|
||||
null_media_status(if_ctx_t ctx __unused, struct ifmediareq *ifmr)
|
||||
{
|
||||
ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
|
||||
ifmr->ifm_active = IFM_ETHER | IFM_25G_ACC | IFM_FDX;
|
||||
}
|
||||
|
||||
static int
|
||||
null_cloneattach(if_ctx_t ctx __unused, struct if_clone *ifc __unused,
|
||||
const char *name __unused, caddr_t params __unused)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
null_rx_clset(if_ctx_t _ctx __unused, uint16_t _flid __unused,
|
||||
uint16_t _qid __unused, caddr_t *_sdcl __unused)
|
||||
{
|
||||
}
|
||||
static void
|
||||
null_object_info_get(if_ctx_t ctx __unused, void *data __unused, int size __unused)
|
||||
{
|
||||
}
|
||||
static int
|
||||
default_mac_set(if_ctx_t ctx, const uint8_t *mac)
|
||||
{
|
||||
struct ifnet *ifp = iflib_get_ifp(ctx);
|
||||
struct sockaddr_dl *sdl;
|
||||
|
||||
if (ifp && ifp->if_addr) {
|
||||
sdl = (struct sockaddr_dl *)ifp->if_addr->ifa_addr;
|
||||
MPASS(sdl->sdl_type == IFT_ETHER);
|
||||
memcpy(LLADDR(sdl), mac, ETHER_ADDR_LEN);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
null_needs_restart(if_ctx_t _ctx __unused, enum iflib_restart_event _event __unused)
|
||||
{
|
||||
@ -178,58 +120,25 @@ CODE {
|
||||
}
|
||||
};
|
||||
|
||||
#
|
||||
# kevent interfaces
|
||||
#
|
||||
|
||||
METHOD int knlist_add {
|
||||
if_ctx_t _ctx;
|
||||
struct knote *_kn;
|
||||
} DEFAULT null_knlist_add;
|
||||
|
||||
METHOD int knote_event {
|
||||
if_ctx_t _ctx;
|
||||
struct knote *_kn;
|
||||
int hint;
|
||||
} DEFAULT null_knote_event;
|
||||
|
||||
|
||||
#
|
||||
# query
|
||||
#
|
||||
|
||||
METHOD int object_info_get {
|
||||
if_ctx_t _ctx;
|
||||
void *data;
|
||||
int size;
|
||||
} DEFAULT null_object_info_get;
|
||||
|
||||
#
|
||||
# bus interfaces
|
||||
#
|
||||
|
||||
METHOD int attach_pre {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_int_op;
|
||||
};
|
||||
|
||||
METHOD int attach_post {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_int_op;
|
||||
};
|
||||
|
||||
METHOD int reinit_pre {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_int_op;
|
||||
};
|
||||
|
||||
METHOD int reinit_post {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_int_op;
|
||||
|
||||
METHOD int cloneattach {
|
||||
if_ctx_t _ctx;
|
||||
struct if_clone *_ifc;
|
||||
const char *_name;
|
||||
caddr_t params;
|
||||
} DEFAULT null_cloneattach;
|
||||
};
|
||||
|
||||
METHOD int detach {
|
||||
if_ctx_t _ctx;
|
||||
@ -270,14 +179,7 @@ METHOD int rx_queues_alloc {
|
||||
|
||||
METHOD void queues_free {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_void_op;
|
||||
|
||||
METHOD void rx_clset {
|
||||
if_ctx_t _ctx;
|
||||
uint16_t _fl;
|
||||
uint16_t _qsetid;
|
||||
caddr_t *_sdcl;
|
||||
} DEFAULT null_rx_clset;
|
||||
};
|
||||
|
||||
#
|
||||
# interface reset / stop
|
||||
@ -298,7 +200,7 @@ METHOD void stop {
|
||||
METHOD int msix_intr_assign {
|
||||
if_ctx_t _sctx;
|
||||
int msix;
|
||||
} DEFAULT null_int_int_op;
|
||||
};
|
||||
|
||||
METHOD void intr_enable {
|
||||
if_ctx_t _ctx;
|
||||
@ -338,10 +240,6 @@ METHOD int mtu_set {
|
||||
if_ctx_t _ctx;
|
||||
uint32_t _mtu;
|
||||
};
|
||||
METHOD int mac_set {
|
||||
if_ctx_t _ctx;
|
||||
const uint8_t *_mac;
|
||||
} DEFAULT default_mac_set;
|
||||
|
||||
METHOD void media_set{
|
||||
if_ctx_t _ctx;
|
||||
@ -394,11 +292,11 @@ METHOD void update_admin_status {
|
||||
METHOD void media_status {
|
||||
if_ctx_t _ctx;
|
||||
struct ifmediareq *_ifm;
|
||||
} DEFAULT null_media_status;
|
||||
};
|
||||
|
||||
METHOD int media_change {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_int_op;
|
||||
};
|
||||
|
||||
METHOD uint64_t get_counter {
|
||||
if_ctx_t _ctx;
|
||||
@ -439,11 +337,6 @@ METHOD void watchdog_reset {
|
||||
if_ctx_t _ctx;
|
||||
} DEFAULT null_void_op;
|
||||
|
||||
METHOD void watchdog_reset_queue {
|
||||
if_ctx_t _ctx;
|
||||
uint16_t _q;
|
||||
} DEFAULT null_timer_op;
|
||||
|
||||
METHOD void led_func {
|
||||
if_ctx_t _ctx;
|
||||
int _onoff;
|
||||
|
295
sys/net/iflib.c
295
sys/net/iflib.c
@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/pci/pci_private.h>
|
||||
|
||||
#include <net/iflib.h>
|
||||
#include <net/iflib_private.h>
|
||||
|
||||
#include "ifdi_if.h"
|
||||
|
||||
@ -127,7 +126,7 @@ __FBSDID("$FreeBSD$");
|
||||
*
|
||||
*
|
||||
*/
|
||||
MALLOC_DEFINE(M_IFLIB, "iflib", "ifnet library");
|
||||
static MALLOC_DEFINE(M_IFLIB, "iflib", "ifnet library");
|
||||
|
||||
#define IFLIB_RXEOF_MORE (1U << 0)
|
||||
#define IFLIB_RXEOF_EMPTY (2U << 0)
|
||||
@ -245,12 +244,6 @@ iflib_get_media(if_ctx_t ctx)
|
||||
return (ctx->ifc_mediap);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
iflib_get_flags(if_ctx_t ctx)
|
||||
{
|
||||
return (ctx->ifc_flags);
|
||||
}
|
||||
|
||||
void
|
||||
iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN])
|
||||
{
|
||||
@ -310,6 +303,21 @@ typedef struct iflib_sw_tx_desc_array {
|
||||
|
||||
#define IFLIB_RESTART_BUDGET 8
|
||||
|
||||
#define IFC_LEGACY 0x001
|
||||
#define IFC_QFLUSH 0x002
|
||||
#define IFC_MULTISEG 0x004
|
||||
#define IFC_SPARE1 0x008
|
||||
#define IFC_SC_ALLOCATED 0x010
|
||||
#define IFC_INIT_DONE 0x020
|
||||
#define IFC_PREFETCH 0x040
|
||||
#define IFC_DO_RESET 0x080
|
||||
#define IFC_DO_WATCHDOG 0x100
|
||||
#define IFC_SPARE0 0x200
|
||||
#define IFC_SPARE2 0x400
|
||||
#define IFC_IN_DETACH 0x800
|
||||
|
||||
#define IFC_NETMAP_TX_IRQ 0x80000000
|
||||
|
||||
#define CSUM_OFFLOAD (CSUM_IP_TSO|CSUM_IP6_TSO|CSUM_IP| \
|
||||
CSUM_IP_UDP|CSUM_IP_TCP|CSUM_IP_SCTP| \
|
||||
CSUM_IP6_UDP|CSUM_IP6_TCP|CSUM_IP6_SCTP)
|
||||
@ -495,16 +503,6 @@ pkt_info_zero(if_pkt_info_t pi)
|
||||
#endif
|
||||
}
|
||||
|
||||
static device_method_t iflib_pseudo_methods[] = {
|
||||
DEVMETHOD(device_attach, noop_attach),
|
||||
DEVMETHOD(device_detach, iflib_pseudo_detach),
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
driver_t iflib_pseudodriver = {
|
||||
"iflib_pseudo", iflib_pseudo_methods, sizeof(struct iflib_ctx),
|
||||
};
|
||||
|
||||
static inline void
|
||||
rxd_info_zero(if_rxd_info_t ri)
|
||||
{
|
||||
@ -544,14 +542,6 @@ rxd_info_zero(if_rxd_info_t ri)
|
||||
#define CALLOUT_LOCK(txq) mtx_lock(&txq->ift_mtx)
|
||||
#define CALLOUT_UNLOCK(txq) mtx_unlock(&txq->ift_mtx)
|
||||
|
||||
void
|
||||
iflib_set_detach(if_ctx_t ctx)
|
||||
{
|
||||
STATE_LOCK(ctx);
|
||||
ctx->ifc_flags |= IFC_IN_DETACH;
|
||||
STATE_UNLOCK(ctx);
|
||||
}
|
||||
|
||||
/* Our boot-time initialization hook */
|
||||
static int iflib_module_event_handler(module_t, int, void *);
|
||||
|
||||
@ -718,6 +708,7 @@ static void iflib_add_device_sysctl_pre(if_ctx_t ctx);
|
||||
static void iflib_add_device_sysctl_post(if_ctx_t ctx);
|
||||
static void iflib_ifmp_purge(iflib_txq_t txq);
|
||||
static void _iflib_pre_assert(if_softc_ctx_t scctx);
|
||||
static void iflib_stop(if_ctx_t ctx);
|
||||
static void iflib_if_init_locked(if_ctx_t ctx);
|
||||
static void iflib_free_intr_mem(if_ctx_t ctx);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
@ -5447,237 +5438,6 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
struct iflib_cloneattach_ctx *clctx)
|
||||
{
|
||||
int num_txd, num_rxd;
|
||||
int err;
|
||||
if_ctx_t ctx;
|
||||
if_t ifp;
|
||||
if_softc_ctx_t scctx;
|
||||
int i;
|
||||
void *sc;
|
||||
|
||||
ctx = malloc(sizeof(*ctx), M_IFLIB, M_WAITOK|M_ZERO);
|
||||
sc = malloc(sctx->isc_driver->size, M_IFLIB, M_WAITOK|M_ZERO);
|
||||
ctx->ifc_flags |= IFC_SC_ALLOCATED;
|
||||
if (sctx->isc_flags & (IFLIB_PSEUDO|IFLIB_VIRTUAL))
|
||||
ctx->ifc_flags |= IFC_PSEUDO;
|
||||
|
||||
ctx->ifc_sctx = sctx;
|
||||
ctx->ifc_softc = sc;
|
||||
ctx->ifc_dev = dev;
|
||||
|
||||
if ((err = iflib_register(ctx)) != 0) {
|
||||
device_printf(dev, "%s: iflib_register failed %d\n", __func__, err);
|
||||
goto fail_ctx_free;
|
||||
}
|
||||
iflib_add_device_sysctl_pre(ctx);
|
||||
|
||||
scctx = &ctx->ifc_softc_ctx;
|
||||
ifp = ctx->ifc_ifp;
|
||||
|
||||
iflib_reset_qvalues(ctx);
|
||||
CTX_LOCK(ctx);
|
||||
if ((err = IFDI_ATTACH_PRE(ctx)) != 0) {
|
||||
device_printf(dev, "IFDI_ATTACH_PRE failed %d\n", err);
|
||||
goto fail_unlock;
|
||||
}
|
||||
if (sctx->isc_flags & IFLIB_GEN_MAC)
|
||||
ether_gen_addr(ifp, &ctx->ifc_mac);
|
||||
if ((err = IFDI_CLONEATTACH(ctx, clctx->cc_ifc, clctx->cc_name,
|
||||
clctx->cc_params)) != 0) {
|
||||
device_printf(dev, "IFDI_CLONEATTACH failed %d\n", err);
|
||||
goto fail_unlock;
|
||||
}
|
||||
#ifdef INVARIANTS
|
||||
if (scctx->isc_capabilities & IFCAP_TXCSUM)
|
||||
MPASS(scctx->isc_tx_csum_flags);
|
||||
#endif
|
||||
|
||||
if_setcapabilities(ifp, scctx->isc_capabilities | IFCAP_HWSTATS | IFCAP_LINKSTATE);
|
||||
if_setcapenable(ifp, scctx->isc_capenable | IFCAP_HWSTATS | IFCAP_LINKSTATE);
|
||||
|
||||
if_setflagbits(ifp, IFF_NOGROUP, 0);
|
||||
if (sctx->isc_flags & IFLIB_PSEUDO) {
|
||||
ifmedia_add(ctx->ifc_mediap, IFM_ETHER | IFM_AUTO, 0, NULL);
|
||||
ifmedia_set(ctx->ifc_mediap, IFM_ETHER | IFM_AUTO);
|
||||
if (sctx->isc_flags & IFLIB_PSEUDO_ETHER) {
|
||||
ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac.octet);
|
||||
} else {
|
||||
if_attach(ctx->ifc_ifp);
|
||||
bpfattach(ctx->ifc_ifp, DLT_NULL, sizeof(u_int32_t));
|
||||
}
|
||||
|
||||
if ((err = IFDI_ATTACH_POST(ctx)) != 0) {
|
||||
device_printf(dev, "IFDI_ATTACH_POST failed %d\n", err);
|
||||
goto fail_detach;
|
||||
}
|
||||
*ctxp = ctx;
|
||||
|
||||
/*
|
||||
* Tell the upper layer(s) if IFCAP_VLAN_MTU is supported.
|
||||
* This must appear after the call to ether_ifattach() because
|
||||
* ether_ifattach() sets if_hdrlen to the default value.
|
||||
*/
|
||||
if (if_getcapabilities(ifp) & IFCAP_VLAN_MTU)
|
||||
if_setifheaderlen(ifp,
|
||||
sizeof(struct ether_vlan_header));
|
||||
|
||||
if_setgetcounterfn(ctx->ifc_ifp, iflib_if_get_counter);
|
||||
iflib_add_device_sysctl_post(ctx);
|
||||
ctx->ifc_flags |= IFC_INIT_DONE;
|
||||
CTX_UNLOCK(ctx);
|
||||
return (0);
|
||||
}
|
||||
ifmedia_add(ctx->ifc_mediap, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
|
||||
ifmedia_add(ctx->ifc_mediap, IFM_ETHER | IFM_AUTO, 0, NULL);
|
||||
ifmedia_set(ctx->ifc_mediap, IFM_ETHER | IFM_AUTO);
|
||||
|
||||
_iflib_pre_assert(scctx);
|
||||
ctx->ifc_txrx = *scctx->isc_txrx;
|
||||
|
||||
if (scctx->isc_ntxqsets == 0 || (scctx->isc_ntxqsets_max && scctx->isc_ntxqsets_max < scctx->isc_ntxqsets))
|
||||
scctx->isc_ntxqsets = scctx->isc_ntxqsets_max;
|
||||
if (scctx->isc_nrxqsets == 0 || (scctx->isc_nrxqsets_max && scctx->isc_nrxqsets_max < scctx->isc_nrxqsets))
|
||||
scctx->isc_nrxqsets = scctx->isc_nrxqsets_max;
|
||||
|
||||
num_txd = iflib_num_tx_descs(ctx);
|
||||
num_rxd = iflib_num_rx_descs(ctx);
|
||||
|
||||
/* XXX change for per-queue sizes */
|
||||
device_printf(dev, "Using %d TX descriptors and %d RX descriptors\n",
|
||||
num_txd, num_rxd);
|
||||
|
||||
if (scctx->isc_tx_nsegments > num_txd / MAX_SINGLE_PACKET_FRACTION)
|
||||
scctx->isc_tx_nsegments = max(1, num_txd /
|
||||
MAX_SINGLE_PACKET_FRACTION);
|
||||
if (scctx->isc_tx_tso_segments_max > num_txd /
|
||||
MAX_SINGLE_PACKET_FRACTION)
|
||||
scctx->isc_tx_tso_segments_max = max(1,
|
||||
num_txd / MAX_SINGLE_PACKET_FRACTION);
|
||||
|
||||
/* TSO parameters - dig these out of the data sheet - simply correspond to tag setup */
|
||||
if (if_getcapabilities(ifp) & IFCAP_TSO) {
|
||||
/*
|
||||
* The stack can't handle a TSO size larger than IP_MAXPACKET,
|
||||
* but some MACs do.
|
||||
*/
|
||||
if_sethwtsomax(ifp, min(scctx->isc_tx_tso_size_max,
|
||||
IP_MAXPACKET));
|
||||
/*
|
||||
* Take maximum number of m_pullup(9)'s in iflib_parse_header()
|
||||
* into account. In the worst case, each of these calls will
|
||||
* add another mbuf and, thus, the requirement for another DMA
|
||||
* segment. So for best performance, it doesn't make sense to
|
||||
* advertize a maximum of TSO segments that typically will
|
||||
* require defragmentation in iflib_encap().
|
||||
*/
|
||||
if_sethwtsomaxsegcount(ifp, scctx->isc_tx_tso_segments_max - 3);
|
||||
if_sethwtsomaxsegsize(ifp, scctx->isc_tx_tso_segsize_max);
|
||||
}
|
||||
if (scctx->isc_rss_table_size == 0)
|
||||
scctx->isc_rss_table_size = 64;
|
||||
scctx->isc_rss_table_mask = scctx->isc_rss_table_size-1;
|
||||
|
||||
GROUPTASK_INIT(&ctx->ifc_admin_task, 0, _task_fn_admin, ctx);
|
||||
/* XXX format name */
|
||||
taskqgroup_attach(qgroup_if_config_tqg, &ctx->ifc_admin_task, ctx,
|
||||
NULL, NULL, "admin");
|
||||
|
||||
/* XXX --- can support > 1 -- but keep it simple for now */
|
||||
scctx->isc_intr = IFLIB_INTR_LEGACY;
|
||||
|
||||
/* Get memory for the station queues */
|
||||
if ((err = iflib_queues_alloc(ctx))) {
|
||||
device_printf(dev, "Unable to allocate queue memory\n");
|
||||
goto fail_iflib_detach;
|
||||
}
|
||||
|
||||
if ((err = iflib_qset_structures_setup(ctx))) {
|
||||
device_printf(dev, "qset structure setup failed %d\n", err);
|
||||
goto fail_queues;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX What if anything do we want to do about interrupts?
|
||||
*/
|
||||
ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac.octet);
|
||||
if ((err = IFDI_ATTACH_POST(ctx)) != 0) {
|
||||
device_printf(dev, "IFDI_ATTACH_POST failed %d\n", err);
|
||||
goto fail_detach;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell the upper layer(s) if IFCAP_VLAN_MTU is supported.
|
||||
* This must appear after the call to ether_ifattach() because
|
||||
* ether_ifattach() sets if_hdrlen to the default value.
|
||||
*/
|
||||
if (if_getcapabilities(ifp) & IFCAP_VLAN_MTU)
|
||||
if_setifheaderlen(ifp, sizeof(struct ether_vlan_header));
|
||||
|
||||
/* XXX handle more than one queue */
|
||||
for (i = 0; i < scctx->isc_nrxqsets; i++)
|
||||
IFDI_RX_CLSET(ctx, 0, i, ctx->ifc_rxqs[i].ifr_fl[0].ifl_sds.ifsd_cl);
|
||||
|
||||
*ctxp = ctx;
|
||||
|
||||
if_setgetcounterfn(ctx->ifc_ifp, iflib_if_get_counter);
|
||||
iflib_add_device_sysctl_post(ctx);
|
||||
ctx->ifc_flags |= IFC_INIT_DONE;
|
||||
CTX_UNLOCK(ctx);
|
||||
|
||||
return (0);
|
||||
fail_detach:
|
||||
ether_ifdetach(ctx->ifc_ifp);
|
||||
fail_queues:
|
||||
iflib_tqg_detach(ctx);
|
||||
iflib_tx_structures_free(ctx);
|
||||
iflib_rx_structures_free(ctx);
|
||||
fail_iflib_detach:
|
||||
IFDI_DETACH(ctx);
|
||||
IFDI_QUEUES_FREE(ctx);
|
||||
fail_unlock:
|
||||
CTX_UNLOCK(ctx);
|
||||
iflib_deregister(ctx);
|
||||
fail_ctx_free:
|
||||
free(ctx->ifc_softc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
iflib_pseudo_deregister(if_ctx_t ctx)
|
||||
{
|
||||
if_t ifp = ctx->ifc_ifp;
|
||||
if_shared_ctx_t sctx = ctx->ifc_sctx;
|
||||
|
||||
/* Unregister VLAN event handlers early */
|
||||
iflib_unregister_vlan_handlers(ctx);
|
||||
|
||||
if ((sctx->isc_flags & IFLIB_PSEUDO) &&
|
||||
(sctx->isc_flags & IFLIB_PSEUDO_ETHER) == 0) {
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
} else {
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
|
||||
iflib_tqg_detach(ctx);
|
||||
iflib_tx_structures_free(ctx);
|
||||
iflib_rx_structures_free(ctx);
|
||||
IFDI_DETACH(ctx);
|
||||
IFDI_QUEUES_FREE(ctx);
|
||||
|
||||
iflib_deregister(ctx);
|
||||
|
||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED)
|
||||
free(ctx->ifc_softc, M_IFLIB);
|
||||
free(ctx, M_IFLIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
iflib_device_attach(device_t dev)
|
||||
{
|
||||
@ -5977,22 +5737,12 @@ iflib_register(if_ctx_t ctx)
|
||||
driver_t *driver = sctx->isc_driver;
|
||||
device_t dev = ctx->ifc_dev;
|
||||
if_t ifp;
|
||||
u_char type;
|
||||
int iflags;
|
||||
|
||||
if ((sctx->isc_flags & IFLIB_PSEUDO) == 0)
|
||||
_iflib_assert(sctx);
|
||||
|
||||
CTX_LOCK_INIT(ctx);
|
||||
STATE_LOCK_INIT(ctx, device_get_nameunit(ctx->ifc_dev));
|
||||
if (sctx->isc_flags & IFLIB_PSEUDO) {
|
||||
if (sctx->isc_flags & IFLIB_PSEUDO_ETHER)
|
||||
type = IFT_ETHER;
|
||||
else
|
||||
type = IFT_PPP;
|
||||
} else
|
||||
type = IFT_ETHER;
|
||||
ifp = ctx->ifc_ifp = if_alloc(type);
|
||||
ifp = ctx->ifc_ifp = if_alloc(IFT_ETHER);
|
||||
if (ifp == NULL) {
|
||||
device_printf(dev, "can not allocate ifnet structure\n");
|
||||
return (ENOMEM);
|
||||
@ -6017,14 +5767,7 @@ iflib_register(if_ctx_t ctx)
|
||||
if_settransmitfn(ifp, iflib_if_transmit);
|
||||
#endif
|
||||
if_setqflushfn(ifp, iflib_if_qflush);
|
||||
iflags = IFF_MULTICAST;
|
||||
|
||||
if ((sctx->isc_flags & IFLIB_PSEUDO) &&
|
||||
(sctx->isc_flags & IFLIB_PSEUDO_ETHER) == 0)
|
||||
iflags |= IFF_POINTOPOINT;
|
||||
else
|
||||
iflags |= IFF_BROADCAST | IFF_SIMPLEX;
|
||||
if_setflags(ifp, iflags);
|
||||
if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
|
||||
ctx->ifc_vlan_attach_event =
|
||||
EVENTHANDLER_REGISTER(vlan_config, iflib_vlan_register, ctx,
|
||||
EVENTHANDLER_PRI_FIRST);
|
||||
|
@ -36,8 +36,6 @@
|
||||
#include <sys/nv.h>
|
||||
#include <sys/gtaskqueue.h>
|
||||
|
||||
struct if_clone;
|
||||
|
||||
/*
|
||||
* The value type for indexing, limits max descriptors
|
||||
* to 65535 can be conditionally redefined to uint32_t
|
||||
@ -52,8 +50,6 @@ struct if_shared_ctx;
|
||||
typedef const struct if_shared_ctx *if_shared_ctx_t;
|
||||
struct if_int_delay_info;
|
||||
typedef struct if_int_delay_info *if_int_delay_info_t;
|
||||
struct if_pseudo;
|
||||
typedef struct if_pseudo *if_pseudo_t;
|
||||
|
||||
/*
|
||||
* File organization:
|
||||
@ -280,7 +276,6 @@ struct if_shared_ctx {
|
||||
int __spare0__;
|
||||
int isc_tx_reclaim_thresh;
|
||||
int isc_flags;
|
||||
const char *isc_name;
|
||||
};
|
||||
|
||||
typedef struct iflib_dma_info {
|
||||
@ -354,35 +349,13 @@ typedef enum {
|
||||
* Driver needs frames padded to some minimum length
|
||||
*/
|
||||
#define IFLIB_NEED_ETHER_PAD 0x100
|
||||
/*
|
||||
* Packets can be freed immediately after encap
|
||||
*/
|
||||
#define IFLIB_TXD_ENCAP_PIO 0x00200
|
||||
/*
|
||||
* Use RX completion handler
|
||||
*/
|
||||
#define IFLIB_RX_COMPLETION 0x00400
|
||||
/*
|
||||
* Skip refilling cluster free lists
|
||||
*/
|
||||
#define IFLIB_SKIP_CLREFILL 0x00800
|
||||
/*
|
||||
* Don't reset on hang
|
||||
*/
|
||||
#define IFLIB_NO_HANG_RESET 0x01000
|
||||
/*
|
||||
* Don't need/want most of the niceties of
|
||||
* queue management
|
||||
*/
|
||||
#define IFLIB_PSEUDO 0x02000
|
||||
/*
|
||||
* No DMA support needed / wanted
|
||||
*/
|
||||
#define IFLIB_VIRTUAL 0x04000
|
||||
/*
|
||||
* autogenerate a MAC address
|
||||
*/
|
||||
#define IFLIB_GEN_MAC 0x08000
|
||||
#define IFLIB_SPARE7 0x200
|
||||
#define IFLIB_SPARE6 0x400
|
||||
#define IFLIB_SPARE5 0x800
|
||||
#define IFLIB_SPARE4 0x1000
|
||||
#define IFLIB_SPARE3 0x2000
|
||||
#define IFLIB_SPARE2 0x4000
|
||||
#define IFLIB_SPARE1 0x8000
|
||||
/*
|
||||
* Interface needs admin task to ignore interface up/down status
|
||||
*/
|
||||
@ -396,11 +369,7 @@ typedef enum {
|
||||
* interrupts instead of doing combined RX/TX processing.
|
||||
*/
|
||||
#define IFLIB_SINGLE_IRQ_RX_ONLY 0x40000
|
||||
/*
|
||||
* Don't need/want most of the niceties of
|
||||
* emulating ethernet
|
||||
*/
|
||||
#define IFLIB_PSEUDO_ETHER 0x80000
|
||||
#define IFLIB_SPARE0 0x80000
|
||||
/*
|
||||
* Interface has an admin completion queue
|
||||
*/
|
||||
@ -520,10 +489,4 @@ void iflib_led_create(if_ctx_t ctx);
|
||||
void iflib_add_int_delay_sysctl(if_ctx_t, const char *, const char *,
|
||||
if_int_delay_info_t, int, int);
|
||||
|
||||
/*
|
||||
* Pseudo device support
|
||||
*/
|
||||
if_pseudo_t iflib_clone_register(if_shared_ctx_t);
|
||||
void iflib_clone_deregister(if_pseudo_t);
|
||||
|
||||
#endif /* __IFLIB_H_ */
|
||||
|
@ -1,303 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2018, Matthew Macy <mmacy@mattmacy.io>
|
||||
* Copyright (C) 2017-2018 Joyent Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Neither the name of Matthew Macy nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_acpi.h"
|
||||
#include "opt_sched.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/kobj.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_private.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_clone.h>
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/vnet.h>
|
||||
|
||||
#include <net/iflib.h>
|
||||
#include <net/iflib_private.h>
|
||||
#include "ifdi_if.h"
|
||||
|
||||
int
|
||||
noop_attach(device_t dev)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
iflib_pseudo_detach(device_t dev)
|
||||
{
|
||||
if_ctx_t ctx;
|
||||
|
||||
ctx = device_get_softc(dev);
|
||||
if ((iflib_get_flags(ctx) & (IFC_INIT_DONE | IFC_IN_DETACH)) ==
|
||||
IFC_INIT_DONE)
|
||||
return (EBUSY);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_t iflib_pseudodev;
|
||||
|
||||
static struct mtx pseudoif_mtx;
|
||||
MTX_SYSINIT(pseudoif_mtx, &pseudoif_mtx, "pseudoif_mtx", MTX_DEF);
|
||||
|
||||
#define PSEUDO_LOCK() mtx_lock(&pseudoif_mtx);
|
||||
#define PSEUDO_UNLOCK() mtx_unlock(&pseudoif_mtx);
|
||||
|
||||
struct if_pseudo {
|
||||
eventhandler_tag ip_detach_tag;
|
||||
eventhandler_tag ip_lladdr_tag;
|
||||
struct if_clone *ip_ifc;
|
||||
if_shared_ctx_t ip_sctx;
|
||||
devclass_t ip_dc;
|
||||
LIST_ENTRY(if_pseudo) ip_list;
|
||||
int ip_on_list;
|
||||
};
|
||||
|
||||
static LIST_HEAD(, if_pseudo) iflib_pseudos = LIST_HEAD_INITIALIZER(iflib_pseudos);
|
||||
|
||||
/*
|
||||
* XXX this assumes that the rest of the
|
||||
* code won't hang on to it after it's
|
||||
* removed / unloaded
|
||||
*/
|
||||
static if_pseudo_t
|
||||
iflib_ip_lookup(const char *name)
|
||||
{
|
||||
if_pseudo_t ip = NULL;
|
||||
|
||||
PSEUDO_LOCK();
|
||||
LIST_FOREACH(ip, &iflib_pseudos, ip_list) {
|
||||
if (!strcmp(ip->ip_sctx->isc_name, name))
|
||||
break;
|
||||
}
|
||||
PSEUDO_UNLOCK();
|
||||
return (ip);
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_ip_delete(if_pseudo_t ip)
|
||||
{
|
||||
PSEUDO_LOCK();
|
||||
if (ip->ip_on_list) {
|
||||
LIST_REMOVE(ip, ip_list);
|
||||
ip->ip_on_list = 0;
|
||||
}
|
||||
PSEUDO_UNLOCK();
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_ip_insert(if_pseudo_t ip)
|
||||
{
|
||||
PSEUDO_LOCK();
|
||||
if (!ip->ip_on_list) {
|
||||
LIST_INSERT_HEAD(&iflib_pseudos, ip, ip_list);
|
||||
ip->ip_on_list = 1;
|
||||
}
|
||||
PSEUDO_UNLOCK();
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_ifdetach(void *arg __unused, if_t ifp)
|
||||
{
|
||||
|
||||
/* If the ifnet is just being renamed, don't do anything. */
|
||||
if (ifp->if_flags & IFF_RENAMING)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_iflladdr(void *arg __unused, if_t ifp __unused)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
iflib_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
{
|
||||
const char *name = ifc_name(ifc);
|
||||
struct iflib_cloneattach_ctx clctx;
|
||||
if_ctx_t ctx;
|
||||
if_pseudo_t ip;
|
||||
device_t dev;
|
||||
int rc;
|
||||
|
||||
clctx.cc_ifc = ifc;
|
||||
clctx.cc_len = 0;
|
||||
clctx.cc_params = params;
|
||||
clctx.cc_name = name;
|
||||
|
||||
if (__predict_false(iflib_pseudodev == NULL)) {
|
||||
/* SYSINIT initialization would panic !?! */
|
||||
bus_topo_lock();
|
||||
iflib_pseudodev = device_add_child(root_bus, "ifpseudo", 0);
|
||||
bus_topo_unlock();
|
||||
MPASS(iflib_pseudodev != NULL);
|
||||
}
|
||||
ip = iflib_ip_lookup(name);
|
||||
if (ip == NULL) {
|
||||
printf("no ip found for %s\n", name);
|
||||
return (ENOENT);
|
||||
}
|
||||
if ((dev = devclass_get_device(ip->ip_dc, unit)) != NULL) {
|
||||
printf("unit %d allocated\n", unit);
|
||||
bus_generic_print_child(iflib_pseudodev, dev);
|
||||
return (EBUSY);
|
||||
}
|
||||
PSEUDO_LOCK();
|
||||
dev = device_add_child(iflib_pseudodev, name, unit);
|
||||
device_set_driver(dev, &iflib_pseudodriver);
|
||||
PSEUDO_UNLOCK();
|
||||
device_quiet(dev);
|
||||
rc = device_attach(dev);
|
||||
MPASS(rc == 0);
|
||||
MPASS(dev != NULL);
|
||||
MPASS(devclass_get_device(ip->ip_dc, unit) == dev);
|
||||
rc = iflib_pseudo_register(dev, ip->ip_sctx, &ctx, &clctx);
|
||||
if (rc) {
|
||||
bus_topo_lock();
|
||||
device_delete_child(iflib_pseudodev, dev);
|
||||
bus_topo_unlock();
|
||||
} else
|
||||
device_set_softc(dev, ctx);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static void
|
||||
iflib_clone_destroy(if_t ifp)
|
||||
{
|
||||
if_ctx_t ctx;
|
||||
device_t dev;
|
||||
struct sx *ctx_lock;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Detach device / free / free unit
|
||||
*/
|
||||
ctx = if_getsoftc(ifp);
|
||||
dev = iflib_get_dev(ctx);
|
||||
ctx_lock = iflib_ctx_lock_get(ctx);
|
||||
sx_xlock(ctx_lock);
|
||||
iflib_set_detach(ctx);
|
||||
iflib_stop(ctx);
|
||||
sx_xunlock(ctx_lock);
|
||||
|
||||
bus_topo_lock();
|
||||
rc = device_delete_child(iflib_pseudodev, dev);
|
||||
bus_topo_unlock();
|
||||
if (rc == 0)
|
||||
iflib_pseudo_deregister(ctx);
|
||||
}
|
||||
|
||||
if_pseudo_t
|
||||
iflib_clone_register(if_shared_ctx_t sctx)
|
||||
{
|
||||
if_pseudo_t ip;
|
||||
|
||||
if (sctx->isc_name == NULL) {
|
||||
printf("iflib_clone_register failed - shared_ctx needs to have a device name\n");
|
||||
return (NULL);
|
||||
}
|
||||
if (iflib_ip_lookup(sctx->isc_name) != NULL) {
|
||||
printf("iflib_clone_register failed - shared_ctx %s alread registered\n",
|
||||
sctx->isc_name);
|
||||
return (NULL);
|
||||
}
|
||||
ip = malloc(sizeof(*ip), M_IFLIB, M_WAITOK|M_ZERO);
|
||||
ip->ip_sctx = sctx;
|
||||
ip->ip_dc = devclass_create(sctx->isc_name);
|
||||
if (ip->ip_dc == NULL)
|
||||
goto fail_clone;
|
||||
/* XXX --- we can handle clone_advanced later */
|
||||
ip->ip_ifc = if_clone_simple(sctx->isc_name, iflib_clone_create, iflib_clone_destroy, 0);
|
||||
if (ip->ip_ifc == NULL) {
|
||||
printf("clone_simple failed -- cloned %s devices will not be available\n", sctx->isc_name);
|
||||
goto fail_clone;
|
||||
}
|
||||
ip->ip_lladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
|
||||
iflib_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
|
||||
if (ip->ip_lladdr_tag == NULL)
|
||||
goto fail_addr;
|
||||
ip->ip_detach_tag = EVENTHANDLER_REGISTER(ifnet_departure_event,
|
||||
iflib_ifdetach, NULL, EVENTHANDLER_PRI_ANY);
|
||||
|
||||
if (ip->ip_detach_tag == NULL)
|
||||
goto fail_depart;
|
||||
|
||||
iflib_ip_insert(ip);
|
||||
return (ip);
|
||||
fail_depart:
|
||||
EVENTHANDLER_DEREGISTER(iflladdr_event, ip->ip_lladdr_tag);
|
||||
fail_addr:
|
||||
if_clone_detach(ip->ip_ifc);
|
||||
fail_clone:
|
||||
free(ip, M_IFLIB);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
iflib_clone_deregister(if_pseudo_t ip)
|
||||
{
|
||||
/* XXX check that is not still in use */
|
||||
iflib_ip_delete(ip);
|
||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ip->ip_detach_tag);
|
||||
EVENTHANDLER_DEREGISTER(iflladdr_event, ip->ip_lladdr_tag);
|
||||
if_clone_detach(ip->ip_ifc);
|
||||
/* XXX free devclass */
|
||||
free(ip, M_IFLIB);
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2018, Matthew Macy (mmacy@freebsd.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Neither the name of Matthew Macy nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __NET_IFLIB_PRIVATE_H_
|
||||
#define __NET_IFLIB_PRIVATE_H_
|
||||
|
||||
#define IFC_LEGACY 0x001
|
||||
#define IFC_QFLUSH 0x002
|
||||
#define IFC_MULTISEG 0x004
|
||||
#define IFC_SPARE1 0x008
|
||||
#define IFC_SC_ALLOCATED 0x010
|
||||
#define IFC_INIT_DONE 0x020
|
||||
#define IFC_PREFETCH 0x040
|
||||
#define IFC_DO_RESET 0x080
|
||||
#define IFC_DO_WATCHDOG 0x100
|
||||
#define IFC_SPARE0 0x200
|
||||
#define IFC_PSEUDO 0x400
|
||||
#define IFC_IN_DETACH 0x800
|
||||
|
||||
#define IFC_NETMAP_TX_IRQ 0x80000000
|
||||
|
||||
MALLOC_DECLARE(M_IFLIB);
|
||||
|
||||
struct iflib_cloneattach_ctx {
|
||||
struct if_clone *cc_ifc;
|
||||
caddr_t cc_params;
|
||||
const char *cc_name;
|
||||
int cc_len;
|
||||
};
|
||||
|
||||
extern driver_t iflib_pseudodriver;
|
||||
int noop_attach(device_t dev);
|
||||
int iflib_pseudo_detach(device_t dev);
|
||||
|
||||
int iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
|
||||
struct iflib_cloneattach_ctx *clctx);
|
||||
|
||||
int iflib_pseudo_deregister(if_ctx_t ctx);
|
||||
|
||||
uint32_t iflib_get_flags(if_ctx_t ctx);
|
||||
void iflib_set_detach(if_ctx_t ctx);
|
||||
void iflib_stop(if_ctx_t ctx);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user