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

615 lines
20 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_cmd_ip_vr.c,v $ $Revision: 1.2.40.4 $
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_cmd_ip_vr.c,v $
* $Author: hxie $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifdef IPCOM_KERNEL
#undef IPCOM_KERNEL
#endif
#include "ipnet_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_cmd.h>
#include <ipcom_getopt.h>
#include <ipcom_shell.h>
#include <ipcom_sysctl.h>
#include "ipnet.h"
#include "ipnet_cmd.h"
#include "ipnet_ctrl.h"
#include "ipnet_h.h"
#include "ipnet_sysctl.h"
#include "ipnet_cmd_ip.h"
#ifdef IPNET_USE_NETLINK
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
enum
{
IPNET_IP_VR_HELP,
IPNET_IP_VR_LIST,
IPNET_IP_VR_ADD,
IPNET_IP_VR_DEL,
IPNET_IP_VR_CHANGE,
IPNET_IP_VR_MONITOR
};
enum
{
IPNET_IP_VR_ATTRIBUTE_VR,
IPNET_IP_VR_ATTRIBUTE_NEWVR,
IPNET_IP_VR_ATTRIBUTE_DEVNAME,
IPNET_IP_VR_ATTRIBUTE_TABLE,
IPNET_IP_VR_ATTRIBUTE_HELP
};
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef struct Ipnet_cmd_ip_module_vr_filter_struct
{
Ip_u64 mask;
Ip_u16 vr;
char ifname[IP_IFNAMSIZ+1];
} Ipnet_cmd_ip_module_vr_filter_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
static Ipcom_cmd_int_str_map ipnet_ip_vr_main[] =
{
{ IPNET_IP_VR_HELP, "help" },
{ IPNET_IP_VR_LIST, "show" },
{ IPNET_IP_VR_LIST, "list" },
{ IPNET_IP_VR_LIST, "lst" },
{ IPNET_IP_VR_LIST, "get" },
{ IPNET_IP_VR_ADD, "add" },
{ IPNET_IP_VR_DEL, "delete" },
{ IPNET_IP_VR_DEL, "del" },
{ IPNET_IP_VR_CHANGE, "change" },
{ IPNET_IP_VR_CHANGE, "chg" },
{ IPNET_IP_VR_MONITOR, "monitor" },
{ -1, IP_NULL },
};
static Ipcom_cmd_int_str_map ipnet_ip_vr_attributes[] =
{
{ IPNET_IP_VR_ATTRIBUTE_VR, "vr" },
{ IPNET_IP_VR_ATTRIBUTE_NEWVR, "newvr" },
{ IPNET_IP_VR_ATTRIBUTE_DEVNAME, "dev" },
{ IPNET_IP_VR_ATTRIBUTE_TABLE, "table" },
{ IPNET_IP_VR_ATTRIBUTE_HELP, "help" },
{ -1, IP_NULL },
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* IPLINK - VLAN
****************************************************************************
*/
/*
****************************************************************************
* IPVR
****************************************************************************
*/
IP_STATIC int
ipnet_cmd_ip_vr_usage(Ipnet_ip_config_t *cfg, int ret)
{
ipnet_ip_stdio_printf(cfg, ""IP_LF);
ipnet_ip_stdio_printf(cfg, "NAME"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr - Display and modify the IPNET virtual router states and configurations"IP_LF);
ipnet_ip_stdio_printf(cfg, ""IP_LF);
ipnet_ip_stdio_printf(cfg, "SYNOPSIS"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr list [vr <vr>] [dev <devname>]"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr <add|delete> <vr <vr>> [table <table>]"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr change <vr <vr>> dev <devname> <newvr <vr>>"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr help"IP_LF);
ipnet_ip_stdio_printf(cfg, " ip vr monitor"IP_LF);
ipnet_ip_stdio_printf(cfg, ""IP_LF);
ipnet_ip_stdio_printf(cfg, "DESCRIPTION"IP_LF);
ipnet_ip_stdio_printf(cfg, " help Display usage information"IP_LF);
ipnet_ip_stdio_printf(cfg, " list List all links"IP_LF);
ipnet_ip_stdio_printf(cfg, " add Add a link"IP_LF);
ipnet_ip_stdio_printf(cfg, " set Manipulate paramters on an existing link"IP_LF);
ipnet_ip_stdio_printf(cfg, " delete Remove a link"IP_LF);
ipnet_ip_stdio_printf(cfg, " Selector Decription:"IP_LF);
ipnet_ip_stdio_printf(cfg, " vr <vr> - The Virtual Router Identifier we are requesting in"IP_LF);
ipnet_ip_stdio_printf(cfg, " newvr <vr> - The Virtual Router Identifier we want to move the device to"IP_LF);
ipnet_ip_stdio_printf(cfg, " dev <devname> - The name of the device we are working on"IP_LF);
ipnet_ip_stdio_printf(cfg, " table <table> - Routing Table number"IP_LF);
return ret;
}
IP_STATIC void
ipnet_cmd_ip_module_vr_filter(Ipnet_ip_config_t *cfg, Ipnet_cmd_ip_module_vr_filter_t *filter)
{
Ipnet_ip_handle_msg_t *nlmsg, *nnlmsg;
nlmsg = IPCOM_LIST_FIRST(&cfg->handle->replies);
for ( ; IP_NULL != nlmsg; nlmsg = nnlmsg)
{
unsigned i;
struct Ip_vrmsg *vrm = IP_NLMSG_DATA(nlmsg->hdr);
nnlmsg = IPCOM_LIST_NEXT(&nlmsg->next);
if (0 != ipnet_ip_parse_reply(nlmsg, IP_VR_MAX, sizeof(struct Ip_vrmsg)))
{
ipnet_ip_free_reply(nlmsg);
continue;
}
for (i = 0; i < sizeof(filter->mask) * 8; i++)
{
if (IP_BIT_ISSET(filter->mask, IP_BIT_UVAL64(i)))
{
switch (i)
{
case IPNET_IP_VR_ATTRIBUTE_DEVNAME:
if (IP_NULL == nlmsg->rta[IP_VR_IFNAME] || ipcom_strcmp(ipnet_ip_rta_str(nlmsg->rta[IP_VR_IFNAME]), filter->ifname))
{
ipnet_ip_free_reply(nlmsg);
goto next_message;
}
break;
case IPNET_IP_VR_ATTRIBUTE_VR:
if (filter->vr != vrm->vr_vr)
{
ipnet_ip_free_reply(nlmsg);
goto next_message;
}
break;
}
}
}
next_message:
IP_NOOP;
}
}
IP_STATIC int
ipnet_cmd_ip_module_vr_print(Ipnet_ip_config_t *cfg, Ipnet_cmd_ip_module_vr_filter_t *filter, Ipnet_ip_handle_msg_t *nlmsg)
{
struct Ip_vrmsg *vrm = IP_NLMSG_DATA(nlmsg->hdr);
(void) filter;
if (cfg->is_silent)
return 0;
(void)ipnet_ip_parse_reply(nlmsg, IP_VR_MAX, sizeof(struct Ip_vrmsg));
if (nlmsg->hdr->nlmsg_type == IP_RTM_DELVR)
ipnet_ip_stdio_printf(cfg, "Deleted ");
else if (nlmsg->hdr->nlmsg_type == IP_RTM_CHANGEVR)
ipnet_ip_stdio_printf(cfg, "Change ");
/* Index & Name */
ipnet_ip_stdio_printf(cfg, "vr %d", vrm->vr_vr);
if (IP_NULL != nlmsg->rta[IP_VR_VR])
ipnet_ip_stdio_printf(cfg, " newvr %d", ipnet_ip_rta_u32(nlmsg->rta[IP_VR_VR]));
if (IP_NULL != nlmsg->rta[IP_VR_TABLE])
ipnet_ip_stdio_printf(cfg, " table %d", ipnet_ip_rta_u32(nlmsg->rta[IP_VR_TABLE]));
if (IP_NULL != nlmsg->rta[IP_VR_IFNAME])
ipnet_ip_stdio_printf(cfg, " dev %s", ipnet_ip_rta_str(nlmsg->rta[IP_VR_IFNAME]));
ipnet_ip_stdio_printf(cfg, IP_LF);
return 0;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_list_parse(Ipnet_ip_config_t *cfg, Ipnet_cmd_ip_module_vr_filter_t *filter)
{
char *sarg;
int arg;
Ip_u32 uarg;
/* Time to go through the filter parameters */
while (IP_FALSE != ipnet_ip_cmd_param_str(&sarg, cfg))
{
if (IP_FALSE == ipnet_ip_str_to_key(&arg, ipnet_ip_vr_attributes, sarg))
{
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_VR)))
{
(void)ipnet_cmd_ip_check_mask(cfg, IP_NULL, IPNET_IP_VR_ATTRIBUTE_VR);
if (IP_TRUE != ipnet_ip_str_to_uint(&uarg, sarg, IP_NULL))
return ipnet_cmd_ip_unknown_keyword(cfg, sarg);
filter->vr = (Ip_u16) uarg;
continue;
}
return ipnet_cmd_ip_unknown_keyword(cfg, sarg);
}
switch (arg)
{
case IPNET_IP_VR_ATTRIBUTE_VR:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "vr <vr>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_uint(&uarg, cfg, IP_NULL))
return ipnet_cmd_ip_requires_argument(cfg, "vr <vr>");
filter->vr = (Ip_u16) uarg;
break;
case IPNET_IP_VR_ATTRIBUTE_DEVNAME:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "dev <devname>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_str(&sarg, cfg))
return ipnet_cmd_ip_requires_argument(cfg, "dev <devname>");
if (ipcom_strlen(sarg) >= sizeof(filter->ifname))
return -1;
ipcom_strncpy(filter->ifname, sarg, sizeof(filter->ifname));
filter->ifname[sizeof(filter->ifname)-1] = '\0';
break;
default:
return ipnet_cmd_ip_unknown_keyword(cfg, sarg);
}
}
/* All parameters are parsed
* Store the argument match mask
*/
ipcom_memcpy(&filter->mask, &cfg->mask, sizeof(filter->mask));
return 0;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_list(Ipnet_ip_config_t *cfg)
{
Ipnet_cmd_ip_module_vr_filter_t filter;
Ip_ssize_t ret = ipnet_cmd_ip_module_vr_list_parse(cfg, &filter);
if (0 <= ret)
{
Ipnet_ip_handle_msg_t *nlmsg;
/* Dump the NETLINK information */
if (0 > (ret = ipnet_ip_dump_netlink(cfg, cfg->handle, IP_RTM_GETVR, cfg->family, cfg->core, IP_TRUE)))
{
ipnet_ip_stdio_printf(cfg, "Unable to dump virtual routers, error = %d"IP_LF, (int)ret);
return ret;
}
/* Filter the reply chain */
ipnet_cmd_ip_module_vr_filter(cfg, &filter);
for (nlmsg = IPCOM_LIST_FIRST(&cfg->handle->replies); IP_NULL != nlmsg; nlmsg = IPCOM_LIST_NEXT(&nlmsg->next))
ipnet_cmd_ip_module_vr_print(cfg, &filter, nlmsg);
}
return ret;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_modify(Ipnet_ip_config_t *cfg)
{
char *sarg;
int arg;
struct Ip_nlmsghdr *nlh = (struct Ip_nlmsghdr *)&cfg->handle->tx[0];
struct Ip_vrmsg *vrm;
Ip_u32 uarg;
ipcom_memset(nlh, 0, sizeof(*nlh));
nlh->nlmsg_len = IP_NLMSG_LENGTH(0);
/* Start of the routing message */
vrm = (struct Ip_vrmsg *)IP_NLMSG_DATA(nlh);
ipcom_memset(vrm, 0, sizeof(*vrm));
vrm->vr_family = IP_AF_PACKET;
vrm->vr_vr = IPCOM_VR_ANY;
/* Move past the routing header */
nlh->nlmsg_len = (Ip_u32) (IP_NLMSG_ALIGN(nlh->nlmsg_len) + sizeof(*vrm));
/* Time to go through the filter parameters */
while (IP_FALSE != ipnet_ip_cmd_param_str(&sarg, cfg))
{
if (IP_FALSE == ipnet_ip_str_to_key(&arg, ipnet_ip_vr_attributes, sarg))
{
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_VR)))
{
(void)ipnet_cmd_ip_check_mask(cfg, IP_NULL, IPNET_IP_VR_ATTRIBUTE_VR);
if (IP_TRUE != ipnet_ip_str_to_uint(&uarg, sarg, IP_NULL))
return ipnet_cmd_ip_unknown_keyword(cfg, sarg);
vrm->vr_vr = (Ip_u16) uarg;
continue;
}
return ipnet_cmd_ip_unknown_keyword(cfg, sarg);
}
switch (arg)
{
case IPNET_IP_VR_ATTRIBUTE_HELP:
return ipnet_cmd_ip_vr_usage(cfg, 0);
case IPNET_IP_VR_ATTRIBUTE_DEVNAME:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "dev <devname>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_str(&sarg, cfg))
return ipnet_cmd_ip_requires_argument(cfg, "dev <devname>");
ipcom_netlink_addattr_l(nlh, IPNET_IP_HANDLE_BUFFER, IP_VR_IFNAME, sarg, ipcom_strlen(sarg) + 1);
break;
case IPNET_IP_VR_ATTRIBUTE_VR:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "vr <vr>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_uint(&uarg, cfg, IP_NULL))
return ipnet_cmd_ip_requires_argument(cfg, "vr <vr>");
vrm->vr_vr = (Ip_u16) uarg;
break;
case IPNET_IP_VR_ATTRIBUTE_NEWVR:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "newvr <vr>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_uint(&uarg, cfg, IP_NULL))
return ipnet_cmd_ip_requires_argument(cfg, "newvr <vr>");
ipcom_netlink_addattr_l(nlh, IPNET_IP_HANDLE_BUFFER, IP_VR_VR, &uarg, sizeof(uarg));
break;
case IPNET_IP_VR_ATTRIBUTE_TABLE:
if (IP_TRUE != ipnet_cmd_ip_check_mask(cfg, "table <table>", arg))
return -1;
if (IP_TRUE != ipnet_ip_cmd_param_uint(&uarg, cfg, IP_NULL))
return ipnet_cmd_ip_requires_argument(cfg, "table <table>");
ipcom_netlink_addattr_l(nlh, IPNET_IP_HANDLE_BUFFER, IP_VR_TABLE, &uarg, sizeof(uarg));
break;
}
}
return 0;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_add(Ipnet_ip_config_t *cfg)
{
Ip_ssize_t ret = ipnet_cmd_ip_module_vr_modify(cfg);
struct Ip_nlmsghdr *nlh = (struct Ip_nlmsghdr *)&cfg->handle->tx[0];
if (0 <= ret)
{
nlh->nlmsg_flags = IP_NLM_F_CREATE|IP_NLM_F_EXCL|IP_NLM_F_REQUEST|IP_NLM_F_ACK;
nlh->nlmsg_type = IP_RTM_NEWVR;
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_VR)))
{
ipnet_ip_stdio_printf(cfg, "\'vr <vr>\' argument is required"IP_LF);
return -1;
}
if (0 > (ret = ipnet_ip_request_netlink(cfg, cfg->handle, IP_NULL, cfg->core, IP_TRUE)))
ipnet_ip_stdio_printf(cfg, "RTNETLINK answers: %s"IP_LF, ipcom_strerror(-(int)ret));
}
return ret;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_change(Ipnet_ip_config_t *cfg)
{
Ip_ssize_t ret = ipnet_cmd_ip_module_vr_modify(cfg);
struct Ip_nlmsghdr *nlh = (struct Ip_nlmsghdr *)&cfg->handle->tx[0];
if (0 <= ret)
{
nlh->nlmsg_flags = IP_NLM_F_REQUEST|IP_NLM_F_ACK;
nlh->nlmsg_type = IP_RTM_CHANGEVR;
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_NEWVR)))
{
ipnet_ip_stdio_printf(cfg, "\'newvr <vr>\' argument is required"IP_LF);
return -1;
}
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_DEVNAME)))
{
ipnet_ip_stdio_printf(cfg, "\'dev <devname>\' argument is required"IP_LF);
return -1;
}
if (0 > (ret = ipnet_ip_request_netlink(cfg, cfg->handle, IP_NULL, cfg->core, IP_TRUE)))
ipnet_ip_stdio_printf(cfg, "RTNETLINK answers: %s"IP_LF, ipcom_strerror(-(int)ret));
}
return ret;
}
IP_STATIC Ip_ssize_t
ipnet_cmd_ip_module_vr_del(Ipnet_ip_config_t *cfg)
{
Ip_ssize_t ret = ipnet_cmd_ip_module_vr_modify(cfg);
struct Ip_nlmsghdr *nlh = (struct Ip_nlmsghdr *)&cfg->handle->tx[0];
if (0 <= ret)
{
nlh->nlmsg_flags = IP_NLM_F_REQUEST|IP_NLM_F_ACK;
nlh->nlmsg_type = IP_RTM_DELVR;
if (IP_BIT_ISFALSE(cfg->mask, IP_BIT_UVAL64(IPNET_IP_VR_ATTRIBUTE_VR)))
{
ipnet_ip_stdio_printf(cfg, "\'vr <vr>\' argument is required"IP_LF);
return -1;
}
if (0 > (ret = ipnet_ip_request_netlink(cfg, cfg->handle, IP_NULL, cfg->core, IP_TRUE)))
ipnet_ip_stdio_printf(cfg, "RTNETLINK answers: %s"IP_LF, ipcom_strerror(-(int)ret));
}
return ret;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
IP_GLOBAL Ip_ssize_t
ipnet_cmd_ip_module_vr(Ipnet_ip_config_t *cfg)
{
int arg;
char *sparam;
cfg->handle = ipnet_ip_open_netlink(cfg, 0, IP_NETLINK_ROUTE);
if (IP_NULL == cfg->handle)
return -1;
/* START */
/* Resolve the subcommand */
if (IP_TRUE != ipnet_ip_cmd_param_str(&sparam, cfg))
return ipnet_cmd_ip_vr_usage(cfg, -1);
/* Resolve the module */
if (IP_FALSE == ipnet_ip_str_to_key(&arg, ipnet_ip_vr_main, sparam))
return ipnet_cmd_ip_unknown_keyword(cfg, sparam);
else
{
ipnet_cmd_ip_clear_mask(cfg);
switch (arg)
{
case IPNET_IP_VR_HELP:
return ipnet_cmd_ip_vr_usage(cfg, 0);
case IPNET_IP_VR_LIST:
return ipnet_cmd_ip_module_vr_list(cfg);
case IPNET_IP_VR_ADD:
return ipnet_cmd_ip_module_vr_add(cfg);
case IPNET_IP_VR_CHANGE:
return ipnet_cmd_ip_module_vr_change(cfg);
case IPNET_IP_VR_DEL:
return ipnet_cmd_ip_module_vr_del(cfg);
case IPNET_IP_VR_MONITOR:
return ipnet_cmd_ip_module_monitor(cfg, IP_BIT_VAL(IPNET_IP_MODULE_VR));
}
}
return 0;
}
IP_GLOBAL Ip_u32
ipnet_cmd_ip_module_vr_monitor_groups(Ipnet_ip_config_t *cfg)
{
(void) cfg;
return IP_RTMGRP_RTAB;
}
IP_GLOBAL Ip_bool
ipnet_cmd_ip_module_vr_monitor(Ipnet_ip_config_t *cfg, Ipnet_ip_handle_msg_t *nlmsg)
{
if (nlmsg->hdr->nlmsg_type == IP_RTM_NEWVR || nlmsg->hdr->nlmsg_type == IP_RTM_DELVR || nlmsg->hdr->nlmsg_type == IP_RTM_CHANGEVR)
{
ipnet_cmd_ip_module_vr_print(cfg, IP_NULL, nlmsg);
return IP_TRUE;
}
return IP_FALSE;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
#endif /* IPNET_USE_NETLINK */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/