#include <linux/mutex.h>
#include <linux/inetdevice.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <net/arp.h>
#include <net/neighbour.h>
#include <net/route.h>
#include <net/netevent.h>
#include <net/ipv6_stubs.h>
#include <net/ip6_route.h>
#include <rdma/ib_addr.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_sa.h>
#include <rdma/ib.h>
#include <rdma/rdma_netlink.h>
#include <net/netlink.h>
#include "core_priv.h"
struct addr_req { … };
static atomic_t ib_nl_addr_request_seq = …;
static DEFINE_SPINLOCK(lock);
static LIST_HEAD(req_list);
static struct workqueue_struct *addr_wq;
static const struct nla_policy ib_nl_addr_policy[LS_NLA_TYPE_MAX] = …;
static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh)
{ … }
static void ib_nl_process_good_ip_rsep(const struct nlmsghdr *nlh)
{ … }
int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr,
const void *daddr,
u32 seq, u16 family)
{ … }
int rdma_addr_size(const struct sockaddr *addr)
{ … }
EXPORT_SYMBOL(…);
int rdma_addr_size_in6(struct sockaddr_in6 *addr)
{ … }
EXPORT_SYMBOL(…);
int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr)
{ … }
EXPORT_SYMBOL(…);
void rdma_copy_src_l2_addr(struct rdma_dev_addr *dev_addr,
const struct net_device *dev)
{ … }
EXPORT_SYMBOL(…);
static struct net_device *
rdma_find_ndev_for_src_ip_rcu(struct net *net, const struct sockaddr *src_in)
{ … }
int rdma_translate_ip(const struct sockaddr *addr,
struct rdma_dev_addr *dev_addr)
{ … }
EXPORT_SYMBOL(…);
static void set_timeout(struct addr_req *req, unsigned long time)
{ … }
static void queue_req(struct addr_req *req)
{ … }
static int ib_nl_fetch_ha(struct rdma_dev_addr *dev_addr,
const void *daddr, u32 seq, u16 family)
{ … }
static int dst_fetch_ha(const struct dst_entry *dst,
struct rdma_dev_addr *dev_addr,
const void *daddr)
{ … }
static bool has_gateway(const struct dst_entry *dst, sa_family_t family)
{ … }
static int fetch_ha(const struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
const struct sockaddr *dst_in, u32 seq)
{ … }
static int addr4_resolve(struct sockaddr *src_sock,
const struct sockaddr *dst_sock,
struct rdma_dev_addr *addr,
struct rtable **prt)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static int addr6_resolve(struct sockaddr *src_sock,
const struct sockaddr *dst_sock,
struct rdma_dev_addr *addr,
struct dst_entry **pdst)
{ … }
#else
static int addr6_resolve(struct sockaddr *src_sock,
const struct sockaddr *dst_sock,
struct rdma_dev_addr *addr,
struct dst_entry **pdst)
{
return -EADDRNOTAVAIL;
}
#endif
static int addr_resolve_neigh(const struct dst_entry *dst,
const struct sockaddr *dst_in,
struct rdma_dev_addr *addr,
unsigned int ndev_flags,
u32 seq)
{ … }
static int copy_src_l2_addr(struct rdma_dev_addr *dev_addr,
const struct sockaddr *dst_in,
const struct dst_entry *dst,
const struct net_device *ndev)
{ … }
static int rdma_set_src_addr_rcu(struct rdma_dev_addr *dev_addr,
unsigned int *ndev_flags,
const struct sockaddr *dst_in,
const struct dst_entry *dst)
{ … }
static int set_addr_netns_by_gid_rcu(struct rdma_dev_addr *addr)
{ … }
static void rdma_addr_set_net_defaults(struct rdma_dev_addr *addr)
{ … }
static int addr_resolve(struct sockaddr *src_in,
const struct sockaddr *dst_in,
struct rdma_dev_addr *addr,
bool resolve_neigh,
bool resolve_by_gid_attr,
u32 seq)
{ … }
static void process_one_req(struct work_struct *_work)
{ … }
int rdma_resolve_ip(struct sockaddr *src_addr, const struct sockaddr *dst_addr,
struct rdma_dev_addr *addr, unsigned long timeout_ms,
void (*callback)(int status, struct sockaddr *src_addr,
struct rdma_dev_addr *addr, void *context),
bool resolve_by_gid_attr, void *context)
{ … }
EXPORT_SYMBOL(…);
int roce_resolve_route_from_path(struct sa_path_rec *rec,
const struct ib_gid_attr *attr)
{ … }
void rdma_addr_cancel(struct rdma_dev_addr *addr)
{ … }
EXPORT_SYMBOL(…);
struct resolve_cb_context { … };
static void resolve_cb(int status, struct sockaddr *src_addr,
struct rdma_dev_addr *addr, void *context)
{ … }
int rdma_addr_find_l2_eth_by_grh(const union ib_gid *sgid,
const union ib_gid *dgid,
u8 *dmac, const struct ib_gid_attr *sgid_attr,
int *hoplimit)
{ … }
static int netevent_callback(struct notifier_block *self, unsigned long event,
void *ctx)
{ … }
static struct notifier_block nb = …;
int addr_init(void)
{ … }
void addr_cleanup(void)
{ … }