Sie sind auf Seite 1von 91

NS-2 Internal Structure and Extension

KAIST
(swkim@cnlab.kaist.ac.kr)

Contents
Internal structure of NS-2 objects NS-2 Extension using OTcl object inheritance NS-2 Extension using C++ object inheritance Debugging

Original Materials from


http://www.isi.edu/nsnam/dist/ns-workshop00/ http://www.isi.edu/nsnam/ns/ns-tutorial/tutorial-02/index.html Network Laboratory ns-2 tutorial by Changhee Joo (http://netlab.snu.ac.kr/, http://web.ics.purdue.edu/~cjoo/)
2

Contents Internal structure of NS-2 objects


NS-2 Extension using OTcl object inheritance NS-2 Extension using C++ object inheritance Debugging

Ns Internals
Tcl commands translates into
series of object creation plumbing of these objects

Step-by-step review of how each network component gets set up in ns


Network Topology: Node, Link Routing Transport: Agent Packet flow Packet format
4

Hierarchy of Network Components


TclObject NsObject Connector Queue Delay Agent TCP SACK
5

Handler

Classifier Trace AddrClassifier McastClasifier Drop

DropTail RED

Enq Deq

Reno

TclObject & NsObject


TclObject
Defined in $ns/../tclcl-1.15/{tclcl.h, Tcl.cc} Functions of command, trace, bind

NsObject
Defined in $ns/common/object.{h, cc} Inherit class TclObject Functions of recv, handle, reset
handle(Event *e) { recv(Packet *e); }

Connector
Single input, single output
Used for normal packet processing Examples: Queue, Agent, Delay, Trace

Defined in $ns/common/connector.{h, cc} Variables: send(p,h) recv(p,h)


NsObject* target_

Functions

Connector

send(Packet* p, Handler* h) {target_->recv(p,h);} recv(Packet* p, Handler* h) {send(p,h);} drop(Packet* p) {Packet::free(p);}


7

Classifier
Single input, multiple output
Used for routing Examples: AddrClassifier, PortClassifier

Defined in $ns/classifier/classifier.{h, cc} Variables: Functions


NsObject** slot_ NsObject* default_target_
Classifier

install(int slot, NsObject* p) {slot_[slot] = p;} find(Packet* p) {return slot_[classify(p)];} recv(Packet* p, Handler* h) {

NsObject* node = find(p); node->recv(p, h); }

Network Topology: Node


n0
Port Classifier Addr Classifier Node entry entry_ classifier_

n1 Unicast Node Multicast Node classifier_


Node entry entry_ dmux_

dmux_

0 1
Multicast Classifier multiclassifier_

set n0 [$ns_ node]

set ns_ [new Simulator multicast on] set n1 [$ns_ node]

Defined in $ns/common/node.{h, cc}, $ns/tcl/lib/ns-node.tcl Standalone class in Otcl Most components are TclObjects

Node Addressing
Two basic address styles available:
flat and hierarchical

Default flat address:


32 bits each for node and port id

Default hier address:


3 levels of hierarchy 10 11 11 or 1 9 11 11 if mcast specified

Different bit allocation possible for specific hier addresses

10

Hierarchical Node
n2

Address classifier Node entry Level 3 Level 2 Level 1

To Port demux

$ns_ node-config addressing hier


11

Network Topology: Link


[$ns_ duplex-link $n0 $n1 5Mb 2ms drop-tail] n0 duplex link n1

head_

enqT_ tracing

queue_
drophead_

deqT_
drpT_

link_

ttl_ simplex link

n1 entry_

Defined in $ns/tcl/lib/ns-link.tcl Standalone class in Otcl

12

Queue
Location where packets may be held or dropped Implement
Packet scheduling CBQ, FQ, SFQ, DRR Buffer Management drop-tail(FIFO), RED

Defined in $ns/queue/queue.{h, cc}


Inherit class Connector Include an instance of PacketQueue Virtual functions of enque and deque
recv calls enque resume calls deque and target_->recv

Queue
recv enque

PacketQueue deque

resume
13

Queue blocking
Queue is blocked (stop transmitting)
When a packet is in transit

Transmit a packet with queue handler


