@@ -8815,111 +8815,128 @@ static void dev_xdp_uninstall(struct net_device *dev)
8815
8815
}
8816
8816
}
8817
8817
8818
- /**
8819
- * dev_change_xdp_fd - set or clear a bpf program for a device rx path
8820
- * @dev: device
8821
- * @extack: netlink extended ack
8822
- * @fd: new program fd or negative value to clear
8823
- * @expected_fd: old program fd that userspace expects to replace or clear
8824
- * @flags: xdp-related flags
8825
- *
8826
- * Set or clear a bpf program for a device
8827
- */
8828
- int dev_change_xdp_fd (struct net_device * dev , struct netlink_ext_ack * extack ,
8829
- int fd , int expected_fd , u32 flags )
8818
+ static int dev_xdp_attach (struct net_device * dev , struct netlink_ext_ack * extack ,
8819
+ struct bpf_prog * new_prog , struct bpf_prog * old_prog ,
8820
+ u32 flags )
8830
8821
{
8831
- const struct net_device_ops * ops = dev -> netdev_ops ;
8832
- enum bpf_xdp_mode mode = dev_xdp_mode (flags );
8833
- bool offload = mode == XDP_MODE_HW ;
8834
- u32 prog_id , expected_id = 0 ;
8835
- struct bpf_prog * prog ;
8822
+ struct bpf_prog * cur_prog ;
8823
+ enum bpf_xdp_mode mode ;
8836
8824
bpf_op_t bpf_op ;
8837
8825
int err ;
8838
8826
8839
8827
ASSERT_RTNL ();
8840
8828
8841
- bpf_op = dev_xdp_bpf_op (dev , mode );
8842
- if (!bpf_op ) {
8843
- NL_SET_ERR_MSG (extack , "underlying driver does not support XDP in native mode" );
8844
- return - EOPNOTSUPP ;
8829
+ /* just one XDP mode bit should be set, zero defaults to SKB mode */
8830
+ if (hweight32 (flags & XDP_FLAGS_MODES ) > 1 ) {
8831
+ NL_SET_ERR_MSG (extack , "Only one XDP mode flag can be set" );
8832
+ return - EINVAL ;
8833
+ }
8834
+ /* old_prog != NULL implies XDP_FLAGS_REPLACE is set */
8835
+ if (old_prog && !(flags & XDP_FLAGS_REPLACE )) {
8836
+ NL_SET_ERR_MSG (extack , "XDP_FLAGS_REPLACE is not specified" );
8837
+ return - EINVAL ;
8845
8838
}
8846
8839
8847
- prog_id = dev_xdp_prog_id (dev , mode );
8848
- if (flags & XDP_FLAGS_REPLACE ) {
8849
- if (expected_fd >= 0 ) {
8850
- prog = bpf_prog_get_type_dev (expected_fd ,
8851
- BPF_PROG_TYPE_XDP ,
8852
- bpf_op == ops -> ndo_bpf );
8853
- if (IS_ERR (prog ))
8854
- return PTR_ERR (prog );
8855
- expected_id = prog -> aux -> id ;
8856
- bpf_prog_put (prog );
8857
- }
8858
-
8859
- if (prog_id != expected_id ) {
8860
- NL_SET_ERR_MSG (extack , "Active program does not match expected" );
8861
- return - EEXIST ;
8862
- }
8840
+ mode = dev_xdp_mode (flags );
8841
+ cur_prog = dev_xdp_prog (dev , mode );
8842
+ if ((flags & XDP_FLAGS_REPLACE ) && cur_prog != old_prog ) {
8843
+ NL_SET_ERR_MSG (extack , "Active program does not match expected" );
8844
+ return - EEXIST ;
8863
8845
}
8864
- if (fd >= 0 ) {
8846
+ if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST ) && cur_prog ) {
8847
+ NL_SET_ERR_MSG (extack , "XDP program already attached" );
8848
+ return - EBUSY ;
8849
+ }
8850
+
8851
+ if (new_prog ) {
8852
+ bool offload = mode == XDP_MODE_HW ;
8865
8853
enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
8866
8854
? XDP_MODE_DRV : XDP_MODE_SKB ;
8867
8855
8868
- if (!offload && dev_xdp_prog_id (dev , other_mode )) {
8856
+ if (!offload && dev_xdp_prog (dev , other_mode )) {
8869
8857
NL_SET_ERR_MSG (extack , "Native and generic XDP can't be active at the same time" );
8870
8858
return - EEXIST ;
8871
8859
}
8872
-
8873
- if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST ) && prog_id ) {
8874
- NL_SET_ERR_MSG (extack , "XDP program already attached" );
8875
- return - EBUSY ;
8876
- }
8877
-
8878
- prog = bpf_prog_get_type_dev (fd , BPF_PROG_TYPE_XDP ,
8879
- bpf_op == ops -> ndo_bpf );
8880
- if (IS_ERR (prog ))
8881
- return PTR_ERR (prog );
8882
-
8883
- if (!offload && bpf_prog_is_dev_bound (prog -> aux )) {
8860
+ if (!offload && bpf_prog_is_dev_bound (new_prog -> aux )) {
8884
8861
NL_SET_ERR_MSG (extack , "Using device-bound program without HW_MODE flag is not supported" );
8885
- bpf_prog_put (prog );
8886
8862
return - EINVAL ;
8887
8863
}
8888
-
8889
- if (prog -> expected_attach_type == BPF_XDP_DEVMAP ) {
8864
+ if (new_prog -> expected_attach_type == BPF_XDP_DEVMAP ) {
8890
8865
NL_SET_ERR_MSG (extack , "BPF_XDP_DEVMAP programs can not be attached to a device" );
8891
- bpf_prog_put (prog );
8892
8866
return - EINVAL ;
8893
8867
}
8894
-
8895
- if (prog -> expected_attach_type == BPF_XDP_CPUMAP ) {
8896
- NL_SET_ERR_MSG (extack ,
8897
- "BPF_XDP_CPUMAP programs can not be attached to a device" );
8898
- bpf_prog_put (prog );
8868
+ if (new_prog -> expected_attach_type == BPF_XDP_CPUMAP ) {
8869
+ NL_SET_ERR_MSG (extack , "BPF_XDP_CPUMAP programs can not be attached to a device" );
8899
8870
return - EINVAL ;
8900
8871
}
8872
+ }
8901
8873
8902
- /* prog->aux->id may be 0 for orphaned device-bound progs */
8903
- if (prog -> aux -> id && prog -> aux -> id == prog_id ) {
8904
- bpf_prog_put (prog );
8905
- return 0 ;
8874
+ /* don't call drivers if the effective program didn't change */
8875
+ if (new_prog != cur_prog ) {
8876
+ bpf_op = dev_xdp_bpf_op (dev , mode );
8877
+ if (!bpf_op ) {
8878
+ NL_SET_ERR_MSG (extack , "Underlying driver does not support XDP in native mode" );
8879
+ return - EOPNOTSUPP ;
8906
8880
}
8907
- } else {
8908
- if (!prog_id )
8909
- return 0 ;
8910
- prog = NULL ;
8911
- }
8912
8881
8913
- err = dev_xdp_install (dev , mode , bpf_op , extack , flags , prog );
8914
- if (err < 0 && prog ) {
8915
- bpf_prog_put (prog );
8916
- return err ;
8882
+ err = dev_xdp_install (dev , mode , bpf_op , extack , flags , new_prog );
8883
+ if (err )
8884
+ return err ;
8917
8885
}
8918
- dev_xdp_set_prog (dev , mode , prog );
8886
+
8887
+ dev_xdp_set_prog (dev , mode , new_prog );
8888
+ if (cur_prog )
8889
+ bpf_prog_put (cur_prog );
8919
8890
8920
8891
return 0 ;
8921
8892
}
8922
8893
8894
+ /**
8895
+ * dev_change_xdp_fd - set or clear a bpf program for a device rx path
8896
+ * @dev: device
8897
+ * @extack: netlink extended ack
8898
+ * @fd: new program fd or negative value to clear
8899
+ * @expected_fd: old program fd that userspace expects to replace or clear
8900
+ * @flags: xdp-related flags
8901
+ *
8902
+ * Set or clear a bpf program for a device
8903
+ */
8904
+ int dev_change_xdp_fd (struct net_device * dev , struct netlink_ext_ack * extack ,
8905
+ int fd , int expected_fd , u32 flags )
8906
+ {
8907
+ enum bpf_xdp_mode mode = dev_xdp_mode (flags );
8908
+ struct bpf_prog * new_prog = NULL , * old_prog = NULL ;
8909
+ int err ;
8910
+
8911
+ ASSERT_RTNL ();
8912
+
8913
+ if (fd >= 0 ) {
8914
+ new_prog = bpf_prog_get_type_dev (fd , BPF_PROG_TYPE_XDP ,
8915
+ mode != XDP_MODE_SKB );
8916
+ if (IS_ERR (new_prog ))
8917
+ return PTR_ERR (new_prog );
8918
+ }
8919
+
8920
+ if (expected_fd >= 0 ) {
8921
+ old_prog = bpf_prog_get_type_dev (expected_fd , BPF_PROG_TYPE_XDP ,
8922
+ mode != XDP_MODE_SKB );
8923
+ if (IS_ERR (old_prog )) {
8924
+ err = PTR_ERR (old_prog );
8925
+ old_prog = NULL ;
8926
+ goto err_out ;
8927
+ }
8928
+ }
8929
+
8930
+ err = dev_xdp_attach (dev , extack , new_prog , old_prog , flags );
8931
+
8932
+ err_out :
8933
+ if (err && new_prog )
8934
+ bpf_prog_put (new_prog );
8935
+ if (old_prog )
8936
+ bpf_prog_put (old_prog );
8937
+ return err ;
8938
+ }
8939
+
8923
8940
/**
8924
8941
* dev_new_index - allocate an ifindex
8925
8942
* @net: the applicable net namespace
0 commit comments