Skip to content

Commit

Permalink
Fixed an issue where the Port and REDPort does not drop packets prope…
Browse files Browse the repository at this point in the history
…rly when downstream nodes have zero buffer. (#16)

Co-authored-by: Baochun Li <[email protected]>
  • Loading branch information
kai6808 and baochunli authored Mar 10, 2023
1 parent 9fda532 commit ec2d4af
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 4 deletions.
82 changes: 82 additions & 0 deletions examples/fair_packet_switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""
An very simple example of using the test the packet drop in FairPacketSwitch.
It shows a bug in packet dropping process.
"""
import simpy
from ns.packet.dist_generator import DistPacketGenerator
from ns.packet.sink import PacketSink
from ns.switch.switch import FairPacketSwitch


def packet_arrival():
"""Constant packet arrival interval."""
return 1.0


def const_size():
"""Constant packet size in bytes."""
return 1000.0


env = simpy.Environment()
pg1 = DistPacketGenerator(
env,
"flow_0",
packet_arrival,
const_size,
initial_delay=0.0,
finish=3,
flow_id=0,
rec_flow=True,
)
pg2 = DistPacketGenerator(
env,
"flow_1",
packet_arrival,
const_size,
initial_delay=0.1,
finish=3,
flow_id=1,
rec_flow=True,
)
ps = PacketSink(env)

port_rate = 8000.1 # in bits
buffer_size = 1100 # in bytes

switch = FairPacketSwitch(
env,
nports=1,
port_rate=port_rate,
buffer_size=buffer_size,
weights=[1, 2],
server="DRR",
debug=True,
)
switch.egress_ports[0].limit_bytes = True
pg1.out = switch
pg2.out = switch
switch.demux.fib = {0: 0, 1: 0}
switch.ports[0].out = ps

env.run()

print("\n==========Basic Info==========")

print(
f"The buffer size is {buffer_size} bytes, the port rate is {port_rate / 8} bytes/sec, "
f"and the packet size is {const_size()} bytes."
)

print("==========Result==========")
print("For the switch, the packet arrival times for flow 0 are:")
print(pg1.time_rec)

print("For the switch, the packet arrival times for flow 1 are:")
print(pg2.time_rec)

print("At the packet sink, packet arrival times for flow 0 are:")
print(ps.arrivals[0])

print("At the packet sink, packet arrival times for flow 1 are:")
print(ps.arrivals[1])
16 changes: 12 additions & 4 deletions ns/port/port.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Port:
debug: bool
If True, prints more verbose debug information.
"""

def __init__(self,
env,
rate: float,
Expand Down Expand Up @@ -66,8 +67,9 @@ def update(self, packet):
"""
# There is nothing that needs to be done, just print a debug message
if self.debug:
print(f"Retrieved Packet {packet.packet_id} from flow {packet.flow_id}.")

print(
f"Retrieved Packet {packet.packet_id} from flow {packet.flow_id}."
)

def run(self):
"""The generator function used in simulations."""
Expand All @@ -82,8 +84,7 @@ def run(self):

if self.rate > 0:
yield self.env.timeout(packet.size * 8.0 / self.rate)

self.byte_size -= packet.size
self.byte_size -= packet.size

if self.zero_downstream_buffer:
self.out.put(packet,
Expand All @@ -98,6 +99,13 @@ def run(self):
def put(self, packet):
""" Sends a packet to this element. """
self.packets_received += 1

if self.zero_downstream_buffer:
# If the downstream node has no buffer, packets will be removed
# from this buffer by the downstream node, and the byte size of the
# buffer should be recomputed
self.byte_size = sum(packet.size for packet in self.store.items)

byte_count = self.byte_size + packet.size

if self.element_id is not None:
Expand Down
7 changes: 7 additions & 0 deletions ns/port/red_port.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class REDPort(Port):
debug: bool
If True, prints more verbose debug information.
"""

def __init__(self,
env,
rate: float,
Expand Down Expand Up @@ -91,6 +92,12 @@ def put(self, packet):
""" Sends a packet to this element. """
self.packets_received += 1

if self.zero_downstream_buffer:
# If the downstream node has no buffer, packets will be removed
# from this buffer by the downstream node, and the byte size of the
# buffer should be recomputed
self.byte_size = sum(packet.size for packet in self.store.items)

if self.limit_bytes:
current_queue_size = self.byte_size
else:
Expand Down

0 comments on commit ec2d4af

Please sign in to comment.