original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,557 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_pkt_queue_netemu.c,v $ $Revision: 1.23.10.1 $
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_pkt_queue_netemu.c,v $
* $Author: kenneth $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/* Network emulator.
This queue can
- Add latency
- Drop packets randomly or at a deterministic rate
- Corrupt packets randomly or at a deterministic rate */
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipnet_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef IPNET_USE_IFO_NETEMU
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_cstyle.h>
#include <ipcom_err.h>
#include <ipcom_pqueue.h>
#include <ipcom_syslog.h>
#include <ipcom_type.h>
#include "ipnet.h"
#include "ipnet_h.h"
#include "ipnet_pkt_queue.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPNET_NETEMU_DROP_PATTERN_INACTIVE 255
#define IPNET_NETEMU_SET_PKT_SEQ_NUM(pkt, seq) \
ipcom_pkt_set_int(pkt, IPNET_PKT_INFO_NETEMU_SEQ_NUM, seq, Ip_u32)
#define IPNET_NETEMU_GET_PKT_SEQ_NUM(pkt) \
ipcom_pkt_get_int(pkt, IPNET_PKT_INFO_NETEMU_SEQ_NUM, Ip_u32)
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* netemu queue */
typedef struct Ipnet_pkt_queue_netemu_struct
{
Ipnet_pkt_queue hdr;
Ipcom_pqueue *pq;
Ipnet_timeout *tmo;
int limit; /* Maximum number of packets that can be queued */
Ip_u32 enqueue_count; /* Total number of packets that has been queued */
Ip_u32 min_latency_msec; /* Minimum latency added to packets in milliseconds */
Ip_u32 max_latency_msec; /* Maximum latency added to packets in milliseconds */
Ip_bool random_drop; /* IP_FALSE -> drop every drop_probability packet
IP_TRUE -> there is 1/every drop_probability
chance that at packet is dropped */
Ip_u32 drop_probability; /* 1 means every packet dropped, 10 means that
every 10 packet is dropped */
Ip_u32 drop_pattern; /* Bit field where 1 means drop and 0 means pass */
Ip_u8 drop_pattern_len; /* Number of bits that is valid in 'drop_pattern' */
Ip_u8 drop_pattern_index; /* Current bit used */
Ip_bool random_corrupt; /* IP_FALSE -> corrupt every corrupt_probability packet
IP_TRUE -> there is 1/every corrupt_probability
chance that a packet is corrupted */
Ip_u32 corrupt_probability;/* 1 means every packet corrupted, 10 means that
every 10 packet is corrupted */
Ip_u32 seq; /* Sequence number that is increased each time
a packet is added */
}
Ipnet_pkt_queue_netemu;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_pkt_queue_netemu_pq_cmp
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipnet_pkt_queue_netemu_pq_cmp(const Ipcom_pkt *pkt1, const Ipcom_pkt *pkt2)
{
if (IPNET_PKT_GET_TIMEOUT_ABS(pkt1) == IPNET_PKT_GET_TIMEOUT_ABS(pkt2))
return IPCOM_IS_LT(IPNET_NETEMU_GET_PKT_SEQ_NUM(pkt1),
IPNET_NETEMU_GET_PKT_SEQ_NUM(pkt2))
? 1 : -1;
if (IPCOM_IS_LT(IPNET_PKT_GET_TIMEOUT_ABS(pkt1),
IPNET_PKT_GET_TIMEOUT_ABS(pkt2)))
return 1;
return -1;
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_corrupt
*===========================================================================
* Description: Inserts a packet into the queue.
* Parameters: pkt - The packet to corrupt
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_corrupt(Ipcom_pkt *pkt)
{
int i;
int c = 1 + ipcom_rand() % 10;
for (i = 0; i < c; i++)
pkt->data[pkt->start + ipcom_rand() % (pkt->end - pkt->start)] = (Ip_u8) ipcom_rand();
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_to_string
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
#ifdef IPNET_DEBUG
IP_STATIC int
ipnet_pkt_queue_netemu_to_string(Ipnet_pkt_queue_netemu *netemu, char *buf, Ip_size_t buf_len)
{
return ipcom_snprintf(buf, buf_len, "NetEmu if %s limit %d size %d",
netemu->hdr.netif->ipcom.name, netemu->limit, ipcom_pqueue_size(netemu->pq));
}
#endif
/*
*===========================================================================
* ipnet_pkt_queue_netemu_retry_cb
*===========================================================================
* Description: Retries to transmit packets queued in the 'netemu' queue
* Parameters: netemu - a netemu-queue instance
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_retry_cb(Ipnet_pkt_queue_netemu *netemu)
{
Ipcom_pkt *pkt;
Ipnet_pkt_queue *q = netemu->hdr.netif->snd_queue;
while (IP_NULL != (pkt = q->dequeue(q)))
{
int ret = ipnet_if_drv_output(q->netif, pkt);
if (ret < 0)
{
q->requeue(q, pkt);
break;
}
}
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_enqueue
*===========================================================================
* Description: Inserts a packet into the queue.
* Parameters: q - A NETEMU based queue.
* pkt - The packet to store.
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_pkt_queue_netemu_enqueue(Ipnet_pkt_queue_netemu *q,
Ipcom_pkt *pkt)
{
Ip_u32 tmo_msec;
Ip_bool drop = IP_FALSE;
Ip_bool corrupt = IP_FALSE;
if (ipcom_pqueue_size(q->pq) == q->limit)
{
IPCOM_LOG0(DEBUG, "NETEMU enqueue: queue full");
return -IP_ERRNO_ENOBUFS;
}
++q->enqueue_count;
if (q->drop_probability)
{
Ip_bool restart_pattern = IP_FALSE;
if(q->random_drop)
restart_pattern = !((Ip_u32) ipcom_rand() % q->drop_probability);
else
restart_pattern = !(q->enqueue_count % q->drop_probability);
if (restart_pattern)
{
if (q->drop_pattern_len == 0)
drop = IP_TRUE;
else
q->drop_pattern_index = 0;
}
if (q->drop_pattern_index < q->drop_pattern_len)
{
drop = IP_BIT_ISSET(q->drop_pattern, 1 << q->drop_pattern_index);
++q->drop_pattern_index;
}
}
if (drop)
{
IPCOM_LOG0(DEBUG, "NETEMU enqueue: dropping packet");
return -IP_ERRNO_ECOMM;
}
if (q->corrupt_probability)
{
if (q->random_corrupt)
corrupt = !((Ip_u32) ipcom_rand() % q->corrupt_probability);
else
corrupt = !(q->enqueue_count % q->corrupt_probability);
}
if (corrupt)
{
Ipcom_pkt *corrupt_pkt;
/* Must clone the packet since IPNET does not expect the data
be corrupted on the original packet */
corrupt_pkt = ipnet_pkt_clone(pkt, IP_FALSE);
if (corrupt_pkt != IP_NULL)
{
IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_NETIF_DEQUEUE);
ipcom_pkt_free(pkt);
pkt = corrupt_pkt;
IPCOM_LOG0(DEBUG, "NETEMU enqueue: corrupting packet");
ipnet_pkt_queue_netemu_corrupt(pkt);
}
}
tmo_msec = q->min_latency_msec;
if (q->max_latency_msec > q->min_latency_msec)
tmo_msec += (Ip_u32) ipcom_rand() % (q->max_latency_msec - q->min_latency_msec);
ipnet->msec_now = ipnet_msec_now();
IPNET_PKT_SET_TIMEOUT_ABS(pkt, tmo_msec + ipnet->msec_now);
IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_NETIF_OUTQ);
IPNET_NETEMU_SET_PKT_SEQ_NUM(pkt, ++q->seq);
return ipcom_pqueue_insert(q->pq, pkt) == IPCOM_SUCCESS ? 0 : -IP_ERRNO_ENOMEM;
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_dequeue
*===========================================================================
* Description: Removed a packet from the queue.
* Parameters: q - A NETEMU based queue.
* Returns: A packet from the queue or IP_NULL if the queue is empty.
*
*/
IP_STATIC Ipcom_pkt *
ipnet_pkt_queue_netemu_dequeue(Ipnet_pkt_queue_netemu *q)
{
Ipcom_pkt *pkt;
Ip_s64 msec_now;
pkt = ipcom_pqueue_get_next(q->pq);
if (pkt == IP_NULL)
return IP_NULL;
msec_now = ipnet->msec_now;
if (IPCOM_IS_GT64(IPNET_PKT_GET_TIMEOUT_ABS(pkt), msec_now))
{
/* More latency to add */
if (q->tmo == IP_NULL)
{
(void)ipnet_timeout_schedule(IPNET_PKT_GET_TIMEOUT_ABS(pkt) - msec_now,
(Ipnet_timeout_handler) ipnet_pkt_queue_netemu_retry_cb,
q,
&q->tmo);
}
return IP_NULL;
}
IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_NETIF_DEQUEUE);
return ipcom_pqueue_remove_next(q->pq);
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_requeue
*===========================================================================
* Description: Puts back a packet so it will be the first to dequeue next
* time.
* Parameters: netemu - A NETEMU packet queue.
*
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_requeue(Ipnet_pkt_queue_netemu *netemu, Ipcom_pkt *pkt)
{
(void)ipcom_pqueue_insert(netemu->pq, pkt);
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_count
*===========================================================================
* Description: Returns the number of packets that is currently queued.
* Parameters: netemu - A NETEMU based queue.
* Returns:
*
*/
IP_STATIC int
ipnet_pkt_queue_netemu_count(Ipnet_pkt_queue_netemu *netemu)
{
return ipcom_pqueue_size(netemu->pq);
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_reset
*===========================================================================
* Description: Resets the queue, all packets is discarded.
* Parameters: netemu - A NETEMU based queue.
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_reset(Ipnet_pkt_queue_netemu *netemu)
{
Ipcom_pkt *pkt;
while (IP_NULL != (pkt = ipcom_pqueue_remove_next(netemu->pq)))
{
IPCOM_PKT_TRACE(pkt, IPCOM_PKT_ID_NETIF_DEQUEUE);
ipcom_pkt_free(pkt);
}
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_dump
*===========================================================================
* Description: Dumps the configuration to the supplied buffer.
* Parameters: q - A packet queue.
* n - The buffer where the data should be dumped.
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_dump(Ipnet_pkt_queue_netemu *q, struct Ipnet_ifqueue_netemu *n)
{
n->netemu_limit = q->limit;
n->netemu_min_latency = q->min_latency_msec;
n->netemu_max_latency = q->max_latency_msec;
n->netemu_random_drop = q->random_drop;
n->netemu_drop_probability = q->drop_probability;
n->netemu_random_corrupt = q->random_corrupt;
n->netemu_corrupt_probability = q->corrupt_probability;
n->netemu_drop_pattern = q->drop_pattern;
n->netemu_drop_pattern_len = q->drop_pattern_len;
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_configure
*===========================================================================
* Description: Configures a queue with new parameters.
* Parameters: q - A packet queue.
* n - The queue parameters.
* Returns: 0 = success
* <0 = error code
*/
IP_STATIC int
ipnet_pkt_queue_netemu_configure(Ipnet_pkt_queue_netemu *q, struct Ipnet_ifqueue_netemu *n)
{
q->limit = n->netemu_limit;
q->min_latency_msec = n->netemu_min_latency;
q->max_latency_msec = n->netemu_max_latency;
q->random_drop = n->netemu_random_drop;
q->drop_probability = n->netemu_drop_probability;
q->random_corrupt = n->netemu_random_corrupt;
q->corrupt_probability = n->netemu_corrupt_probability;
q->drop_pattern = n->netemu_drop_pattern;
q->drop_pattern_len = n->netemu_drop_pattern_len;
return 0;
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_init
*===========================================================================
* Description: Configures a queue with new parameters.
* Parameters: q - A packet queue.
* Returns:
*
*/
IP_STATIC int
ipnet_pkt_queue_netemu_init(Ipnet_pkt_queue_netemu *q)
{
ipcom_memset((Ip_u8 *) q + sizeof(Ipnet_pkt_queue),
0,
sizeof(Ipnet_pkt_queue_netemu) - sizeof(Ipnet_pkt_queue));
q->drop_pattern_index = IPNET_NETEMU_DROP_PATTERN_INACTIVE;
q->pq = ipcom_pqueue_new((Ipcom_pqueue_cmp_func) ipnet_pkt_queue_netemu_pq_cmp,
ipcom_pqueue_nop_store_index);
return 0;
}
/*
*===========================================================================
* ipnet_pkt_queue_netemu_destroy
*===========================================================================
* Description: Frees all contained queues.
* Parameters: netemu - A NETEMU based queue.
* Returns:
*
*/
IP_STATIC void
ipnet_pkt_queue_netemu_destroy(Ipnet_pkt_queue_netemu *netemu)
{
ipnet_timeout_cancel(netemu->tmo);
ipnet_pkt_queue_netemu_reset(netemu);
ipcom_pqueue_delete(netemu->pq);
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_pkt_queue_netemu_template
*===========================================================================
* Description: Returns a template for NETEMU queue.
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipnet_pkt_queue *
ipnet_pkt_queue_netemu_template()
{
static Ipnet_pkt_queue netemu_template =
{
"netemu",
sizeof(Ipnet_pkt_queue_netemu),
IP_NULL, /* Not a container */
(Ipnet_pkt_queue_enqueue) ipnet_pkt_queue_netemu_enqueue,
(Ipnet_pkt_queue_dequeue) ipnet_pkt_queue_netemu_dequeue,
(Ipnet_pkt_queue_requeue) ipnet_pkt_queue_netemu_requeue,
(Ipnet_pkt_queue_count) ipnet_pkt_queue_netemu_count,
(Ipnet_pkt_queue_reset) ipnet_pkt_queue_netemu_reset,
(Ipnet_pkt_queue_dump) ipnet_pkt_queue_netemu_dump,
(Ipnet_pkt_queue_configure) ipnet_pkt_queue_netemu_configure,
(Ipnet_pkt_queue_init) ipnet_pkt_queue_netemu_init,
(Ipnet_pkt_queue_destroy) ipnet_pkt_queue_netemu_destroy,
};
#ifdef IPNET_DEBUG
ipnet_timeout_to_string((Ipnet_timeout_handler) ipnet_pkt_queue_netemu_retry_cb,
(Ipnet_timeout_to_string_f) ipnet_pkt_queue_netemu_to_string);
#endif
return &netemu_template;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
#else
int ipnet_pkt_queue_netemu_empty_file;
#endif /* IPNET_USE_IFO_NETEMU */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/