diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 470dbbd..c6924ab 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -650,7 +650,7 @@ static void amt_send_discovery(struct amt_dev *amt)
IPPROTO_UDP, 0,
amt->stream_dev->ifindex);
if (IS_ERR(rt)) {
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -660,7 +660,7 @@ static void amt_send_discovery(struct amt_dev *amt)
skb = netdev_alloc_skb_ip_align(amt->dev, len);
if (!skb) {
ip_rt_put(rt);
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -705,7 +705,7 @@ static void amt_send_discovery(struct amt_dev *amt)
ip_send_check(iph);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
amt_update_gw_status(amt, AMT_STATUS_SENT_DISCOVERY, true);
out:
@@ -741,7 +741,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
IPPROTO_UDP, 0,
amt->stream_dev->ifindex);
if (IS_ERR(rt)) {
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -751,7 +751,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
skb = netdev_alloc_skb_ip_align(amt->dev, len);
if (!skb) {
ip_rt_put(rt);
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -798,7 +798,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
ip_send_check(iph);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
out:
rcu_read_unlock();
@@ -820,7 +820,7 @@ static void amt_send_igmp_gq(struct amt_dev *amt,
skb_pull(skb, sizeof(struct ethhdr));
if (amt_send_membership_query(amt, skb, tunnel, false)) {
- amt->dev->stats.tx_dropped++;
+ DEV_STATS_INC(amt->dev, tx_dropped);
kfree_skb(skb);
}
}@@ -864,7 +864,7 @@ static struct sk_buff *amt_build_mld_gq(struct amt_dev *amt)
if (ipv6_dev_get_saddr(amt->net, amt->dev, &ip6h->daddr, 0,
&ip6h->saddr)) {
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
kfree_skb(skb);
return NULL;
}@@ -908,7 +908,7 @@ static void amt_send_mld_gq(struct amt_dev *amt, struct amt_tunnel_list *tunnel)
skb_pull(skb, sizeof(struct ethhdr));
if (amt_send_membership_query(amt, skb, tunnel, true)) {
- amt->dev->stats.tx_dropped++;
+ DEV_STATS_INC(amt->dev, tx_dropped);
kfree_skb(skb);
}
}@@ -1258,7 +1258,7 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
group.ip6 = ipv6_hdr(skb)->daddr;
#endif
} else {
- dev->stats.tx_errors++;
+ DEV_STATS_INC(dev, tx_errors);
goto free;
}
@@ -1271,12 +1271,21 @@ static netdev_tx_t amt_dev_xmit(struct sk_buff *skb, struct net_device *dev)
/* Gateway only passes IGMP/MLD packets */
if (!report)
goto free;
+ /* A validated report can only be forwarded after the relay's
+ * family-specific Membership Query supplies the state echoed
+ * by the Membership Update. Log this readiness failure before
+ * the shared drop path accounts it.
+ */
if ((!v6 && !READ_ONCE(amt->ready4)) ||
- (v6 && !READ_ONCE(amt->ready6)))
+ (v6 && !READ_ONCE(amt->ready6))) {
+ netdev_dbg(dev, "drop %s report: waiting for Membership Query\n",
+ v6 ? "MLD" : "IGMP");
goto free;
+ }
if (amt_send_membership_update(amt, skb, v6))
goto free;
- goto unlock;
+ /* Sent: the tunnel consumed the skb. Not a drop. */
+ return NETDEV_TX_OK;
} else if (amt->mode == AMT_MODE_RELAY) {
if (!data)
goto free;@@ -1305,8 +1314,7 @@ found:
return NETDEV_TX_OK;
free:
dev_kfree_skb(skb);
-unlock:
- dev->stats.tx_dropped++;
+ DEV_STATS_INC(dev, tx_dropped);
return NETDEV_TX_OK;
}
@@ -2653,7 +2661,7 @@ static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
IPPROTO_UDP, 0,
amt->stream_dev->ifindex);
if (IS_ERR(rt)) {
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -2663,7 +2671,7 @@ static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
skb = netdev_alloc_skb_ip_align(amt->dev, len);
if (!skb) {
ip_rt_put(rt);
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
goto out;
}
@@ -2709,7 +2717,7 @@ static void amt_send_advertisement(struct amt_dev *amt, __be32 nonce,
ip_send_check(iph);
err = ip_local_out(amt->net, sk, skb);
if (unlikely(net_xmit_eval(err)))
- amt->dev->stats.tx_errors++;
+ DEV_STATS_INC(amt->dev, tx_errors);
out:
rcu_read_unlock();
--
2.43.0