@@ -447,6 +447,13 @@ static struct sock *fanout_demux_lb(struct packet_fanout *f, struct sk_buff *skb
447
447
return f -> arr [cur ];
448
448
}
449
449
450
+ static struct sock * fanout_demux_cpu (struct packet_fanout * f , struct sk_buff * skb , unsigned int num )
451
+ {
452
+ unsigned int cpu = smp_processor_id ();
453
+
454
+ return f -> arr [cpu % num ];
455
+ }
456
+
450
457
static struct sk_buff * fanout_check_defrag (struct sk_buff * skb )
451
458
{
452
459
const struct iphdr * iph ;
@@ -482,8 +489,8 @@ static struct sk_buff *fanout_check_defrag(struct sk_buff *skb)
482
489
return skb ;
483
490
}
484
491
485
- static int packet_rcv_fanout_hash (struct sk_buff * skb , struct net_device * dev ,
486
- struct packet_type * pt , struct net_device * orig_dev )
492
+ static int packet_rcv_fanout (struct sk_buff * skb , struct net_device * dev ,
493
+ struct packet_type * pt , struct net_device * orig_dev )
487
494
{
488
495
struct packet_fanout * f = pt -> af_packet_priv ;
489
496
unsigned int num = f -> num_members ;
@@ -496,35 +503,25 @@ static int packet_rcv_fanout_hash(struct sk_buff *skb, struct net_device *dev,
496
503
return 0 ;
497
504
}
498
505
499
- if (f -> defrag ) {
500
- skb = fanout_check_defrag (skb );
501
- if (!skb )
502
- return 0 ;
503
- }
504
-
505
- skb_get_rxhash (skb );
506
-
507
- sk = fanout_demux_hash (f , skb , num );
508
- po = pkt_sk (sk );
509
-
510
- return po -> prot_hook .func (skb , dev , & po -> prot_hook , orig_dev );
511
- }
512
-
513
- static int packet_rcv_fanout_lb (struct sk_buff * skb , struct net_device * dev ,
514
- struct packet_type * pt , struct net_device * orig_dev )
515
- {
516
- struct packet_fanout * f = pt -> af_packet_priv ;
517
- unsigned int num = f -> num_members ;
518
- struct packet_sock * po ;
519
- struct sock * sk ;
520
-
521
- if (!net_eq (dev_net (dev ), read_pnet (& f -> net )) ||
522
- !num ) {
523
- kfree_skb (skb );
524
- return 0 ;
506
+ switch (f -> type ) {
507
+ case PACKET_FANOUT_HASH :
508
+ default :
509
+ if (f -> defrag ) {
510
+ skb = fanout_check_defrag (skb );
511
+ if (!skb )
512
+ return 0 ;
513
+ }
514
+ skb_get_rxhash (skb );
515
+ sk = fanout_demux_hash (f , skb , num );
516
+ break ;
517
+ case PACKET_FANOUT_LB :
518
+ sk = fanout_demux_lb (f , skb , num );
519
+ break ;
520
+ case PACKET_FANOUT_CPU :
521
+ sk = fanout_demux_cpu (f , skb , num );
522
+ break ;
525
523
}
526
524
527
- sk = fanout_demux_lb (f , skb , num );
528
525
po = pkt_sk (sk );
529
526
530
527
return po -> prot_hook .func (skb , dev , & po -> prot_hook , orig_dev );
@@ -571,6 +568,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
571
568
switch (type ) {
572
569
case PACKET_FANOUT_HASH :
573
570
case PACKET_FANOUT_LB :
571
+ case PACKET_FANOUT_CPU :
574
572
break ;
575
573
default :
576
574
return - EINVAL ;
@@ -606,14 +604,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
606
604
atomic_set (& match -> sk_ref , 0 );
607
605
match -> prot_hook .type = po -> prot_hook .type ;
608
606
match -> prot_hook .dev = po -> prot_hook .dev ;
609
- switch (type ) {
610
- case PACKET_FANOUT_HASH :
611
- match -> prot_hook .func = packet_rcv_fanout_hash ;
612
- break ;
613
- case PACKET_FANOUT_LB :
614
- match -> prot_hook .func = packet_rcv_fanout_lb ;
615
- break ;
616
- }
607
+ match -> prot_hook .func = packet_rcv_fanout ;
617
608
match -> prot_hook .af_packet_priv = match ;
618
609
dev_add_pack (& match -> prot_hook );
619
610
list_add (& match -> list , & fanout_list );
0 commit comments