target_->recv(p, &ph_); target_ (LinkDelay) is responsible for scheduling the handler after transmission Hander calls resume

14

Transport
n0
Port Classifier Addr Classifier dst_=1.0 Agent/TCP agents_ entry_ classifier_ classifier_

n1
Port Classifier Addr Classifier dst_=0.0 Agent/TCPSink agents_

0
dmux_

0
dmux_

0
entry_

set tcp [new Agent/TCP] $ns_ attach-agent $n0 $tcp

set tcpsink [new Agent/TCPSink] $ns_ attach-agent $n1 $tcpsink


15

$ns_ connect $tcp $tcpsink

Agent
Defined in $ns/common/agent.{h,cc} & $ns/tcl/lib/ns-agent.tcl Internal states
Node address Destination address Fixed packet size Type in packet header (protocol type) IP flow ID, priority, Flags

16

Agent Functions
Packet allocation
allocpkt()

Main entry point


recv(Packet*, Handler*) For incoming and/or outgoing packets
TcpAgent for incoming ACK, PingAgent for both

Packet forwarding
send(Packet* p, Handler* h) {

target_->recv(p, h);

17

Application: Traffic Generator


n0
Port Classifier Addr Classifier Application/FTP dst_=1.0 Agent/TCP agents_ entry_ classifier_ classifier_

n1
Port Classifier Addr Classifier dst_=0.0 Agent/TCPSink agents_

0
dmux_

0
dmux_

0
entry_

set ftp [new Application/FTP] $ftp attach-agent $tcp $ns at 1.2 $ftp start
18

Routing
n0
Port Classifier Addr Classifier Node entry entry_ Application/FTP Agent/TCP agents_ head_ enqT_ queue_ drophead_ deqT_ drpT_ link_ ttl_ n1 entry _

n1

0
dmux_

0 1
classifier_

19

Routing (cont)
n0
Port Classifier Addr Classifier agents_ dmux_ Link n0-n1 entry_ Application/FTP Agent/TCP

n1
Port Classifier Addr Classifier Agent/TCP

0
entry_

1 0
classifier_

dmux_

1
classifier_

Link n1-n0

20

Routing
Three function blocks
Routing agent
Exchange routing packets

Route logic
Perform actual route computation

Classifier
Forward packet

21

Routing module (RtModule)


Routing Module
Manage function blocks Interface with node to organize its own classifier

Functionalities
Management register/unregister at node Routing add/delete-route Transport attach/detach agent

Node configures its classifiers through RtModule


22

When add-route?
$ns run
$ns/tcl/lib/ns-{lib, rtmodule, route}.tcl Simulator get-routelogic
New RouteLogic

RouteLogic configure
Agent/rtProto/Static init-all (or other rtProto) Simulator compute-routes Simulator compute-flat-routes (or hier0routes)

RouteLogic compute Simulator populate-flat-classifier


Node add-route (for each node)
23

Plumbing: Packet Flow


n0
Port Classifier Addr Classifier Application/FTP dst_=1.0 Agent/TCP

n1
Port Classifier Addr Classifier Link n0-n1 entry_ dst_=0.0 Agent/TCPSink

0
entry_

1 0

Link n1-n0

24

Packet
Fundamental unit of exchange between objects
Information to link a packet on to a list or queue Contain packet headers

Packet Header
Per-protocol information New protocols may define their own header or may extend existing headers
25

Packet Format

cmn header header data ip header tcp header rtp header trace header ...

ts_ ptype_ uid_ size_ iface_

26

Wireless Network Components


Packet headers Mobile node Wireless channel Forwarding and routing

27

Wireless Packet Format


cmn header header data IP header ...... LL MAC 802_11 ARP ......
28

ts_ ptype_ uid_ size_ iface_ wireless headers

Mobile Node Abstraction


Location
Coordinates (x,y,z)

Movement
Speed, direction, starting/ending location, time ...

29

Portrait of A Mobile Node


Node
port classifier protocol agent 255 addr defaulttarget_ classifier LL IFQ routing agent

Classifier: Forwarding Agent: Protocol Entity Node Entry


LL

ARP

LL: Link layer object IFQ: Interface queue MAC: Mac object PHY: Net interface
30

IFQ

MAC PHY Propagation and antenna models MAC PHY

MobileNode
CHANNEL

Mobile Node: Components


Link Layer
Same as LAN, but with a separate ARP module

Interface queue
Give priority to routing protocol packets

Mac Layer
IEEE 802.11 RTS/CTS/DATA/ACK for all unicast packets DATA for all broadcast packets

31

Mobile Node: Components


Network interface (PHY)
Parameters based on Direct Sequence Spread Spectrum (WaveLan) Interface with: antenna and propagation models Update energy: transmission and reception

Radio Propagation Model


Friss-space attenuation(1/r2) at near distance Two-ray Ground (1/r4) at far distance

Antenna
Omni-directional, unity-gain
32

Wireless Channel
Duplicate packets to all mobile nodes attached to the channel except the sender It is the receivers responsibility to decide if it will accept the packet

33

Contents
Internal structure of NS-2 objects

NS-2 Extension using OTcl object inheritance


NS-2 Extension using C++ object inheritance Debugging

34

ns Directory Structure
ns-allinone Tcl8.3 TK8.3 OTcl tcl ex
examples

tclcl ... lib

ns-2

nam-1

C++ code

test
validation tests

mcast
OTcl code

...

35

Extending ns in OTcl
If you dont want to compile
source your changes in your sim scripts

Otherwise
Modifying code; recompile Adding new files
Change Makefile (NS_TCL_LIB), tcl/lib/ns-lib.tcl Recompile

36

Example: Agent/Message

C
cross traffic

n2 n0 n3
128Kb, 50ms

n4 n1
10Mb, 1ms

10Mb, 1ms

S
msg agent

n5

37

Agent/Message
pkt: 64 bytes of arbitrary string Receiver-side processing

A UDP agent (without UDP header) Up to 64 bytes user message Good for fast prototyping a simple idea Usage requires extending ns functionality 38

Agent/Message: Step 1
Define sender
Class Sender superclass Agent/Message
# Message format: Addr Op SeqNo Sender instproc send-next {} { $self instvar seq_ agent_addr_ $self send $agent_addr_ send $seq_ incr seq_ global ns $ns at [expr [$ns now]+0.1] "$self send-next" }

39

Agent/Message: Step 2
Define sender packet processing
Sender instproc recv msg { $self instvar agent_addr_ set sdr [lindex $msg 0] set seq [lindex $msg 2] puts "Sender gets ack $seq from $sdr" }

40

Agent/Message: Step 3
Define receiver packet processing
Class Receiver superclass Agent/Message Receiver instproc recv msg { $self instvar agent_addr_ set sdr [lindex $msg 0] set seq [lindex $msg 2] puts Receiver gets seq $seq from $sdr $self send $agent_addr_ ack $seq }

41

Agent/Message: Step 4
Scheduler and tracing
# Create scheduler set ns [new Simulator] # Turn on Tracing set fd [open message.tr w] $ns trace-all $fd

42

Agent/Message: Step 5
Topology
for {set i 0} {$i < 6} {incr i} { set n($i) [$ns node] } $ns duplex-link $n(0) $n(1) 128kb 50ms DropTail $ns duplex-link $n(1) $n(4) 10Mb 1ms DropTail $ns duplex-link $n(1) $n(5) 10Mb 1ms DropTail $ns duplex-link $n(0) $n(2) 10Mb 1ms DropTail $ns duplex-link $n(0) $n(3) 10Mb 1ms DropTail $ns queue-limit $n(0) $n(1) 5 $ns queue-limit $n(1) $n(0) 5

43

Agent/Message: Step 6
Routing
# Packet loss produced by queueing # Routing protocol: lets run distance vector $ns rtproto DV

44

Agent/Message: Step 7
Cross traffic
set $ns set $ns $ns udp0 [new Agent/UDP] attach-agent $n(2) $udp0 null0 [new Agent/Null] attach-agent $n(4) $null0 connect $udp0 $null0

set exp0 [new Application/Traffic/Exponential] $exp0 set rate_ 128k $exp0 attach-agent $udp0 $ns at 1.0 $exp0 start

45

Agent/Message: Step 8
Message agents
set sdr [new Sender] $sdr set seq_ 0 $sdr set packetSize_ 1000 set rcvr [new Receiver] $rcvr set packetSize_ 40 $ns $ns $ns attach-agent attach-agent connect $sdr $n(3) $sdr $n(5) $rcvr $rcvr

$ns at 1.1 $sdr send-next

46

Agent/Message: Step 9
End-of-simulation wrapper (as usual)
$ns at 2.0 finish proc finish {} { global ns fd $ns flush-trace close $fd exit 0 } $ns run

47

Agent/Message: Result
Example output
% ./ns msg.tcl
Receiver gets seq Sender gets ack 0 Receiver gets seq Sender gets ack 1 Receiver gets seq Sender gets ack 2 Receiver gets seq Sender gets ack 4 Receiver gets seq 0 from from 5 1 from from 5 2 from from 5 4 from from 5 7 from 3 3 3 3 3
48

Add Your Changes into ns


ns-allinone Tcl8.3 TK8.3 OTcl tcl ex
examples

tclcl ... lib

ns-2

nam-1

C++ code

test
validation tests

mysrc msg.tcl

mcast
OTcl code

...

49

Add Your Change into ns


tcl/lib/ns-lib.tcl
Class Simulator source ../mysrc/msg.tcl

Makefile
NS_TCL_LIB = \ tcl/mysrc/msg.tcl \ Or: change Makefile.in, make distclean, then ./configure --enable-debug , make depend and make

50

Contents
Internal structure of NS-2 objects NS-2 Extension using OTcl object inheritance

NS-2 Extension using C++ object inheritance


Debugging

51

Extending ns in C++
Modifying code
make depend Recompile

Adding code in new files


Change Makefile make depend recompile

52

Creating New Components


Guidelines Two styles
New agent based on existing packet headers Add new packet header

53

Guidelines
Decide position in class hierarchy
i.e., which class to derive from?

Create new packet header (if necessary) Create C++ class, fill in methods Define OTcl linkage (if any) Write OTcl code (if any) Build (and debug)

54

New Agent, Existing Header


TCP jump start
Wide-open transmission window at the beginning From cwnd_ += 1 To cwnd_ = MAXWIN_

55

TCP Jump Start Step 1


TclObject NsObject Connector Queue Delay Agent TCP SACK Trace Classifier AddrClassifier McastClasifier Drop Handler

DropTail RED

Enq Deq JS

Reno

56

Reminder: C++/OTcl Linkage


$ns/tcp/tcp.{h,cc} class TcpAgent : public Agent { public: Class Definition TcpAgent(); } static class TcpClass: public TclClass { public: TcpClass() : TclClass(Agent/Tcp){} TclClass TclObject* create(int , const char*const*) { return (new TcpAgent()); } } class_tcp;
57

Reminder: C++/OTcl Linkage


$ns/tcp/tcp.{h,cc} TcpAgent::TcpAgent(): Agent(PT_TCP), { bind_(t_seqno_, &t_seqno_); } int TcpAgent::command(int argc, const char*const* argv){ if (argc == 3) { if (strcmp(argv[1], advance) == 0) { } } } $ns/tcl/lib/ns-agent.tcl: Agent/TCP instproc init {} { } $ns/tcl/lib/ns-default.tcl: Agent/TCP set t_seqno_ 0

Class Body

Otcl setting
58

TCP Jump Start Step 2


New file: tcp-js.h
#include tcp.h
class JSTCPAgent : public TcpAgent { public: virtual void set_initial_window() { cwnd_ = MAXWIN_; } private: int MAXWIN_; };
59

TCP Jump Start Step 3


New file: tcp-js.cc
#include <tclcl.h> #include tcp.h #include tcp-js.h static class JSTcpClass : public TclClass { public: JSTcpClass() : TclClass("Agent/TCP/JS") {} TclObject* create(int, const char*const*){ return (new JSTcpAgent()); } } tcpjs_agent; JSTcpAgent::JSTcpAgent() { bind(MAXWIN_, &MAXWIN_); }

60

TCP Jump Start Step 4


Set default value of MAXWIN_ in tcl
$ns/tcl/lib/ns-default.tcl Agent/TCP/JS set MAXWIN_ 1

Add tcp-js.o in Makefile.in


$ns/Makefile.in OBJ_CC = ... tcp/tcp-js.o @V_STOLOBJ@

Re-configure, make depend and recompile


% configure --enable-debug with-tcldebug=../tcl-debug-2.0 % make depend % make

61

TCP Jump Start Step 5


Create an instance of jump-start TCP in your tcl script tcp-js.tcl
set tcp [new Agent/TCP/JS]

Set value of MAXWIN_ for the simulation


e.g., $tcp set MAXWIN_ 10;# set MAXWIN_ value to 10

Run:
% ns tcp-js.tcl

62

TCP vs TCP-JS
Packet sequence number

time

time

TCP: initial cwnd = 1

TCP-JS: initial cwnd = 10 63

New Packet Header


Create new header structure Enable tracing support of new header Create static class for OTcl linkage (packet.h) Enable new header in OTcl (tcl/lib/nspacket.tcl) This does not apply when you add a new field into an existing header!

64

Packet Format

cmn header header data ip header tcp header rtp header trace header ...

ts_ ptype_ uid_ size_ iface_

65

How Packet Header Works


Packet next_ hdrlen_ bits_
PacketHeader/Common

size determined hdr_cmn at compile time PacketHeader/IP size determined at compile time size determined at compile time
66

size determined at simulator startup time


(PacketHeaderManager)

hdr_ip
PacketHeader/TCP

hdr_tcp

Example: Agent/Message
New packet header for 64-byte message New transport agent to process this new header

67

New Packet Header Step 1


Create header structure Construct your own fields Define offset_ and access function struct hdr_msg { char msg_[64]; static int offset_; inline static int& offset() { return offset_; } inline static hdr_msg* access(Packet* p) { return (hdr_msg*) p->access(offset_); } /* per-field member functions */ char* msg() { return (msg_); } int maxmsg() { return (sizeof(msg_)); } };
68

New Packet Header Step 2


Create a static class performing Otcl linkage
Bind offset_ using bind_offset in its constructor

PacketHeader/Message
static class MessageHeaderClass : public PacketHeaderClass { public: MessageHeaderClass() : PacketHeaderClass("PacketHeader/Message", sizeof(hdr_msg)) { bind_offset(&hdr_msg::offset_); } } class_msghdr;

69

New Packet Header Step 3


Enable tracing (packet.h):
enum packet_t { PT_TCP, , PT_MESSAGE, // Packet Type PT_NTYPE // This MUST be the LAST one }; class p_info { name_[PT_MESSAGE] = message; name_[PT_NTYPE]= "undefined"; };
70

New Packet Header Step 4


Register new header (tcl/lib/ns-packet.tcl)
foreach prot { Common Message # Protocol name }{ add-packet-header $prot }

71

Accessing the Header Step 5


hdr_msg* mh = hdr_msg::access(p);
Calls p->access with offset_ of Message Returns starting location of Message header

Accesssing Message structure


mh->msg()

72

Agent/Message Step 1
TclObject NsObject Connector Queue Delay Agent TCP Trace Classifier AddrClassifier McastClasifier Drop

DropTail RED

Message Enq Deq

Reno

SACK
73

Agent/Message Step 2
C++ class definition
// Standard split object declaration static class MessageAgent : public Agent { public: MessageAgent() : Agent(PT_MESSAGE) {} virtual int command(int argc, const char*const* argv); virtual void recv(Packet*, Handler*); };

static class MessageClass : public TclClass { public: MessageClass() : TclClass("Agent/Message") {} TclObject* create(int, const char*const*) { return (new MessageAgent()); } } class_message;

74

Agent/Message Step 3
Packet processing: send
int MessageAgent::command(int, const char*const* argv) { Tcl& tcl = Tcl::instance(); if (strcmp(argv[1], "send") == 0) { Packet* pkt = allocpkt(); hdr_msg* mh = hdr_msg::access(pkt); // We ignore message size check... strcpy(mh->msg(), argv[2]); send(pkt, 0); return (TCL_OK); } return (Agent::command(argc, argv)); }
75

Agent/Message Step 4
Packet processing: receive
void MessageAgent::recv(Packet* pkt, Handler*) { hdr_msg* mh = hdr_msg::access(pkt); // OTcl callback char wrk[128]; sprintf(wrk, "%s recv {%s}", name(), mh->msg()); Tcl& tcl = Tcl::instance(); tcl.eval(wrk); Packet::free(pkt); }

76

Contents
Internal structure of NS-2 objects NS-2 Extension using OTcl object inheritance NS-2 Extension using C++ object inheritance

Debugging
OTcl/C++, memory

77

Debugging C++ in ns
C++/OTcl debugging Memory debugging
purify dmalloc

78

C++/OTcl Debugging
Usual technique
Break inside command() Cannot examine states inside OTcl!

Solution
Execute tcl-debug inside gdb

79

C++/OTcl Debugging
(gdb) call Tcl::instance().eval(debug 1) 15: lappend auto_path $dbg_library dbg15.3> w *0: application 15: lappend auto_path $dbg_library dbg15.4> Simulator info instances _o1 dbg15.5> _o1 now 0 dbg15.6> # and other fun stuff dbg15.7> c (gdb) where #0 0x102218 in write() ......

80

Memory Debugging in ns
Purify
Set PURIFY macro in ns Makefile Usually, put -colloctor=<ld_path>

Gray Watsons dmalloc library


http://www.dmalloc.com make distclean ./configure --with-dmalloc=<dmalloc_path> Analyze results: dmalloc_summarize

81

dmalloc: Usage
Turn on dmalloc
alias dmalloc eval dmalloc C !*` dmalloc -l log low

dmalloc_summarize ns < logfile


ns must be in current directory Itemize how much memory is allocated in each function

82

Pitfalls
Scalability vs flexibility
Or, how to write scalable simulation?

Memory conservation tips Memory leaks

83

Scalability vs Flexibility
Its tempting to write all-OTcl simulation
Benefit: quick prototyping Cost: memory + runtime

Solution
Control the granularity of your split object by migrating methods from OTcl to C++

84

THE Merit of OTcl


high

Program size, complexity C/C++ split objects OTcl

low

Smoothly adjust the granularity of scripting to balance extensibility and performance With complete compatibility with existing simulation scripts

85

Object Granularity Tips


Functionality
Per-packet processing C++ Hooks, frequently changing code OTcl

Data management
Complex/large data structure C++ One-time configuration variables OTcl

86

Memory Conservation Tips


Remove unused packet headers Avoid trace-all Use arrays for a sequence of variables
Instead of n$i, say n($i) n$i

Avoid OTcl temporary variables Use dynamic binding


delay_bind() instead of bind() See object.{h,cc}
87

Memory Leaks
Purify or dmalloc, but be careful about split objects:
for {set i 0} {$i < 500} {incr i} { set a [new RandomVariable/Constant] }

It leaks memory, but cant be detected!

Solution
Explicitly delete EVERY split object that was new-ed
88

Final Word
When extended ns dumps OTcl scripts!
Find the last 10-20 lines of the dump Is the error related to _o*** cmd ?
Check your command()

Otherwise, check the OTcl script pointed by the error message

89

Thank you

Installing tcl-debug in ns-2


1. tcl-debug-2.0 http://www.isi.edu/nsnam/ns/ns-debugging.html Tcl-level Debugging tcl-debug.tar.gz ns-2.2x parallel ~/ns-allinone-2.2x/tcl-debug-2.0 tcl-debug-2.0/INSTALL 1$ ./configure --enable-gcc 2$ make 3$ make install 2. ns-2.2x tcl-debug ns-2.2x/ns_tclsh.cc // tcldbg.h include 29th line : #include "tcldbg.h // // TclAppInit(Tcl ...) Tcldbg_Init(interp); 42nd line : Tcl::init(interp, "ns"); 43rd line : Tcldbg_Init(interp); // ns-2.2x 1$ ./configure --enable-debug --with-tcldebug=../tcl-debug-2.0 2$ make depend 3$ make
91

Das könnte Ihnen auch gefallen