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

473 lines
15 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip_if.c,v $ $Revision: 1.7.16.4 $
* $Source: /home/interpeak/CVSRoot/ipmip/src/ipmip_if.c,v $
* $Author: jsheng $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include <ipmip_config.h>
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_list.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_syslog.h>
#include <ipcom_sysvar.h>
#include <ipmip.h>
#include <private/ipmip_context.h>
#include <private/ipmip_if.h>
#include <private/ipmip_util.h>
#include <private/ipmip_buffer.h>
#include <private/ipmip_netlink.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_SYSLOG_PRIORITY IPCOM_LOG_DEBUG2
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPMIP
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip_if_alloc
*===========================================================================
* Description: Allocate and initialize the interface structure
* Parameters: ctx - Context
* proc - Process
* ifsize - the size of the interface structure
* ifname - The interface name
* ifindex - The interface index.
* cleanup - Function to be invoked prior to free.
* Returns: The interface structure on success.
*/
IP_GLOBAL Ipmip_if_t *
ipmip_if_alloc(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ip_size_t ifsize,
const char *ifname,
Ip_u32 ifindex,
Ip_u8 type,
Ip_u8 identity,
Ipmip_if_cleanup_t cleanup)
{
Ipmip_if_t *iff = ipcom_calloc(1, ifsize);
IPMIP_UNUSED_PARAMETER(ctx);
IPMIP_UNUSED_PARAMETER(proc);
if (iff == IP_NULL)
return IP_NULL;
iff->ifindex = ifindex;
if (ifname)
ipcom_strncpy(iff->ifname, ifname, IP_IFNAMSIZ);
iff->type = type;
iff->identity = identity;
iff->lladdr = IP_NULL;
iff->cleanup = cleanup;
return iff;
}
/*
*===========================================================================
* ipmip_if_free
*===========================================================================
* Description: Destroy and free the interface specific data.
* Parameters: ctx - Context
* proc - Process
* iff - the interface to destroy
* Returns:
*/
IP_GLOBAL void
ipmip_if_free(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff)
{
/* If we're in any list; remove us */
if (iff->next.head != IP_NULL)
ipcom_list_remove(&iff->next);
/* Invoke cleanup functionality */
if (iff->cleanup)
(*iff->cleanup) (ctx, proc, iff);
if (iff->lladdr)
{
ipcom_free(iff->lladdr);
iff->lladdr = IP_NULL;
}
ipcom_free(iff);
}
/*
*===========================================================================
* ipmip4_if_ioctl
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipmip_if_ioctl(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff,
unsigned long ioctl,
struct Ip_ifreq *ifreq)
{
if((IP_IFNAMSIZ - 1) < strlen(iff->ifname))
{
return -1;
}
ipcom_strcpy(ifreq->ifr_name, iff->ifname);
return ipmip_util_ioctl(ctx, proc, ioctl, ifreq);
}
/*
*===========================================================================
* ipmip_if_get_flags
*===========================================================================
* Description: Get the current interface flags.
* Parameters: ctx - The context
* proc - The process.
* iff - The interface
* flags - Where to store the flags.
* Returns: IP_TRUE on success
*
*/
IP_GLOBAL Ip_bool
ipmip_if_get_flags(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff,
Ip_u16 *flags)
{
struct Ip_ifreq ifreq;
if (ipmip_if_ioctl(ctx, proc, iff, IP_SIOCGIFFLAGS, &ifreq) < 0)
return IP_FALSE;
*flags = ifreq.ifr_ifru.ifru_flags;
return IP_TRUE;
}
/*
*===========================================================================
* ipmip_if_set_flags
*===========================================================================
* Description: Set the current interface flags.
* Parameters: ctx - The context
* proc - The process
* iff - The interface
* flags - The flags to set
* Returns: IP_TRUE on success
*
*/
IP_GLOBAL Ip_bool
ipmip_if_set_flags(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff,
Ip_u16 flags)
{
struct Ip_ifreq ifreq;
if (ipmip_if_ioctl(ctx, proc, iff, IP_SIOCGIFFLAGS, &ifreq) < 0)
return IP_FALSE;
IP_BIT_SET(ifreq.ifr_ifru.ifru_flags, flags);
if (ipmip_util_ioctl(ctx, proc, IP_SIOCSIFFLAGS, &ifreq) < 0)
return IP_FALSE;
return IP_TRUE;
}
/*
*===========================================================================
* ipmip_if_clear_flags
*===========================================================================
* Description: Clear the current interface flags.
* Parameters: iff - The interface
* flags - The flags to clear
* Returns: IP_TRUE on success
*
*/
IP_GLOBAL Ip_bool
ipmip_if_clear_flags(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff,
Ip_u16 flags)
{
struct Ip_ifreq ifreq;
if (ipmip_if_ioctl(ctx, proc, iff, IP_SIOCGIFFLAGS, &ifreq) < 0)
return IP_FALSE;
IP_BIT_CLR(ifreq.ifr_ifru.ifru_flags, flags);
if (ipmip_util_ioctl(ctx, proc, IP_SIOCSIFFLAGS, &ifreq) < 0)
return IP_FALSE;
return IP_TRUE;
}
/*
*===========================================================================
* ipmip_if_resolve_lla
*===========================================================================
* Description: Resolve the LLA of the interface
* Parameters: ctx - Context
* proc - Process
* iff - Interface
* Returns: IP_TRUE on success; IP_FALSE otherwise.
*
*/
IP_GLOBAL Ip_bool
ipmip_if_resolve_lla(Ipmip_context_t *ctx,
Ipmip_proc_t *proc,
Ipmip_if_t *iff)
{
Ipmip_buffer_t req;
Ipmip_buffer_t answer;
struct Ip_ifinfomsg *ifi;
struct Ip_nlmsghdr *nlh;
int ret;
Ip_size_t nlh_size;
Ip_size_t addr_size = 0;
Ip_u8 *addr_data = IP_NULL;
ipmip_buffer_init(&req);
ipmip_buffer_init(&answer);
/**/
ipmip_netlink_nlmsghdr_request(&req, 0, 0, IP_RTM_GETLINK, 0);
ifi = (struct Ip_ifinfomsg *)ipmip_buffer_offset(&req, ipmip_netlink_nlmsghdr_put(&req, IP_NULL, sizeof(*ifi)));
ipcom_memset(ifi, 0, sizeof(*ifi));
ifi->ifi_family = IP_AF_LINK;
ifi->ifi_index = iff->ifindex;
ipmip_netlink_nlmsghdr_done(&req, 0);
ret = ipmip_netlink_request(ctx, proc, ctx->nl_req, 0, 0, IPMIP_BUFFER_PTR(&req), &answer);
ipmip_buffer_release(&req);
if (ret < 0)
return IP_FALSE;
/* We've gotten an answer */
nlh = IPMIP_BUFFER_PTR(&answer);
nlh_size = IPMIP_BUFFER_SIZE(&answer);
/**/
while (IP_NLMSG_OK(nlh, nlh_size))
{
/**/
if (nlh->nlmsg_type == IP_RTM_NEWLINK)
{
struct Ip_rtattr *iflap[IP_IFLA_MAX + 1];
Ip_u8 ll_type;
Ip_u8 ll_subtype;
/* Resolve this entry; I want the prefix length and the address */
ifi = IP_NLMSG_DATA(nlh);
/* Parse */
ipmip_netlink_nlmsghdr_rta_parse(IP_IFLA_MAX + 1,
IP_IFLA_RTA(ifi),
IP_IFLA_PAYLOAD(nlh),
iflap);
if (ipmip_lladdr_arphdr_to_lltype(ifi->ifi_type, &ll_type, &ll_subtype))
{
/* Need to subresolve any ethernet? */
if (ll_type == IPMIP_LLADDR_TYPE_MAC && ll_subtype == IPMIP_LLADDR_SUBTYPE_MAC_802_3)
{
struct Ip_rtattr *linfo = iflap[IP_IFLA_LINKINFO];
if (linfo)
{
linfo = ipmip_netlink_nlmsghdr_rta_find(IP_RTA_DATA(linfo), IP_RTA_PAYLOAD(linfo), IP_IFLA_INFO_KIND);
if (linfo != IP_NULL)
{
if (ipcom_strcmp("vlan", IP_RTA_DATA(linfo)) == 0)
ll_subtype = IPMIP_LLADDR_SUBTYPE_MAC_802_1Q;
}
}
}
/* Found one */
if (iflap[IP_IFLA_ADDRESS])
{
/* Found a LLA address */
addr_size = IP_RTA_PAYLOAD(iflap[IP_IFLA_ADDRESS]);
addr_data = IP_RTA_DATA(iflap[IP_IFLA_ADDRESS]);
}
/* Time to create */
/* Free old */
if (iff->lladdr != IP_NULL)
ipcom_free(iff->lladdr);
/* Initialize the structure; used in router advertisements */
iff->lladdr = ipmip_lladdr_build(IP_NULL,
ll_type,
ll_subtype,
addr_data,
addr_size);
ipmip_buffer_release(&answer);
return IP_TRUE;
}
else
{
IPCOM_LOG1(ERR, "UNSUCCESSFUL ARPHRD FOR %s", iff->ifname);
}
}
/**/
nlh = IP_NLMSG_NEXT(nlh, nlh_size);
}
IPCOM_LOG1(ERR, "FAILED TO RESOLVE MAC FOR %s", iff->ifname);
ipmip_buffer_release(&answer);
return IP_FALSE;
}
/*
*===========================================================================
* ipmip_if_findbyindex
*===========================================================================
* Description: Locate an interface in our configuration based on index
* Parameters: iflist - The list of interfaces
* idx - The interface index
* Returns: The interface pointer if it exists, IP_NULL otherwise.
*/
IP_GLOBAL Ipmip_if_t *
ipmip_if_findbyindex(Ipcom_list *iflist,
Ip_u32 idx)
{
Ipmip_if_t *iff;
for (iff = IPCOM_LIST_FIRST(iflist); iff; iff = IPCOM_LIST_NEXT(&iff->next))
{
if (iff->ifindex == 0)
continue;
if (iff->ifindex == idx)
return iff;
}
return IP_NULL;
}
/*
*===========================================================================
* ipmip_if_findbyname
*===========================================================================
* Description: Locate an interface in our configuration based on name.
* Parameters: iflist - The list of interfaces.
* ifname - The interface name
* Returns: The interface pointer if it exists, IP_NULL otherwise.
*/
IP_GLOBAL Ipmip_if_t *
ipmip_if_findbyname(Ipcom_list *iflist,
const char *ifname)
{
Ipmip_if_t *iff;
ip_assert(ifname);
for (iff = IPCOM_LIST_FIRST(iflist); iff; iff = IPCOM_LIST_NEXT(&iff->next))
{
if (*ifname == '\0' || ipcom_strcmp(iff->ifname, ifname) == 0)
return iff;
}
return IP_NULL;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/