/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 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 #include #include #include #include #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 **************************************************************************** */