import * from qos_includes def __init__(): # internal to run upon QoS initialization global shaping_queue global Tc global Bc global CIR global token_bucket global time_commit token_bucket = 0 time_commit = 0 shaping_queue = INIT_QMBUF() # cir = 1 Gbps, bc = 256 KB CIR = 1000000000 Bc = 256000 # Tc = Bc / CIR, or 2.048 milliseconds in this case. Tc = (Bc * 8) / CIR def token_bucket_filter( a_pkt_size ): global Bc global token_bucket if token_bucket <= 0: return False else: token_bucket -= a_pkt_size return True def process_tx_queue(received_packet): global Tc global Bc global CIR global token_bucket global time_commit global shaping_queue # Main processing loop in the router -- this function is called every clock cycle, non-stop # get byte size of the packet received pkt_size = len(received_packet) time_since = Get_Current_Time() - time_commit if time_since >= Tc: token_bucket += Bc time_commit = Get_Current_Time() ts_active = 0 if len(shaping_queue) > 0: # shaping queue is NOT EMPTY ts_active = 1 if time_since >= Tc: # For every Tc, dequeue the entire egress queue # the *entire* shaping_queue will leave the router at line rate try: XMIT_OUT_IF( shaping_queue ) except InterfaceBusyError: raise TxRing_Exhausted_Exception, TailDrop_M_Exception QMBUF_FREE( shaping_queue ) return False # process new packet received just now ts_active = 0 else: # keep shoving received_packet into the shaping_queue train, until it fills try: ENQUEUE_ADD( shaping_queue, received_packet ) except BufferSchedError: raise TailDropException QMBUF_FREE( received_packet ) return False # shaping queue is EMPTY if ts_active is 0: if self.token_bucket_filter( pkt_size ) is True: # no further action required, send the packet straight to wire. try: XMIT_OUT_IF( received_packet ) except InterfaceBusyError: # interface is locked -- this shouldn't happen, are you setting the CIR higher than the output interface's speed? raise TxRing_Exhausted_Exception, TailDrop_Exception QMBUF_FREE( received_packet ) return False else: # add the received_packet onto shaping_queue ENQUEUE_ADD( shaping_queue, received_packet ) # processing completed successfully return True