/* ipmacsec_netlink.h - IPMACSEC Netlink header file */ /* * Copyright (c) 2010 Wind River Systems, Inc. * * The right to copy, distribute, modify, or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. * */ /* modification history -------------------- 01a,17mar10,mry Created */ #ifndef IPMACSEC_NETLINK_H #define IPMACSEC_NETLINK_H /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* This header file is to be included by internal or external modules * that use Netlink to interface to the MACsec SecY management entity * (for control, configuration, notification, status/statistics retrieval) */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #include #include #ifdef IP_PORT_VXWORKS #include #endif #include #include #include "ipmacsec_lmi.h" #ifdef __cplusplus extern "C" { #endif /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* Buffer size for MACsec netlink messages */ #define IPMACSEC_NETLINK_BUFSIZ (16*1024) /* MACsec Netlink type validation macro */ #define IPMACSEC_NLTYPE_IS_VALID(nltype) (((nltype) >= __IPMACSEC_NLTYPE_BASE) && ((nltype) < __IPMACSEC_NLTYPE_MAX)) /* MACsec Netlink Command and Notification messages macros */ #define IPMACSEC_NLCMD_LENGTH(len) (IP_NLMSG_LENGTH(sizeof(Ipmacsec_nlcmd_hdr)+(len))) #define IPMACSEC_NLCMD_DATA(nlmsg) ((void*)(((Ip_u8 *)nlmsg) + IPMACSEC_NLCMD_LENGTH(0))) #define IPMACSEC_NLNOTE_LENGTH(len) (IP_NLMSG_LENGTH(sizeof(Ipmacsec_nlnote_hdr)+(len))) #define IPMACSEC_NLNOTE_DATA(nlmsg) ((void*)(((Ip_u8 *)nlmsg) + IPMACSEC_NLNOTE_LENGTH(0))) /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* IPMACSEC netlink multicast groups */ typedef enum { IPMACSEC_NLGRP_NONE = 0, IPMACSEC_NLGRP_RESERVED, /* RESERVED for netlink management. NOT USED BY APPLICATIONS */ IPMACSEC_NLGRP_NOTIFY, /* Notification Group */ IPMACSEC_NLGRP_MONITOR, /* Monitor Group; Mainly used for debugging to monitor SecY events */ /* Do not insert anything below this */ __IPMACSEC_NLGRP_MAX } Ip_macsec_netlink_groups; /* IPMACSEC NETLINK TYPE DEFINITIONS */ typedef enum { __IPMACSEC_NLTYPE_BASE = 16, IPMACSEC_NLTYPE_TEST = __IPMACSEC_NLTYPE_BASE, /* For debugging purposes only (produces no action other than an ACK) * Does not contain anything besides the netlink message header */ /* * Notification messages of the following types always contain an Ipmacsec_nlnote_hdr * after the netlink message header, in addition to any applicable parameters that follow. */ IPMACSEC_NLTYPE_NOTIFY, /* Notification events */ /* * Command messages of the following types always contain an Ipmacsec_nlcmd_hdr * after the netlink message header, in addition to any applicable parameters that follow. */ IPMACSEC_NLTYPE_SECY_COMMAND, /* SECY commands. */ IPMACSEC_NLTYPE_CP_COMMAND, /* Controlled Port commands. */ IPMACSEC_NLTYPE_UCP_COMMAND, /* Uncontrolled Port commands. */ IPMACSEC_NLTYPE_SIG_EXIT, /* Netlink socket exit signal. FOR INTERNAL USE ONLY, not used directly by applications */ /* Do not insert anything below this. MUST not exceed the maximum size of nlmsg_type in Ip_nlmsghdr */ __IPMACSEC_NLTYPE_MAX } Ipmacsec_netlink_type; /* Header for all IPMACsec netlink messages containing a command (follows the netlink message header) */ typedef struct Ipmacsec_nlcmd_hdr_struct { char ifname[IP_IFNAMSIZ]; /* Interface name for the corresponding command */ Ipmacsec_lmi_command command; /* interpreted by the appropriate handler */ Ip_bool get; /* TRUE for a get command, FALSE for a set command * Get commands have no request params, * Set commands have no reply params */ Ip_bool reply; /* TRUE for a reply (get commands only), FALSE for a request */ Ip_u16 param_len; /* Command parameter(s) length */ Ip_u16 param_off; /* Offset of next available parameter (used when removing params) */ } Ipmacsec_nlcmd_hdr; /* Header for all IPMACsec netlink messages containing a notification (follows the netlink message header) */ typedef struct Ipmacsec_nlnote_hdr_struct { char ifname[IP_IFNAMSIZ]; /* Interface name for the corresponding command */ Ipmacsec_lmi_note note; /* interpreted by the appropriate handler */ Ip_u16 param_len; /* Notification parameter(s) length */ Ip_u16 param_off; /* Offset of next available parameter (used when removing params) */ } Ipmacsec_nlnote_hdr; /* IPMACSEC netlink callback function signature */ typedef int (* IPMACSEC_NL_CB)(struct Ip_nlmsghdr *nlmsg, int error); /* IPMACSEC NETLINK HANDLE Structure: * ================================= * Note that the members of this structure MUST not be manipulated directly by * applications. Instead the ipmacsec_netlink_open() and ipmacsec_netlink_register() * APIs should be used. */ typedef struct Ipmacsec_netlink_handle_struct { Ip_fd nlsock; struct Ip_sockaddr_nl local_nladdr; Ip_u32 sequence; char nlbuf[IPMACSEC_NETLINK_BUFSIZ]; IPMACSEC_NL_CB callback; struct Ip_timeval nl_tmo; Ip_bool exit_loop_on_error; Ip_u32 dest_pid; /* RESERVED for MACsec Netlink operation. Not to be modified by applications. */ Ip_u32 dest_groups; /* RESERVED for MACsec Netlink operation. Not to be modified by applications. */ } Ipmacsec_netlink_handle; /* **************************************************************************** * 6 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_netlink_open *=========================================================================== * Description: Allocates a MACsec netlink handles and opens and binds the netlink socket so you can send requests and receive responses. * Must call ipmacsec_netlink_register() if you want to receive notifications. * Parameters: groups - The netlink groups for this socket. * Returns: A handle pointer that can be passed to ipmacsec_netlink_register(), * ipmacsec_netlink_send_request() or ipmacsec_netlink_loop(). * IP_NULL is returned upon error */ IP_GLOBAL Ipmacsec_netlink_handle * ipmacsec_netlink_open(Ip_macsec_netlink_groups groups); /* *=========================================================================== * ipmacsec_netlink_close *=========================================================================== * Description: Closes a MACsec netlink socket and frees the handle * Parameters: nlhandle - Pointer to a MACsec netlink handle * Returns: 0 upon success. * */ IP_GLOBAL int ipmacsec_netlink_close(Ipmacsec_netlink_handle *nlhandle); /* *=========================================================================== * ipmacsec_netlink_request *=========================================================================== * Description: Sends a MACsec netlink request and pends for response * Parameters: nlhandle - netlink handle allocated with ipmacsec_netlink_open() * request - A non NULL netlink request buffer starting with * an Ip_nlmsghdr and optionally containing additional * netlink message(s) * response - If NULL, the caller does not care for the response and * will only process the return code. * If not NULL, it must point to a proper Ipmacsec_buffer * with enough buffer space to receive the response * (if there is not enough space, the response is truncated) * "response" contents are only valid if the return code is 0. * Returns: 0 if successful in sending and receives a positive ACK * < 0 if it fails, times out waiting for ACK, or receives a negative ACK * */ IP_GLOBAL int ipmacsec_netlink_request(Ipmacsec_netlink_handle *nlhandle, struct Ip_nlmsghdr *request, Ipmacsec_buffer *response); /* *=========================================================================== * ipmacsec_netlink_register *=========================================================================== * Description: Register for netlink notifications: * It Associates the callback routine with the handle so that when * ipmacsec_netlink_loop() is invoked, it will call the callback routine * for every received packet or upon timeouts/errors. It also sets supplied * parameters for the nlhandle. * * Note that ipmacsec_netlink_register() can be called again for the same * nlhandle (assuming mutual exclusions is provided or ipmacsec_netlink_loop() * is not currently invoked/running) to update the callback, nl_tmo * and/or exit_loop_on_error. * Parameters: * nlhandle - The MACsec netlink handler to register with. * MUST be allocated with ipmacsec_netlink_open() and * have a valid netlink socket. * callback - The callback function to register for this handle. * nl_tmo - Pointer to a timeout value to be used by the * ipmacsec_netlink_loop() when invoked. * A NULL nl_tmo or an nl_tmo containing a 0 value * means no timeout is set. * exit_loop_on_error - If set, indicates that ipmacsec_netlink_loop() * will exit upon an error condition, otherwise * the callback is invoked with an error condition * and ipmacsec_netlink_loop() will only exit if * the callback returns < 0. * Returns: 0 upon success * <0 upon failure * */ IP_GLOBAL int ipmacsec_netlink_register(Ipmacsec_netlink_handle *nlhandle, IPMACSEC_NL_CB callback, struct Ip_timeval *nl_tmo, Ip_bool exit_loop_on_error); /* *=========================================================================== * ipmacsec_netlink_loop *=========================================================================== * Description: Invoke a continuous loop that blocks on the netlink socket * (in the nlhandle). * The callback will be invoked under these conditions: * 1- For every successfully received message the nlhandle registred * callback will be invoked passing a pointer to the nlmsg * containing the received netlink message, and an error value of 0. * 2- It will be invoked upon timeouts, in which case a NULL nlmsg * pointer is provided and a positive error value is returned. * 3- It will be invoked if socket select/read errors occur * if the nlhandle exit_loop_on_error is not set. In this case, * a NULL nlmsg pointer is provided and a negative error value * is returned. * 4- It will be invoked when a MACsec netlink EXIT message is * received on the nlhandler netlink socket, in which case a * pointer to the the EXIT nlmsg is provided and a positive error * value is returned. * * The loop will only exit upon one of these conditions: * 1- An error occurs during its initialization. * 2- An error occurs during socket select/read and * the nlhandle exit_loop_on_error flag is set. * 3- The callback routine returns <0 after being invoked. * 4- A MACsec netlink EXIT message is received. * Note that if the loop is called with an nlhandle nl_tmo set to * 0, it may loop/block forever if none of the above conditions are met. * You can either set a nl_tmo to a certain reasonable value which * causes your callback to be invoked and it can return -1 to cause * the loop to exit. Or if nl_tmo is 0, you can use ipmacsec_netlink_loop_exit() * to send a netlink message to the netlink socket to cause an exit. * * Also note that when ipmacsec_netlink_loop() is invoked and while it has not * returned, the same nlhandle MUST not be passed to another invocation of * ipmacsec_netlink_request(), ipmacsec_netlink_loop() or ipmacsec_netlink_close() * unless the caller has provided mutual exclusion for the nlhanle before * invoking those routines in separate threads/contexts. * * Parameters: nlhandle - valid pointer to properly allocated and registered netlink handle * Returns: >= 0 upon successful exit (including timeout) * <0 upon exit due to errors * */ IP_GLOBAL int ipmacsec_netlink_loop(Ipmacsec_netlink_handle *nlhandle); /* *=========================================================================== * ipmacsec_netlink_loop_exit *=========================================================================== * Description: Causes a netlink EXIT message to be sent to the socket * associated with the specified nl_handle. * Parameters: nlhandle - Specifies the nlhandle whose socket will receive * the netlink EXIT message (based on nl_pid of the * nlhandler local_addr). * Returns: 0 upon success * <0 upon error * */ IP_GLOBAL int ipmacsec_netlink_loop_exit(Ipmacsec_netlink_handle *nlhandle); /* *=========================================================================== * ipmacsec_netlink_type_name *=========================================================================== * Description: Return a string describing the name of a MACsec netlink type * Parameters: nltype - netlink type to describe * Returns: String pointer (always != NULL) * */ IP_GLOBAL IP_CONST char * ipmacsec_netlink_type_name(Ipmacsec_netlink_type nltype); /* *=========================================================================== * ipmacsec_nlmsg_alloc *=========================================================================== * Description: Allocates a netlink message buffer using the buf container. * Parameters: buf - Pointer to a properly intialized or previously freed * buffer container. * Returns: Pointer to allocated and initialized buffer memory, * IP_NULL if allocation fails. * */ IP_GLOBAL Ip_u8 * ipmacsec_nlmsg_alloc(Ipmacsec_buffer *buf); /* *=========================================================================== * ipmacsec_nlmsg_free *=========================================================================== * Description: Frees a netlink message buffer. * Parameters: buf - Pointer to allocated buffer container. * Returns: 0 * */ IP_GLOBAL int ipmacsec_nlmsg_free(Ipmacsec_buffer *buf); /* *=========================================================================== * ipmacsec_nlcmd_add *=========================================================================== * Description: Adds a netlink command message to a buffer and initializes the * Ipmacsec_nlcmd_hdr inside the nlmsg netlink message * updating both in the process along with the buffer container. * Parameters: * buf - Pointer to an allocated buffer container. * nltype - A valid MACsec netlink message type * cmd - The command type. * ifname - Valid pointer to an interface name NULL terminated string * getCmd - TRUE for a get command, FALSE for a set command * isReply - Indicates a reply (not set by apps) * Returns: Pointer to the initialized netlink message * NULL if failed (not enough space or other failure). * */ IP_GLOBAL struct Ip_nlmsghdr * ipmacsec_nlcmd_add(Ipmacsec_buffer *buf, Ipmacsec_netlink_type nltype, Ipmacsec_lmi_command cmd, char *ifname, Ip_bool getCmd, Ip_bool isReply); /* *=========================================================================== * ipmacsec_nlcmd_get *=========================================================================== * Description: Retrieves a pointer to an nlcmd from a netlink message * (only supports one command per message) * Parameters: nlmsg - Pointer to the netlink message containing the nlcmd * Returns: pointer to nlcmd_hdr if successful * IP_NULL if not enough space to contain an nlcmd_hdr or upon error * */ IP_GLOBAL struct Ipmacsec_nlcmd_hdr_struct * ipmacsec_nlcmd_get(struct Ip_nlmsghdr *nlmsg); /* *=========================================================================== * ipmacsec_nlcmd_add_param *=========================================================================== * Description: Adds a parameter to a MACsec netlink cmd msg and to the * associated buffer container, updating the buffer container, * the netlink header and Ipmacsec_nlcmd_hdr in the process. * May be called repeatedly for the same netlink cmd msg as long as * there is enough buffer space. * Parameters: * buf - Pointer to a valid buffer container. * nlmsg - Ptr to header for current netlink message being * manipulated in buffer * param - Pointer to param to add * param_size - size of param to add * Returns: number of octets added if adding a param was successful * <0 if error (space not available or other error) * */ IP_GLOBAL int ipmacsec_nlcmd_add_param(Ipmacsec_buffer *buf, struct Ip_nlmsghdr *nlmsg, void *param, Ip_u32 param_size); /* *=========================================================================== * ipmacsec_nlcmd_retrieve_init *=========================================================================== * Description: Initialize an nlcmd struct before retrieving params. * Parameters: nlmsg - Ptr to header for current netlink message being parsed * Returns: >0 is successful (= size of param field), <0 if error occurs */ IP_GLOBAL int ipmacsec_nlcmd_retrieve_init(struct Ip_nlmsghdr *nlmsg); /* *=========================================================================== * ipmacsec_nlcmd_retrieve_param *=========================================================================== * Description: Retrieves a parameter from a MACsec netlink cmd msg * updating the Ipmacsec_nlcmd_hdr's param_offset in the process. * May be called repeatedly for the same netlink cmd msg as long as * there are remaining param bytes. * Make sure ipmacsec_nlcmd_retrieve_init() is called ONCE and ONLY ONCE * before subsequent ipmacsec_nlcmd_retrieve_param() calls. * Note that the paramter remains unchanged in the nlmsg * (e.g. for retransmission,forwarding, etc.). * Parameters: * nlmsg - Ptr to header for current netlink message * (Must be a valid MACsec netlink command message) * param - Pointer to data here to store removed param * If NULL, param is removed but no data copied. * param_size - size of param to retrieve * Returns: number of octets removed if a param was successfully removed * <0 if error (no param bytes or other error) * */ IP_GLOBAL int ipmacsec_nlcmd_retrieve_param(struct Ip_nlmsghdr *nlmsg, void *param, Ip_u32 param_size); /* *=========================================================================== * ipmacsec_nlnote_get *=========================================================================== * Description: Retrieves a pointer to an nlnote from a netlink message * (only supports one notification per message) * Parameters: nlmsg - Pointer to the netlink message containing the nlnote * Returns: pointer to nlnote_hdr if successful * IP_NULL if not enough space to contain an nlnote_hdr or upon error * */ IP_GLOBAL struct Ipmacsec_nlnote_hdr_struct * ipmacsec_nlnote_get(struct Ip_nlmsghdr *nlmsg); /* *=========================================================================== * ipmacsec_nlnote_retrieve_init *=========================================================================== * Description: Initialize an nlnote struct before retrieving params. * Parameters: nlmsg - Ptr to header for current netlink message being parsed * Returns: 0 is successful, <0 if error occurs */ IP_GLOBAL int ipmacsec_nlnote_retrieve_init(struct Ip_nlmsghdr *nlmsg); /* *=========================================================================== * ipmacsec_nlnote_retrieve_param *=========================================================================== * Description: Retrieves a parameter from a MACsec netlink note msg * updating the Ipmacsec_nlnote_hdr's param_offset in the process. * May be called repeatedly for the same netlink note msg as long as * there are remaining param bytes. * Make sure ipmacsec_nlnote_retrieve_init() is called ONCE and ONLY ONCE * before subsequent ipmacsec_nlnote_retrieve_param() calls. * Note that the paramter remains unchanged in the nlmsg * (e.g. for retransmission,forwarding, etc.). * Parameters: * nlmsg - Ptr to header for current netlink message * (Must be a valid MACsec netlink notification message) * param - Pointer to data here to store removed param * If NULL, param is removed but no data copied. * param_size - size of param to retrieve * Returns: number of octets removed if a param was successfully removed * <0 if error (no param bytes or other error) * */ IP_GLOBAL int ipmacsec_nlnote_retrieve_param(struct Ip_nlmsghdr *nlmsg, void *param, Ip_u32 param_size); /* **************************************************************************** * 6 PRIVATE FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmacsec_nlcmd_response_add *=========================================================================== * Description: Add a command response netlink message to a buffer. * Parameters: reply - buffer container to add response netlink command message to * nlmsg - request message being replied to * param - optional parameter pointer * param_size - size of optional param * src_pid - pid to respond to * Returns: Pointer to response message upon success, IP_NULL on failure * */ IPMACSEC_PRIVATE struct Ip_nlmsghdr * ipmacsec_nlcmd_response_add(Ipmacsec_buffer *reply, struct Ip_nlmsghdr *nlreq, void *param, Ip_u32 param_size, Ip_pid_t src_pid); /* *=========================================================================== * ipmacsec_nlnote_add *=========================================================================== * Description: Adds a netlink notification message to a buffer and initializes the * Ipmacsec_nlnote_hdr inside the nlmsg netlink message * updating both in the process along with the buffer container. * Parameters: * buf - Pointer to an allocated buffer container. * nltype - A valid MACsec netlink message type * note - The notification type. * ifname - Valid pointer to an interface name NULL terminated string * Returns: Pointer to the initialized netlink message * NULL if failed (not enough space or other failure). * */ IPMACSEC_PRIVATE struct Ip_nlmsghdr * ipmacsec_nlnote_add(Ipmacsec_buffer *buf, Ipmacsec_netlink_type nltype, Ipmacsec_lmi_note note, char *ifname); /* *=========================================================================== * ipmacsec_nlnote_add_param *=========================================================================== * Description: Adds a parameter to a MACsec netlink note msg and to the * associated buffer container, updating the buffer container, * the netlink header and Ipmacsec_nlnote_hdr in the process. * May be called repeatedly for the same netlink note msg as long as * there is enough buffer space. * Parameters: * buf - Pointer to a valid buffer container. * nlmsg - Ptr to header for current netlink message being * manipulated in buffer * param - Pointer to param to add * param_size - size of param to add * Returns: number of octets added if adding a param was successful * <0 if error (space not available or other error) * */ IPMACSEC_PRIVATE int ipmacsec_nlnote_add_param(Ipmacsec_buffer *buf, struct Ip_nlmsghdr *nlmsg, void *param, Ip_u32 param_size); /* *=========================================================================== * ipmacsec_netlink_broadcast *=========================================================================== * Description: Broadcast a MACsec netlink message to specified groups * Parameters: secy - MACsec secy instance pointer * notification - Pointer to buffer containing the notification * netlink message payload. * size - size of notification buffer * nl_type - netlink message type * nl_flags - netlink message flags * msg_group - netlink groups to bcast message to * Returns: 0 upon success * <0 on error * */ IPMACSEC_PRIVATE int ipmacsec_netlink_broadcast(Ipnet_secy *secy, Ip_u8 *notification, Ip_u32 size, Ipmacsec_netlink_type nl_type, Ip_u16 nl_flags, Ip_macsec_netlink_groups msg_group); #endif /* **************************************************************************** * END OF FILE **************************************************************************** */