Skip to content

Commit

Permalink
net/packet: Fix Tx queue selection for AF_PACKET
Browse files Browse the repository at this point in the history
When PACKET_QDISC_BYPASS is not used, Tx queue selection will be done
before the packet is enqueued, taking into account any mappings set by
a queuing discipline such as mqprio without hardware offloading. This
selection may be affected by a previously saved queue_mapping, either on
the Rx path, or done before the packet reaches the device, as it's
currently the case for AF_PACKET.

In order for queue selection to work as expected when using traffic
control, there can't be another selection done before that point is
reached, so move the call to packet_pick_tx_queue to
packet_direct_xmit, leaving the default xmit path as it was before
PACKET_QDISC_BYPASS was introduced.

A forward declaration of packet_pick_tx_queue() is introduced to avoid
the need to reorder the functions within the file.

Fixes: d346a3f ("packet: introduce PACKET_QDISC_BYPASS socket option")
Signed-off-by: Iván Briano <ivan.briano@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Iván Briano authored and David S. Miller committed Jul 14, 2017
1 parent 31a4562 commit ccd4eb4
Showing 1 changed file with 2 additions and 4 deletions.
6 changes: 2 additions & 4 deletions net/packet/af_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ static void prb_clear_rxhash(struct tpacket_kbdq_core *,
static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
struct tpacket3_hdr *);
static void packet_flush_mclist(struct sock *sk);
static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb);

struct packet_skb_cb {
union {
Expand Down Expand Up @@ -260,6 +261,7 @@ static int packet_direct_xmit(struct sk_buff *skb)
if (skb != orig_skb)
goto drop;

packet_pick_tx_queue(dev, skb);
txq = skb_get_tx_queue(dev, skb);

local_bh_disable();
Expand Down Expand Up @@ -2747,8 +2749,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
goto tpacket_error;
}

packet_pick_tx_queue(dev, skb);

skb->destructor = tpacket_destruct_skb;
__packet_set_status(po, ph, TP_STATUS_SENDING);
packet_inc_pending(&po->tx_ring);
Expand Down Expand Up @@ -2931,8 +2931,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
skb->priority = sk->sk_priority;
skb->mark = sockc.mark;

packet_pick_tx_queue(dev, skb);

if (po->has_vnet_hdr) {
err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
if (err)
Expand Down

0 comments on commit ccd4eb4

Please sign in to comment.