diff options
-rw-r--r-- | include/uapi/linux/if_packet.h | 1 | ||||
-rw-r--r-- | net/packet/af_packet.c | 13 |
2 files changed, 13 insertions, 1 deletions
diff --git a/include/uapi/linux/if_packet.h b/include/uapi/linux/if_packet.h index b950c02030c0..dbf06667394b 100644 --- a/include/uapi/linux/if_packet.h +++ b/include/uapi/linux/if_packet.h | |||
@@ -56,6 +56,7 @@ struct sockaddr_ll { | |||
56 | #define PACKET_FANOUT_LB 1 | 56 | #define PACKET_FANOUT_LB 1 |
57 | #define PACKET_FANOUT_CPU 2 | 57 | #define PACKET_FANOUT_CPU 2 |
58 | #define PACKET_FANOUT_ROLLOVER 3 | 58 | #define PACKET_FANOUT_ROLLOVER 3 |
59 | #define PACKET_FANOUT_RND 4 | ||
59 | #define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 | 60 | #define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 |
60 | #define PACKET_FANOUT_FLAG_DEFRAG 0x8000 | 61 | #define PACKET_FANOUT_FLAG_DEFRAG 0x8000 |
61 | 62 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1fdf9ab91c3f..bee9bfdc8d05 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -88,7 +88,7 @@ | |||
88 | #include <linux/virtio_net.h> | 88 | #include <linux/virtio_net.h> |
89 | #include <linux/errqueue.h> | 89 | #include <linux/errqueue.h> |
90 | #include <linux/net_tstamp.h> | 90 | #include <linux/net_tstamp.h> |
91 | 91 | #include <linux/reciprocal_div.h> | |
92 | #ifdef CONFIG_INET | 92 | #ifdef CONFIG_INET |
93 | #include <net/inet_common.h> | 93 | #include <net/inet_common.h> |
94 | #endif | 94 | #endif |
@@ -1158,6 +1158,13 @@ static unsigned int fanout_demux_cpu(struct packet_fanout *f, | |||
1158 | return smp_processor_id() % num; | 1158 | return smp_processor_id() % num; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static unsigned int fanout_demux_rnd(struct packet_fanout *f, | ||
1162 | struct sk_buff *skb, | ||
1163 | unsigned int num) | ||
1164 | { | ||
1165 | return reciprocal_divide(prandom_u32(), num); | ||
1166 | } | ||
1167 | |||
1161 | static unsigned int fanout_demux_rollover(struct packet_fanout *f, | 1168 | static unsigned int fanout_demux_rollover(struct packet_fanout *f, |
1162 | struct sk_buff *skb, | 1169 | struct sk_buff *skb, |
1163 | unsigned int idx, unsigned int skip, | 1170 | unsigned int idx, unsigned int skip, |
@@ -1215,6 +1222,9 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, | |||
1215 | case PACKET_FANOUT_CPU: | 1222 | case PACKET_FANOUT_CPU: |
1216 | idx = fanout_demux_cpu(f, skb, num); | 1223 | idx = fanout_demux_cpu(f, skb, num); |
1217 | break; | 1224 | break; |
1225 | case PACKET_FANOUT_RND: | ||
1226 | idx = fanout_demux_rnd(f, skb, num); | ||
1227 | break; | ||
1218 | case PACKET_FANOUT_ROLLOVER: | 1228 | case PACKET_FANOUT_ROLLOVER: |
1219 | idx = fanout_demux_rollover(f, skb, 0, (unsigned int) -1, num); | 1229 | idx = fanout_demux_rollover(f, skb, 0, (unsigned int) -1, num); |
1220 | break; | 1230 | break; |
@@ -1284,6 +1294,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | |||
1284 | case PACKET_FANOUT_HASH: | 1294 | case PACKET_FANOUT_HASH: |
1285 | case PACKET_FANOUT_LB: | 1295 | case PACKET_FANOUT_LB: |
1286 | case PACKET_FANOUT_CPU: | 1296 | case PACKET_FANOUT_CPU: |
1297 | case PACKET_FANOUT_RND: | ||
1287 | break; | 1298 | break; |
1288 | default: | 1299 | default: |
1289 | return -EINVAL; | 1300 | return -EINVAL; |