af_packet: Add Queue mapping mode to af_packet fanout operation
authorNeil Horman <nhorman@tuxdriver.com>
Wed, 22 Jan 2014 21:01:44 +0000 (16:01 -0500)
committerDavid S. Miller <davem@davemloft.net>
Thu, 23 Jan 2014 01:35:50 +0000 (17:35 -0800)
This patch adds a queue mapping mode to the fanout operation of af_packet
sockets.  This allows user space af_packet users to better filter on flows
ingressing and egressing via a specific hardware queue, and avoids the potential
packet reordering that can occur when FANOUT_CPU is being used and irq affinity
varies.

Tested successfully by myself.  applies to net-next

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: "David S. Miller" <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/if_packet.h
net/packet/af_packet.c

index 1988a02842cc539c20381c0fbe412e2ce4c7f30d..bac27fa05f5b83f4323d18075d4f53a98aeec2fc 100644 (file)
@@ -60,6 +60,7 @@ struct sockaddr_ll {
 #define PACKET_FANOUT_CPU              2
 #define PACKET_FANOUT_ROLLOVER         3
 #define PACKET_FANOUT_RND              4
+#define PACKET_FANOUT_QM               5
 #define PACKET_FANOUT_FLAG_ROLLOVER    0x1000
 #define PACKET_FANOUT_FLAG_DEFRAG      0x8000
 
index 97346162803d87f7a4c5355b0ae54dca17296f53..6a2bb37506c567c1f03de74bf51eb8aa357e318e 100644 (file)
@@ -1312,6 +1312,13 @@ static unsigned int fanout_demux_rollover(struct packet_fanout *f,
        return idx;
 }
 
+static unsigned int fanout_demux_qm(struct packet_fanout *f,
+                                   struct sk_buff *skb,
+                                   unsigned int num)
+{
+       return skb_get_queue_mapping(skb) % num;
+}
+
 static bool fanout_has_flag(struct packet_fanout *f, u16 flag)
 {
        return f->flags & (flag >> 8);
@@ -1351,6 +1358,9 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev,
        case PACKET_FANOUT_RND:
                idx = fanout_demux_rnd(f, skb, num);
                break;
+       case PACKET_FANOUT_QM:
+               idx = fanout_demux_qm(f, skb, num);
+               break;
        case PACKET_FANOUT_ROLLOVER:
                idx = fanout_demux_rollover(f, skb, 0, (unsigned int) -1, num);
                break;
@@ -1421,6 +1431,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
        case PACKET_FANOUT_LB:
        case PACKET_FANOUT_CPU:
        case PACKET_FANOUT_RND:
+       case PACKET_FANOUT_QM:
                break;
        default:
                return -EINVAL;