[Intel-wired-lan] [net-next PATCH v4 1/2] ixgbe: add XDP support for pass and drop actions
John Fastabend
john.fastabend at gmail.com
Sat Mar 11 16:48:18 UTC 2017
On 17-03-11 07:49 AM, William Tu wrote:
> On Fri, Mar 10, 2017 at 11:11 AM, John Fastabend
> <john.fastabend at gmail.com> wrote:
>> Basic XDP drop support for ixgbe. Uses READ_ONCE/xchg semantics on XDP
>> programs instead of rcu primitives as suggested by Daniel Borkmann and
>> Alex Duyck.
>>
>> Signed-off-by: John Fastabend <john.r.fastabend at intel.com>
>> ---
[...]
>> /**
>> * ixgbe_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf
>> * @q_vector: structure containing interrupt and ring information
>> @@ -2184,6 +2230,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
>> union ixgbe_adv_rx_desc *rx_desc;
>> struct ixgbe_rx_buffer *rx_buffer;
>> struct sk_buff *skb;
>> + struct xdp_buff xdp;
>> unsigned int size;
>>
>> /* return some buffers to hardware, one at a time is too slow */
>> @@ -2205,15 +2252,29 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
>>
>> rx_buffer = ixgbe_get_rx_buffer(rx_ring, rx_desc, &skb, size);
>>
>> - /* retrieve a buffer from the ring */
>> - if (skb)
>> + if (!skb) {
>> + xdp.data = page_address(rx_buffer->page) +
>> + rx_buffer->page_offset;
>> + xdp.data_hard_start = xdp.data -
>> + ixgbe_rx_offset(rx_ring);
We have ixgbe_rx_offset(rx_ring) headroom to support adding headers.
>> + xdp.data_end = xdp.data + size;
>> +
>> + skb = ixgbe_run_xdp(rx_ring, &xdp);
>> + }
>> +
>> + if (IS_ERR(skb)) {
>> + total_rx_packets++;
>> + total_rx_bytes += size;
>> + rx_buffer->pagecnt_bias++;
>> + } else if (skb) {
>> ixgbe_add_rx_frag(rx_ring, rx_buffer, skb, size);
>> - else if (ring_uses_build_skb(rx_ring))
>> + } else if (ring_uses_build_skb(rx_ring)) {
>> skb = ixgbe_build_skb(rx_ring, rx_buffer,
>> - rx_desc, size);
>> - else
>> + &xdp, rx_desc);
>> + } else {
>> skb = ixgbe_construct_skb(rx_ring, rx_buffer,
>> - rx_desc, size);
>> + &xdp, rx_desc);
>> + }
>>
>> /* exit if we failed to retrieve a buffer */
>> if (!skb) {
[...]
>> +static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
>> +{
>> + int i, frame_size = dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
>> + struct ixgbe_adapter *adapter = netdev_priv(dev);
>> + struct bpf_prog *old_prog;
>> +
>> + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
>> + return -EINVAL;
>> +
>> + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
>> + return -EINVAL;
>> +
>> + /* verify ixgbe ring attributes are sufficient for XDP */
>> + for (i = 0; i < adapter->num_rx_queues; i++) {
>> + struct ixgbe_ring *ring = adapter->rx_ring[i];
>> +
>> + if (ring_is_rsc_enabled(ring))
>> + return -EINVAL;
>> +
>> + if (frame_size > ixgbe_rx_bufsz(ring))
>> + return -EINVAL;
>> + }
>> +
>> + old_prog = xchg(&adapter->xdp_prog, prog);
>> + for (i = 0; i < adapter->num_rx_queues; i++)
>> + xchg(&adapter->rx_ring[i]->xdp_prog, adapter->xdp_prog);
>> +
>> + if (old_prog)
>> + bpf_prog_put(old_prog);
>> +
>> + return 0;
>> +}
>
> Since the patch does not support xdp_adjust_head() yet, should we
> detect and return -EOPNOTSUPP?
>
It actually should support xdp_adjust_head() :)
At least I tested the xdp tunnel program in ./bpf/samples/ and it worked.
Also I do a standard test where I push the packet up the stack after adding
headers and that appears to work although I wonder a bit about some of the
skb metadata. By working in this case I just use tshark and verify the pkt
is received with the new header by the stack.
> --William
More information about the Intel-wired-lan
mailing list