iflib: fix cloneattach fail and generalize pseudo device handling

- a cloneattach failure will not currently be handled correctly,
  jump to the right target

- pseudo devices are all treat as if they're ethernet devices -
  this often doesn't make sense

MFC after:	1 week
Sponsored by:	Netgate, Inc.
Differential Revision:	https://reviews.freebsd.org/D25083
This commit is contained in:
Matt Macy 2020-06-21 22:02:49 +00:00
parent 9daf71541c
commit 9aeca21324
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362471
2 changed files with 44 additions and 10 deletions

View File

@ -4874,12 +4874,8 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
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_ctx_free;
goto fail_unlock;
}
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);
#ifdef INVARIANTS
if (scctx->isc_capabilities & IFCAP_TXCSUM)
MPASS(scctx->isc_tx_csum_flags);
@ -4890,7 +4886,14 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
ifp->if_flags |= IFF_NOGROUP;
if (sctx->isc_flags & IFLIB_PSEUDO) {
ether_ifattach(ctx->ifc_ifp, ctx->ifc_mac.octet);
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);
@ -4913,6 +4916,10 @@ iflib_pseudo_register(device_t dev, if_shared_ctx_t sctx, if_ctx_t *ctxp,
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;
@ -5028,6 +5035,7 @@ int
iflib_pseudo_deregister(if_ctx_t ctx)
{
if_t ifp = ctx->ifc_ifp;
if_shared_ctx_t sctx = ctx->ifc_sctx;
iflib_txq_t txq;
iflib_rxq_t rxq;
int i, j;
@ -5037,7 +5045,13 @@ iflib_pseudo_deregister(if_ctx_t ctx)
/* Unregister VLAN event handlers early */
iflib_unregister_vlan_handlers(ctx);
ether_ifdetach(ifp);
if ((sctx->isc_flags & IFLIB_PSEUDO) &&
(sctx->isc_flags & IFLIB_PSEUDO_ETHER) == 0) {
bpfdetach(ifp);
if_detach(ifp);
} else {
ether_ifdetach(ifp);
}
/* XXX drain any dependent tasks */
tqg = qgroup_if_io_tqg;
for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) {
@ -5362,13 +5376,22 @@ 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));
ifp = ctx->ifc_ifp = if_alloc(IFT_ETHER);
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);
if (ifp == NULL) {
device_printf(dev, "can not allocate ifnet structure\n");
return (ENOMEM);
@ -5393,9 +5416,14 @@ iflib_register(if_ctx_t ctx)
if_settransmitfn(ifp, iflib_if_transmit);
#endif
if_setqflushfn(ifp, iflib_if_qflush);
if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST |
IFF_KNOWSEPOCH);
iflags = IFF_MULTICAST | IFF_KNOWSEPOCH;
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);
ctx->ifc_vlan_attach_event =
EVENTHANDLER_REGISTER(vlan_config, iflib_vlan_register, ctx,
EVENTHANDLER_PRI_FIRST);

View File

@ -375,6 +375,12 @@ 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
/*
* These enum values are used in iflib_needs_restart to indicate to iflib