Move input processing of lagg(4) before ether_input

to get rid of dependence.

This implementation is similar with that of bridge(4).
This commit is contained in:
yamaguchi 2022-04-04 06:10:00 +00:00
parent 4776dc4064
commit d1fb119648
6 changed files with 57 additions and 98 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ethersubr.c,v 1.310 2021/12/31 14:26:09 riastradh Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.311 2022/04/04 06:10:00 yamaguchi Exp $ */
/* /*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,7 +61,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.310 2021/12/31 14:26:09 riastradh Exp $"); __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.311 2022/04/04 06:10:00 yamaguchi Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_inet.h" #include "opt_inet.h"
@ -125,8 +125,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.310 2021/12/31 14:26:09 riastradh
#include <net/agr/if_agrvar.h> #include <net/agr/if_agrvar.h>
#endif #endif
#include <net/lagg/if_laggvar.h>
#if NBRIDGE > 0 #if NBRIDGE > 0
#include <net/if_bridgevar.h> #include <net/if_bridgevar.h>
#endif #endif
@ -185,9 +183,6 @@ const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN] =
static pktq_rps_hash_func_t ether_pktq_rps_hash_p; static pktq_rps_hash_func_t ether_pktq_rps_hash_p;
/* if_lagg(4) support */
struct mbuf *(*lagg_input_ethernet_p)(struct ifnet *, struct mbuf *);
static int ether_output(struct ifnet *, struct mbuf *, static int ether_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, const struct rtentry *); const struct sockaddr *, const struct rtentry *);
@ -657,9 +652,6 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
size_t ehlen; size_t ehlen;
static int earlypkts; static int earlypkts;
int isr = 0; int isr = 0;
#if NAGR > 0
void *agrprivate;
#endif
KASSERT(!cpu_intr_p()); KASSERT(!cpu_intr_p());
KASSERT((m->m_flags & M_PKTHDR) != 0); KASSERT((m->m_flags & M_PKTHDR) != 0);
@ -764,12 +756,7 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
} }
#if NAGR > 0 #if NAGR > 0
if (ifp->if_type != IFT_IEEE8023ADLAG) { if (ifp->if_lagg != NULL &&
agrprivate = ifp->if_lagg;
} else {
agrprivate = NULL;
}
if (agrprivate != NULL &&
__predict_true(etype != ETHERTYPE_SLOWPROTOCOLS)) { __predict_true(etype != ETHERTYPE_SLOWPROTOCOLS)) {
m->m_flags &= ~M_PROMISC; m->m_flags &= ~M_PROMISC;
agr_input(ifp, m); agr_input(ifp, m);
@ -777,14 +764,6 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
} }
#endif #endif
/* Handle input from a lagg(4) port */
if (ifp->if_type == IFT_IEEE8023ADLAG) {
KASSERT(lagg_input_ethernet_p != NULL);
m = (*lagg_input_ethernet_p)(ifp, m);
if (m == NULL)
return;
}
/* /*
* If VLANs are configured on the interface, check to * If VLANs are configured on the interface, check to
* see if the device performed the decapsulation and * see if the device performed the decapsulation and
@ -859,14 +838,14 @@ ether_input(struct ifnet *ifp, struct mbuf *m)
switch (subtype) { switch (subtype) {
#if NAGR > 0 #if NAGR > 0
case SLOWPROTOCOLS_SUBTYPE_LACP: case SLOWPROTOCOLS_SUBTYPE_LACP:
if (agrprivate != NULL) { if (ifp->if_lagg != NULL) {
ieee8023ad_lacp_input(ifp, m); ieee8023ad_lacp_input(ifp, m);
return; return;
} }
break; break;
case SLOWPROTOCOLS_SUBTYPE_MARKER: case SLOWPROTOCOLS_SUBTYPE_MARKER:
if (agrprivate != NULL) { if (ifp->if_lagg != NULL) {
ieee8023ad_marker_input(ifp, m); ieee8023ad_marker_input(ifp, m);
return; return;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_lagg.c,v 1.45 2022/04/01 07:26:51 yamaguchi Exp $ */ /* $NetBSD: if_lagg.c,v 1.46 2022/04/04 06:10:00 yamaguchi Exp $ */
/* /*
* Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
@ -20,7 +20,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.45 2022/04/01 07:26:51 yamaguchi Exp $"); __KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.46 2022/04/04 06:10:00 yamaguchi Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_inet.h" #include "opt_inet.h"
@ -66,7 +66,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.45 2022/04/01 07:26:51 yamaguchi Exp $
#endif #endif
#include <net/lagg/if_lagg.h> #include <net/lagg/if_lagg.h>
#include <net/lagg/if_laggvar.h>
#include <net/lagg/if_laggproto.h> #include <net/lagg/if_laggproto.h>
#include "ioconf.h" #include "ioconf.h"
@ -134,8 +133,7 @@ static const struct lagg_proto lagg_protos[] = {
}; };
static int lagg_chg_sadl(struct ifnet *, const uint8_t *, size_t); static int lagg_chg_sadl(struct ifnet *, const uint8_t *, size_t);
static struct mbuf * static void lagg_input_ethernet(struct ifnet *, struct mbuf *);
lagg_input_ethernet(struct ifnet *, struct mbuf *);
static int lagg_clone_create(struct if_clone *, int); static int lagg_clone_create(struct if_clone *, int);
static int lagg_clone_destroy(struct ifnet *); static int lagg_clone_destroy(struct ifnet *);
static int lagg_init(struct ifnet *); static int lagg_init(struct ifnet *);
@ -338,7 +336,6 @@ lagginit(void)
lagg_protos[i].pr_init(); lagg_protos[i].pr_init();
} }
lagg_input_ethernet_p = lagg_input_ethernet;
if_clone_attach(&lagg_cloner); if_clone_attach(&lagg_cloner);
} }
@ -351,7 +348,6 @@ laggdetach(void)
return EBUSY; return EBUSY;
if_clone_detach(&lagg_cloner); if_clone_detach(&lagg_cloner);
lagg_input_ethernet_p = NULL;
for (i = 0; i < LAGG_PROTO_MAX; i++) { for (i = 0; i < LAGG_PROTO_MAX; i++) {
if (lagg_protos[i].pr_fini != NULL) if (lagg_protos[i].pr_fini != NULL)
@ -1096,12 +1092,13 @@ lagg_proto_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
return m; return m;
} }
static struct mbuf * static void
lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m) lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m)
{ {
struct ifnet *ifp; struct ifnet *ifp;
struct psref psref; struct psref psref;
struct lagg_port *lp; struct lagg_port *lp;
struct ether_header *eh;
int s; int s;
/* sanity check */ /* sanity check */
@ -1110,7 +1107,9 @@ lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m)
if (lp == NULL) { if (lp == NULL) {
/* This interface is not a member of lagg */ /* This interface is not a member of lagg */
pserialize_read_exit(s); pserialize_read_exit(s);
return m; m_freem(m);
if_statinc(ifp_port, if_ierrors);
return;
} }
lagg_port_getref(lp, &psref); lagg_port_getref(lp, &psref);
pserialize_read_exit(s); pserialize_read_exit(s);
@ -1121,21 +1120,38 @@ lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m)
* Drop promiscuously received packets * Drop promiscuously received packets
* if we are not in promiscuous mode. * if we are not in promiscuous mode.
*/ */
if ((m->m_flags & (M_BCAST | M_MCAST)) == 0 &&
(ifp_port->if_flags & IFF_PROMISC) != 0 &&
(ifp->if_flags & IFF_PROMISC) == 0) {
struct ether_header *eh;
eh = mtod(m, struct ether_header *); if (__predict_false(m->m_len < sizeof(*eh))) {
if (memcmp(CLLADDR(ifp->if_sadl), if ((m = m_pullup(m, sizeof(*eh))) == NULL) {
eh->ether_dhost, ETHER_ADDR_LEN) != 0) {
m_freem(m);
m = NULL;
if_statinc(ifp, if_ierrors); if_statinc(ifp, if_ierrors);
goto out; goto out;
} }
} }
eh = mtod(m, struct ether_header *);
if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
/*
* If this is not a simplex interface, drop the packet
* if it came from us.
*/
if ((ifp->if_flags & IFF_SIMPLEX) == 0 &&
memcmp(CLLADDR(ifp->if_sadl), eh->ether_shost,
ETHER_ADDR_LEN) == 0) {
goto drop;
}
if_statinc(ifp_port, if_imcasts);
} else {
if ((ifp->if_flags & IFF_PROMISC) == 0 &&
(ifp_port->if_flags & IFF_PROMISC) != 0 &&
memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
ETHER_ADDR_LEN) != 0)
goto drop;
}
if_statadd(ifp_port, if_ibytes, m->m_pkthdr.len);
if (pfil_run_hooks(ifp_port->if_pfil, &m, if (pfil_run_hooks(ifp_port->if_pfil, &m,
ifp_port, PFIL_IN) != 0) ifp_port, PFIL_IN) != 0)
goto out; goto out;
@ -1145,13 +1161,17 @@ lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m)
m_set_rcvif(m, ifp); m_set_rcvif(m, ifp);
m->m_flags &= ~M_PROMISC; m->m_flags &= ~M_PROMISC;
if_input(ifp, m); if_input(ifp, m);
m = NULL;
} }
out: out:
lagg_port_putref(lp, &psref); lagg_port_putref(lp, &psref);
return;
return m; drop:
lagg_port_putref(lp, &psref);
m_freem(m);
if_statinc(ifp_port, if_iqdrops);
return;
} }
static int static int
@ -2193,6 +2213,7 @@ lagg_port_setup(struct lagg_softc *sc,
/* backup members */ /* backup members */
lp->lp_iftype = ifp_port->if_type; lp->lp_iftype = ifp_port->if_type;
lp->lp_ioctl = ifp_port->if_ioctl; lp->lp_ioctl = ifp_port->if_ioctl;
lp->lp_input = ifp_port->_if_input;
lp->lp_output = ifp_port->if_output; lp->lp_output = ifp_port->if_output;
lp->lp_ifcapenable = ifp_port->if_capenable; lp->lp_ifcapenable = ifp_port->if_capenable;
lp->lp_mtu = ifp_port->if_mtu; lp->lp_mtu = ifp_port->if_mtu;
@ -2208,6 +2229,7 @@ lagg_port_setup(struct lagg_softc *sc,
atomic_store_release(&ifp_port->if_lagg, (void *)lp); atomic_store_release(&ifp_port->if_lagg, (void *)lp);
ifp_port->if_type = if_type; ifp_port->if_type = if_type;
ifp_port->if_ioctl = lagg_port_ioctl; ifp_port->if_ioctl = lagg_port_ioctl;
ifp_port->_if_input = lagg_input_ethernet;
ifp_port->if_output = lagg_port_output; ifp_port->if_output = lagg_port_output;
if (is_1st_port) { if (is_1st_port) {
if (lp->lp_iftype != ifp_port->if_type) if (lp->lp_iftype != ifp_port->if_type)
@ -2292,6 +2314,7 @@ restore_sadl:
} }
ifp_port->if_ioctl = lp->lp_ioctl; ifp_port->if_ioctl = lp->lp_ioctl;
ifp_port->_if_input = lp->lp_input;
ifp_port->if_output = lp->lp_output; ifp_port->if_output = lp->lp_output;
atomic_store_release(&ifp_port->if_lagg, NULL); atomic_store_release(&ifp_port->if_lagg, NULL);
IFNET_UNLOCK(ifp_port); IFNET_UNLOCK(ifp_port);
@ -2390,6 +2413,7 @@ lagg_port_teardown(struct lagg_softc *sc, struct lagg_port *lp,
(void)lagg_setmtu(ifp_port, lp->lp_mtu); (void)lagg_setmtu(ifp_port, lp->lp_mtu);
} }
ifp_port->_if_input = lp->lp_input;
ifp_port->if_output = lp->lp_output; ifp_port->if_output = lp->lp_output;
if (ifp_port->if_ioctl == lagg_port_ioctl) if (ifp_port->if_ioctl == lagg_port_ioctl)
ifp_port->if_ioctl = lp->lp_ioctl; ifp_port->if_ioctl = lp->lp_ioctl;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_lagg_lacp.c,v 1.22 2022/04/01 07:26:51 yamaguchi Exp $ */ /* $NetBSD: if_lagg_lacp.c,v 1.23 2022/04/04 06:10:00 yamaguchi Exp $ */
/*- /*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD * SPDX-License-Identifier: BSD-2-Clause-NetBSD
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_lagg_lacp.c,v 1.22 2022/04/01 07:26:51 yamaguchi Exp $"); __KERNEL_RCSID(0, "$NetBSD: if_lagg_lacp.c,v 1.23 2022/04/04 06:10:00 yamaguchi Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_lagg.h" #include "opt_lagg.h"
@ -1012,9 +1012,6 @@ lacp_pdu_input(struct lacp_softc *lsc, struct lacp_port *lacpp, struct mbuf *m)
if (m->m_pkthdr.len != sizeof(*du)) if (m->m_pkthdr.len != sizeof(*du))
goto bad; goto bad;
if ((m->m_flags & M_MCAST) == 0)
goto bad;
if (m->m_len < (int)sizeof(*du)) { if (m->m_len < (int)sizeof(*du)) {
m = m_pullup(m, sizeof(*du)); m = m_pullup(m, sizeof(*du));
if (m == NULL) { if (m == NULL) {
@ -1091,7 +1088,8 @@ lacp_marker_reply(struct lacp_softc *lsc, struct lacp_port *lacpp,
mdu = mtod(m_info, struct markerdu *); mdu = mtod(m_info, struct markerdu *);
mdu->mdu_tlv_info.tlv_type = MARKER_TYPE_RESPONSE; mdu->mdu_tlv_info.tlv_type = MARKER_TYPE_RESPONSE;
/* ether_dhost is already equals to multicast address */ /* ether_dhost is already ethermulticastaddr_slowprotocols */
m_info->m_flags |= M_MCAST;
memcpy(mdu->mdu_eh.ether_shost, memcpy(mdu->mdu_eh.ether_shost,
CLLADDR(ifp_port->if_sadl), ETHER_ADDR_LEN); CLLADDR(ifp_port->if_sadl), ETHER_ADDR_LEN);
@ -1178,9 +1176,6 @@ lacp_marker_input(struct lacp_softc *lsc, struct lacp_port *lacpp,
if (m->m_pkthdr.len != sizeof(*mdu)) if (m->m_pkthdr.len != sizeof(*mdu))
goto bad; goto bad;
if ((m->m_flags & M_MCAST) == 0)
goto bad;
if (m->m_len < (int)sizeof(*mdu)) { if (m->m_len < (int)sizeof(*mdu)) {
m = m_pullup(m, sizeof(*mdu)); m = m_pullup(m, sizeof(*mdu));
if (m == NULL) { if (m == NULL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_laggproto.h,v 1.15 2022/03/31 07:59:05 yamaguchi Exp $ */ /* $NetBSD: if_laggproto.h,v 1.16 2022/04/04 06:10:00 yamaguchi Exp $ */
/* /*
* Copyright (c) 2021 Internet Initiative Japan Inc. * Copyright (c) 2021 Internet Initiative Japan Inc.
@ -82,6 +82,7 @@ struct lagg_port {
uint64_t lp_mtu; uint64_t lp_mtu;
int (*lp_ioctl)(struct ifnet *, u_long, void *); int (*lp_ioctl)(struct ifnet *, u_long, void *);
void (*lp_input)(struct ifnet *, struct mbuf *);
int (*lp_output)(struct ifnet *, struct mbuf *, int (*lp_output)(struct ifnet *, struct mbuf *,
const struct sockaddr *, const struct sockaddr *,
const struct rtentry *); const struct rtentry *);

View File

@ -1,36 +0,0 @@
/* $NetBSD: if_laggvar.h,v 1.5 2022/03/31 02:00:27 yamaguchi Exp $ */
/*
* Copyright (c) 2021 Internet Initiative Japan 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. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
#ifndef _NET_LAGG_IF_LAGGVAR_H_
#define _NET_LAGG_IF_LAGGVAR_H_
extern struct mbuf *
(*lagg_input_ethernet_p)(struct ifnet *,
struct mbuf *);
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: net_stub.c,v 1.48 2021/09/30 04:13:42 yamaguchi Exp $ */ /* $NetBSD: net_stub.c,v 1.49 2022/04/04 06:10:00 yamaguchi Exp $ */
/* /*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved. * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@ -26,7 +26,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: net_stub.c,v 1.48 2021/09/30 04:13:42 yamaguchi Exp $"); __KERNEL_RCSID(0, "$NetBSD: net_stub.c,v 1.49 2022/04/04 06:10:00 yamaguchi Exp $");
#include <sys/mutex.h> #include <sys/mutex.h>
#include <sys/param.h> #include <sys/param.h>
@ -104,10 +104,6 @@ __weak_alias(ipsec_pcbdisconn,rumpnet_stub);
__weak_alias(key_sa_routechange,rumpnet_stub); __weak_alias(key_sa_routechange,rumpnet_stub);
__weak_alias(key_sp_unref,rumpnet_stub); __weak_alias(key_sp_unref,rumpnet_stub);
/* lagg */
__weak_alias(lagg_ifdetach,rumpnet_stub);
__weak_alias(lagg_input_ethernet,rumpnet_stub);
/* altq */ /* altq */
int (*altq_input)(struct mbuf *, int); int (*altq_input)(struct mbuf *, int);
__weak_alias(in6mask128,rumpnet_stub); __weak_alias(in6mask128,rumpnet_stub);