Files
m241Neelima/components/ip_net2-6.9/ipdhcpc6/src/ipdhcpc6_rtsock.c
T
2026-07-30 11:19:44 +05:30

462 lines
15 KiB
C

/*
******************************************************************************
* 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
****************************************************************************
*/