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

862 lines
27 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_rtnetlink_nae.c,v $ $Revision: 1.2.16.2 $
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_rtnetlink_nae.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation Jonas Rendel <Jonas.Rendel@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
* Contains netlink handlers for managing Ipv4 and Ipv6 routes as well as
* MPLS shortcut routes.
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipnet_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef IPCOM_FORWARDER_NAE
#define IPCOM_USE_CLIB_PROTO
#include <ipcom.h>
#include <ipcom_type.h>
#include <ipcom_clib.h>
#include <ipcom_cstyle.h>
#include <ipcom_sock.h>
#include <ipcom_sock6.h>
#include <ipcom_sock2.h>
#include <ipcom_route.h>
#include <ipcom_errno.h>
#include "ipnet_h.h"
#include "ipnet_ctrl.h"
#include "ipnet_route.h"
#include "ipnet_netlink_h.h"
#include "ipnet_rtnetlink_h.h"
#include "ipcom_sock.h"
#include "ipcom_forwarder.h"
#include "ipnet_loopback.h"
#ifdef IP_PORT_LKM
#include "ipcom_lkm.h" /* Needed for Linux PPP interface config */
#endif /* IP_PORT_LKM */
#include "ipnet_eth.h"
#ifdef IPCOM_USE_FORWARDER_IPSEC
#include <ipipsec_h.h>
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IP_IN4_IS_ADDR_MULTICAST(x) (((x) & ip_htonl(0xf0000000)) == ip_ntohl (0xe0000000))
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef struct Ipnet_rtnetlink_fwc_family
{
struct
{
Ip_ptrdiff_t *hash;
Ip_ptrdiff_t *done;
int aborted;
int cont;
} state;
/* Requested */
struct Ip_nlmsghdr *nlmsg;
Ip_u8 family;
/* Buffering */
Ipnet_netlink_mem_t *mem;
}
Ipnet_rtnetlink_fwc_family_t;
typedef struct Ipnet_rtnetlink_sac_family
{
struct
{
Ip_ptrdiff_t *hash;
Ip_ptrdiff_t *done;
int aborted;
int cont;
} state;
/* Requested */
struct Ip_nlmsghdr *nlmsg;
Ip_u8 family;
/* Buffering */
Ipnet_netlink_mem_t *mem;
}
Ipnet_rtnetlink_sac_family_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
IP_STATIC int
ipnet_rtnetlink_fwcache_entry(Ipnet_rtnetlink_fwc_family_t *param,
Ip_u32 hash_entry,
int domain,
Ip_u32 vlan,
void *dst,
Ip_size_t dst_size,
Ip_u8 *mac,
Ip_u32 unused)
{
struct Ip_nlmsghdr *nlh;
struct Ip_fwcmsg *fwc;
nlh = ipnet_netlink_nlmsg_sz_begin(param->mem, param->nlmsg->nlmsg_seq, IP_RTM_NEWFWCACHE, IP_NLM_F_MULTI);
if (!nlh)
return -1;
fwc = ipnet_netlink_sz_put(param->mem, IP_NULL, sizeof (*fwc));
if (!fwc)
return -1;
/*
* Add route message header
*/
fwc->fwc_family = domain;
fwc->fwc_entry = hash_entry;
fwc->fwc_core = ipcom_nae_current_core();
fwc->fwc_nae = ipcom_nae_id();
fwc->fwc_port = mac[0];
fwc->fwc_index = ipcom_nae.nae_port[fwc->fwc_port].netif->ifindex;
/*
* Add IPSec info
*/
if ((mac[1] & 0x0f) == IPCOM_FWD_IPSEC_ENCRYPT)
fwc->sac_encrypt = 1;
else
fwc->sac_encrypt = 0;
if ((mac[1] & 0x0f) == IPCOM_FWD_IPSEC_DECRYPT)
fwc->sac_decrypt = 1;
else
fwc->sac_decrypt = 0;
/*
* Put destination address
*/
if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_DST, dst_size, dst))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_LLADDR, 6, &mac[2]))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_UNUSED, sizeof(Ip_u32), &unused))
return -1;
if (0 != vlan && !ipnet_rtnetlink_rta_sz_put(param->mem, IP_FWC_VLAN, sizeof(vlan), &vlan))
return -1;
/*
* Done
*/
return ipnet_netlink_nlmsg_sz_end(param->mem, nlh);
}
#ifdef IPCOM_USE_INET
IP_STATIC int
ipnet_rtnetlink_fwcache_foreach_inet(Ipnet_rtnetlink_fwc_family_t *param)
{
unsigned int i = 0;
unsigned int f4_limit = ipcom_nae_shm->fw_v4_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS;
#ifdef IPCOM_USE_FORWARDER_VLAN
unsigned int f6_limit = ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS + f4_limit;
#endif
if (*param->state.hash < f4_limit)
{
/* Going through the 'ordinary' v4 */
for (i = *param->state.hash; i < f4_limit; i++)
{
fw_cache_entry_v4_t *e4 = &ipcom_nae.fw_cache_tbl_v4[i];
if (e4->ip4.rci == ipnet->route_cache_id)
{
/* Got a player */
if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET, 0, &e4->ip4.addr, sizeof(e4->ip4.addr), (Ip_u8 *)e4->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(e4) != 0))
goto aborted;
}
}
*param->state.hash = f4_limit;
}
#ifdef IPCOM_USE_FORWARDER_VLAN
if (*param->state.hash < f6_limit)
{
/* We're going through the VLAN v4 */
for (i = *param->state.hash; i < f6_limit; i++)
{
fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)&ipcom_nae.fw_cache_tbl_v6[i - f4_limit];
if (ev->ipvlan.rci == ipnet->route_cache_id && ev->ipvlan.type == IPCOM_FORWARDER_PACKET_TYPE_IPV4_VLAN)
{
/* Got a player */
if (0 > ipnet_rtnetlink_fwcache_entry(param, i - f4_limit, IP_AF_INET, ev->ipvlan.vlan_id, &ev->ipvlan.a.addr_v4, sizeof(ev->ipvlan.a.addr_v4), (Ip_u8 *)ev->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(ev) != 0))
goto aborted;
}
}
*param->state.hash = f6_limit;
}
#endif
return 0;
aborted:
param->state.aborted = 1;
*param->state.hash = (Ip_ptrdiff_t)i;
return -1;
}
#endif
#ifdef IPCOM_USE_INET6
IP_STATIC int
ipnet_rtnetlink_fwcache_foreach_inet6(Ipnet_rtnetlink_fwc_family_t *param)
{
unsigned int i = 0;
unsigned int f6_limit = ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS;
if (*param->state.hash < f6_limit)
{
/* We're going through the VLAN v4 */
for (i = *param->state.hash; i < f6_limit; i++)
{
fw_cache_entry_v6_t *e6 = &ipcom_nae.fw_cache_tbl_v6[i];
if (e6->ip6.rci != ipnet->route_cache_id)
continue;
#ifdef IPCOM_USE_FORWARDER_VLAN
if (e6->ip6.type == IPCOM_FORWARDER_PACKET_TYPE_IPV6_VLAN)
{
fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)e6;
/* Got a player */
if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET6, ev->ipvlan.vlan_id, &ev->ipvlan.a.addr_v6, sizeof(ev->ipvlan.a.addr_v6), (Ip_u8 *)ev->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(ev) != 0))
goto aborted;
}
else if (e6->ip6.type == IPCOM_FORWARDER_PACKET_TYPE_IPV6)
#endif
{
/* Got a player */
if (0 > ipnet_rtnetlink_fwcache_entry(param, i, IP_AF_INET6, 0, &e6->ip6.addr, sizeof(e6->ip6.addr), (Ip_u8 *)e6->mac_if.dst_mac, IPCOM_FW_NBR_UNUSED_GET(e6) != 0))
goto aborted;
}
}
*param->state.hash = f6_limit;
}
return 0;
aborted:
param->state.aborted = 1;
*param->state.hash = (Ip_ptrdiff_t)i;
return -1;
}
#endif
#ifdef IPCOM_USE_FORWARDER_IPSEC
IP_STATIC int
ipnet_rtnetlink_sacache_entry(Ipnet_rtnetlink_sac_family_t *param,
Ip_u32 hash_entry,
int domain,
Ip_u32 algid,
Ip_u32 spi,
void *src,
void *dst)
{
struct Ip_nlmsghdr *nlh;
struct Ip_sacmsg *sac;
Ip_size_t size;
nlh = ipnet_netlink_nlmsg_sz_begin(param->mem, param->nlmsg->nlmsg_seq, IP_RTM_NEWSACACHE, IP_NLM_F_MULTI);
if (!nlh)
return -1;
sac = ipnet_netlink_sz_put(param->mem, IP_NULL, sizeof (*sac));
if (!sac)
return -1;
/*
* Add SA message header
*/
sac->sac_family = (Ip_u8)domain;
sac->sac_algid = (Ip_u8)algid;
sac->sac_core = ipcom_nae_current_core();
sac->sac_nae = ipcom_nae_id();
sac->sac_entry = hash_entry;
sac->sac_spi = spi;
size = domain == IP_AF_INET ? sizeof(struct Ip_in_addr) : sizeof(struct Ip_in6_addr);
/*
* Put source address
*/
if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_SAC_SRC, size, src))
return -1;
/*
* Put destination address
*/
if (!ipnet_rtnetlink_rta_sz_put(param->mem, IP_SAC_DST, size, dst))
return -1;
/*
* Done
*/
return ipnet_netlink_nlmsg_sz_end(param->mem, nlh);
}
#ifdef IPCOM_USE_INET
IP_STATIC int
ipnet_rtnetlink_sacache_foreach_inet(Ipnet_rtnetlink_sac_family_t *param)
{
unsigned int i = 0;
unsigned int sa_limit = ipcom_nae.fw_ipsec_entries * 2;
if (*param->state.hash < sa_limit)
{
for (i = *param->state.hash; i < sa_limit; i++)
{
Ipcom_fw_ipsec_sa_t *fw_ipsec_sa;
if (i >= ipcom_nae.fw_ipsec_entries)
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[i - ipcom_nae.fw_ipsec_entries]; /* Input SA */
else
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[i]; /* Output SA */
if (fw_ipsec_sa->cache_id != 0
&& fw_ipsec_sa->domain == IP_AF_INET
&& !IPIPSEC_SA_MARKED_FOR_DELETION(fw_ipsec_sa))
{
/* Got a player */
if (0 > ipnet_rtnetlink_sacache_entry(param, i, fw_ipsec_sa->domain, fw_ipsec_sa->algid,
fw_ipsec_sa->spi, fw_ipsec_sa->src, fw_ipsec_sa->dst))
goto aborted;
}
}
*param->state.hash = sa_limit;
}
return 0;
aborted:
param->state.aborted = 1;
*param->state.hash = (Ip_ptrdiff_t)i;
return -1;
}
#endif
#ifdef IPCOM_USE_INET6
IP_STATIC int
ipnet_rtnetlink_sacache_foreach_inet6(Ipnet_rtnetlink_sac_family_t *param)
{
unsigned int i = 0;
unsigned int sa_limit = ipcom_nae.fw_ipsec_entries * 2;
if (*param->state.hash < sa_limit)
{
for (i = *param->state.hash; i < sa_limit; i++)
{
Ipcom_fw_ipsec_sa_t *fw_ipsec_sa;
if (i >= ipcom_nae.fw_ipsec_entries)
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[i - ipcom_nae.fw_ipsec_entries]; /* Input SA */
else
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[i]; /* Output SA */
if (fw_ipsec_sa->cache_id != 0
&& fw_ipsec_sa->domain == IP_AF_INET6
&& !IPIPSEC_SA_MARKED_FOR_DELETION(fw_ipsec_sa))
{
/* Got a player */
if (0 > ipnet_rtnetlink_sacache_entry(param, i, fw_ipsec_sa->domain, fw_ipsec_sa->algid,
fw_ipsec_sa->spi, fw_ipsec_sa->src, fw_ipsec_sa->dst))
goto aborted;
}
}
*param->state.hash = sa_limit;
}
return 0;
aborted:
param->state.aborted = 1;
*param->state.hash = (Ip_ptrdiff_t)i;
return -1;
}
#endif
#endif /* IPCOM_USE_FORWARDER_IPSEC */
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*==========================================================================
* ipnet_rtnetlink_fwcache_dump_family
*===========================================================================
* Description: Get interface info via NETLINK
* Parameters: data - Message payload.
* len - Length of message.
* cb - NETLINK callback entry
*
* Returns: 0 - Success
* <0 - Failure
*
*/
IP_GLOBAL int
ipnet_rtnetlink_fwcache_dump_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlmsg,
int family,
Ip_ptrdiff_t *args)
{
Ipnet_rtnetlink_fwc_family_t param;
Ip_ptrdiff_t *done = &args[0];
Ip_ptrdiff_t *s_hash = &args[1];
Ip_ptrdiff_t *s_continue = &args[2];
param.nlmsg = nlmsg;
param.family = family;
param.mem = mem;
if (*done)
goto exit_out;
param.state.aborted = 0;
param.state.done = done;
param.state.hash = s_hash;
param.state.cont = *s_continue;
#ifdef IPCOM_USE_INET
if (family == IP_AF_INET)
ipnet_rtnetlink_fwcache_foreach_inet(&param);
#endif
#ifdef IPCOM_USE_INET6
if (family == IP_AF_INET6)
ipnet_rtnetlink_fwcache_foreach_inet6(&param);
#endif
/* Are we aborted? */
*s_continue = param.state.aborted;
/* If not aborted; we're done */
if (!param.state.aborted)
*done = 1;
exit_out:
return param.mem->used;
}
IP_GLOBAL int
ipnet_rtnetlink_fwcache_delfwcache_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlh,
struct Ip_rtattr **rta,
int family)
{
struct Ip_fwcmsg *fwc = IP_NLMSG_DATA(nlh);
#ifdef IPCOM_USE_FORWARDER_VLAN
if (IP_NULL != rta[IP_FWC_VLAN - 1])
{
fw_cache_entry_vlan_t *ev = (fw_cache_entry_vlan_t *)&ipcom_nae.fw_cache_tbl_v6[fwc->fwc_entry];
if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS))
return -IP_ERRNO_EINVAL;
ev->ipvlan.rci = 0;
return 0;
}
#endif
#ifdef IPCOM_USE_INET
if (fwc->fwc_family == IP_AF_INET)
{
fw_cache_entry_v4_t *e4 = &ipcom_nae.fw_cache_tbl_v4[fwc->fwc_entry];
if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v4_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS))
return -IP_ERRNO_EINVAL;
e4->ip4.rci = 0;
return 0;
}
#endif
#ifdef IPCOM_USE_INET6
if (fwc->fwc_family == IP_AF_INET6)
{
fw_cache_entry_v6_t *e6 = &ipcom_nae.fw_cache_tbl_v6[fwc->fwc_entry];
if (fwc->fwc_entry >= (ipcom_nae_shm->fw_v6_entries * IPCOM_FORWARDER_TRUE_CACHE_WAYS))
return -IP_ERRNO_EINVAL;
e6->ip6.rci = 0;
return 0;
}
#endif
return -IP_ERRNO_ENOENT;
}
#ifdef IPCOM_USE_FORWARDER_IPSEC
/*
*==========================================================================
* ipnet_rtnetlink_sacache_dump_family
*===========================================================================
* Description: Get SA cache via NETLINK
* Parameters: data - Message payload.
* len - Length of message.
* cb - NETLINK callback entry
*
* Returns: 0 - Success
* <0 - Failure
*
*/
IP_GLOBAL int
ipnet_rtnetlink_sacache_dump_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlmsg,
int family,
Ip_ptrdiff_t *args)
{
Ipnet_rtnetlink_sac_family_t param;
Ip_ptrdiff_t *done = &args[0];
Ip_ptrdiff_t *s_hash = &args[1];
Ip_ptrdiff_t *s_continue = &args[2];
param.nlmsg = nlmsg;
param.family = family;
param.mem = mem;
if (*done)
goto exit_out;
param.state.aborted = 0;
param.state.done = done;
param.state.hash = s_hash;
param.state.cont = *s_continue;
#ifdef IPCOM_USE_INET
if (family == IP_AF_INET)
ipnet_rtnetlink_sacache_foreach_inet(&param);
#endif
#ifdef IPCOM_USE_INET6
if (family == IP_AF_INET6)
ipnet_rtnetlink_sacache_foreach_inet6(&param);
#endif
/* Are we aborted? */
*s_continue = param.state.aborted;
/* If not aborted; we're done */
if (!param.state.aborted)
*done = 1;
exit_out:
return param.mem->used;
}
IP_GLOBAL int
ipnet_rtnetlink_sacache_delsacache_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlh,
struct Ip_rtattr **rta,
int family)
{
struct Ip_sacmsg *sac = IP_NLMSG_DATA(nlh);
#if defined(IPCOM_USE_INET) && defined(IPCOM_USE_INET6)
if (sac->sac_family == IP_AF_INET || sac->sac_family == IP_AF_INET6)
#elif defined(IPCOM_USE_INET)
if (sac->sac_family == IP_AF_INET)
#elif defined(IPCOM_USE_INET6)
if (sac->sac_family == IP_AF_INET6)
#endif
{
Ipcom_fw_ipsec_sa_t *fw_ipsec_sa;
if (sac->sac_entry >= (ipcom_nae.fw_ipsec_entries * 2))
return -IP_ERRNO_EINVAL;
else if (sac->sac_entry >= ipcom_nae.fw_ipsec_entries)
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_dec[sac->sac_entry - ipcom_nae.fw_ipsec_entries]; /* Input SA */
else
fw_ipsec_sa = &ipcom_nae.fw_cache_tbl_enc[sac->sac_entry]; /* Output SA */
ipcom_memset(fw_ipsec_sa, 0, sizeof(*fw_ipsec_sa));
return 0;
}
return -IP_ERRNO_ENOENT;
}
#endif /* IPCOM_USE_FORWARDER_IPSEC */
IP_GLOBAL int
ipnet_rtnetlink_nae_setnae_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlh,
struct Ip_rtattr **rta,
int family)
{
(void) mem;
(void) nlh;
(void) rta;
(void) family;
return -IP_ERRNO_ENOSYS;
}
IP_GLOBAL int
ipnet_rtnetlink_nae_getnae_family(Ipnet_netlink_mem_t *mem,
struct Ip_nlmsghdr *nlhreq,
struct Ip_rtattr **rta,
int family)
{
struct Ip_nlmsghdr *nlh;
struct Ip_naemsg *nae;
Ip_u32 tmp32;
Ip_u64 tmp64;
unsigned long ticks;
unsigned hz;
int i;
nlh = ipnet_netlink_nlmsg_sz_begin(mem, nlhreq->nlmsg_seq, IP_RTM_NEWNAE, 0);
if (!nlh)
return -1;
nae = ipnet_netlink_sz_put(mem, IP_NULL, sizeof (*nae));
if (!nae)
return -1;
nae->nae_family = IP_AF_UNSPEC;
nae->nae_id = ipcom_nae_id();
nae->nae_core = ipcom_nae_current_core();
tmp32 = (Ip_u32)ipcom_forwarder_fw_enable;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_ENABLE, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_started;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_STARTED, sizeof(Ip_u32), &tmp32))
return -1;
ipcom_nae_tick_get(&ticks, &hz);
tmp64 = (Ip_u64)ticks;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_TICK_COUNT, sizeof(Ip_u64), &tmp64))
return -1;
tmp32 = (Ip_u32)hz;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_TICK_HZ, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_selective_invalid;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_SELECTIVE_INVALID, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_total_invalid;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INVALID, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_delete;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_DELETE, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_incomplete;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_INCOMPLETE, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_invalid_lladdr;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_INVALID_LLADDR, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_timeout;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_TIMEOUT, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_external_delete;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_EXTERNAL, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_garbage_collect;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_GARBAGE_COLLECT, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_flushed;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_FLUSHED, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_failed;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_FAILED, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_neigh_resource;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_NEIGH_DELETE_RESOURCE, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_entries_inet;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_CURRENT_INET, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_nae_shm->fw_v4_entries;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INET, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_entries_inet6;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_CURRENT_INET6, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_nae_shm->fw_v6_entries;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_TOTAL_INET6, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_collissions;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_COLLISSIONS, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipcom_forwarder_fw_collissions_invalidate;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_COLLISSIONS_INVALIDATE, sizeof(Ip_u32), &tmp32))
return -1;
tmp32 = (Ip_u32)ipnet->route_cache_id;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_FWCACHE_ROUTE_CACHE_ID, sizeof(Ip_u32), &tmp32))
return -1;
if (IP_NULL != ipcom_nae_shm_table.nae_shm_get_pkt_pool)
{
int pool_mtu, pool_max, pool_avail, pool_numa;
char *pool_name;
for (i = 0;;i++)
{
struct Ip_rtattr *rta_nest;
if (0 > (*ipcom_nae_shm_table.nae_shm_get_pkt_pool) (i, &pool_max, &pool_avail, &pool_mtu, &pool_numa, &pool_name))
break;
rta_nest = ipnet_rtnetlink_rta_sz_nested_begin(mem, IP_NAE_PKT_POOL);
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NAME, ipcom_strlen(pool_name) + 1, pool_name))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_MTU, sizeof(Ip_u32), &pool_mtu))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_SIZE, sizeof(Ip_u32), &pool_max))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_AVAIL, sizeof(Ip_u32), &pool_avail))
return -1;
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NUMA, sizeof(Ip_u32), &pool_numa))
return -1;
ipnet_rtnetlink_rta_sz_nested_end(mem, rta_nest);
}
}
/* */
{
Ipcom_forwarder_capability_t *cap_e, *cap_v;
for (cap_e = IPCOM_LIST_FIRST(&ipcom_nae.capability); cap_e != IP_NULL; cap_e = IPCOM_LIST_NEXT(&cap_e->next))
{
struct Ip_rtattr *rta_nest;
rta_nest = ipnet_rtnetlink_rta_sz_nested_begin(mem, IP_NAE_CAPABILITY);
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_PKTPOOL_NAME, ipcom_strlen(cap_e->cap) + 1, cap_e->cap))
return -1;
for (cap_v = IPCOM_LIST_FIRST(&cap_e->values); cap_v != IP_NULL; cap_v = IPCOM_LIST_NEXT(&cap_v->next))
if (!ipnet_rtnetlink_rta_sz_put(mem, IP_NAE_CAPABILITY_VALUE, ipcom_strlen(cap_v->cap) + 1, cap_v->cap))
return -1;
ipnet_rtnetlink_rta_sz_nested_end(mem, rta_nest);
}
}
/*
* Done
*/
return ipnet_netlink_nlmsg_sz_end(mem, nlh);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
#endif /* IPNET_USE_NETLINK */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/