@@ -3614,55 +3614,80 @@ static struct notifier_block bond_netdev_notifier = {
3614
3614
3615
3615
/*---------------------------- Hashing Policies -----------------------------*/
3616
3616
3617
+ /* Helper to access data in a packet, with or without a backing skb.
3618
+ * If skb is given the data is linearized if necessary via pskb_may_pull.
3619
+ */
3620
+ static inline const void * bond_pull_data (struct sk_buff * skb ,
3621
+ const void * data , int hlen , int n )
3622
+ {
3623
+ if (likely (n <= hlen ))
3624
+ return data ;
3625
+ else if (skb && likely (pskb_may_pull (skb , n )))
3626
+ return skb -> head ;
3627
+
3628
+ return NULL ;
3629
+ }
3630
+
3617
3631
/* L2 hash helper */
3618
- static inline u32 bond_eth_hash (struct sk_buff * skb )
3632
+ static inline u32 bond_eth_hash (struct sk_buff * skb , const void * data , int mhoff , int hlen )
3619
3633
{
3620
- struct ethhdr * ep , hdr_tmp ;
3634
+ struct ethhdr * ep ;
3621
3635
3622
- ep = skb_header_pointer (skb , 0 , sizeof (hdr_tmp ), & hdr_tmp );
3623
- if (ep )
3624
- return ep -> h_dest [5 ] ^ ep -> h_source [5 ] ^ ep -> h_proto ;
3625
- return 0 ;
3636
+ data = bond_pull_data (skb , data , hlen , mhoff + sizeof (struct ethhdr ));
3637
+ if (!data )
3638
+ return 0 ;
3639
+
3640
+ ep = (struct ethhdr * )(data + mhoff );
3641
+ return ep -> h_dest [5 ] ^ ep -> h_source [5 ] ^ ep -> h_proto ;
3626
3642
}
3627
3643
3628
- static bool bond_flow_ip (struct sk_buff * skb , struct flow_keys * fk ,
3629
- int * noff , int * proto , bool l34 )
3644
+ static bool bond_flow_ip (struct sk_buff * skb , struct flow_keys * fk , const void * data ,
3645
+ int hlen , __be16 l2_proto , int * nhoff , int * ip_proto , bool l34 )
3630
3646
{
3631
3647
const struct ipv6hdr * iph6 ;
3632
3648
const struct iphdr * iph ;
3633
3649
3634
- if (skb -> protocol == htons (ETH_P_IP )) {
3635
- if (unlikely (!pskb_may_pull (skb , * noff + sizeof (* iph ))))
3650
+ if (l2_proto == htons (ETH_P_IP )) {
3651
+ data = bond_pull_data (skb , data , hlen , * nhoff + sizeof (* iph ));
3652
+ if (!data )
3636
3653
return false;
3637
- iph = (const struct iphdr * )(skb -> data + * noff );
3654
+
3655
+ iph = (const struct iphdr * )(data + * nhoff );
3638
3656
iph_to_flow_copy_v4addrs (fk , iph );
3639
- * noff += iph -> ihl << 2 ;
3657
+ * nhoff += iph -> ihl << 2 ;
3640
3658
if (!ip_is_fragment (iph ))
3641
- * proto = iph -> protocol ;
3642
- } else if (skb -> protocol == htons (ETH_P_IPV6 )) {
3643
- if (unlikely (!pskb_may_pull (skb , * noff + sizeof (* iph6 ))))
3659
+ * ip_proto = iph -> protocol ;
3660
+ } else if (l2_proto == htons (ETH_P_IPV6 )) {
3661
+ data = bond_pull_data (skb , data , hlen , * nhoff + sizeof (* iph6 ));
3662
+ if (!data )
3644
3663
return false;
3645
- iph6 = (const struct ipv6hdr * )(skb -> data + * noff );
3664
+
3665
+ iph6 = (const struct ipv6hdr * )(data + * nhoff );
3646
3666
iph_to_flow_copy_v6addrs (fk , iph6 );
3647
- * noff += sizeof (* iph6 );
3648
- * proto = iph6 -> nexthdr ;
3667
+ * nhoff += sizeof (* iph6 );
3668
+ * ip_proto = iph6 -> nexthdr ;
3649
3669
} else {
3650
3670
return false;
3651
3671
}
3652
3672
3653
- if (l34 && * proto >= 0 )
3654
- fk -> ports .ports = skb_flow_get_ports (skb , * noff , * proto );
3673
+ if (l34 && * ip_proto >= 0 )
3674
+ fk -> ports .ports = __skb_flow_get_ports (skb , * nhoff , * ip_proto , data , hlen );
3655
3675
3656
3676
return true;
3657
3677
}
3658
3678
3659
- static u32 bond_vlan_srcmac_hash (struct sk_buff * skb )
3679
+ static u32 bond_vlan_srcmac_hash (struct sk_buff * skb , const void * data , int mhoff , int hlen )
3660
3680
{
3661
- struct ethhdr * mac_hdr = ( struct ethhdr * ) skb_mac_header ( skb ) ;
3681
+ struct ethhdr * mac_hdr ;
3662
3682
u32 srcmac_vendor = 0 , srcmac_dev = 0 ;
3663
3683
u16 vlan ;
3664
3684
int i ;
3665
3685
3686
+ data = bond_pull_data (skb , data , hlen , mhoff + sizeof (struct ethhdr ));
3687
+ if (!data )
3688
+ return 0 ;
3689
+ mac_hdr = (struct ethhdr * )(data + mhoff );
3690
+
3666
3691
for (i = 0 ; i < 3 ; i ++ )
3667
3692
srcmac_vendor = (srcmac_vendor << 8 ) | mac_hdr -> h_source [i ];
3668
3693
@@ -3678,49 +3703,46 @@ static u32 bond_vlan_srcmac_hash(struct sk_buff *skb)
3678
3703
}
3679
3704
3680
3705
/* Extract the appropriate headers based on bond's xmit policy */
3681
- static bool bond_flow_dissect (struct bonding * bond , struct sk_buff * skb ,
3682
- struct flow_keys * fk )
3706
+ static bool bond_flow_dissect (struct bonding * bond , struct sk_buff * skb , const void * data ,
3707
+ __be16 l2_proto , int nhoff , int hlen , struct flow_keys * fk )
3683
3708
{
3684
3709
bool l34 = bond -> params .xmit_policy == BOND_XMIT_POLICY_LAYER34 ;
3685
- int noff , proto = -1 ;
3710
+ int ip_proto = -1 ;
3686
3711
3687
3712
switch (bond -> params .xmit_policy ) {
3688
3713
case BOND_XMIT_POLICY_ENCAP23 :
3689
3714
case BOND_XMIT_POLICY_ENCAP34 :
3690
3715
memset (fk , 0 , sizeof (* fk ));
3691
3716
return __skb_flow_dissect (NULL , skb , & flow_keys_bonding ,
3692
- fk , NULL , 0 , 0 , 0 , 0 );
3717
+ fk , data , l2_proto , nhoff , hlen , 0 );
3693
3718
default :
3694
3719
break ;
3695
3720
}
3696
3721
3697
3722
fk -> ports .ports = 0 ;
3698
3723
memset (& fk -> icmp , 0 , sizeof (fk -> icmp ));
3699
- noff = skb_network_offset (skb );
3700
- if (!bond_flow_ip (skb , fk , & noff , & proto , l34 ))
3724
+ if (!bond_flow_ip (skb , fk , data , hlen , l2_proto , & nhoff , & ip_proto , l34 ))
3701
3725
return false;
3702
3726
3703
3727
/* ICMP error packets contains at least 8 bytes of the header
3704
3728
* of the packet which generated the error. Use this information
3705
3729
* to correlate ICMP error packets within the same flow which
3706
3730
* generated the error.
3707
3731
*/
3708
- if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6 ) {
3709
- skb_flow_get_icmp_tci (skb , & fk -> icmp , skb -> data ,
3710
- skb_transport_offset (skb ),
3711
- skb_headlen (skb ));
3712
- if (proto == IPPROTO_ICMP ) {
3732
+ if (ip_proto == IPPROTO_ICMP || ip_proto == IPPROTO_ICMPV6 ) {
3733
+ skb_flow_get_icmp_tci (skb , & fk -> icmp , data , nhoff , hlen );
3734
+ if (ip_proto == IPPROTO_ICMP ) {
3713
3735
if (!icmp_is_err (fk -> icmp .type ))
3714
3736
return true;
3715
3737
3716
- noff += sizeof (struct icmphdr );
3717
- } else if (proto == IPPROTO_ICMPV6 ) {
3738
+ nhoff += sizeof (struct icmphdr );
3739
+ } else if (ip_proto == IPPROTO_ICMPV6 ) {
3718
3740
if (!icmpv6_is_err (fk -> icmp .type ))
3719
3741
return true;
3720
3742
3721
- noff += sizeof (struct icmp6hdr );
3743
+ nhoff += sizeof (struct icmp6hdr );
3722
3744
}
3723
- return bond_flow_ip (skb , fk , & noff , & proto , l34 );
3745
+ return bond_flow_ip (skb , fk , data , hlen , l2_proto , & nhoff , & ip_proto , l34 );
3724
3746
}
3725
3747
3726
3748
return true;
@@ -3736,33 +3758,26 @@ static u32 bond_ip_hash(u32 hash, struct flow_keys *flow)
3736
3758
return hash >> 1 ;
3737
3759
}
3738
3760
3739
- /**
3740
- * bond_xmit_hash - generate a hash value based on the xmit policy
3741
- * @bond: bonding device
3742
- * @skb: buffer to use for headers
3743
- *
3744
- * This function will extract the necessary headers from the skb buffer and use
3745
- * them to generate a hash based on the xmit_policy set in the bonding device
3761
+ /* Generate hash based on xmit policy. If @skb is given it is used to linearize
3762
+ * the data as required, but this function can be used without it if the data is
3763
+ * known to be linear (e.g. with xdp_buff).
3746
3764
*/
3747
- u32 bond_xmit_hash (struct bonding * bond , struct sk_buff * skb )
3765
+ static u32 __bond_xmit_hash (struct bonding * bond , struct sk_buff * skb , const void * data ,
3766
+ __be16 l2_proto , int mhoff , int nhoff , int hlen )
3748
3767
{
3749
3768
struct flow_keys flow ;
3750
3769
u32 hash ;
3751
3770
3752
- if (bond -> params .xmit_policy == BOND_XMIT_POLICY_ENCAP34 &&
3753
- skb -> l4_hash )
3754
- return skb -> hash ;
3755
-
3756
3771
if (bond -> params .xmit_policy == BOND_XMIT_POLICY_VLAN_SRCMAC )
3757
- return bond_vlan_srcmac_hash (skb );
3772
+ return bond_vlan_srcmac_hash (skb , data , mhoff , hlen );
3758
3773
3759
3774
if (bond -> params .xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
3760
- !bond_flow_dissect (bond , skb , & flow ))
3761
- return bond_eth_hash (skb );
3775
+ !bond_flow_dissect (bond , skb , data , l2_proto , nhoff , hlen , & flow ))
3776
+ return bond_eth_hash (skb , data , mhoff , hlen );
3762
3777
3763
3778
if (bond -> params .xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
3764
3779
bond -> params .xmit_policy == BOND_XMIT_POLICY_ENCAP23 ) {
3765
- hash = bond_eth_hash (skb );
3780
+ hash = bond_eth_hash (skb , data , mhoff , hlen );
3766
3781
} else {
3767
3782
if (flow .icmp .id )
3768
3783
memcpy (& hash , & flow .icmp , sizeof (hash ));
@@ -3773,6 +3788,25 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
3773
3788
return bond_ip_hash (hash , & flow );
3774
3789
}
3775
3790
3791
+ /**
3792
+ * bond_xmit_hash - generate a hash value based on the xmit policy
3793
+ * @bond: bonding device
3794
+ * @skb: buffer to use for headers
3795
+ *
3796
+ * This function will extract the necessary headers from the skb buffer and use
3797
+ * them to generate a hash based on the xmit_policy set in the bonding device
3798
+ */
3799
+ u32 bond_xmit_hash (struct bonding * bond , struct sk_buff * skb )
3800
+ {
3801
+ if (bond -> params .xmit_policy == BOND_XMIT_POLICY_ENCAP34 &&
3802
+ skb -> l4_hash )
3803
+ return skb -> hash ;
3804
+
3805
+ return __bond_xmit_hash (bond , skb , skb -> head , skb -> protocol ,
3806
+ skb -> mac_header , skb -> network_header ,
3807
+ skb_headlen (skb ));
3808
+ }
3809
+
3776
3810
/*-------------------------- Device entry points ----------------------------*/
3777
3811
3778
3812
void bond_work_init_all (struct bonding * bond )
@@ -4434,8 +4468,7 @@ static netdev_tx_t bond_xmit_roundrobin(struct sk_buff *skb,
4434
4468
return bond_tx_drop (bond_dev , skb );
4435
4469
}
4436
4470
4437
- static struct slave * bond_xmit_activebackup_slave_get (struct bonding * bond ,
4438
- struct sk_buff * skb )
4471
+ static struct slave * bond_xmit_activebackup_slave_get (struct bonding * bond )
4439
4472
{
4440
4473
return rcu_dereference (bond -> curr_active_slave );
4441
4474
}
@@ -4449,7 +4482,7 @@ static netdev_tx_t bond_xmit_activebackup(struct sk_buff *skb,
4449
4482
struct bonding * bond = netdev_priv (bond_dev );
4450
4483
struct slave * slave ;
4451
4484
4452
- slave = bond_xmit_activebackup_slave_get (bond , skb );
4485
+ slave = bond_xmit_activebackup_slave_get (bond );
4453
4486
if (slave )
4454
4487
return bond_dev_queue_xmit (bond , skb , slave -> dev );
4455
4488
@@ -4747,7 +4780,7 @@ static struct net_device *bond_xmit_get_slave(struct net_device *master_dev,
4747
4780
slave = bond_xmit_roundrobin_slave_get (bond , skb );
4748
4781
break ;
4749
4782
case BOND_MODE_ACTIVEBACKUP :
4750
- slave = bond_xmit_activebackup_slave_get (bond , skb );
4783
+ slave = bond_xmit_activebackup_slave_get (bond );
4751
4784
break ;
4752
4785
case BOND_MODE_8023AD :
4753
4786
case BOND_MODE_XOR :
0 commit comments