original files of m241
This commit is contained in:
@@ -0,0 +1,461 @@
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* INTERPEAK SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipdhcpc6_rtsock.c,v $ $Revision: 1.4.56.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipdhcpc6/src/ipdhcpc6_rtsock.c,v $
|
||||
* $Author: svc-cmnet $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 1 DESCRIPTION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 2 CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "ipdhcpc6_config.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 3 INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPCOM_USE_CLIB_PROTO
|
||||
#include <ipcom_clib.h>
|
||||
#include <ipcom_sock.h>
|
||||
#include <ipcom_sock6.h>
|
||||
#include <ipcom_list.h>
|
||||
#include <ipcom_hash.h>
|
||||
#include <ipcom_syslog.h>
|
||||
#include <ipcom_err.h>
|
||||
#include <ipcom_tmo2.h>
|
||||
|
||||
#include <ipnet.h>
|
||||
#include <ipnet_ctrl.h>
|
||||
#include <ipcom_netlink.h>
|
||||
|
||||
#include "ipdhcpc6.h"
|
||||
#include "ipdhcpc6_h.h"
|
||||
#include "ipdhcpc6_msg.h"
|
||||
#include "ipdhcpc6_if.h"
|
||||
#include "ipdhcpc6_ia.h"
|
||||
#include "ipdhcpc6_sock.h"
|
||||
#include "ipdhcpc6_rtsock.h"
|
||||
#include "ipdhcpc6_rtadv.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 4 DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 5 TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 6 EXTERN PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 7 LOCAL PROTOTYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 8 DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 9 STATIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_nlsock_process
|
||||
*===========================================================================
|
||||
* Description:
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC void
|
||||
ipdhcpc6_nlsock_process(Ipdhcpc6_rtsock_context_t *rtctx, int vr_index)
|
||||
{
|
||||
Ip_ssize_t length;
|
||||
|
||||
/* Read routing messages */
|
||||
length = ipcom_recv(rtctx->nl_fd[vr_index],
|
||||
rtctx->buffer,
|
||||
sizeof(rtctx->buffer),
|
||||
0);
|
||||
if (length > 0)
|
||||
{
|
||||
Ipdhcpc6_rtadv_context_t *rtadvctx = rtctx->context->rtadvctx;
|
||||
Ipdhcpc6_sock_context_t *sctx = rtctx->context->sctx;
|
||||
struct Ip_nlmsghdr *nlh = (struct Ip_nlmsghdr *)rtctx->buffer;
|
||||
|
||||
/* Parse the messages */
|
||||
while (IP_NLMSG_OK(nlh, (unsigned)length))
|
||||
{
|
||||
switch (nlh->nlmsg_type)
|
||||
{
|
||||
/* we must listen this event due to if the vr delete and we has
|
||||
* DHCPC6 entity on that vr, the DHCP6 entity will not have a
|
||||
* chance to restart when the deleted vr re-created */
|
||||
case IP_RTM_NEWLINK:
|
||||
case IP_RTM_DELLINK:
|
||||
{
|
||||
char ifname[IP_IFNAMSIZ + 1];
|
||||
struct Ip_ifinfomsg *ifm;
|
||||
Ipdhcpc6_if_t *ifp;
|
||||
|
||||
/* re-create the send/receive socket */
|
||||
ipdhcpc6_sock_create(sctx, vr_index);
|
||||
ipdhcpc6_rtadv_sock_create(rtadvctx, vr_index);
|
||||
|
||||
ifm = (struct Ip_ifinfomsg *)IP_NLMSG_DATA(nlh);
|
||||
ip_assert(IP_NULL != ifm);
|
||||
|
||||
if (ipdhcpc6_if_indextoname(ifm->ifi_index, ifname, vr_index))
|
||||
{
|
||||
ifp = ipdhcpc6_if_lookup_by_name(rtctx->context, ifname);
|
||||
if (ifp)
|
||||
{
|
||||
IPCOM_LOG4(INFO,
|
||||
"%s: received %d for interface [%d,%s]",
|
||||
rtctx->context->name,
|
||||
nlh->nlmsg_type,
|
||||
vr_index,
|
||||
ifname);
|
||||
|
||||
ipdhcpc6_if_update_state(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* 1, this VR socket will exist in system, because the NEWVR event
|
||||
* can ONLY be received on this vr NL socket, .
|
||||
* 2, there is no chance for us to get the VR changed event(no
|
||||
* this kind of event), SO for the following scenario, do nothing :
|
||||
* ifconfig simnet1 vr 1 -- first in VR 1 and begin DHCPC6 process
|
||||
* ifconfig simnet1 vr 0 -- change this interface to 0 */
|
||||
case IP_RTM_DELVR:
|
||||
{
|
||||
/*struct Ip_vrmsg *ipvr = (struct Ip_vrmsg *)IP_NLMSG_DATA(nlh);*/
|
||||
|
||||
/* close the send/receive socket */
|
||||
if (sctx->udp_fd[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
int ret = ipcom_socketclose(sctx->udp_fd[vr_index]);
|
||||
if (ret < 0)
|
||||
{
|
||||
IPCOM_LOG3(ERR,
|
||||
"close socket [%d, %d] error = %d",
|
||||
vr_index,
|
||||
sctx->udp_fd[vr_index],
|
||||
ipcom_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG3(DEBUG,
|
||||
"close socket [%d, %d] error = %d",
|
||||
vr_index,
|
||||
sctx->udp_fd[vr_index],
|
||||
ipcom_errno);
|
||||
|
||||
sctx->udp_fd[vr_index] = IP_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
/* close the RT adv socket */
|
||||
if (rtadvctx->fd_icmp[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
int ret = ipcom_socketclose(rtadvctx->fd_icmp[vr_index]);
|
||||
if (ret < 0)
|
||||
{
|
||||
IPCOM_LOG3(ERR,
|
||||
"close socket [%d, %d] error = %d",
|
||||
vr_index,
|
||||
rtadvctx->fd_icmp[vr_index],
|
||||
ipcom_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPCOM_LOG3(DEBUG,
|
||||
"close socket [%d, %d] error = %d",
|
||||
vr_index,
|
||||
rtadvctx->fd_icmp[vr_index],
|
||||
ipcom_errno);
|
||||
|
||||
rtadvctx->fd_icmp[vr_index] = IP_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
/* detached the interface */
|
||||
ipdhcpc6_if_context_update(rtctx->context->ifctx, vr_index);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nlh = IP_NLMSG_NEXT(nlh, length);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 10 GLOBAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_nlsock_create
|
||||
*===========================================================================
|
||||
* Description: Allocate an rtsock
|
||||
* Parameters: context - The DHCPC6 rtsock context.
|
||||
* vr_index - vr index
|
||||
* Returns: NA.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcpc6_nlsock_create(Ipdhcpc6_rtsock_context_t *rtctx, int vr_index)
|
||||
{
|
||||
int cur_vr = ipcom_proc_vr_get();
|
||||
|
||||
ip_assert(IP_NULL != rtctx);
|
||||
|
||||
if ((rtctx->nl_fd[vr_index] == IP_INVALID_SOCKET)
|
||||
&& (vr_index < IPCOM_VR_MAX))
|
||||
{
|
||||
struct Ip_sockaddr_nl nl_addr;
|
||||
|
||||
if (cur_vr != vr_index)
|
||||
ipcom_proc_vr_set(vr_index);
|
||||
|
||||
rtctx->nl_fd[vr_index] = ipcom_socket(IP_AF_NETLINK,
|
||||
IP_SOCK_RAW,
|
||||
IP_NETLINK_ROUTE);
|
||||
if (rtctx->nl_fd[vr_index] == IP_INVALID_SOCKET)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"Failed to bind on NL socket, errno = %d",
|
||||
ipcom_errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ipcom_setsockopt(rtctx->nl_fd[vr_index],
|
||||
IP_SOL_SOCKET,
|
||||
IP_SO_X_VR,
|
||||
&vr_index,
|
||||
sizeof(vr_index)) != 0)
|
||||
{
|
||||
IPCOM_LOG2(WARNING,
|
||||
"Failed to set VR %d on NL socket, errno = %d",
|
||||
vr_index,
|
||||
ipcom_errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ipcom_memset(&nl_addr, 0, sizeof(nl_addr));
|
||||
nl_addr.nl_family = IP_AF_NETLINK;
|
||||
IPCOM_SA_LEN_SET(&nl_addr, sizeof(nl_addr));
|
||||
nl_addr.nl_groups = IP_NLMSG_GROUP_MASK(IP_RTNLGRP_RTAB)
|
||||
| IP_NLMSG_GROUP_MASK(IP_RTNLGRP_LINK);
|
||||
|
||||
/* Bind socket */
|
||||
if (ipcom_bind(rtctx->nl_fd[vr_index],
|
||||
(struct Ip_sockaddr *)&nl_addr,
|
||||
sizeof(nl_addr)) < 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"Failed to bind on NL socket, errno = %d",
|
||||
ipcom_errno);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (cur_vr != vr_index)
|
||||
ipcom_proc_vr_set(cur_vr);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
errout:
|
||||
if (rtctx->nl_fd[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
ipcom_socketclose(rtctx->nl_fd[vr_index]);
|
||||
rtctx->nl_fd[vr_index] = IP_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (cur_vr != vr_index)
|
||||
ipcom_proc_vr_set(cur_vr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_rtsock_context_alloc
|
||||
*===========================================================================
|
||||
* Description: Allocate an rtsock context
|
||||
* Parameters: context - The DHCPC6 context.
|
||||
* Returns: An rtsock context.
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL Ipdhcpc6_rtsock_context_t *
|
||||
ipdhcpc6_rtsock_context_alloc(struct Ipdhcpc6_context *context)
|
||||
{
|
||||
Ipdhcpc6_rtsock_context_t *rtctx = ipcom_calloc(1, sizeof(*rtctx));
|
||||
if (rtctx)
|
||||
{
|
||||
int vr_index;
|
||||
|
||||
rtctx->context = context;
|
||||
|
||||
for (vr_index = 0; vr_index < IPCOM_VR_MAX; vr_index++)
|
||||
{
|
||||
rtctx->nl_fd[vr_index] = IP_INVALID_SOCKET;
|
||||
}
|
||||
ipdhcpc6_nlsock_create(rtctx, 0);
|
||||
}
|
||||
|
||||
return rtctx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_rtsock_context_free
|
||||
*===========================================================================
|
||||
* Description: Free an rtsock context
|
||||
* Parameters: rtctxp - Pointer to the DHCPC6 rtsock context.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcpc6_rtsock_context_free(Ipdhcpc6_rtsock_context_t **rtctxp)
|
||||
{
|
||||
Ipdhcpc6_rtsock_context_t *rtctx = *rtctxp;
|
||||
if (rtctx)
|
||||
{
|
||||
int vr_index;
|
||||
|
||||
for (vr_index = 0; vr_index < IPCOM_VR_MAX; vr_index++)
|
||||
{
|
||||
if (rtctx->nl_fd[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
ipcom_socketclose(rtctx->nl_fd[vr_index]);
|
||||
rtctx->nl_fd[vr_index] = IP_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
ipdhcpc6_util_free(&rtctx);
|
||||
}
|
||||
*rtctxp = IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_rtsock_context_fdset_init
|
||||
*===========================================================================
|
||||
* Description: Initialize all file descriptors of this context
|
||||
* Parameters: rtctx - rtsock context
|
||||
* rset - Read set to initialize.
|
||||
* mfd - Maximum file descriptor.
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL void
|
||||
ipdhcpc6_rtsock_context_fdset_init(Ipdhcpc6_rtsock_context_t *rtctx,
|
||||
Ip_fd_set *rset,
|
||||
int *mfd)
|
||||
{
|
||||
int vr_index;
|
||||
|
||||
for (vr_index = 0; vr_index < IPCOM_VR_MAX; vr_index++)
|
||||
{
|
||||
if (rtctx->nl_fd[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
*mfd = IP_MAX(*mfd, rtctx->nl_fd[vr_index]);
|
||||
IP_FD_SET(rtctx->nl_fd[vr_index], rset);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipdhcpc6_rtsock_context_fdset_process
|
||||
*===========================================================================
|
||||
* Description: Process all file descriptors of this context
|
||||
* Parameters: rtctx - rtsock context
|
||||
* rset - Read set to initialize.
|
||||
* status - Incoming status
|
||||
* Returns: Outgoing status
|
||||
*
|
||||
*/
|
||||
IP_GLOBAL int
|
||||
ipdhcpc6_rtsock_context_fdset_process(Ipdhcpc6_rtsock_context_t *rtctx,
|
||||
Ip_fd_set *rset,
|
||||
int status)
|
||||
{
|
||||
int vr_index;
|
||||
|
||||
/* */
|
||||
for (vr_index = 0; vr_index < IPCOM_VR_MAX; vr_index++)
|
||||
{
|
||||
if (rtctx->nl_fd[vr_index] != IP_INVALID_SOCKET)
|
||||
{
|
||||
if (IP_FD_ISSET(rtctx->nl_fd[vr_index], rset))
|
||||
ipdhcpc6_nlsock_process(rtctx, vr_index);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* 11 PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user