/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip4_netlink.c,v $ $Revision: 1.7.10.1 $ * $Source: /home/interpeak/CVSRoot/ipmip4/src/ipmip4_netlink.c,v $ * $Author: svc-cmnet $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip4_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmip4_h.h" #include #include #include #include /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ IP_GLOBAL Ip_bool ipmip4_netlink_get_handle_stat(struct Ipmip4_context *ctx, struct Ipmip_proc *proc, Ipmip_netlink_kern_handle_t *handle, Ipmip4_netlink_kern_statistics_t *link_recv, Ipmip4_netlink_kern_statistics_t *link_send) { Ipmip_buffer_t rbuf; Ip_size_t hdr_off; struct Ip_mipmsg *msg; int ret; Ipmip_buffer_t reply; ipmip_buffer_init(&rbuf); ipmip_buffer_init(&reply); /* Create NLMSG HDR */ ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_GETMIP, 0); msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg))); msg->mip_family = IP_AF_INET; msg->mip_type = IP_WRMOB4_GET_HANDLE_STAT; msg->mip_flags = 0; /* Create the nested HoA attribute */ hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP); ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(*handle), handle); ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off); /* Complete the buffer */ ipmip_netlink_nlmsghdr_done(&rbuf, 0); /* NETLINK request */ ret = ipmip_netlink_request(&ctx->ipmip, proc, ctx->ipmip.nl_req, 0, 0, (struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf), &reply); /**/ ipmip_buffer_release(&rbuf); if (ret >= 0) { struct Ip_nlmsghdr *nlhdr = IPMIP_BUFFER_PTR(&reply); Ip_size_t sz = IPMIP_BUFFER_SIZE(&reply); while (IP_NLMSG_OK(nlhdr, sz)) { if (nlhdr->nlmsg_type == IP_RTM_GETMIP) { struct Ip_rtattr *rta = IP_MIP_RTA(IP_NLMSG_DATA(nlhdr)); Ip_size_t rta_sz = IP_MIP_PAYLOAD(nlhdr); while (IP_RTA_OK(rta, rta_sz)) { if (rta->rta_type == IP_MIP_ENCAP) { /**/ struct Ip_rtattr *srta[IP_WRMOB4_STATS_MAX + 1]; ipmip_netlink_nlmsghdr_rta_parse(IP_WRMOB4_STATS_MAX + 1, IP_RTA_DATA(rta), IP_RTA_PAYLOAD(rta), srta); /* Add statistics */ ipcom_memcpy(link_recv, IP_RTA_DATA(srta[IP_WRMOB4_STATS_LINK_RECV]), sizeof(*link_recv)); ipcom_memcpy(link_send, IP_RTA_DATA(srta[IP_WRMOB4_STATS_LINK_SEND]), sizeof(*link_send)); ipmip_buffer_release(&reply); return IP_TRUE; } rta = IP_RTA_NEXT(rta, rta_sz); } } nlhdr = IP_NLMSG_NEXT(nlhdr, sz); } } ipmip_buffer_release(&reply); return IP_FALSE; } IP_GLOBAL int ipmip4_netlink_del_handle(struct Ipmip4_context *ctx, struct Ipmip_proc *proc, Ip_u32 facility, Ip_u32 identity) { Ipmip_buffer_t rbuf; Ip_size_t hdr_off; struct Ip_mipmsg *msg; int ret; Ipmip_netlink_kern_handle_t handle; ipmip_buffer_init(&rbuf); /* Create NLMSG HDR */ ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_DELMIP, 0); msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg))); msg->mip_family = IP_AF_INET; msg->mip_type = IP_WRMOB4_DEL_HANDLE; msg->mip_flags = 0; /* Create the nested HoA attribute */ hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP); /* Identity */ handle.mip_facility = facility; handle.mip_ident = identity; ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle); ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off); /* Complete the buffer */ ipmip_netlink_nlmsghdr_done(&rbuf, 0); /* NETLINK request */ ret = ipmip_netlink_request(&ctx->ipmip, proc, ctx->ipmip.nl_req, 0, 0, (struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf), IP_NULL); /**/ ipmip_buffer_release(&rbuf); if (ret < 0) { IPMIP4_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip, proc, "Unable to perform MIP4 DEL HANDLE = %d", -ret)); } return ret; } IP_GLOBAL int ipmip4_netlink_new_handle(struct Ipmip4_context *ctx, struct Ipmip_proc *proc, Ip_u32 facility, Ip_u32 identity) { Ipmip_buffer_t rbuf; Ip_size_t hdr_off; struct Ip_mipmsg *msg; int ret; Ipmip_netlink_kern_handle_t handle; ipmip_buffer_init(&rbuf); /* Create NLMSG HDR */ ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_NEWMIP, 0); msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg))); msg->mip_family = IP_AF_INET; msg->mip_type = IP_WRMOB4_NEW_HANDLE; msg->mip_flags = 0; /* Create the nested HoA attribute */ hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP); /* Identity */ handle.mip_facility = facility; handle.mip_ident = identity; ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle); ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off); /* Complete the buffer */ ipmip_netlink_nlmsghdr_done(&rbuf, 0); /* NETLINK request */ ret = ipmip_netlink_request(&ctx->ipmip, proc, ctx->ipmip.nl_req, 0, 0, (struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf), IP_NULL); /**/ ipmip_buffer_release(&rbuf); if (ret < 0) { IPMIP4_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip, proc, "Unable to perform MIP4 NEW HANDLE = %d", -ret)); } return ret; } IP_GLOBAL int ipmip4_netlink_address_do(Ipmip4_context_t *ctx, Ipmip_proc_t *proc, int cmd, Ip_u16 type, Ip_u8 flags, Ip_u32 ifindex, Ip_u8 family, const void *addr, Ipmip_buffer_t *reply) { Ipmip_buffer_t rbuf; Ip_size_t hdr_off; struct Ip_mipmsg *msg; int ret; ipmip_buffer_init(&rbuf); /* Create NLMSG HDR */ ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, cmd, 0); msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg))); msg->mip_family = IP_AF_INET; msg->mip_type = type; msg->mip_flags = flags; /* Create the nested HoA attribute */ hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP); if (addr) ipmip_netlink_nlmsghdr_rta_put_inX(&rbuf, IP_WRMOB4_HOA_ADDRESS, family, addr); ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_HOA_IFINDEX, ifindex); ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off); /* Complete the buffer */ ipmip_netlink_nlmsghdr_done(&rbuf, 0); /* NETLINK request */ ret = ipmip_netlink_request(&ctx->ipmip, proc, ctx->ipmip.nl_req, 0, 0, (struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf), reply); /**/ ipmip_buffer_release(&rbuf); return ret; } IP_GLOBAL int ipmip4_netlink_route_validate(Ipmip4_context_t *ctx, Ipmip_proc_t *proc, Ip_u32 ifindex, Ip_u32 addr, Ipmip_buffer_t *reply) { Ipmip_buffer_t rbuf; Ip_size_t hdr_off; struct Ip_mipmsg *msg; int ret; ipmip_buffer_init(&rbuf); /* Create NLMSG HDR */ ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_GETMIP, 0); msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg))); msg->mip_family = IP_AF_INET; msg->mip_type = IP_WRMOB4_GET_VALIDATE_ROUTE; msg->mip_flags = 0; /* Create the nested HoA attribute */ hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP); ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, ifindex); ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &addr); ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off); /* Complete the buffer */ ipmip_netlink_nlmsghdr_done(&rbuf, 0); /* NETLINK request */ ret = ipmip_netlink_request(&ctx->ipmip, proc, ctx->ipmip.nl_req, 0, 0, (struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf), reply); /**/ ipmip_buffer_release(&rbuf); if (ret < 0) { IPMIP4_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip, proc, "Unable to perform MIP4 command VALIDATE = %d", -ret)); } return ret; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * END OF FILE **************************************************************************** */