Convert if_foreach_llmaddr() KPI.

Reviewed by:	erj
This commit is contained in:
Gleb Smirnoff 2019-10-14 20:21:02 +00:00
parent 2a0f8518d6
commit ba76aa6357
4 changed files with 55 additions and 80 deletions

View File

@ -2333,7 +2333,7 @@ ixgbe_if_promisc_set(if_ctx_t ctx, int flags)
if (ifp->if_flags & IFF_ALLMULTI)
mcnt = MAX_NUM_MULTICAST_ADDRESSES;
else {
mcnt = if_multiaddr_count(ifp, MAX_NUM_MULTICAST_ADDRESSES);
mcnt = min(if_llmaddr_count(ifp), MAX_NUM_MULTICAST_ADDRESSES);
}
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
rctl &= (~IXGBE_FCTRL_MPE);
@ -3207,18 +3207,15 @@ ixgbe_config_delay_values(struct adapter *adapter)
*
* Called whenever multicast address list is updated.
************************************************************************/
static int
ixgbe_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int count)
static u_int
ixgbe_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int count)
{
struct adapter *adapter = arg;
struct ixgbe_mc_addr *mta = adapter->mta;
if (ifma->ifma_addr->sa_family != AF_LINK)
return (0);
if (count == MAX_NUM_MULTICAST_ADDRESSES)
return (0);
bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
mta[count].addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
bcopy(LLADDR(sdl), mta[count].addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
mta[count].vmdq = adapter->pool;
return (1);
@ -3231,15 +3228,16 @@ ixgbe_if_multi_set(if_ctx_t ctx)
struct ixgbe_mc_addr *mta;
struct ifnet *ifp = iflib_get_ifp(ctx);
u8 *update_ptr;
int mcnt = 0;
u32 fctrl;
u_int mcnt;
IOCTL_DEBUGOUT("ixgbe_if_multi_set: begin");
mta = adapter->mta;
bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES);
mcnt = if_multi_apply(iflib_get_ifp(ctx), ixgbe_mc_filter_apply, adapter);
mcnt = if_foreach_llmaddr(iflib_get_ifp(ctx), ixgbe_mc_filter_apply,
adapter);
fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);

View File

@ -1225,18 +1225,13 @@ iavf_if_update_admin_status(if_ctx_t ctx)
iavf_enable_adminq_irq(hw);
}
static int
iavf_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int count __unused)
static u_int
iavf_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int count __unused)
{
struct iavf_sc *sc = arg;
int error = 0;
if (ifma->ifma_addr->sa_family != AF_LINK)
return (0);
error = iavf_add_mac_filter(sc,
(u8*)LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
IXL_FILTER_MC);
int error;
error = iavf_add_mac_filter(sc, (u8*)LLADDR(sdl), IXL_FILTER_MC);
return (!error);
}
@ -1244,12 +1239,11 @@ static void
iavf_if_multi_set(if_ctx_t ctx)
{
struct iavf_sc *sc = iflib_get_softc(ctx);
int mcnt = 0;
IOCTL_DEBUGOUT("iavf_if_multi_set: begin");
mcnt = if_multiaddr_count(iflib_get_ifp(ctx), MAX_MULTICAST_ADDR);
if (__predict_false(mcnt == MAX_MULTICAST_ADDR)) {
if (__predict_false(if_llmaddr_count(iflib_get_ifp(ctx)) >=
MAX_MULTICAST_ADDR)) {
/* Delete MC filters and enable mulitcast promisc instead */
iavf_init_multi(sc);
sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
@ -1261,9 +1255,8 @@ iavf_if_multi_set(if_ctx_t ctx)
iavf_init_multi(sc);
/* And (re-)install filters for all mcast addresses */
mcnt = if_multi_apply(iflib_get_ifp(ctx), iavf_mc_filter_apply, sc);
if (mcnt > 0)
if (if_foreach_llmaddr(iflib_get_ifp(ctx), iavf_mc_filter_apply, sc) >
0)
iavf_send_vc_msg(sc, IAVF_FLAG_AQ_ADD_MAC_FILTER);
}
@ -1358,8 +1351,8 @@ iavf_if_promisc_set(if_ctx_t ctx, int flags)
sc->promisc_flags = 0;
if (flags & IFF_ALLMULTI ||
if_multiaddr_count(ifp, MAX_MULTICAST_ADDR) == MAX_MULTICAST_ADDR)
if (flags & IFF_ALLMULTI || if_llmaddr_count(ifp) >=
MAX_MULTICAST_ADDR)
sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
if (flags & IFF_PROMISC)
sc->promisc_flags |= FLAG_VF_UNICAST_PROMISC;

View File

@ -122,7 +122,7 @@ static void ixl_if_vflr_handle(if_ctx_t ctx);
#endif
/*** Other ***/
static int ixl_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int);
static u_int ixl_mc_filter_apply(void *, struct sockaddr_dl *, u_int);
static void ixl_save_pf_tunables(struct ixl_pf *);
static int ixl_allocate_pci_resources(struct ixl_pf *);
@ -1298,12 +1298,12 @@ ixl_if_multi_set(if_ctx_t ctx)
struct ixl_pf *pf = iflib_get_softc(ctx);
struct ixl_vsi *vsi = &pf->vsi;
struct i40e_hw *hw = vsi->hw;
int mcnt = 0, flags;
int mcnt, flags;
int del_mcnt;
IOCTL_DEBUGOUT("ixl_if_multi_set: begin");
mcnt = if_multiaddr_count(iflib_get_ifp(ctx), MAX_MULTICAST_ADDR);
mcnt = min(if_llmaddr_count(iflib_get_ifp(ctx)), MAX_MULTICAST_ADDR);
/* Delete filters for removed multicast addresses */
del_mcnt = ixl_del_multi(vsi);
vsi->num_macs -= del_mcnt;
@ -1315,8 +1315,7 @@ ixl_if_multi_set(if_ctx_t ctx)
}
/* (re-)install filters for all mcast addresses */
/* XXX: This bypasses filter count tracking code! */
mcnt = if_multi_apply(iflib_get_ifp(ctx), ixl_mc_filter_apply, vsi);
mcnt = if_foreach_llmaddr(iflib_get_ifp(ctx), ixl_mc_filter_apply, vsi);
if (mcnt > 0) {
vsi->num_macs += mcnt;
flags = (IXL_FILTER_ADD | IXL_FILTER_USED | IXL_FILTER_MC);
@ -1504,8 +1503,8 @@ ixl_if_promisc_set(if_ctx_t ctx, int flags)
if (flags & IFF_PROMISC)
uni = multi = TRUE;
else if (flags & IFF_ALLMULTI ||
if_multiaddr_count(ifp, MAX_MULTICAST_ADDR) == MAX_MULTICAST_ADDR)
else if (flags & IFF_ALLMULTI || if_llmaddr_count(ifp) >=
MAX_MULTICAST_ADDR)
multi = TRUE;
err = i40e_aq_set_vsi_unicast_promiscuous(hw,
@ -1634,15 +1633,12 @@ ixl_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data)
return (error);
}
static int
ixl_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int count __unused)
static u_int
ixl_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int count __unused)
{
struct ixl_vsi *vsi = arg;
if (ifma->ifma_addr->sa_family != AF_LINK)
return (0);
ixl_add_mc_filter(vsi,
(u8*)LLADDR((struct sockaddr_dl *) ifma->ifma_addr));
ixl_add_mc_filter(vsi, (u8*)LLADDR(sdl));
return (1);
}

