1 / 62

NS Tutorial

NS Tutorial. PMIPv6 Implementation in NS HyonYoung Choi (commani@gmail.com). 목차. NS 기초 PMIPv6 Implementation. NS 기초. Tcl 와 C++ 의 연관관계. Tcl Object 와 C++ Object 의 매핑 일반적으로 Tcl Object 당 C++ Object 가 존재 TclClass 가 Tcl 에서 C++ object 를 만들 수 있도록 해줌

sadah
Download Presentation

NS Tutorial

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. NS Tutorial PMIPv6 Implementation in NS HyonYoung Choi (commani@gmail.com)

  2. 목차 • NS 기초 • PMIPv6 Implementation

  3. NS 기초

  4. Tcl와 C++의 연관관계 • Tcl Object와 C++ Object의 매핑 • 일반적으로 Tcl Object당 C++ Object가 존재 • TclClass가 Tcl에서 C++ object를만들 수 있도록 해줌 • TclClass의 생성자 인수가 Tcl에서 사용가능한 Object 이름 set mag [new Agent/PMIPv6/MAG] static class MAGAgentClass : public TclClass { public: MAGAgentClass() : TclClass("Agent/PMIPv6/MAG") {} TclObject* create(int, const char*const*) { return (new MAGAgent()); } } class_magagent; class MAGAgent : public PMIPv6Agent { public: MAGAgent(); …… };

  5. NS의 함수(1/4) • 함수의 정의 • Tcl: instproc를 사용하여 정의 • C++: TclObject class의 command 함수 overriding후 if-else-if로 string match Classifier/Addr/PMIPv6Dest instproc install {dst target} { $self instvar classifier_ $classifier_ install $dst $target } int MAGAgent::command(int argc, const char*const* argv) { if(argc==3) { if(strcmp(argv[1], "new-mn") == 0) { …… return TCL_OK; } else if(strcmp(argv[1], "set-lmaa") == 0) { …… return (PMIPv6Agent::command(argc, argv)); }

  6. NS의 함수(2/4) • Tcl 함수와 C++ 함수의 장단점

  7. NS의 함수(3/4) • Tcl 함수와 C++ 함수의 상호접근 • 함수 호출의 우선순위: Tcl > C++ • Tcl의 함수에서 찾은 뒤 없으면 C++의 command 함수 호출 • Tcl과 C++에 같은 이름의 함수가 있는 경우 • Tcl의 함수 호출: 일반적인 함수 호출 • C++의 함수 호출: 함수이름 앞에 “cmd”를 추가 Classifier/Addr/PMIPv6Dest instproc clear { dst } { $self instvar classifier_ $classifier_ clear $dst } Classifier/Addr/PMIPv6Dest instproc clear-by-dest { addr } { $self cmd clear $addr }

  8. NS의 함수(4/4) • Tcl 함수와 C++ 함수의 상호접근 (cont’d) • C++에서 Tcl 함수 호출 • Tcl::eval, Tcl::evalf 함수 사용 • C++에서 Tcl 함수의 결과값 얻기 • Tcl::result 함수 사용 • C++ 함수에서 Tcl로 결과값 반환(return) • Tcl::resultf 함수 사용 Tcl& tcl = Tcl::instance(); tcl.evalf("%s setup-route %ld %ld", name(), bule->mn_prefix(), bule->lmaa()); tcl.evalf ("%s getRXThresh",netif_->name()); RXThreshold_ = atof (tcl.result()); if (strcmp(argv[1], "ifq") == 0) { tcl.resultf("%s", ifq_->name()); return (TCL_OK); }

  9. 새로운 packet type 만들기(1/4) • 1. Packet 헤더 작성 • offset_, offset(), access(Packet *p) 작성 (필수) • HDR_XXX define 작성 (옵션) • offset_이 static이므로 C++소스 파일에 선언 #define HDR_PMIPv6((p) ((struct hdr_pmipv6*)(p)->access(hdr_pmipv6::offset_)) struct hdr_pmipv6 { ……(패킷 헤더의 필드들) static int offset_; inline static int& offset() { return offset_; } inline static hdr_pmipv6* access(Packet* p) { return (hdr_pmipv6*) p->access(offset_); } }; int hdr_pmipv6::offset_;

  10. 새로운 packet type 만들기(2/4) • 2. PacketHeaderClass 작성 • Packet Manager용 class 작성 • 3. ns-packet.tcl 수정 (ns-2.29/tcl/lib/) • PacketHeaderClass 생성자의 이름과 일치해야 함 static class PMIPv6HeaderClass : public PacketHeaderClass { public: PMIPv6HeaderClass() : PacketHeaderClass("PacketHeader/PMIPv6", sizeof(hdr_pmipv6)) { bind_offset(&hdr_pmipv6::offset_); } } class_pmipv6hdr; foreach prot { …… PMIPv6 } { add-packet-header $prot }

  11. 새로운 packet type 만들기(3/4) • 4. packet.h 수정 (ns-2.29/common/) • enum packet_t의 PT_NTYPE 전에 넣음 • name_ 작성: trace에 표시되는 패킷 type enum packet_t { …… //PMIP6: type PT_PBU, PT_PBACK, PT_NTYPE // This MUST be the LAST one }; p_info() { …… name_[PT_PBU]="pbu"; name_[PT_PBACK]="pba"; name_[PT_NTYPE]= "undefined"; }

  12. 새로운 packet type 만들기(4/4) • 패킷 생성 • allockpkt 함수 사용 • hdr_cmn 정보 반드시 채울 것 • size: 실제 전송되는 총 패킷 크기 • ptype: packet type Packet *p = allocpkt(); hdr_cmn *hdrc = HDR_CMN(p); hdr_ip *iph = HDR_IP(p); hdr_pmipv6 *h = HDR_PMIPv6(p); hdrc->size() = IPv6_HEADER_SIZE; hdrc->ptype() = PT_PBU; hdrc->size() += PBU_SIZE; iph->saddr() = proxy_coa; iph->sport() = port(); ……

  13. List 관리 – Tcl (1/2) • 배열로 처리 (index에 문자도 가능) • 중복처리를 쉽게 할 수 있음 • 간단한 형태만 가능 • 1. List 추가 • 덮어 쓰는 경우는 바로 추가 • 이미 존재하면 에러인 경우는 이미 있는지 검사 • info exists 사용 Node instproclistadd {index value} { $self instvar List_ if { ! [info exists List_($index)] || $List_($index)==“”} { set List_($index) $value } }

  14. List 관리 – Tcl (2/2) • 2. List 제거 • 존재 하는 경우 “”로 만들거나 unset Node instproc listdel {index} { $self instvar List_ if { [info exists List_($index)] && $List_($index)!=“”} { set List_($index) “” unset List_($index) } }

  15. List 관리 - C++ (1/2) • List 관련매크로 활용 • 1. LIST_HEAD 정의 • 데이터 클래스와 그에 연결되는 head 정의 • 2. 리스트 각 entry 내용 정의 • insert_entry. next_entry, remove_entry, link 정의 class BULEntry; LIST_HEAD(bulEntry, BULEntry); class BULEntry { …… public: inline void insert_entry(struct bulEntry *head) { LIST_INSERT_HEAD(head, this, link); } BULEntry* next_entry(void) const { return link.le_next; } inline void remove_entry() { LIST_REMOVE(this, link); } protected: LIST_ENTRY(BULEntry) link; };

  16. List 관리 - C++ (2/2) • 3. List 사용 • List 변수 정의 • List에 추가 • List에서 찾기 class MAGAgent : public PMIPv6Agent { …… struct bulEntry bul_list_; void MAGAgent::process_new_mn(int32_t mn_id) { …… bule->insert_entry(&bul_list_); BULEntry *MAGAgent::find_bule(int32_t mn_id) { for(BULEntry *bule=bul_list_.lh_first; bule; bule=bule->next_entry()) { if(bule->mn_id() == mn_id) return bule; } return NULL; }

  17. Timer 관리 - Tcl • ns simulator의 at 함수 활용 • 1. timeout시 실행될 함수 정의 • 2. Timer 시작과중단 Node instproc record {} { set ns [Simulator instance] …….. } Node instproc start { mnaddr } { $self instvar RTimer_ set ns [Simulator instance] set now [$ns now] if {![info exists RTimer_($mnaddr)] || $RTimer_($mnaddr) == ""} { $ns at [expr $now + 1.0] “$self record” } } Node instproc stop { mnaddr } { $self instvar RTimer_ set ns [Simulator instance] if {[info exists RTimer_($mnaddr)] && $RTimer_($mnaddr) != ""} { $ns cancel $RTimer_($mnaddr) set Rtimer_($mnaddr) “” } }

  18. Timer 관리 – C++ (1/2) • TimerHandler를 사용하여 구현 • 1. TimerHandler를상속한 클래스 정의 • 생성자에 호출할 정보를 넣도록 작성 • expire 함수를 반드시 overriding class BindingTimer : public TimerHandler { public: BindingTimer(PMIPv6Agent *pagent, void *data): TimerHandler() { pagent_ = pagent; data_ = data; } protected: PMIPv6Agent *pagent_; void *data_; void expire(Event *); };

  19. Timer 관리 – C++ (2/2) • 2. expire 함수 정의 • Timer를 설정해 놓으면 지정된 시간 이후 호출되는 함수 • 생성자로 받은 정보를 사용해 원하는 작업 수행 • 3. timer 시작과 중단 하기 • resched 함수와 cancel 함수 사용 void BindingTimer::expire(Event *) { pagent_->BindingTimeout(data_); } bule->BULTimer_.resched(1.0); bule->BULTimer_.cancel ();

  20. PMIPv6 Implementation

  21. PMIPv6 Objects (1/2) • PacketHeader/PMIPv6 (struct hdr_pmipv6) • PBU, PBACK 패킷을 위한 헤더 • PacketHeader/IP6Encap (struct hdr_ip6encap) • IPv6-in-IPv6 패킷을 위한 헤더 • Agent/PMIPv6 (class PMIPv6Agent) • LMA와 MAG의 상위 클래스 • Agent/PMIPv6/LMA (class LMAAgent) • LMA Agent • Agent/PMIPv6/MAG (class MAGAgent) • MAG Agent

  22. PMIPv6 Objects (2/2) • PMIPv6Encapsulator (class PMIPv6Encapsulator) • IPv6-in-IPv6 Encapsulator • Classifier/Addr/PMIPv6Src (class PMIPv6Src) • Source address based routing • Classifier/Addr/PMIPv6Dest (class PMIPv6Dest) • Destination address routing • Classifier/Addr/PMIPv6Decapsulator (class PMIPv6Decapsulator) • IPv6-in-IPv6 Decapsulator

  23. PMIPv6 example script

  24. General Initialization • Hierarchical routing • MN 패킷이 LMA로 routing 되도록 하기 위함 • Wireless configuration # set up for hierarchical routing (needed for routing over a basestation) $ns node-config -addressType hierarchical AddrParams set domain_num_ 5 ;# domain number AddrParams set cluster_num_ {1 1 1 1 1} AddrParams set nodes_num_ {1 2 1 1 1} # Parameter for wireless nodes set opt(chan) Channel/WirelessChannel ;# channel type set opt(prop) Propagation/TwoRayGround ;# radio-propagation model set opt(netif) Phy/WirelessPhy ;# network interface type set opt(mac) Mac/802_11 ;# MAC type set opt(ifq) Queue/DropTail/PriQueue ;# interface queue type set opt(ll) LL ;# link layer type set opt(ant) Antenna/OmniAntenna ;# antenna model set opt(ifqlen) 50 ;# max packet in ifq set opt(adhocRouting) DSDV ;# routing protocol

  25. PMIPv6 Initialization (1/8) • LMA • LMA Node 생성 후 install-lma 함수 호출 • 주의사항: duplex-link 호출 전에 install-lma 호출 set lma [$ns node 1.0.0] #attach Agent/PMIPv6/LMA to the LMA set lma_pm [$lma install-lma] #BE CAREFUL!. PMIPv6 agent must be installed before connecting link(duplex-link) $ns duplex-link $lma $router 100Mb $opt(dfLinkDelay) DropTail

  26. PMIPv6 Initialization (2/8) • LMA (cont’d) • install-lma 함수

  27. PMIPv6 Initialization (3/8) • install-lma 함수 Node instproc install-lma {} { $self instvar classifier_ decap_ dmux_ agents_ $self instvar pmip6_agent_ $self instvardst_classifier_ old_classifier_ #attach pmip6 agent set lma [new Agent/PMIPv6/LMA] $self attach $lma [$lma set default_port_] set pmip6_agent_ $lma #attach dest classifier set old_classifier_ $classifier_ set dst_classifier_ [new Classifier/Addr/PMIPv6Dest] $dst_classifier_ set mask_ 0xffffffff $dst_classifier_ set shift_ 0 $dst_classifier_ defaulttarget $old_classifier_

  28. PMIPv6 Initialization (4/8) • install-lma 함수 (cont’d) set nodetype [[Simulator instance] get-nodetype] $self insert-entry [$self get-module $nodetype] $dst_classifier_ $dst_classifier_ install-by-dest 0 $old_classifier_ #attach decapsulator set decap_ [new Classifier/Addr/PMIPv6Decapsulator] $decap_ set mask_ 0xffffffff $decap_ set shift_ 0 $decap_ defaulttarget $dst_classifier_ lappend $agents_ $decap_ $dmux_ install [Simulator set PMIPv6_TUNNEL_PORT] $decap_ return $lma }

  29. PMIPv6 Initialization (5/8) • MAG • NIST settings: bssid, channel, beacon 설정 • install-mag 호출 • set-lmaa 호출: LMA Address 지정 • 802.11 MAC에 trigger를 위한 설정 set mag1 [$ns node 3.0.0] $mag1 random-motion 0 $mag1 set X_ 100.0 $mag1 set Y_ 200.0 $mag1 set Z_ 0.0 #NIST settings set mag1_mac [$mag1 getMac 0] set mag1_addr [$mag1_mac id] $mag1_mac bss_id $mag1_addr $mag1_mac set-channel 1 $mag1_mac enable-beacon #install PMIPv6/MAG agent to the MAG1 set mag1_pm [$mag1 install-mag] set lmaa [$lma node-addr] $mag1_pm set-lmaa [AddrParams addr2id $lmaa] #setup 802.11 MAC to support MN ATTACH Event $mag1_mac set use_pmip6_ext_ 1 $mag1_mac pmip6-agent $mag1_pm $ns duplex-link $mag1 $router 100Mb $opt(dfLinkDelay) DropTail

  30. PMIPv6 Initialization (6/8) • MAG (cont’d)

  31. PMIPv6 Initialization (7/8) • install-mag 함수 Node instproc install-mag {} { $self instvar classifier_ dmux_ agents_ ll_ $self instvar pmip6_agent_ $self instvar src_classifier_ old_classifier_ $self instvar decap_ set mag [new Agent/PMIPv6/MAG] $self attach $mag [$mag set default_port_] set pmip6_agent_ $mag #attach src classifier set old_classifier_ $classifier_ set src_classifier_ [new Classifier/Addr/PMIPv6Src] $src_classifier_ set mask_ 0xffffffff $src_classifier_ set shift_ 0 $src_classifier_ defaulttarget $old_classifier_

  32. PMIPv6 Initialization (8/8) • install-mag 함수 (cont’d) set nodetype [[Simulator instance] get-nodetype] $self insert-entry [$self get-module $nodetype] $src_classifier_ $src_classifier_ install-by-src 0 $old_classifier_ #attach decap_ set decap_ [new Classifier/Addr/PMIPv6Decapsulator] $decap_ set mask_ 0xffffffff $decap_ set shift_ 0 lappend $agents_ $decap_ $dmux_ install [Simulator set PMIPv6_TUNNEL_PORT] $decap_ # LL points previous hier_classifier as up-target # we should change this to our classifier if {[info exists ll_(0)] && $ll_(0) != ""} { $ll_(0) up-target $src_classifier_ } return $mag }

  33. Binding Update Process (1/3) • Sending PBU PMIPv6Agent Mac802_11 MAGAgent new-mn/TCL command() process_new_mn() -find_bule send_pbu() create_pbu() send()

  34. Binding Update Process (2/3) • Receiving PBU/Sending PBACK PMIPv6Agent LMAAgent recv() process_packet() process_pbu() -find_bce() setup_route() setup-route/TCL -get-pmip6-encap/TCL send_pback() create_pback() send()

  35. Binding Update Process (3/3) • Receiving PBACK PMIPv6Agent MAGAgent recv() process_packet() process_pback() -find_bule() setup_route() bule_state: BUL_S_SETUP setup-route/TCL -get-pmip6-encap/TCL clear_route() bule_state: BUL_S_DELETE clear-route/TCL

  36. Data Process (1/2) • LMA  MAG PMIPv6Decapsulator PMIPv6Dest PMIPv6Encapsulator recv() classify() recv() target_->recv() recv() find() link->recv()

  37. Data Process (2/2) • MAG  LMA PMIPv6Decapsulator PMIPv6Src PMIPv6Encapsulator recv() classify() recv() target_->recv() recv() find() link->recv()

  38. 802.11 MAC Operation (1/5) • 802.11 MAC에서 Layer 2 Trigger 발생 PMIPv6Agent Mac802_11 MAGAgent new-mn/TCL command() process_new_mn() -find_bule send_pbu() create_pbu() send()

  39. 802.11 MAC Operation (2/5) • 802.11 MAC 수정 • class Mac802_11 (ns-2.29/mac/mac-802_11.h) • use_pmip6_ext_: PMIPv6용 L2 trigger 사용 • pmip6_agent_: L2 trigger를 전달할 PMIPv6 agent • pmip6-agent 함수 추가 class Mac802_11 : public Mac { …… //PMIPv6 int use_pmip6_ext_; Agent* pmip6_agent_; //End PMIPv6 int Mac802_11::command(int argc, const char*const* argv) { …… else if (strcmp(argv[1], "pmip6-agent") == 0) { if(use_pmip6_ext_==0) return TCL_ERROR; pmip6_agent_ = (Agent *)TclObject::lookup(argv[2]); return TCL_OK; }

  40. 802.11 MAC Operation (3/5) • 802.11 MAC 수정 (cont’d) • 802.11 MAC에서 AP address 적용 버그 수정 • Link 가 끊어졌을 때 자동으로 스캔하도록 수정 inline int Mac802_11::hdr_dst(char* hdr, int dst ) { …… //PMIPv6 if(dst != bss_id_) STORE4BYTE(&bss_id_, (dh->dh_3a)); //end PMIPv6 void Mac802_11::link_disconnect (link_down_reason_t reason) { …… //PMIPv6 if(!mih_) { //If disconnected, it automatically starts scanning Tcl& tcl = Tcl::instance(); tcl.evalf ("%s autoscan", name()); } //PMIPv6 end

  41. 802.11 MAC Operation (4/5) • 802.11 MAC 수정 (cont’d) • AP를 발견하면 바로 연결되도록 수정 void Mac802_11::nextScan () { …… //PMIPv6 if(!mih_) { BSSDescription *n; n=scan_status_.resp->bssDesc_head.lh_first; //store structure scan bssid/channel Vincent Gauthier channelIDAfterScan_[n->bss_id()] = n->channel(); link_connect(n->bss_id()); } //PMIPv6 end

  42. 802.11 MAC Operation (5/5) • Layer 2 Trigger 발생 • AssocRes 메시지가 도착하면 시작 • PMIPv6 agent의 new-mn 함수 호출 void Mac802_11::recvACK(Packet *p) { …… //PMIPv6 if(use_pmip6_ext_) { if(pmip6_agent_) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s new-mn %d", pmip6_agent_->name(), n->id()); } } //end PMIPv6

  43. MAG Operation #1 (1/5) • MAG에서 L2 Trigger 처리 후 PBU 전송 PMIPv6Agent Mac802_11 MAGAgent new-mn/TCL command() process_new_mn() -find_bule send_pbu() create_pbu() send()

  44. MAG Operation #1 (1/4) • new-mn 함수 이후 process_new_mn 호출 • process_new_mn 함수 • Binding Update List 처리 • BUL entry (bule) • PBU retransmission timer • 마지막 PBU 저장 (pktPBU_) int MAGAgent::command(int argc, const char*const* argv) { …… else if(argc==3) { if(strcmp(argv[1], "new-mn") == 0) { uint32_t id; id = atoi(argv[2]); process_new_mn(id); return TCL_OK; }

  45. MAG Operation #1 (2/4) • process_new_mn 함수 (cont’d) void MAGAgent::process_new_mn(int32_t mn_id) { BULEntry *bule; bule = find_bule(mn_id); if(!bule) { bule = create_bule(mn_id); bule->lmaa() = lma_addr_; bule->proxy_coa() = addr(); bule->lifetime() = binding_lifetime_; bule->insert_entry(&bul_list_); } else { bule->BULTimer_.cancel(); if(bule->pktPBU_) { Packet::free(bule->pktPBU_); bule->pktPBU_ = 0; } } bule->set_state(BUL_S_SETUP); bule->retry_count_ = 0; send_pbu(bule); }

  46. MAG Operation #1 (3/4) • send_pbu 함수 • PMIPv6Agent의 create_pbu 함수로 PBU 생성 • bule에 생성된 PBU를 저장하고 복사본 전송 • Retransmission timer 설정 void MAGAgent::send_pbu(BULEntry *bule) { if(!bule->pktPBU_) { bule->pktPBU_ = create_pbu(bule->lmaa(), bule->mn_id(), bule->lifetime(), bule->proxy_coa()); } send(bule->pktPBU_->copy(), 0); //FIXME: adjust retransmit timeout (Random backoff??) bule->BULTimer_.resched(1.0); }

  47. MAG Operation #1 (4/4) • create_pbu 함수 Packet *PMIPv6Agent::create_pbu( int32_t dst, int32_t mn_id, uint32_t lifetime, int32_t proxy_coa) { Packet *p = allocpkt(); hdr_cmn *hdrc = HDR_CMN(p); hdr_ip *iph = HDR_IP(p); hdr_pmipv6 *h = HDR_PMIPv6(p); hdrc->size() = IPv6_HEADER_SIZE; hdrc->ptype() = PT_PBU; hdrc->size() += PBU_SIZE; iph->saddr() = proxy_coa; iph->sport() = port(); iph->daddr() = dst; iph->dport() = port(); h->H() = 1; h->A() = 1; h->P() = 1; h->type() = PBU; h->seqno() = 0; h->lifetime() = lifetime; h->mn_id() = mn_id; h->coa() = proxy_coa; h->haddr() = -1; h->status() = 0; return p; }

  48. LMA Operation (1/7) • Receiving PBU/Sending PBACK PMIPv6Agent LMAAgent recv() process_packet() process_pbu() -find_bce() setup_route() setup-route/TCL -get-pmip6-encap/TCL send_pback() create_pback() send()

  49. LMA Operation (2/7) • PMIPv6Agent의 recv 함수 • PBU의 IP헤더 dest port에 따라 recv함수 호출됨 void PMIPv6Agent::recv(Packet* p, Handler *) { hdr_cmn *hdrc = HDR_CMN(p); intptype; ptype = hdrc->ptype(); if((ptype==PT_PBU && strcmp(node_info_, "LMA")==0) || (ptype==PT_PBACK && strcmp(node_info_, "MAG")==0)) { process_packet(p); } else { fprintf(stderr, "%s received packet with wrong type %d\n", node_info_, ptype); Packet::free(p); } }

  50. LMA Operation (3/7) • process_packet 함수 • virtual이며, LMAAgent와 MAGAgent에서 override함 • process_pbu 함수 호출 • process_pbu 함수 • Binding cache 찾기, lifetime처리 • Lifetime에 따라 Routing 설정 • PBACK 보내기 void LMAAgent::process_packet(Packet *p) { hdr_cmn *ch = HDR_CMN(p); if(ch->ptype() == PT_PBU) { process_pbu(p); } Packet::free(p); }

More Related