patch2.2
来自「BCAST Implementation for NS2」· 2 代码 · 共 853 行 · 第 1/2 页
2
853 行
diff -X exclude_files -Nabur ospfd2.1/linux/linux.C ospfd2.2/linux/linux.C--- ospfd2.1/linux/linux.C Thu Apr 19 17:50:48 2001+++ ospfd2.2/linux/linux.C Mon May 14 14:27:10 2001@@ -90,6 +90,20 @@ } } +/* Cloase all monitor connections. Necessary when, for example,+ * simulated ospfd restarts but its process remains.+ */++void Linux::close_monitor_connections()++{+ AVLsearch iter(&monfds);+ TcpConn *conn;++ while ((conn = (TcpConn *)iter.next()))+ close_monitor_connection(conn);+}+ void Linux::process_mon_io(fd_set *fdsetp, fd_set *wrsetp) {@@ -123,7 +137,7 @@ fd = conn->monfd(); if ((nbytes = conn->monpkt.receive((void **)&msg, type, subtype)) < 0) close_monitor_connection(conn);- else if (type != 0)+ else if (type != 0 && ospf) ospf->monitor((MonMsg *)msg, type, nbytes, fd); } @@ -157,6 +171,7 @@ { close(conn->monfd()); monfds.remove(conn);+ if (ospf) ospf->register_for_opqs(conn->monfd(), true); delete conn; }diff -X exclude_files -Nabur ospfd2.1/linux/linux.h ospfd2.2/linux/linux.h--- ospfd2.1/linux/linux.h Thu Apr 19 17:50:48 2001+++ ospfd2.2/linux/linux.h Mon May 14 14:27:10 2001@@ -37,6 +37,7 @@ void process_monitor_request(class TcpConn *); void accept_monitor_connection(); void close_monitor_connection(class TcpConn *);+ void close_monitor_connections(); void monitor_listen(); }; diff -X exclude_files -Nabur ospfd2.1/linux/ospfd_linux.C ospfd2.2/linux/ospfd_linux.C--- ospfd2.1/linux/ospfd_linux.C Thu Apr 19 17:50:48 2001+++ ospfd2.2/linux/ospfd_linux.C Mon May 14 14:27:10 2001@@ -267,7 +267,8 @@ syslog(LOG_ERR, "rtnetlink recvfrom: %m"); return; }- msg = (nlmsghdr *)buffer;+ for (msg = (nlmsghdr *)buffer; NLMSG_OK(msg, (uns32)plen);+ msg = NLMSG_NEXT(msg, plen)) { switch (msg->nlmsg_type) { in_addr in; ifinfomsg *ifinfo;@@ -277,6 +278,7 @@ rtmsg *rtm; InAddr net; InMask mask;+ nlmsgerr *errmsg; case RTM_NEWLINK: // Interface flags change ifinfo = (ifinfomsg *)NLMSG_DATA(msg); syslog(LOG_NOTICE, "Ifc change IfIndex %d flags 0x%x",@@ -307,6 +309,7 @@ syslog(LOG_NOTICE, "Interface addr change %s", inet_ntoa(in)); read_config(); break;+ case RTM_NEWROUTE: case RTM_DELROUTE: rtm = (rtmsg *)NLMSG_DATA(msg); if (rtm->rtm_protocol != PROT_OSPF)@@ -328,12 +331,27 @@ mask = ~((1 << (32-rtm->rtm_dst_len)) - 1); net = ntoh32(in.s_addr) & mask; }+ if (msg->nlmsg_type == RTM_DELROUTE) { syslog(LOG_NOTICE, "Krt Delete %s", inet_ntoa(in)); ospf->krt_delete_notification(net, mask);+ }+ else if (dumping_remnants)+ ospf->remnant_notification(net, mask);+ break;+ case NLMSG_DONE:+ dumping_remnants = false;+ break;+ case NLMSG_OVERRUN:+ syslog(LOG_ERR, "Overrun on routing socket: %m");+ break;+ case NLMSG_ERROR:+ errmsg = (nlmsgerr *)NLMSG_DATA(msg);+ syslog(LOG_ERR, "Netlink error %d", errmsg->error); break; default: break; }+ } } #else void LinuxOspfd::netlink_receive(int)@@ -394,6 +412,7 @@ (void) gettimeofday(&last_time, NULL); changing_routerid = false; change_complete = false;+ dumping_remnants = false; // Allow core files rlim.rlim_max = RLIM_INFINITY; (void) setrlimit(RLIMIT_CORE, &rlim);diff -X exclude_files -Nabur ospfd2.1/linux/ospfd_linux.h ospfd2.2/linux/ospfd_linux.h--- ospfd2.1/linux/ospfd_linux.h Thu Apr 19 17:50:48 2001+++ ospfd2.2/linux/ospfd_linux.h Mon May 14 14:27:11 2001@@ -38,6 +38,7 @@ FILE *logstr; bool changing_routerid; bool change_complete;+ bool dumping_remnants; public: LinuxOspfd(); ~LinuxOspfd();@@ -57,6 +58,7 @@ void rtdel(InAddr, InMask, MPath *ompp); void add_mcache(InAddr src, InAddr group, MCache *); void del_mcache(InAddr src, InAddr group);+ void upload_remnants(); char *phyname(int phyint); void sys_spflog(int msgno, char *msgbuf); void halt(int code, char *string);diff -X exclude_files -Nabur ospfd2.1/linux/system.C ospfd2.2/linux/system.C--- ospfd2.1/linux/system.C Thu Apr 19 17:50:48 2001+++ ospfd2.2/linux/system.C Mon May 14 14:27:11 2001@@ -407,6 +407,16 @@ if (-1 == ioctl(udpfd, SIOCDELRT, (char *)&m)) syslog(LOG_ERR, "SIOCDELRT: %m"); }++/* Uploading remnant routing table entries is not supported+ * on older Linux versions.+ */++void LinuxOspfd::upload_remnants()++{+}+ #else /* On Linux 2.2, add and delete routing table entries * via the rtnetlink interface. Note that we are setting@@ -553,6 +563,45 @@ if (-1 == send(rtsock, nlm, size, 0)) syslog(LOG_ERR, "del route through routing socket: %m"); }++/* Request the kernel to upload the current set of routing+ * table entries that it has.+ */++void LinuxOspfd::upload_remnants()++{+ nlmsghdr *nlm;+ rtmsg *rtm;+ int size;++ // Set state to dumping+ dumping_remnants = true;++ // Calculate size of netlink message+ size = NLMSG_SPACE(sizeof(*rtm)); // Only a routing message+ // Allocate netlink message+ nlm = (nlmsghdr *) new char[size];+ nlm->nlmsg_len = size;+ nlm->nlmsg_type = RTM_GETROUTE;+ nlm->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;+ nlm->nlmsg_seq = nlm_seq++;+ nlm->nlmsg_pid = 0;+ rtm = (rtmsg *) NLMSG_DATA(nlm);+ rtm->rtm_family = AF_INET;+ rtm->rtm_dst_len = 0;+ rtm->rtm_src_len = 0;+ rtm->rtm_table = 0;+ rtm->rtm_protocol = PROT_OSPF;+ rtm->rtm_scope = RT_SCOPE_UNIVERSE;+ rtm->rtm_type = RTN_UNICAST;+ rtm->rtm_flags = 0;++ // Send to routing socket+ if (-1 == send(rtsock, nlm, size, 0))+ syslog(LOG_ERR, "routing table dump: %m");+}+ #endif /* Add a multicast routing table entry to the kernel.diff -X exclude_files -Nabur ospfd2.1/ospf_sim/ospf_sim.tcl ospfd2.2/ospf_sim/ospf_sim.tcl--- ospfd2.1/ospf_sim/ospf_sim.tcl Thu Apr 19 17:50:50 2001+++ ospfd2.2/ospf_sim/ospf_sim.tcl Mon May 14 14:27:15 2001@@ -1514,9 +1514,11 @@ .mbar.add add command -label "Virtual Link" -command "AddVL" .mbar.add add command -label "Static Route" -command [list SelectRouter add_static_menu] menu .mbar.toggle -tearoff 0-.mbar add cascade -label "Toggle" -underline 0 -menu .mbar.toggle-.mbar.toggle add command -label "Router" -command [list SelectRouter togglertr]-.mbar.toggle add command -label "Interface" -command "ToggleInterface"+.mbar add cascade -label "Router" -underline 0 -menu .mbar.toggle+.mbar.toggle add command -label "Toggle" -command [list SelectRouter togglertr]+.mbar.toggle add command -label "Restart" -command [list SelectRouter rstrtr]+.mbar.toggle add command -label "Hitless Restart" -command [list SelectRouter hitlessrtr]+.mbar.toggle add command -label "Toggle Interface" -command "ToggleInterface" menu .mbar.sim .mbar add cascade -label "Simulation" -underline 0 -menu .mbar.sim .mbar.sim add command -label "Resume" -command "time_resume"diff -X exclude_files -Nabur ospfd2.1/ospf_sim/ospfd_sim.C ospfd2.2/ospf_sim/ospfd_sim.C--- ospfd2.1/ospf_sim/ospfd_sim.C Thu Apr 19 17:50:50 2001+++ ospfd2.2/ospf_sim/ospfd_sim.C Mon May 14 14:27:15 2001@@ -189,6 +189,11 @@ { InPkt *pkt; InAddr daddr;+ SimRte *rte;++ // Discard packet if OSPF not ready+ if (!ospf)+ return; pkt = (InPkt *) (pkthdr+1); daddr = ntoh32(pkt->i_dest);@@ -196,8 +201,7 @@ if (!IN_CLASSD(daddr)) { InAddr home; if ((!get_port_addr(daddr, home)) || (home != ospf->my_id())) {- MPath *mpp;- if ((mpp = ospf->ip_lookup(daddr)) == 0) {+ if (!(rte = rttbl.best_match(daddr))) { sendicmp(ICMP_TYPE_UNREACH, ICMP_CODE_UNREACH_HOST, 0, 0, pkt, 0, 0, 0); }@@ -208,10 +212,10 @@ } else { InAddr gw;- gw = mpp->NHs[0].gw;- if (gw != 0 && mpp->NHs[0].if_addr == 0)+ gw = rte->gw;+ if (gw != 0 && rte->if_addr == 0) gw = (InAddr) -1;- sendpkt(pkt, mpp->NHs[0].phyint, gw);+ sendpkt(pkt, rte->phyint, gw); } } else@@ -497,6 +501,14 @@ mtraces.add(mtrace); mtrace->send_query(); break;+ case SIM_RESTART:+ close_monitor_connections();+ delete ospf;+ ospf = 0;+ // Will then get First tick, and config+ break;+ case SIM_RESTART_HITLESS:+ break; default: break; }@@ -961,4 +973,85 @@ else simsys->sendpkt(iphdr); delete [] ((byte *) iphdr);+}++/* The follow two routines taken from ospfd's INtbl+ * and INrte classes.+ * Should make these utility routines.+ */++/* Add an entry to an IP routing table entry. Install the+ * prefix pointers so that the best match operations will+ * work correctly.+ */++SimRte *SimRttbl::add(uns32 net, uns32 mask)++{+ SimRte *rte;+ SimRte *parent;+ SimRte *child;+ AVLsearch iter(&routes);++ if ((rte = (SimRte *) routes.find(net, mask)))+ return(rte);+ // Add to routing table entry+ rte = new SimRte(net, mask);+ routes.add(rte);+ // Set prefix pointer+ parent = (SimRte *) routes.previous(net, mask);+ for (; parent; parent = parent->prefix) {+ if (rte->is_child(parent)) {+ rte->prefix = parent;+ break;+ }+ }+ // Set children's parent pointers+ iter.seek(rte);+ while ((child = (SimRte *)iter.next()) && child->is_child(rte)) {+ if (child->prefix && child->prefix->is_child(rte))+ continue;+ child->prefix = rte;+ }++ return(rte);+}++/* Find the best matching routing table entry for a given+ * IP destination.+ */++SimRte *SimRttbl::best_match(uns32 addr)++{+ SimRte *rte;+ SimRte *prev;++ rte = (SimRte *) routes.root();+ prev = 0;+ while (rte) {+ if (addr < rte->net())+ rte = (SimRte *) rte->go_left();+ else if (addr > rte->net() ||+ 0xffffffff > rte->mask()) {+ prev = rte;+ rte = (SimRte *) rte->go_right();+ }+ else+ // Matching host route+ break;+ }++ // If no exact match, take previous entry+ if (!rte)+ rte = prev;+ // Go up prefix chain, looking for valid routes+ for (; rte; rte = rte->prefix) {+ if ((addr & rte->mask()) != rte->net())+ continue;+ if (rte->reachable)+ break;+ }++ return(rte->reject ? 0 : rte); }diff -X exclude_files -Nabur ospfd2.1/ospf_sim/ospfd_sim.h ospfd2.2/ospf_sim/ospfd_sim.h--- ospfd2.1/ospf_sim/ospfd_sim.h Thu Apr 19 17:50:50 2001+++ ospfd2.2/ospf_sim/ospfd_sim.h Mon May 14 14:27:15 2001@@ -20,6 +20,57 @@ extern char *LOOPADDR; class SimPktQ;+class SimRte;++/* Routing table kept within a simulated OSPF router. We don't+ * use the simulated ospfd's table, so that we can simulate+ * hitless restart scenarios.+ */++class SimRttbl {+ public:+ AVLtree routes;+ SimRte *add(InAddr net, InMask mask);+ SimRte *best_match(InAddr addr);+};++class SimRte : public AVLitem {+ public:+ SimRte *prefix;+ bool reachable;+ bool reject;+ int phyint; // Outgoing interface+ InAddr if_addr;+ InAddr gw; // Next hop address+ + inline SimRte(InAddr, InMask);+ inline InAddr net();+ inline InAddr mask();+ inline int is_child(SimRte *o);+}; ++inline SimRte::SimRte(InAddr a, InMask m) : AVLitem(a, m)+{+ prefix = 0;+ reachable = false;+ reject = false;+}+inline InAddr SimRte::net()+{+ return(index1());+}+inline InAddr SimRte::mask()+{+ return(index2());+}+inline int SimRte::is_child(SimRte *o)+{+ return((net() & o->mask()) == o->net() && mask() >= o->mask());+}++/* Global class representing a simulated OSPF router. Contains+ * the implementation of its system interface.+ */ class SimSys : public Linux { int ctl_fd; // Connection to controller@@ -30,6 +81,7 @@ AVLtree address_map; // IP address to group mapping AVLtree port_map; // Phyint to file descriptor mapping AVLtree membership; // Interface group membership + SimRttbl rttbl; // Routing table SimPktQ *rcv_head; // Queued receives
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?