cregit-Linux how code gets into the kernel

Release 4.18 drivers/infiniband/core/netlink.c

/*
 * Copyright (c) 2017 Mellanox Technologies Inc.  All rights reserved.
 * Copyright (c) 2010 Voltaire Inc.  All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - 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.
 */


#define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__

#include <linux/export.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <rdma/rdma_netlink.h>
#include <linux/module.h>
#include "core_priv.h"

static DEFINE_MUTEX(rdma_nl_mutex);

static struct sock *nls;

static struct {
	
const struct rdma_nl_cbs   *cb_table;

} rdma_nl_types[RDMA_NL_NUM_CLIENTS];


int rdma_nl_chk_listeners(unsigned int group) { return (netlink_has_listeners(nls, group)) ? 0 : -1; }

Contributors

PersonTokensPropCommitsCommitProp
Kaike Wan1875.00%150.00%
Leon Romanovsky625.00%150.00%
Total24100.00%2100.00%

EXPORT_SYMBOL(rdma_nl_chk_listeners);
static bool is_nl_msg_valid(unsigned int type, unsigned int op) { static const unsigned int max_num_ops[RDMA_NL_NUM_CLIENTS] = { [RDMA_NL_RDMA_CM] = RDMA_NL_RDMA_CM_NUM_OPS, [RDMA_NL_IWCM] = RDMA_NL_IWPM_NUM_OPS, [RDMA_NL_LS] = RDMA_NL_LS_NUM_OPS, [RDMA_NL_NLDEV] = RDMA_NLDEV_NUM_OPS, }; /* * This BUILD_BUG_ON is intended to catch addition of new * RDMA netlink protocol without updating the array above. */ BUILD_BUG_ON(RDMA_NL_NUM_CLIENTS != 6); if (type >= RDMA_NL_NUM_CLIENTS) return false; return (op < max_num_ops[type]) ? true : false; }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky4860.00%360.00%
Linus Torvalds1721.25%120.00%
Roland Dreier1518.75%120.00%
Total80100.00%5100.00%


static bool is_nl_valid(unsigned int type, unsigned int op) { const struct rdma_nl_cbs *cb_table; if (!is_nl_msg_valid(type, op)) return false; if (!rdma_nl_types[type].cb_table) { mutex_unlock(&rdma_nl_mutex); request_module("rdma-netlink-subsys-%d", type); mutex_lock(&rdma_nl_mutex); } cb_table = rdma_nl_types[type].cb_table; if (!cb_table || (!cb_table[op].dump && !cb_table[op].doit)) return false; return true; }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky7068.63%360.00%
Jason Gunthorpe3029.41%120.00%
Roland Dreier21.96%120.00%
Total102100.00%5100.00%


void rdma_nl_register(unsigned int index, const struct rdma_nl_cbs cb_table[]) { mutex_lock(&rdma_nl_mutex); if (!is_nl_msg_valid(index, 0)) { /* * All clients are not interesting in success/failure of * this call. They want to see the print to error log and * continue their initialization. Print warning for them, * because it is programmer's error to be here. */ mutex_unlock(&rdma_nl_mutex); WARN(true, "The not-valid %u index was supplied to RDMA netlink\n", index); return; } if (rdma_nl_types[index].cb_table) { mutex_unlock(&rdma_nl_mutex); WARN(true, "The %u index is already registered in RDMA netlink\n", index); return; } rdma_nl_types[index].cb_table = cb_table; mutex_unlock(&rdma_nl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky6166.30%266.67%
Roland Dreier3133.70%133.33%
Total92100.00%3100.00%

EXPORT_SYMBOL(rdma_nl_register);
void rdma_nl_unregister(unsigned int index) { mutex_lock(&rdma_nl_mutex); rdma_nl_types[index].cb_table = NULL; mutex_unlock(&rdma_nl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Roland Dreier1860.00%150.00%
Leon Romanovsky1240.00%150.00%
Total30100.00%2100.00%

EXPORT_SYMBOL(rdma_nl_unregister);
void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq, int len, int client, int op, int flags) { *nlh = nlmsg_put(skb, 0, seq, RDMA_NL_GET_TYPE(client, op), len, flags); if (!*nlh) return NULL; return nlmsg_data(*nlh); }

Contributors

PersonTokensPropCommitsCommitProp
Roland Dreier5678.87%125.00%
David S. Miller811.27%125.00%
Tatyana Nikolova45.63%125.00%
Leon Romanovsky34.23%125.00%
Total71100.00%4100.00%

EXPORT_SYMBOL(ibnl_put_msg);
int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, int len, void *data, int type) { if (nla_put(skb, type, len, data)) { nlmsg_cancel(skb, nlh); return -EMSGSIZE; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Roland Dreier4481.48%133.33%
Leon Romanovsky611.11%133.33%
David S. Miller47.41%133.33%
Total54100.00%3100.00%

EXPORT_SYMBOL(ibnl_put_attr);
static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { int type = nlh->nlmsg_type; unsigned int index = RDMA_NL_GET_CLIENT(type); unsigned int op = RDMA_NL_GET_OP(type); const struct rdma_nl_cbs *cb_table; if (!is_nl_valid(index, op)) return -EINVAL; cb_table = rdma_nl_types[index].cb_table; if ((cb_table[op].flags & RDMA_NL_ADMIN_PERM) && !netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; /* * LS responses overload the 0x100 (NLM_F_ROOT) flag. Don't * mistakenly call the .dump() function. */ if (index == RDMA_NL_LS) { if (cb_table[op].doit) return cb_table[op].doit(skb, nlh, extack); return -EINVAL; } /* FIXME: Convert IWCM to properly handle doit callbacks */ if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_RDMA_CM || index == RDMA_NL_IWCM) { struct netlink_dump_control c = { .dump = cb_table[op].dump, }; if (c.dump) return netlink_dump_start(nls, skb, nlh, &c); return -EINVAL; } if (cb_table[op].doit) return cb_table[op].doit(skb, nlh, extack); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky8738.84%646.15%
Roland Dreier5625.00%17.69%
Michael J. Ruhl4720.98%17.69%
Kaike Wan146.25%17.69%
Pablo Neira Ayuso135.80%17.69%
Johannes Berg52.23%17.69%
Mark Bloch10.45%17.69%
Greg Rose10.45%17.69%
Total224100.00%13100.00%

/* * This function is similar to netlink_rcv_skb with one exception: * It calls to the callback for the netlink messages without NLM_F_REQUEST * flag. These messages are intended for RDMA_NL_LS consumer, so it is allowed * for that consumer only. */
static int rdma_nl_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, struct nlmsghdr *, struct netlink_ext_ack *)) { struct netlink_ext_ack extack = {}; struct nlmsghdr *nlh; int err; while (skb->len >= nlmsg_total_size(0)) { int msglen; nlh = nlmsg_hdr(skb); err = 0; if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len) return 0; /* * Generally speaking, the only requests are handled * by the kernel, but RDMA_NL_LS is different, because it * runs backward netlink scheme. Kernel initiates messages * and waits for reply with data to keep pathrecord cache * in sync. */ if (!(nlh->nlmsg_flags & NLM_F_REQUEST) && (RDMA_NL_GET_CLIENT(nlh->nlmsg_type) != RDMA_NL_LS)) goto ack; /* Skip control messages */ if (nlh->nlmsg_type < NLMSG_MIN_TYPE) goto ack; err = cb(skb, nlh, &extack); if (err == -EINTR) goto skip; ack: if (nlh->nlmsg_flags & NLM_F_ACK || err) netlink_ack(skb, nlh, err, &extack); skip: msglen = NLMSG_ALIGN(nlh->nlmsg_len); if (msglen > skb->len) msglen = skb->len; skb_pull(skb, msglen); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky11253.59%133.33%
Kaike Wan9645.93%133.33%
Johannes Berg10.48%133.33%
Total209100.00%3100.00%


static void rdma_nl_rcv(struct sk_buff *skb) { mutex_lock(&rdma_nl_mutex); rdma_nl_rcv_skb(skb, &rdma_nl_rcv_msg); mutex_unlock(&rdma_nl_mutex); }

Contributors

PersonTokensPropCommitsCommitProp
Roland Dreier2683.87%133.33%
Leon Romanovsky516.13%266.67%
Total31100.00%3100.00%


int rdma_nl_unicast(struct sk_buff *skb, u32 pid) { int err; err = netlink_unicast(nls, skb, pid, MSG_DONTWAIT); return (err < 0) ? err : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mustafa Ismail1947.50%250.00%
Tatyana Nikolova1947.50%125.00%
Leon Romanovsky25.00%125.00%
Total40100.00%4100.00%

EXPORT_SYMBOL(rdma_nl_unicast);
int rdma_nl_unicast_wait(struct sk_buff *skb, __u32 pid) { int err; err = netlink_unicast(nls, skb, pid, 0); return (err < 0) ? err : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mustafa Ismail3997.50%150.00%
Leon Romanovsky12.50%150.00%
Total40100.00%2100.00%

EXPORT_SYMBOL(rdma_nl_unicast_wait);
int rdma_nl_multicast(struct sk_buff *skb, unsigned int group, gfp_t flags) { return nlmsg_multicast(nls, skb, 0, group, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Tatyana Nikolova3096.77%150.00%
Leon Romanovsky13.23%150.00%
Total31100.00%2100.00%

EXPORT_SYMBOL(rdma_nl_multicast);
int __init rdma_nl_init(void) { struct netlink_kernel_cfg cfg = { .input = rdma_nl_rcv, }; nls = netlink_kernel_create(&init_net, NETLINK_RDMA, &cfg); if (!nls) return -ENOMEM; nls->sk_sndtimeo = 10 * HZ; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Roland Dreier3057.69%120.00%
Pablo Neira Ayuso1223.08%120.00%
Mustafa Ismail815.38%120.00%
Leon Romanovsky23.85%240.00%
Total52100.00%5100.00%


void rdma_nl_exit(void) { int idx; for (idx = 0; idx < RDMA_NL_NUM_CLIENTS; idx++) rdma_nl_unregister(idx); netlink_kernel_release(nls); }

Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky1854.55%150.00%
Roland Dreier1545.45%150.00%
Total33100.00%2100.00%

MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_RDMA);

Overall Contributors

PersonTokensPropCommitsCommitProp
Leon Romanovsky46438.13%1648.48%
Roland Dreier34228.10%13.03%
Kaike Wan12810.52%13.03%
Mustafa Ismail705.75%26.06%
Tatyana Nikolova615.01%13.03%
Michael J. Ruhl473.86%13.03%
Jason Gunthorpe403.29%26.06%
Pablo Neira Ayuso252.05%26.06%
Linus Torvalds171.40%13.03%
David S. Miller120.99%26.06%
Johannes Berg60.49%13.03%
Paul Gortmaker30.25%13.03%
Greg Rose10.08%13.03%
Mark Bloch10.08%13.03%
Total1217100.00%33100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.