View File

@ -637,6 +637,16 @@ ixl_msix_adminq(void *arg)
return (FILTER_HANDLED);
}
static u_int
ixl_add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
{
struct ixl_vsi *vsi = arg;
ixl_add_mc_filter(vsi, (u8*)LLADDR(sdl));
return (1);
}
/*********************************************************************
* Filter Routines
*
@ -646,25 +656,17 @@ ixl_msix_adminq(void *arg)
void
ixl_add_multi(struct ixl_vsi *vsi)
{
struct ifmultiaddr *ifma;
struct ifnet *ifp = vsi->ifp;
struct i40e_hw *hw = vsi->hw;
int mcnt = 0, flags;
IOCTL_DEBUGOUT("ixl_add_multi: begin");
if_maddr_rlock(ifp);
/*
** First just get a count, to decide if we
** we simply use multicast promiscuous.
*/
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
mcnt++;
}
if_maddr_runlock(ifp);
mcnt = if_llmaddr_count(ifp);
if (__predict_false(mcnt >= MAX_MULTICAST_ADDR)) {
/* delete existing MC filters */
ixl_del_hw_filters(vsi, mcnt);
@ -673,16 +675,7 @@ ixl_add_multi(struct ixl_vsi *vsi)
return;
}
mcnt = 0;
if_maddr_rlock(ifp);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
ixl_add_mc_filter(vsi,
(u8*)LLADDR((struct sockaddr_dl *) ifma->ifma_addr));
mcnt++;
}
if_maddr_runlock(ifp);
mcnt = if_foreach_llmaddr(ifp, ixl_add_maddr, vsi);
if (mcnt > 0) {
flags = (IXL_FILTER_ADD | IXL_FILTER_USED | IXL_FILTER_MC);
ixl_add_hw_filters(vsi, flags, mcnt);
@ -691,38 +684,33 @@ ixl_add_multi(struct ixl_vsi *vsi)
IOCTL_DEBUGOUT("ixl_add_multi: end");
}
static u_int
ixl_match_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
{
struct ixl_mac_filter *f = arg;
if (cmp_etheraddr(f->macaddr, (u8 *)LLADDR(sdl)))
return (1);
else
return (0);
}
int
ixl_del_multi(struct ixl_vsi *vsi)
{
struct ifnet *ifp = vsi->ifp;
struct ifmultiaddr *ifma;
struct ixl_mac_filter *f;
int mcnt = 0;
bool match = FALSE;
IOCTL_DEBUGOUT("ixl_del_multi: begin");
/* Search for removed multicast addresses */
if_maddr_rlock(ifp);
SLIST_FOREACH(f, &vsi->ftl, next) {
if ((f->flags & IXL_FILTER_USED) && (f->flags & IXL_FILTER_MC)) {
match = FALSE;
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
continue;
u8 *mc_addr = (u8 *)LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
if (cmp_etheraddr(f->macaddr, mc_addr)) {
match = TRUE;
break;
}
}
if (match == FALSE) {
f->flags |= IXL_FILTER_DEL;
mcnt++;
}
SLIST_FOREACH(f, &vsi->ftl, next)
if ((f->flags & IXL_FILTER_USED) &&
(f->flags & IXL_FILTER_MC) &&
(if_foreach_llmaddr(ifp, ixl_match_maddr, f) == 0)) {
f->flags |= IXL_FILTER_DEL;
mcnt++;
}
}
if_maddr_runlock(ifp);
if (mcnt > 0)
ixl_del_hw_filters(vsi, mcnt);