mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-30 00:00:15 +01:00
287 lines
8.1 KiB
C
287 lines
8.1 KiB
C
/*
|
|
* Copyright (c) 2013 Intel Corporation. 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.
|
|
*
|
|
*/
|
|
|
|
#ifndef IWARP_PM_H
|
|
#define IWARP_PM_H
|
|
|
|
#include <endian.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/select.h>
|
|
#include <sys/stat.h>
|
|
#include <arpa/inet.h>
|
|
#include <errno.h>
|
|
#include <linux/netlink.h>
|
|
#include <netlink/attr.h>
|
|
#include <signal.h>
|
|
#include <ifaddrs.h>
|
|
#include <pthread.h>
|
|
#include <syslog.h>
|
|
#include <netlink/msg.h>
|
|
#include <ccan/list.h>
|
|
#include <rdma/rdma_netlink.h>
|
|
|
|
#define IWARP_PM_PORT 3935
|
|
#define IWARP_PM_VER_SHIFT 6
|
|
#define IWARP_PM_VER_MASK 0xc0
|
|
#define IWARP_PM_MT_SHIFT 4
|
|
#define IWARP_PM_MT_MASK 0x30
|
|
#define IWARP_PM_IPVER_SHIFT 0
|
|
#define IWARP_PM_IPVER_MASK 0x0F
|
|
#define IWARP_PM_MESSAGE_SIZE 48 /* bytes */
|
|
#define IWARP_PM_ASSOC_OFFSET 0x10 /* different assochandles for passive/active side map requests */
|
|
#define IWARP_PM_IPV4_ADDR 4
|
|
|
|
#define IWARP_PM_MT_REQ 0
|
|
#define IWARP_PM_MT_ACC 1
|
|
#define IWARP_PM_MT_ACK 2
|
|
#define IWARP_PM_MT_REJ 3
|
|
|
|
#define IWARP_PM_REQ_QUERY 1
|
|
#define IWARP_PM_REQ_ACCEPT 2
|
|
#define IWARP_PM_REQ_ACK 4
|
|
|
|
#define IWARP_PM_RECV_PAYLOAD 4096
|
|
#define IWARP_PM_MAX_CLIENTS 64
|
|
#define IWPM_MAP_REQ_TIMEOUT 10 /* sec */
|
|
#define IWPM_SEND_MSG_RETRIES 3
|
|
|
|
#define IWPM_ULIB_NAME "iWarpPortMapperUser"
|
|
#define IWPM_ULIBNAME_SIZE 32
|
|
#define IWPM_DEVNAME_SIZE 32
|
|
#define IWPM_IFNAME_SIZE 16
|
|
#define IWPM_IPADDR_SIZE 16
|
|
|
|
#define IWPM_PARAM_NUM 1
|
|
#define IWPM_PARAM_NAME_LEN 64
|
|
|
|
#define IWARP_PM_NETLINK_DBG 0x01
|
|
#define IWARP_PM_WIRE_DBG 0x02
|
|
#define IWARP_PM_RETRY_DBG 0x04
|
|
#define IWARP_PM_ALL_DBG 0x07
|
|
#define IWARP_PM_DEBUG 0x08
|
|
|
|
#define iwpm_debug(dbg_level, str, args...) \
|
|
do { if (dbg_level & IWARP_PM_DEBUG) { \
|
|
syslog(LOG_WARNING, str, ##args); } \
|
|
} while (0)
|
|
|
|
/* Port Mapper errors */
|
|
enum {
|
|
IWPM_INVALID_NLMSG_ERR = 10,
|
|
IWPM_CREATE_MAPPING_ERR,
|
|
IWPM_DUPLICATE_MAPPING_ERR,
|
|
IWPM_UNKNOWN_MAPPING_ERR,
|
|
IWPM_CLIENT_DEV_INFO_ERR,
|
|
IWPM_USER_LIB_INFO_ERR,
|
|
IWPM_REMOTE_QUERY_REJECT
|
|
};
|
|
|
|
/* iwpm param indexes */
|
|
enum {
|
|
NL_SOCK_RBUF_SIZE
|
|
};
|
|
|
|
typedef struct iwpm_client {
|
|
char ifname[IWPM_IFNAME_SIZE]; /* netdev interface name */
|
|
char ibdevname[IWPM_DEVNAME_SIZE]; /* OFED device name */
|
|
char ulibname[IWPM_ULIBNAME_SIZE]; /* library name of the userpace PM agent provider */
|
|
__u32 nl_seq;
|
|
char valid;
|
|
} iwpm_client;
|
|
|
|
typedef union sockaddr_union {
|
|
struct sockaddr_storage s_sockaddr;
|
|
struct sockaddr sock_addr;
|
|
struct sockaddr_in v4_sockaddr;
|
|
struct sockaddr_in6 v6_sockaddr;
|
|
struct sockaddr_nl nl_sockaddr;
|
|
} sockaddr_union;
|
|
|
|
typedef struct iwpm_mapped_port {
|
|
struct list_node entry;
|
|
int owner_client;
|
|
int sd;
|
|
struct sockaddr_storage local_addr;
|
|
struct sockaddr_storage mapped_addr;
|
|
int wcard;
|
|
int ref_cnt; /* the number of owners, if wcard */
|
|
} iwpm_mapped_port;
|
|
|
|
typedef struct iwpm_wire_msg {
|
|
__u8 magic;
|
|
__u8 pmtime;
|
|
__be16 reserved;
|
|
__be16 apport;
|
|
__be16 cpport;
|
|
__be64 assochandle;
|
|
/* big endian IP addresses and ports */
|
|
__u8 cpipaddr[IWPM_IPADDR_SIZE];
|
|
__u8 apipaddr[IWPM_IPADDR_SIZE];
|
|
__u8 mapped_cpipaddr[IWPM_IPADDR_SIZE];
|
|
} iwpm_wire_msg;
|
|
|
|
typedef struct iwpm_send_msg {
|
|
int pm_sock;
|
|
struct sockaddr_storage dest_addr;
|
|
iwpm_wire_msg data;
|
|
int length;
|
|
} iwpm_send_msg;
|
|
|
|
typedef struct iwpm_mapping_request {
|
|
struct list_node entry;
|
|
struct sockaddr_storage src_addr;
|
|
struct sockaddr_storage remote_addr;
|
|
__u16 nlmsg_type; /* Message content */
|
|
__u32 nlmsg_seq; /* Sequence number */
|
|
__u32 nlmsg_pid;
|
|
__u64 assochandle;
|
|
iwpm_send_msg * send_msg;
|
|
int timeout;
|
|
int complete;
|
|
int msg_type;
|
|
} iwpm_mapping_request;
|
|
|
|
typedef struct iwpm_pending_msg {
|
|
struct list_node entry;
|
|
iwpm_send_msg send_msg;
|
|
} iwpm_pending_msg;
|
|
|
|
typedef struct iwpm_msg_parms {
|
|
__u32 ip_ver;
|
|
__u16 address_family;
|
|
char apipaddr[IWPM_IPADDR_SIZE];
|
|
__be16 apport;
|
|
char cpipaddr[IWPM_IPADDR_SIZE];
|
|
__be16 cpport;
|
|
char mapped_cpipaddr[IWPM_IPADDR_SIZE];
|
|
__be16 mapped_cpport;
|
|
unsigned char ver;
|
|
unsigned char mt;
|
|
unsigned char pmtime;
|
|
__u64 assochandle;
|
|
int msize;
|
|
} iwpm_msg_parms;
|
|
|
|
/* iwarp_pm_common.c */
|
|
|
|
void parse_iwpm_config(FILE *);
|
|
|
|
int create_iwpm_socket_v4(__u16);
|
|
|
|
int create_iwpm_socket_v6(__u16);
|
|
|
|
int create_netlink_socket(void);
|
|
|
|
void destroy_iwpm_socket(int);
|
|
|
|
int parse_iwpm_nlmsg(struct nlmsghdr *, int, struct nla_policy *, struct nlattr * [], const char *);
|
|
|
|
int parse_iwpm_msg(iwpm_wire_msg *, iwpm_msg_parms *);
|
|
|
|
void form_iwpm_request(iwpm_wire_msg *, iwpm_msg_parms *);
|
|
|
|
void form_iwpm_accept(iwpm_wire_msg *, iwpm_msg_parms *);
|
|
|
|
void form_iwpm_ack(iwpm_wire_msg *, iwpm_msg_parms *);
|
|
|
|
void form_iwpm_reject(iwpm_wire_msg *, iwpm_msg_parms *);
|
|
|
|
int send_iwpm_nlmsg(int, struct nl_msg *, int);
|
|
|
|
struct nl_msg *create_iwpm_nlmsg(__u16, int);
|
|
|
|
void print_iwpm_sockaddr(struct sockaddr_storage *, const char *, __u32);
|
|
|
|
__be16 get_sockaddr_port(struct sockaddr_storage *sockaddr);
|
|
|
|
void copy_iwpm_sockaddr(__u16, struct sockaddr_storage *, struct sockaddr_storage *,
|
|
char *, char *, __be16 *);
|
|
|
|
int is_wcard_ipaddr(struct sockaddr_storage *);
|
|
|
|
/* iwarp_pm_helper.c */
|
|
|
|
iwpm_mapped_port *create_iwpm_mapped_port(struct sockaddr_storage *, int);
|
|
|
|
iwpm_mapped_port *reopen_iwpm_mapped_port(struct sockaddr_storage *, struct sockaddr_storage *, int);
|
|
|
|
void add_iwpm_mapped_port(iwpm_mapped_port *);
|
|
|
|
iwpm_mapped_port *find_iwpm_mapping(struct sockaddr_storage *, int);
|
|
|
|
iwpm_mapped_port *find_iwpm_same_mapping(struct sockaddr_storage *, int);
|
|
|
|
void remove_iwpm_mapped_port(iwpm_mapped_port *);
|
|
|
|
void print_iwpm_mapped_ports(void);
|
|
|
|
void free_iwpm_port(iwpm_mapped_port *);
|
|
|
|
int free_iwpm_wcard_mapping(iwpm_mapped_port *);
|
|
|
|
iwpm_mapping_request *create_iwpm_map_request(struct nlmsghdr *, struct sockaddr_storage *,
|
|
struct sockaddr_storage *, __u64, int, iwpm_send_msg *);
|
|
|
|
void add_iwpm_map_request(iwpm_mapping_request *);
|
|
|
|
int update_iwpm_map_request(__u64, struct sockaddr_storage *, int, iwpm_mapping_request *, int);
|
|
|
|
void remove_iwpm_map_request(iwpm_mapping_request *);
|
|
|
|
void form_iwpm_send_msg(int, struct sockaddr_storage *, int, iwpm_send_msg *);
|
|
|
|
int send_iwpm_msg(void (*form_msg_type)(iwpm_wire_msg *, iwpm_msg_parms *),
|
|
iwpm_msg_parms *, struct sockaddr_storage *, int);
|
|
|
|
int add_iwpm_pending_msg(iwpm_send_msg *);
|
|
|
|
int check_same_sockaddr(struct sockaddr_storage *, struct sockaddr_storage *);
|
|
|
|
void free_iwpm_mapped_ports(void);
|
|
|
|
extern struct list_head pending_messages;
|
|
extern struct list_head mapping_reqs;
|
|
|
|
extern iwpm_client client_list[IWARP_PM_MAX_CLIENTS];
|
|
|
|
extern pthread_cond_t cond_req_complete;
|
|
extern pthread_mutex_t map_req_mutex;
|
|
extern int wake;
|
|
extern pthread_cond_t cond_pending_msg;
|
|
extern pthread_mutex_t pending_msg_mutex;
|
|
|
|
#endif
|