1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2019, Microsoft Corporation.
5 * Haiyang Zhang <haiyangz@microsoft.com>
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/netdevice.h>
11 #include <linux/etherdevice.h>
12 #include <linux/ethtool.h>
13 #include <linux/netpoll.h>
14 #include <linux/bpf.h>
15 #include <linux/bpf_trace.h>
16 #include <linux/kernel.h>
19 #include <linux/mutex.h>
20 #include <linux/rtnetlink.h>
22 #include "hyperv_net.h"
24 u32
netvsc_run_xdp(struct net_device
*ndev
, struct netvsc_channel
*nvchan
,
27 struct netvsc_stats_rx
*rx_stats
= &nvchan
->rx_stats
;
28 void *data
= nvchan
->rsc
.data
[0];
29 u32 len
= nvchan
->rsc
.len
[0];
30 struct page
*page
= NULL
;
31 struct bpf_prog
*prog
;
35 xdp
->data_hard_start
= NULL
;
38 prog
= rcu_dereference(nvchan
->bpf_prog
);
43 /* Ensure that the below memcpy() won't overflow the page buffer. */
44 if (len
> ndev
->mtu
+ ETH_HLEN
) {
49 /* allocate page buffer for data */
50 page
= alloc_page(GFP_ATOMIC
);
56 xdp_init_buff(xdp
, PAGE_SIZE
, &nvchan
->xdp_rxq
);
57 xdp_prepare_buff(xdp
, page_address(page
), NETVSC_XDP_HDRM
, len
, false);
59 memcpy(xdp
->data
, data
, len
);
61 act
= bpf_prog_run_xdp(prog
, xdp
);
73 if (!xdp_do_redirect(ndev
, xdp
, prog
)) {
74 nvchan
->xdp_flush
= true;
77 u64_stats_update_begin(&rx_stats
->syncp
);
79 rx_stats
->xdp_redirect
++;
81 rx_stats
->bytes
+= nvchan
->rsc
.pktlen
;
83 u64_stats_update_end(&rx_stats
->syncp
);
87 u64_stats_update_begin(&rx_stats
->syncp
);
89 u64_stats_update_end(&rx_stats
->syncp
);
95 trace_xdp_exception(ndev
, prog
, act
);
99 bpf_warn_invalid_xdp_action(ndev
, prog
, act
);
107 xdp
->data_hard_start
= NULL
;
113 unsigned int netvsc_xdp_fraglen(unsigned int len
)
115 return SKB_DATA_ALIGN(len
) +
116 SKB_DATA_ALIGN(sizeof(struct skb_shared_info
));
119 struct bpf_prog
*netvsc_xdp_get(struct netvsc_device
*nvdev
)
121 return rtnl_dereference(nvdev
->chan_table
[0].bpf_prog
);
124 int netvsc_xdp_set(struct net_device
*dev
, struct bpf_prog
*prog
,
125 struct netlink_ext_ack
*extack
,
126 struct netvsc_device
*nvdev
)
128 struct bpf_prog
*old_prog
;
131 old_prog
= netvsc_xdp_get(nvdev
);
133 if (!old_prog
&& !prog
)
136 buf_max
= NETVSC_XDP_HDRM
+ netvsc_xdp_fraglen(dev
->mtu
+ ETH_HLEN
);
137 if (prog
&& buf_max
> PAGE_SIZE
) {
138 netdev_err(dev
, "XDP: mtu:%u too large, buf_max:%u\n",
140 NL_SET_ERR_MSG_MOD(extack
, "XDP: mtu too large");
145 if (prog
&& (dev
->features
& NETIF_F_LRO
)) {
146 netdev_err(dev
, "XDP: not support LRO\n");
147 NL_SET_ERR_MSG_MOD(extack
, "XDP: not support LRO");
153 bpf_prog_add(prog
, nvdev
->num_chn
- 1);
155 for (i
= 0; i
< nvdev
->num_chn
; i
++)
156 rcu_assign_pointer(nvdev
->chan_table
[i
].bpf_prog
, prog
);
159 for (i
= 0; i
< nvdev
->num_chn
; i
++)
160 bpf_prog_put(old_prog
);
165 int netvsc_vf_setxdp(struct net_device
*vf_netdev
, struct bpf_prog
*prog
)
167 struct netdev_bpf xdp
;
175 if (!vf_netdev
->netdev_ops
->ndo_bpf
)
178 memset(&xdp
, 0, sizeof(xdp
));
183 xdp
.command
= XDP_SETUP_PROG
;
186 ret
= dev_xdp_propagate(vf_netdev
, &xdp
);
194 int netvsc_bpf(struct net_device
*dev
, struct netdev_bpf
*bpf
)
196 struct net_device_context
*ndevctx
= netdev_priv(dev
);
197 struct netvsc_device
*nvdev
= rtnl_dereference(ndevctx
->nvdev
);
198 struct net_device
*vf_netdev
= rtnl_dereference(ndevctx
->vf_netdev
);
199 struct netlink_ext_ack
*extack
= bpf
->extack
;
202 if (!nvdev
|| nvdev
->destroy
) {
206 switch (bpf
->command
) {
208 ret
= netvsc_xdp_set(dev
, bpf
->prog
, extack
, nvdev
);
213 ret
= netvsc_vf_setxdp(vf_netdev
, bpf
->prog
);
216 netdev_err(dev
, "vf_setxdp failed:%d\n", ret
);
217 NL_SET_ERR_MSG_MOD(extack
, "vf_setxdp failed");
219 netvsc_xdp_set(dev
, NULL
, extack
, nvdev
);
229 static int netvsc_ndoxdp_xmit_fm(struct net_device
*ndev
,
230 struct xdp_frame
*frame
, u16 q_idx
)
234 skb
= xdp_build_skb_from_frame(frame
, ndev
);
238 netvsc_get_hash(skb
, netdev_priv(ndev
));
240 skb_record_rx_queue(skb
, q_idx
);
242 netvsc_xdp_xmit(skb
, ndev
);
247 int netvsc_ndoxdp_xmit(struct net_device
*ndev
, int n
,
248 struct xdp_frame
**frames
, u32 flags
)
250 struct net_device_context
*ndev_ctx
= netdev_priv(ndev
);
251 const struct net_device_ops
*vf_ops
;
252 struct netvsc_stats_tx
*tx_stats
;
253 struct netvsc_device
*nvsc_dev
;
254 struct net_device
*vf_netdev
;
258 /* Don't transmit if netvsc_device is gone */
259 nvsc_dev
= rcu_dereference_bh(ndev_ctx
->nvdev
);
260 if (unlikely(!nvsc_dev
|| nvsc_dev
->destroy
))
263 /* If VF is present and up then redirect packets to it.
264 * Skip the VF if it is marked down or has no carrier.
265 * If netpoll is in uses, then VF can not be used either.
267 vf_netdev
= rcu_dereference_bh(ndev_ctx
->vf_netdev
);
268 if (vf_netdev
&& netif_running(vf_netdev
) &&
269 netif_carrier_ok(vf_netdev
) && !netpoll_tx_running(ndev
) &&
270 vf_netdev
->netdev_ops
->ndo_xdp_xmit
&&
271 ndev_ctx
->data_path_is_vf
) {
272 vf_ops
= vf_netdev
->netdev_ops
;
273 return vf_ops
->ndo_xdp_xmit(vf_netdev
, n
, frames
, flags
);
276 q_idx
= smp_processor_id() % ndev
->real_num_tx_queues
;
278 for (i
= 0; i
< n
; i
++) {
279 if (netvsc_ndoxdp_xmit_fm(ndev
, frames
[i
], q_idx
))
285 tx_stats
= &nvsc_dev
->chan_table
[q_idx
].tx_stats
;
287 u64_stats_update_begin(&tx_stats
->syncp
);
288 tx_stats
->xdp_xmit
+= count
;
289 u64_stats_update_end(&tx_stats
->syncp
);