|
@@ -308,11 +308,27 @@ static bool packet_use_direct_xmit(const struct packet_sock *po)
|
|
|
return po->xmit == packet_direct_xmit;
|
|
|
}
|
|
|
|
|
|
-static u16 packet_pick_tx_queue(struct net_device *dev)
|
|
|
+static u16 __packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
|
|
|
{
|
|
|
return (u16) raw_smp_processor_id() % dev->real_num_tx_queues;
|
|
|
}
|
|
|
|
|
|
+static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ const struct net_device_ops *ops = dev->netdev_ops;
|
|
|
+ u16 queue_index;
|
|
|
+
|
|
|
+ if (ops->ndo_select_queue) {
|
|
|
+ queue_index = ops->ndo_select_queue(dev, skb, NULL,
|
|
|
+ __packet_pick_tx_queue);
|
|
|
+ queue_index = netdev_cap_txqueue(dev, queue_index);
|
|
|
+ } else {
|
|
|
+ queue_index = __packet_pick_tx_queue(dev, skb);
|
|
|
+ }
|
|
|
+
|
|
|
+ skb_set_queue_mapping(skb, queue_index);
|
|
|
+}
|
|
|
+
|
|
|
/* register_prot_hook must be invoked with the po->bind_lock held,
|
|
|
* or from a context in which asynchronous accesses to the packet
|
|
|
* socket is not possible (packet_create()).
|
|
@@ -2285,7 +2301,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- skb_set_queue_mapping(skb, packet_pick_tx_queue(dev));
|
|
|
+ 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);
|
|
@@ -2499,7 +2516,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
|
|
|
skb->dev = dev;
|
|
|
skb->priority = sk->sk_priority;
|
|
|
skb->mark = sk->sk_mark;
|
|
|
- skb_set_queue_mapping(skb, packet_pick_tx_queue(dev));
|
|
|
+
|
|
|
+ packet_pick_tx_queue(dev, skb);
|
|
|
|
|
|
if (po->has_vnet_hdr) {
|
|
|
if (vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
|