cregit-Linux how code gets into the kernel

Release 4.13 drivers/net/ethernet/netronome/nfp/bpf/main.c

/*
 * Copyright (C) 2017 Netronome Systems, Inc.
 *
 * This software is dual licensed under the GNU General License Version 2,
 * June 1991 as shown in the file COPYING in the top-level directory of this
 * source tree or the BSD 2-Clause License provided below.  You have the
 * option to license this software under the complete terms of either license.
 *
 * The BSD 2-Clause License:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      1. Redistributions of source code must retain the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer.
 *
 *      2. Redistributions in binary form must reproduce the above
 *         copyright notice, this list of conditions and the following
 *         disclaimer in the documentation and/or other materials
 *         provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <net/pkt_cls.h>

#include "../nfpcore/nfp_cpp.h"
#include "../nfp_app.h"
#include "../nfp_main.h"
#include "../nfp_net.h"
#include "../nfp_port.h"
#include "main.h"


static bool nfp_net_ebpf_capable(struct nfp_net *nn) { if (nn->cap & NFP_NET_CFG_CTRL_BPF && nn_readb(nn, NFP_NET_CFG_BPF_ABI) == NFP_NET_BPF_ABI) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński34100.00%1100.00%
Total34100.00%1100.00%


static int nfp_bpf_xdp_offload(struct nfp_app *app, struct nfp_net *nn, struct bpf_prog *prog) { struct tc_cls_bpf_offload cmd = { .prog = prog, }; int ret; if (!nfp_net_ebpf_capable(nn)) return -EINVAL; if (nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF) { if (!nn->dp.bpf_offload_xdp) return prog ? -EBUSY : 0; cmd.command = prog ? TC_CLSBPF_REPLACE : TC_CLSBPF_DESTROY; } else { if (!prog) return 0; cmd.command = TC_CLSBPF_ADD; } ret = nfp_net_bpf_offload(nn, &cmd); /* Stop offload if replace not possible */ if (ret && cmd.command == TC_CLSBPF_REPLACE) nfp_bpf_xdp_offload(app, nn, NULL); nn->dp.bpf_offload_xdp = prog && !ret; return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński147100.00%1100.00%
Total147100.00%1100.00%


static const char *nfp_bpf_extra_cap(struct nfp_app *app, struct nfp_net *nn) { return nfp_net_ebpf_capable(nn) ? "BPF" : ""; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński28100.00%1100.00%
Total28100.00%1100.00%


static int nfp_bpf_vnic_init(struct nfp_app *app, struct nfp_net *nn, unsigned int id) { struct nfp_net_bpf_priv *priv; int ret; /* Limit to single port, otherwise it's just a NIC */ if (id > 0) { nfp_warn(app->cpp, "BPF NIC doesn't support more than one port right now\n"); nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev); return PTR_ERR_OR_ZERO(nn->port); } priv = kmalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; nn->app_priv = priv; spin_lock_init(&priv->rx_filter_lock); setup_timer(&priv->rx_filter_stats_timer, nfp_net_filter_stats_timer, (unsigned long)nn); ret = nfp_app_nic_vnic_init(app, nn, id); if (ret) kfree(priv); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński146100.00%2100.00%
Total146100.00%2100.00%


static void nfp_bpf_vnic_clean(struct nfp_app *app, struct nfp_net *nn) { if (nn->dp.bpf_offload_xdp) nfp_bpf_xdp_offload(app, nn, NULL); kfree(nn->app_priv); }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński40100.00%2100.00%
Total40100.00%2100.00%


static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev, u32 handle, __be16 proto, struct tc_to_netdev *tc) { struct nfp_net *nn = netdev_priv(netdev); if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS)) return -EOPNOTSUPP; if (proto != htons(ETH_P_ALL)) return -EOPNOTSUPP; if (tc->type == TC_SETUP_CLSBPF && nfp_net_ebpf_capable(nn)) { if (!nn->dp.bpf_offload_xdp) return nfp_net_bpf_offload(nn, tc->cls_bpf); else return -EBUSY; } return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński109100.00%1100.00%
Total109100.00%1100.00%


static bool nfp_bpf_tc_busy(struct nfp_app *app, struct nfp_net *nn) { return nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF; }

Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński25100.00%1100.00%
Total25100.00%1100.00%

const struct nfp_app_type app_bpf = { .id = NFP_APP_BPF_NIC, .name = "ebpf", .extra_cap = nfp_bpf_extra_cap, .vnic_init = nfp_bpf_vnic_init, .vnic_clean = nfp_bpf_vnic_clean, .setup_tc = nfp_bpf_setup_tc, .tc_busy = nfp_bpf_tc_busy, .xdp_offload = nfp_bpf_xdp_offload, };

Overall Contributors

PersonTokensPropCommitsCommitProp
Jakub Kiciński598100.00%4100.00%
Total598100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.