/* ds_classifier.fpl - classification for the example DiffServ node */ /* * ---------------------------------------------------------------------- * DiffServ classifier for a boundary node. * Supported classes are: EF, AF1x, AF2x, AF3x, AF4x * Policing is performed for packets from clients; packets to clients are * already policed and marked with a DiffServ codepoint * All frames are Ethernet. * ---------------------------------------------------------------------- */ #include "np5.fpl" #include "np5asi.fpl" /* Setup error handler */ SETUP ERROR(MyError); /* ---------------------------------------------------------------------- * Input Ports */ #define IN_PORT 0 /* traffic from the DS network arrives over Port 0 */ #define C1_PORT 1 /* Traffic from client 1 arrives over Port 1 */ #define C2_PORT 2 /* Traffic from client 2 arrives over Port 2 */ /* ---------------------------------------------------------------------- * Protocol constants */ #define IPT_UDP 17 #define RTP_PORT 5004 /* ---------------------------------------------------------------------- * Data types */ #define UNK 0 /* Unknown */ #define AUD 1 /* Audio */ #define VID 2 /* Video */ /* ---------------------------------------------------------------------- * DiffServ classes */ #define EF 0 #define AF1 1 #define AF2 2 #define AF3 3 #define AF4 4 /* ---------------------------------------------------------------------- * Clients */ #define CL1 0 /* client 1 */ #define CL2IP1 1 /* client 2, IP 1 */ #define CL2IP2 2 /* client 2, IP 2 */ /* ---------------------------------------------------------------------- * Client networks */ #define IP_C1 10.*.*.* #define IP1_C2 128.211.*.* #define IP2_C2 128.10.*.* /* ---------------------------------------------------------------------- * Directions */ #define IN 0 #define OUT 1 /* ---------------------------------------------------------------------- * Flow IDs * (flow ID 0 is dummy flow) */ #define C1_IN_EF_FID 1 #define C2IP1_IN_EF_FID 2 #define C2IP2_IN_EF_FID 2 #define C1_IN_AF1_FID 3 #define C2IP1_IN_AF1_FID 4 #define C2IP2_IN_AF1_FID 4 #define C1_IN_AF2_FID 0 #define C2IP1_IN_AF2_FID 0 #define C2IP2_IN_AF2_FID 0 #define C1_IN_AF3_FID 5 #define C2IP1_IN_AF3_FID 6 #define C2IP2_IN_AF3_FID 7 #define C1_IN_AF4_FID 8 #define C2IP1_IN_AF4_FID 0 #define C2IP2_IN_AF4_FID 0 #define C1_OUT_EF_FID 9 #define C2IP1_OUT_EF_FID 9 #define C2IP2_OUT_EF_FID 9 #define C1_OUT_AF1_FID 10 #define C2IP1_OUT_AF1_FID 10 #define C2IP2_OUT_AF1_FID 10 #define C1_OUT_AF2_FID 0 #define C2IP1_OUT_AF2_FID 0 #define C2IP2_OUT_AF2_FID 0 #define C1_OUT_AF3_FID 11 #define C2IP1_OUT_AF3_FID 12 #define C2IP2_OUT_AF3_FID 13 #define C1_OUT_AF4_FID 14 #define C2IP1_OUT_AF4_FID 0 #define C2IP2_OUT_AF4_FID 0 /* ---------------------------------------------------------------------- * Destination IDs */ #define C1_IN_EF_DID 6 #define C2IP1_IN_EF_DID 11 #define C2IP2_IN_EF_DID 11 #define C1_IN_AF1_DID 7 #define C2IP1_IN_AF1_DID 12 #define C2IP2_IN_AF1_DID 12 #define C1_IN_AF2_DID 8 #define C2IP1_IN_AF2_DID 13 #define C2IP2_IN_AF2_DID 13 #define C1_IN_AF3_DID 9 #define C2IP1_IN_AF3_DID 14 #define C2IP2_IN_AF3_DID 14 #define C1_IN_AF4_DID 10 #define C2IP1_IN_AF4_DID 15 #define C2IP2_IN_AF4_DID 15 #define C1_OUT_EF_DID 1 #define C2IP1_OUT_EF_DID 1 #define C2IP2_OUT_EF_DID 1 #define C1_OUT_AF1_DID 2 #define C2IP1_OUT_AF1_DID 2 #define C2IP2_OUT_AF1_DID 2 #define C1_OUT_AF2_DID 3 #define C2IP1_OUT_AF2_DID 3 #define C2IP2_OUT_AF2_DID 3 #define C1_OUT_AF3_DID 4 #define C2IP1_OUT_AF3_DID 4 #define C2IP2_OUT_AF3_DID 4 #define C1_OUT_AF4_DID 5 #define C2IP1_OUT_AF4_DID 5 #define C2IP2_OUT_AF4_DID 5 /* ---------------------------------------------------------------------- * Root functions for first and second pass */ SETUP ROOT (Pass1); SETUP REPLAYROOT (Pass2); SETUP PROTO (asiPoliceEOF0,24,16,24); SETUP PROTO (asiPoliceEOF0,24,16,8,16); SETUP PROTO (fQueueEOF,2,19,6,1,2,1,11,13); SETUP PROTO (fTransmit, 1, 1, 20, 16, 5, 8, 8, 18); SETUP PROTO (fTransmit, 1, 1, 20, 16, 5, 8, 2, 8, 16); /* * ********************************************************************** * ***** PASS 1 ***** * ********************************************************************** */ Pass1: fbrnz ($framerErr:1, FirstPassException) fbrnz ($framerEOF:1, ProcessLastBlock) fQueue (0:2, $portNumber:19, $offset:6, 0:1, 0:2); ProcessLastBlock: fQueueEOF(0:2,$portNumber:19,$offset:6,0:1,0:2,0:1,$portNumber:11,0:13); /* * ********************************************************************** * ***** PASS 2 ***** * ********************************************************************** * Process Ethernet header, only supporting IP */ Pass2: fSkip(96) 0x0800:16 DemuxPort($tag); /* ---------------------------------------------------------------------- * Demultiplex based on port (extracted from $tag) */ DemuxPort: C1_PORT:3 BITS:21 ProcessClTraffic(); DemuxPort: C2_PORT:3 BITS:21 ProcessClTraffic(); DemuxPort: IN_PORT:3 BITS:21 ProcessIncomingTraffic(); /* ---------------------------------------------------------------------- * Process traffic from clients * Classification based on: Port, Protocol and Source IP */ ProcessClTraffic: fStartIpv4HdrCksum($currOffset:6) /* start calculating header chksum */ 0x4:4 hlen = fExtract(4) /* get header length */ DSCP_CU = fExtract(8) /* get DSCP_CU (TOS) */ fSkip(48) /* skip to TTL */ VerifyTTL() /* verify TTL */ proto = fExtract(8) /* get transport layer protocol */ fSkip(16) /* skip IP header checksum */ port = getPortNum($tag) /* get port number */ code = getFlowCode($port:3) /* get code for a flow */ fskip(32) /* skip destination IP */ opt_words = fSub(hlen:16, 5:16) /* IPv4 options size in words */ opt_bits = fShift(opt_words:24,LEFT_SHIFT:1,5:5) /* IP options bits */ fSkip(opt_bits) /* skip IPv4 options*/ data = getDataType($proto:8) /* get payload type */ FID = getFID($code:2, OUT:1, $data:2,$DSCP_CU:8) /* get Flow ID */ /* assign color based on Flow ID and policing algorithm */ color = asiPoliceEOF0($FID:24,$currLength:16,0:24) DID = getDID($FID:8) /* get Destination ID */ fSkipToEnd() /* skip to the end of packet */ checksum = fGetIpHdrCksum() /* get header checksum */ checkChecksum($checksum:2) /* verify checksum */ TMflags_DSCP = get_TMflags_DSCP(@FID:3,$color:16) /* get TM flags */ /* finish second pass and transmit */ fTransmit (0:1, 0:1, $DID:20, 0:16, 0:5, 0:8, $TMflags_DSCP:8, 0:18); /* ---------------------------------------------------------------------- * Process traffic for clients * Classification based on: Protocol, Destination IP and DSCP (TOS) field */ ProcessIncomingTraffic: fStartIpv4HdrCksum($currOffset:6) /* start calculating header chksum */ 0x4:4 hlen = fExtract(4) /* get header length */ DSCP_CU = fExtract(8) /* get DSCP_CU (TOS) */ fSkip(48) /* skip to TTL */ VerifyTTL() /* verify TTL */ proto = fExtract(8) /* get transport layer protocol */ fSkip(48) /* skip to destination IP */ code = getFlowCode(IN_PORT:3) /* get code for a traffic flow */ opt_words = fSub(hlen:16, 5:16) /* IPv4 options length in words */ opt_bits = fShift(opt_words:24,LEFT_SHIFT:1,5:5) /* IP options bits */ fSkip(opt_bits) /* skip IPv4 options*/ data = getDataType($proto:8) /* get payload type */ FID = getFID($code:2,IN:1,$data:2,$DSCP_CU:8) /* get Flow ID */ /* assign color based on Flow ID and policing algorithm */ color = asiPoliceEOF0($FID:24,$currLength:16,$DSCP_CU:8,0:16) DID = getDID($FID:8) /* get Destination ID */ fSkipToEnd() /* skip to the end of packet */ checksum = fGetIpHdrCksum() /* get header checksum */ checkChecksum($checksum:2) /* verify checksum */ TMflags_DSCP = get_TMflags_DSCP(@FID:3,$color:16) /* get TM flags */ /* finish second pass and transmit */ fTransmit (0:1, 0:1, $DID:20, 0:16, 0:5, 0:8, $TMflags_DSCP:8, 0:18); /* ---------------------------------------------------------------------- * Set of functions to get payload type (Voice, Video or Unknown) */ getDataType: IPT_UDP:8 RTP_PORT:16 fSkip(57) /* skip to RTP PT field */ getRTPDataType(); getDataType: IPT_UDP:8 BITS:16 checkUDPDstPort(); getDataType: BITS:24 fReturn(UNK); checkUDPDstPort: RTP_PORT:16 fSkip(41) /* skip to RTP PT field */ getRTPDataType(); checkUDPDstPort: BITS:16 fReturn(UNK); getRTPDataType: RANGE(0, 19):7 fReturn(AUD); getRTPDataType: RANGE(31,34):7 fReturn(VID); getRTPDataType: RANGE(25,26):7 fReturn(VID); getRTPDataType: 28:7 fReturn(VID); getRTPDataType: BITS:7 fReturn(UNK); /* ---------------------------------------------------------------------- * Get Flow ID */ getFID: CL1:2 OUT:1 AUD:2 0b101110 BITS:2 fReturn(EF,C1_OUT_EF_FID); getFID: CL1:2 OUT:1 VID:2 0b101110 BITS:2 fReturn(EF,C1_OUT_EF_FID); getFID: CL1:2 OUT:1 UNK:2 0b101110 BITS:2 fReturn(EF,C1_OUT_EF_FID); getFID: CL1:2 OUT:1 AUD:2 BITS:8 fReturn(AF3,C1_OUT_AF3_FID); getFID: CL1:2 OUT:1 VID:2 BITS:8 fReturn(AF4,C1_OUT_AF4_FID); getFID: CL1:2 OUT:1 BITS:10 fReturn(AF1,C1_OUT_AF1_FID); getFID: CL2IP1:2 OUT:1 AUD:2 0b101110 BITS:2 fReturn(EF,C2IP1_OUT_EF_FID); getFID: CL2IP1:2 OUT:1 VID:2 0b101110 BITS:2 fReturn(EF,C2IP1_OUT_EF_FID); getFID: CL2IP1:2 OUT:1 UNK:2 0b101110 BITS:2 fReturn(EF,C2IP1_OUT_EF_FID); getFID: CL2IP1:2 OUT:1 AUD:2 BITS:8 fReturn(AF3,C2IP1_OUT_AF3_FID); getFID: CL2IP1:2 OUT:1 BITS:10 fReturn(AF1,C2IP1_OUT_AF1_FID); getFID: CL2IP2:2 OUT:1 AUD:2 0b101110 BITS:2 fReturn(EF,C2IP2_OUT_EF_FID); getFID: CL2IP2:2 OUT:1 VID:2 0b101110 BITS:2 fReturn(EF,C2IP2_OUT_EF_FID); getFID: CL2IP2:2 OUT:1 UNK:2 0b101110 BITS:2 fReturn(EF,C2IP2_OUT_EF_FID); getFID: CL2IP2:2 OUT:1 AUD:2 BITS:8 fReturn(AF3,C2IP2_OUT_AF3_FID); getFID: CL2IP2:2 OUT:1 BITS:10 fReturn(AF1,C2IP2_OUT_AF1_FID); getFID: CL1:2 IN:1 AUD:2 0b101110 BITS:2 fReturn(EF,C1_IN_EF_FID); getFID: CL1:2 IN:1 VID:2 0b101110 BITS:2 fReturn(EF,C1_IN_EF_FID); getFID: CL1:2 IN:1 UNK:2 0b101110 BITS:2 fReturn(EF,C1_IN_EF_FID); getFID: CL1:2 IN:1 AUD:2 0b011 BITS:5 fReturn(AF3,C1_IN_AF3_FID); getFID: CL1:2 IN:1 VID:2 0b100 BITS:5 fReturn(AF4,C1_IN_AF4_FID); getFID: CL1:2 IN:1 BITS:10 fReturn(AF1,C1_IN_AF1_FID); getFID: CL2IP1:2 IN:1 AUD:2 0b101110 BITS:2 fReturn(EF,C2IP1_IN_EF_FID); getFID: CL2IP1:2 IN:1 VID:2 0b101110 BITS:2 fReturn(EF,C2IP1_IN_EF_FID); getFID: CL2IP1:2 IN:1 UNK:2 0b101110 BITS:2 fReturn(EF,C2IP1_IN_EF_FID); getFID: CL2IP1:2 IN:1 AUD:2 0b011 BITS:5 fReturn(AF3,C2IP1_IN_AF3_FID); getFID: CL2IP1:2 IN:1 BITS:10 fReturn(AF1,C2IP1_IN_AF1_FID); getFID: CL2IP2:2 IN:1 AUD:2 0b101110 BITS:2 fReturn(EF,C2IP2_IN_EF_FID); getFID: CL2IP2:2 IN:1 VID:2 0b101110 BITS:2 fReturn(EF,C2IP2_IN_EF_FID); getFID: CL2IP2:2 IN:1 UNK:2 0b101110 BITS:2 fReturn(EF,C2IP2_IN_EF_FID); getFID: CL2IP2:2 IN:1 AUD:2 0b011 BITS:5 fReturn(AF3,C2IP2_IN_AF3_FID); getFID: CL2IP2:2 IN:1 BITS:10 fReturn(AF1,C2IP2_IN_AF1_FID); /* ---------------------------------------------------------------------- * Get Destination ID */ getDID: C1_OUT_EF_FID:8 fReturn(C1_OUT_EF_DID); getDID: C1_OUT_AF1_FID:8 fReturn(C1_OUT_AF1_DID); getDID: C1_OUT_AF2_FID:8 fReturn(C1_OUT_AF2_DID); getDID: C1_OUT_AF3_FID:8 fReturn(C1_OUT_AF3_DID); getDID: C1_OUT_AF4_FID:8 fReturn(C1_OUT_AF4_DID); getDID: C2IP1_OUT_EF_FID:8 fReturn(C2IP1_OUT_EF_DID); getDID: C2IP1_OUT_AF1_FID:8 fReturn(C2IP1_OUT_AF1_DID); getDID: C2IP1_OUT_AF2_FID:8 fReturn(C2IP1_OUT_AF2_DID); getDID: C2IP1_OUT_AF3_FID:8 fReturn(C2IP1_OUT_AF3_DID); getDID: C2IP1_OUT_AF4_FID:8 fReturn(C2IP1_OUT_AF4_DID); getDID: C2IP2_OUT_EF_FID:8 fReturn(C2IP2_OUT_EF_DID); getDID: C2IP2_OUT_AF1_FID:8 fReturn(C2IP2_OUT_AF1_DID); getDID: C2IP2_OUT_AF2_FID:8 fReturn(C2IP2_OUT_AF2_DID); getDID: C2IP2_OUT_AF3_FID:8 fReturn(C2IP2_OUT_AF3_DID); getDID: C2IP2_OUT_AF4_FID:8 fReturn(C2IP2_OUT_AF4_DID); getDID: C1_IN_EF_FID:8 fReturn(C1_IN_EF_DID); getDID: C1_IN_AF1_FID:8 fReturn(C1_IN_AF1_DID); getDID: C1_IN_AF2_FID:8 fReturn(C1_IN_AF2_DID); getDID: C1_IN_AF3_FID:8 fReturn(C1_IN_AF3_DID); getDID: C1_IN_AF4_FID:8 fReturn(C1_IN_AF4_DID); getDID: C2IP1_IN_EF_FID:8 fReturn(C2IP1_IN_EF_DID); getDID: C2IP1_IN_AF1_FID:8 fReturn(C2IP1_IN_AF1_DID); getDID: C2IP1_IN_AF2_FID:8 fReturn(C2IP1_IN_AF2_DID); getDID: C2IP1_IN_AF3_FID:8 fReturn(C2IP1_IN_AF3_DID); getDID: C2IP1_IN_AF4_FID:8 fReturn(C2IP1_IN_AF4_DID); getDID: C2IP2_IN_EF_FID:8 fReturn(C2IP2_IN_EF_DID); getDID: C2IP2_IN_AF1_FID:8 fReturn(C2IP2_IN_AF1_DID); getDID: C2IP2_IN_AF2_FID:8 fReturn(C2IP2_IN_AF2_DID); getDID: C2IP2_IN_AF3_FID:8 fReturn(C2IP2_IN_AF3_DID); getDID: C2IP2_IN_AF4_FID:8 fReturn(C2IP2_IN_AF4_DID); /* ---------------------------------------------------------------------- * Get TM flags (color) and DSCP, depending on class * and color of out-bound packet: GR=Green YE=Yellow RED=RE */ get_TMflags_DSCP: EF:3 0b00:2 BITS:14 fReturn(0b00101110); /* GR EF */ get_TMflags_DSCP: EF:3 0b01:2 BITS:14 fReturn(0b01101110); /* YE EF */ get_TMflags_DSCP: EF:3 0b1:1 BITS:15 fReturn(0b10101110); /* RE EF */ get_TMflags_DSCP: AF1:3 0b00:2 BITS:14 fReturn(0b00001010); /* GR AF11 */ get_TMflags_DSCP: AF1:3 0b01:2 BITS:14 fReturn(0b01001100); /* YE AF12 */ get_TMflags_DSCP: AF1:3 0b1:1 BITS:15 fReturn(0b10001110); /* RE AF13 */ get_TMflags_DSCP: AF2:3 0b00:2 BITS:14 fReturn(0b00010010); /* GR AF21 */ get_TMflags_DSCP: AF2:3 0b01:2 BITS:14 fReturn(0b01010100); /* YE AF22 */ get_TMflags_DSCP: AF2:3 0b1:1 BITS:15 fReturn(0b10010110); /* RE AF23 */ get_TMflags_DSCP: AF3:3 0b00:2 BITS:14 fReturn(0b00011010); /* GR AF31 */ get_TMflags_DSCP: AF3:3 0b01:2 BITS:14 fReturn(0b01011100); /* YE AF32 */ get_TMflags_DSCP: AF3:3 0b1:1 BITS:15 fReturn(0b10011110); /* RE AF33 */ get_TMflags_DSCP: AF4:3 0b00:2 BITS:14 fReturn(0b00100010); /* GR AF41 */ get_TMflags_DSCP: AF4:3 0b01:2 BITS:14 fReturn(0b01100100); /* YE AF42 */ get_TMflags_DSCP: AF4:3 0b1:1 BITS:15 fReturn(0b10100110); /* RE AF43 */ /* ---------------------------------------------------------------------- * Extract port number from $tag */ getPortNum: C1_PORT:3 BITS:21 fReturn(C1_PORT); getPortNum: C2_PORT:3 BITS:21 fReturn(C2_PORT); getPortNum: IN_PORT:3 BITS:21 fReturn(IN_PORT); /* ---------------------------------------------------------------------- * Get flow code based on port and source or destination IP */ getFlowCode: C1_PORT:3 IP_C1 fReturn(CL1); getFlowCode: C2_PORT:3 IP1_C2 fReturn(CL2IP1); getFlowCode: C2_PORT:3 IP2_C2 fReturn(CL2IP2); getFlowCode: IN_PORT:3 IP_C1 fReturn(CL1); getFlowCode: IN_PORT:3 IP1_C2 fReturn(CL2IP1); getFlowCode: IN_PORT:3 IP2_C2 fReturn(CL2IP2); /* ---------------------------------------------------------------------- * Verify the Time To Live field in the IP Header */ VerifyTTL: 0:8 SecondPassException(); VerifyTTL: BITS:8 fReturn(); /* ---------------------------------------------------------------------- * Verify checksum */ checkChecksum: 0b1 0b1 fReturn(); /* check passed */ /* otherwise error handler is called automatically */ /* ---------------------------------------------------------------------- * Main error handler */ MyError: 0b0 BITS:7 FirstPassException(); /* first pass */ MyError: 0b1 BITS:7 SecondPassException(); /* second pass */ /* ---------------------------------------------------------------------- * First pass error handler * Discard */ FirstPassException: fQueueEOF(0:2, 0:19, $offset:6, 0:1, 0:2, 1:1, 0:24); /*---------------------------------------------------------------------- * Second pass error handler * Send PDU to RSP for discard */ SecondPassException: fSkipToEnd() fTransmit (0:1, 0:1, 0:20, 0:16, 0:5, 0:10, 0:24);