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

406 lines
12 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipnet_ds_srtcm.c,v $ $Revision: 1.10.132.1 $
* $Source: /home/interpeak/CVSRoot/ipnet2/src/ipnet_ds_srtcm.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/* Implementation RFC 2697 - Single Rate Three Color Marker (srTMC) */
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
#include "ipnet_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef IPNET_USE_DIFFSERV
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_cstyle.h>
#include <ipcom_pkt.h>
#include <ipcom_type.h>
#include <ipcom_syslog.h>
#include "ipnet_diffserv.h"
#include "ipnet_h.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPNET_SRTCM_METER_COLOR_GREEN 1
#define IPNET_SRTCM_METER_COLOR_YELLOW 2
#define IPNET_SRTCM_METER_COLOR_RED 3
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef struct Ipnet_srtcm_struct
{
Ipnet_diffserv_handlers dsh;
/* Configuration */
struct Ipnet_ds_srtcm conf;
/* One of the IPNET_DS_METER_SRTCM_COLOR_xxx constants */
int color;
/* Token bucket for Committed Burst Size */
Ip_u32 Tc;
/* Token bucket for Excess Burst Size */
Ip_u32 Te;
/* Last tick tokens was added to the buckets */
Ip_u32 msec;
}
Ipnet_srtcm;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_ds_meter_srtcm_class_to_color
*===========================================================================
* Description: Returns the color the packet has been gived by some before
* enter this srTCM (based on the recommended values from RFC2597).
* Parameters: pkt - The packet for which the color should be returned.
* Returns: The color of the packet as IPNET_DS_METER_SRTCM_COLOR_xxx.
*
*/
IP_STATIC int
ipnet_ds_meter_srtcm_class_to_color(Ipcom_pkt *pkt)
{
switch (ipnet_diffserv_get_ds_field(pkt))
{
case 0x0c:
case 0x14:
case 0x1c:
case 0x24:
/* RFC 2597: Medium Drop Prec */
return IPNET_SRTCM_METER_COLOR_YELLOW;
case 0x0e:
case 0x16:
case 0x1e:
case 0x26:
/* RFC 2597: High Drop Prec */
return IPNET_SRTCM_METER_COLOR_RED;
default:
break;
}
return IPNET_SRTCM_METER_COLOR_GREEN;
}
/*
*===========================================================================
* ipnet_ds_meter_srtcm_add_tokens
*===========================================================================
* Description: Adds more token to the stream controlled by this srTCM.
* Parameters: srtcm - A srTCM object.
* Returns:
*
*/
IP_STATIC void
ipnet_ds_meter_srtcm_add_tokens(Ipnet_srtcm *srtcm)
{
Ip_u32 tokens;
Ip_u32 now = ipnet_msec_now();
tokens = (now - srtcm->msec) * srtcm->conf.CIR / 1000;
if (tokens == 0)
return;
if (srtcm->conf.CBS > srtcm->Tc)
{
if (srtcm->Tc + tokens <= srtcm->conf.CBS)
{
srtcm->Tc += tokens;
tokens = 0;
}
else
{
tokens -= srtcm->conf.CBS - srtcm->Tc;
srtcm->Tc = srtcm->conf.CBS;
}
}
if (srtcm->conf.EBS > srtcm->Te)
{
if (srtcm->Te + tokens <= srtcm->conf.EBS)
srtcm->Te += tokens;
else
{
/* tokens -= srtcm->conf.EBS - srtcm->Te; */
srtcm->Te = srtcm->conf.EBS;
}
}
srtcm->msec = now;
}
/*
*===========================================================================
* ipnet_ds_meter_srtcm_input
*===========================================================================
* Description: Input handler for packets that belong to the controlled stream.
* Parameters: h - The collection of diffserv handlers for this class.
* pkt - The IP datagram to process.
* Returns:
*
*/
IP_STATIC void
ipnet_ds_meter_srtcm_input(Ipnet_srtcm *srtcm, Ipcom_pkt *pkt)
{
int initial_color;
Ip_u32 pkt_len = (Ip_u32)ipcom_pkt_get_length(pkt);
ipnet_ds_meter_srtcm_add_tokens(srtcm);
if (srtcm->conf.mode == IPNET_DS_SRTCM_MODE_COLOR_BLIND)
initial_color = IPNET_SRTCM_METER_COLOR_GREEN;
else
initial_color = ipnet_ds_meter_srtcm_class_to_color(pkt);
switch (initial_color)
{
case IPNET_SRTCM_METER_COLOR_GREEN:
if (srtcm->Tc >= pkt_len)
{
srtcm->Tc -= pkt_len;
srtcm->color = IPNET_SRTCM_METER_COLOR_GREEN;
break;
}
/* else: fall through */
case IPNET_SRTCM_METER_COLOR_YELLOW:
if (srtcm->Te >= pkt_len)
{
srtcm->Te -= pkt_len;
srtcm->color = IPNET_SRTCM_METER_COLOR_YELLOW;
break;
}
/* else: fall through */
case IPNET_SRTCM_METER_COLOR_RED:
srtcm->color = IPNET_SRTCM_METER_COLOR_RED;
break;
default:
IP_PANIC();
break;
}
IPCOM_LOG3(INFO, "DiffServ (srTCM): color %d, Tc %d, Te %d",
srtcm->color, srtcm->Tc, srtcm->Te);
}
/*
*===========================================================================
* ipnet_ds_marker_srtcm_input
*===========================================================================
* Description: Input handler for packets that belong to the controlled stream.
* Parameters: srtcm - A srTCM object.
* pkt - The IP datagram to process.
* Returns:
*
*/
IP_STATIC void
ipnet_ds_marker_srtcm_input(Ipnet_srtcm *srtcm, Ipcom_pkt *pkt)
{
switch (srtcm->color)
{
case IPNET_SRTCM_METER_COLOR_GREEN:
ipnet_diffserv_set_ds_field(pkt, srtcm->conf.ds_green);
IPCOM_PKT_SET_DROP_PRECEDENCE(pkt, IPCOM_PKT_DROP_PRECEDENCE_LOW);
break;
case IPNET_SRTCM_METER_COLOR_YELLOW:
ipnet_diffserv_set_ds_field(pkt, srtcm->conf.ds_yellow);
IPCOM_PKT_SET_DROP_PRECEDENCE(pkt, IPCOM_PKT_DROP_PRECEDENCE_MEDIUM);
break;
case IPNET_SRTCM_METER_COLOR_RED:
ipnet_diffserv_set_ds_field(pkt, srtcm->conf.ds_red);
IPCOM_PKT_SET_DROP_PRECEDENCE(pkt, IPCOM_PKT_DROP_PRECEDENCE_HIGH);
break;
default:
IP_PANIC();
break;
}
}
/*
*===========================================================================
* ipnet_ds_srtcm_delete
*===========================================================================
* Description: Deletes the specified srTCM object.
* Parameters: srtcm - The object to delete.
* Returns:
*
*/
IP_STATIC void
ipnet_ds_srtcm_delete(Ipnet_srtcm *srtcm)
{
ipcom_free(srtcm);
}
/*
*===========================================================================
* ipnet_ds_srtcm_get_conf
*===========================================================================
* Description: get the configuration of this DS type.
* Parameters: h - the DS handler.
* ds - the DS information neeed to be filled.
* Returns: void.
*
*/
IP_STATIC void
ipnet_ds_srtcm_get_conf(Ipnet_diffserv_handlers *h,
struct Ipnet_ds *ds)
{
ip_assert(IP_NULL != h);
ip_assert(IP_NULL != ds);
ipcom_strncpy(ds->name,
IPNET_DS_SRTCM_NAME,
(Ip_size_t)IPNET_DS_NAME_SIZE);
ipcom_memcpy((void *)&ds->d.srtcm,
(void *)(h + 1),
(Ip_size_t)sizeof(ds->d.srtcm));
return;
}
/*
*===========================================================================
* ipnet_ds_srtcm_new
*===========================================================================
* Description: Creates a new single rate three color maker meter.
* Note: at least one of cbs and ebs must be >0.
* Parameters:
* Returns: 0 = success
* <0 = error code
*
*/
IP_STATIC int
ipnet_ds_srtcm_new(struct Ipnet_ds_srtcm *conf, Ipnet_diffserv_handlers **phandler)
{
Ipnet_srtcm *srtcm;
srtcm = ipcom_malloc(sizeof(Ipnet_srtcm));
if (srtcm == IP_NULL)
return IP_NULL;
ipcom_memcpy(&srtcm->conf, conf, sizeof(struct Ipnet_ds_srtcm));
srtcm->dsh.destroy = (Ipnet_diffserv_dtor) ipnet_ds_srtcm_delete;
/* Initialize the meter */
srtcm->Tc = conf->CBS;
srtcm->Te = conf->EBS;
srtcm->color = IPNET_SRTCM_METER_COLOR_GREEN;
srtcm->msec = ipnet_msec_now();
srtcm->dsh.meter_input = (Ipnet_diffserv_meter_input) ipnet_ds_meter_srtcm_input;
srtcm->dsh.get_conf = (Ipnet_diffserv_get_conf) ipnet_ds_srtcm_get_conf;
/* Initialize the marker */
srtcm->dsh.marker_input = (Ipnet_diffserv_marker_input) ipnet_ds_marker_srtcm_input;
*phandler = &srtcm->dsh;
return 0;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipnet_diffserv_srtcm_template
*===========================================================================
* Description: Is called at boot to register the constructor for this module.
* Parameters:
* Returns: The template that knows how to create meter/markers for this
* module.
*
*/
IP_GLOBAL Ipnet_diffserv_handlers_template *
ipnet_diffserv_srtcm_template(void)
{
static Ipnet_diffserv_handlers_template t = {
IPNET_DS_SRTCM_NAME,
(Ipnet_diffserv_ctor) ipnet_ds_srtcm_new
};
return &t;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
#else
int ipnet_ds_srtcm_empty_file;
#endif /* IPNET_USE_DIFFSERV */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/