📄 ospfd_xorp.c
字号:
if (!(phyp = (BSDPhyInt *) phyints.find(ifrp->ifr_name))) { phyp = new BSDPhyInt; phystr = new byte[sizeof(ifrp->ifr_name)]; bzero(phystr, sizeof(ifrp->ifr_name)); memcpy(phystr, ifrp->ifr_name, sizeof(ifrp->ifr_name)); phyp->key = phystr; phyp->keylen = strlen(ifrp->ifr_name); phyp->phyint = ++next_phyint; debug_msg("phyint number = %d, key=%s keylen=%d\n", phyp->phyint, phyp->key, phyp->keylen); phyp->flags = 0; phyints.add(phyp); // May have multiple interfaces attached to same physical // net if (!phys[phyp->phyint]) phys[phyp->phyint] = phyp; } if (!memchr(ifrp->ifr_name, ':', strlen(ifrp->ifr_name))) { set_flags(phyp, ifflags); } insock = (sockaddr_in *) &ifrp->ifr_addr; addr = phyp->addr = ntoh32(insock->sin_addr.s_addr); debug_msg("addr = %s\n", inet_ntoa(insock->sin_addr)); // Get subnet mask if (ioctl(_udpfd, SIOCGIFNETMASK, (char *)&ifr) < 0) { XLOG_ERROR("SIOCGIFNETMASK Failed: %s", strerror(errno)); exit(1); } insock = (sockaddr_in *) &ifr.ifr_addr; phyp->mask = ntoh32(insock->sin_addr.s_addr); debug_msg("netmask = %x\n", phyp->mask); add_direct(phyp, addr, phyp->mask); add_direct(phyp, addr, 0xffffffffL); // Get interface MTU phyp->mtu = ((phyp->flags & IFF_BROADCAST) != 0) ? 1500 : 576; if (ioctl(_udpfd, SIOCGIFMTU, (char *)&ifr) >= 0) phyp->mtu = ifr.ifr_mtu; debug_msg("MTU: %d\n", phyp->mtu); // For point-to-point links, get other end's address phyp->dstaddr = 0; if ((phyp->flags & IFF_POINTOPOINT) != 0 && (ioctl(_udpfd, SIOCGIFDSTADDR, (char *)&ifr) >= 0)) { debug_msg("Point-to-point\n"); addr = phyp->dstaddr = ntoh32(insock->sin_addr.s_addr); add_direct(phyp, addr, 0xffffffffL); } // Install map from IP address to physical interface if (!interface_map.find(addr, 0)) { BSDIfMap *map; map = new BSDIfMap(addr, phyp); interface_map.add(map); } } /* Put back any routes that were obscured by formerly * operational direct routes. Take away routes that are * now supplanted by direct routes. */ iter.seek(0, 0); while ((rte = (DirectRoute *)iter.next())) { InAddr net=rte->index1(); InMask mask=rte->index2(); if (!rte->valid) { directs.remove(rte); delete rte; ospf->krt_delete_notification(net, mask); } else sys->rtdel(net, mask, 0); } delete [] ifcbuf;}/* Set the interface flags, If the IFF_UP flag * has changed, call the appropriate OSPFD API * routine. */void XorpOspfd::set_flags(BSDPhyInt *phyp, short flags){ debug_msg("----\nset_flags\n"); short old_flags=phyp->flags; phyp->flags = flags; if (((old_flags^flags) & IFF_UP) != 0 && ospf) { if ((flags & IFF_UP) != 0) ospf->phy_up(phyp->phyint); else ospf->phy_down(phyp->phyint); }}/* Add to the list of directly attached prefixes. These * we will let the kernel manage directly. */void XorpOspfd::add_direct(BSDPhyInt *phyp, InAddr addr, InMask mask){ debug_msg("----\nadd_direct\n"); DirectRoute *rte; if ((phyp->flags & IFF_UP) == 0) { debug_msg("Interface is down!\n"); return; } addr = addr & mask; if (!(rte = (DirectRoute *)directs.find(addr, mask))) { rte = new DirectRoute(addr, mask); debug_msg("new direct route: %x, %x\n", addr, mask); directs.add(rte); } rte->valid = true;}/* Parse an interface identifier, which can either be an address * or a name like "eth0". */bool XorpOspfd::parse_interface(const char *arg, in_addr &addr, BSDPhyInt *&phyp){ phyp = 0; debug_msg("---\nparse_interface: %s\n", arg); if (inet_aton(arg, &addr) == 1) { BSDIfMap *map; InAddr ifaddr; ifaddr = ntoh32(addr.s_addr); map = (BSDIfMap *) interface_map.find(ifaddr, 0); if (map != 0) phyp = map->phyp; } else { char ifname[IFNAMSIZ]; strncpy((char *)ifname, arg, IFNAMSIZ); phyp = (BSDPhyInt *) phyints.find(ifname);#if 0 // Try to detect unnumbered interfaces if (!phyp) { int ifindex; byte *phystr; ifreq ifr; short ifflags; memcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (memchr(ifr.ifr_name, ':', sizeof(ifr.ifr_name))) goto done; if (ioctl(_udpfd, SIOCGIFFLAGS, (char *)&ifr) < 0) goto done; if ((ifr.ifr_flags & IFF_LOOPBACK) != 0) goto done; ifflags = ifr.ifr_flags; // Get interface index if (ioctl(_udpfd, SIOCGIFINDEX, (char *)&ifr) < 0) goto done; ifindex = ifr.ifr_ifindex; if (phys[ifindex]) goto done; phyp = new BSDPhyInt; phystr = new byte[sizeof(ifr.ifr_name)]; memcpy(phystr, ifr.ifr_name, sizeof(ifr.ifr_name)); phyp->key = phystr; phyp->keylen = strlen(ifr.ifr_name); phyp->phyint = ifindex; phyp->flags = 0; phyints.add(phyp); phys[phyp->phyint] = phyp; set_flags(phyp, ifflags); phyp->addr = 0; phyp->mask = 0; phyp->dstaddr = 0; }#endif }#if 0 done:#endif if (!phyp) { XLOG_ERROR("Bad interface identifier %s", arg); return(false); } return(true);}void XorpOspfd::store_hitless_parms(int, int, struct MD5Seq *){ XLOG_WARNING("unhandled call to XorpOspfd::store_hitless_parms.");}/* ------------------------------------------------------------------------- *//* Xorp RIB callbacks and related*/void XorpOspfd::rib_add_table_cb(const XrlError& e){ if (e != XrlError::OKAY()) { XLOG_ERROR("Failed to add igp table for OSPF."); initiate_rib_add_table(); }}void XorpOspfd::rib_add_delete_route_cb(const XrlError& e, const char* action){ if (e != XrlError::OKAY()) { XLOG_ERROR("Failed to %s route.", action); initiate_rib_add_table(); }}voidXorpOspfd::rib_add_table(){ _rib_client.send_add_igp_table4("rib", "ospf", _router.class_name(), _router.instance_name(), /* unicast */ true, /* multicast */ false, callback(this, &XorpOspfd::rib_add_table_cb));}voidXorpOspfd::initiate_rib_add_table() { _rib_add_table_ticker = _eventloop.new_oneoff_after_ms( 100, callback(this, &XorpOspfd::rib_add_table) );}/* ------------------------------------------------------------------------- *//* The main OSPF loop. Loops getting messages (packets, timer * ticks, configuration messages, etc.) and never returns * until the OSPF process is told to exit. */static void ospfd_main(){ EventLoop eventloop; XrlStdRouter xrtr(eventloop, "ospfd"); XorpOspfd ospfd_sys(eventloop, xrtr); sys = &ospfd_sys; // Set global ospf system pointer to the one in use // Instantiate Xrl Handler object XrlOspfTarget xrl_target(eventloop, xrtr, ospfd_sys, &ospf); { // Wait until the XrlRouter becomes ready bool timed_out = false; XorpTimer t = eventloop.set_flag_after_ms(10000, &timed_out); while (xrtr.ready() == false && timed_out == false) { eventloop.run(); } if (xrtr.ready() == false) { XLOG_FATAL("XrlRouter did not become ready. No Finder?"); } } XLOG_INFO("Starting v%d.%d", OSPF::vmajor, OSPF::vminor); XLOG_INFO("Awaiting router id"); // Spin until ospf object instantiated. ospf = 0; while (ospf == 0) eventloop.run(); XLOG_INFO("Router ID set."); ospfd_sys.read_kernel_interfaces(); ospfd_sys.initiate_rib_add_table(); // Set up signals sigset_t sigset, osigset; signal(SIGHUP, quit); signal(SIGTERM, quit); sigemptyset(&sigset); sigaddset(&sigset, SIGHUP); sigaddset(&sigset, SIGTERM); sigprocmask(SIG_BLOCK, &sigset, &osigset); while (1) { // Time till next timer firing int msec_tmo = ospf->timeout(); // Run until next OSPFD timer is scheduled to fire bool breakout = false; XorpTimer t = eventloop.set_flag_after_ms(msec_tmo, &breakout); while (false == breakout) eventloop.run(); // Process pending OSPFD timers ospf->tick(); // Flush any logging messages ospf->logflush(); }}int main(int, const char* argv[]){ // // Initialize and start xlog // xlog_init(argv[0], NULL); xlog_set_verbose(XLOG_VERBOSE_LOW); // Least verbose messages // XXX: verbosity of the error messages temporary increased xlog_level_set_verbose(XLOG_LEVEL_ERROR, XLOG_VERBOSE_HIGH); xlog_add_default_output(); xlog_start(); XorpUnexpectedHandler x(xorp_unexpected_handler); try { ospfd_main(); } catch (...) { xorp_catch_standard_exceptions(); } // // Gracefully stop and exit xlog // xlog_stop(); xlog_exit(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -