⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lookuplocalgridroute.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
字号:
/* * lookuplocalgridroute.{cc,hh} -- Grid multihop local routing element * Douglas S. J. De Couto * * Copyright (c) 2000 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include <click/confparse.hh>#include <click/error.hh>#include <clicknet/ether.h>#include <clicknet/ip.h>#include <click/standard/scheduleinfo.hh>#include <click/router.hh>#include <click/glue.hh>#include <elements/grid/grid.hh>#include <elements/grid/gridgatewayinfo.hh>#include <elements/grid/lookuplocalgridroute.hh>#include <elements/grid/linktracker.hh>#include <elements/grid/gridgenericrt.hh>#include <elements/grid/gridgenericlogger.hh>CLICK_DECLSint GridRouteActor::_next_free_cb = 0;#define NOISY 0LookupLocalGridRoute::LookupLocalGridRoute()  : Element(2, 4),   _gw_info(0), _link_tracker(0), _rtes(0),  _any_gateway_ip(0), _task(this),   _log(0){}LookupLocalGridRoute::~LookupLocalGridRoute(){}void *LookupLocalGridRoute::cast(const char *n){  if (strcmp(n, "LookupLocalGridRoute") == 0)    return (LookupLocalGridRoute *)this;  else    return 0;}intLookupLocalGridRoute::configure(Vector<String> &conf, ErrorHandler *errh){  int res = cp_va_parse(conf, this, errh,			cpEthernetAddress, "source Ethernet address", &_ethaddr,			cpIPAddress, "source IP address", &_ipaddr,			cpOptional,                         cpElement, "GenericGridRouteTable element", &_rtes,			cpKeywords,                        "GWI", cpElement, "GridGatewayInfo element", &_gw_info,			"LT", cpElement, "LinkTracker element", &_link_tracker,			"LOG", cpElement, "GridGenericLogger element", &_log,			cpEnd);  _any_gateway_ip = htonl((ntohl(_ipaddr.addr()) & 0xFFffFF00) | 254);  return res;}intLookupLocalGridRoute::initialize(ErrorHandler *errh){  if (_rtes && _rtes->cast("GridGenericRouteTable") == 0) {    return errh->error("%s: GridRouteTable argument %s has the wrong type",		       id().cc(),		       _rtes->id().cc());  } #if 0  else if (_rtes == 0) {    return errh->error("%s: no GridRouteTable element given",		       id().cc());  }#endif  if (_gw_info && _gw_info->cast("GridGatewayInfo") == 0) {    return errh->error("%s: GridGatewayInfo argument %s has the wrong type",		       id().cc(),		       _gw_info->id().cc());  }   if (_link_tracker && _link_tracker->cast("LinkTracker") == 0) {    return errh->error("%s: LinkTracker argument %s has the wrong type",		       id().cc(),		       _link_tracker->id().cc());  }   if (_log && _log->cast("GridGenericLogger") == 0) {    return errh->error("%s: GridGenericLogger element %s has the wrong type",		       id().cc(),		       _log->id().cc());  }  if (input_is_pull(0))    ScheduleInfo::join_scheduler(this, &_task, errh);  return 0;}boolLookupLocalGridRoute::run_task(){  Packet *p = input(0).pull();  if (p)    push(0, p);  _task.fast_reschedule();  return p != 0;}boolLookupLocalGridRoute::is_gw(){  return _gw_info && _gw_info->is_gateway(); }typedef GridRouteActionCallback GRCB;voidLookupLocalGridRoute::push(int port, Packet *packet){  /*    * input 1 and output 1 hook up to higher level (e.g. ip), input 0   * and output 0 hook up to lower level (e.g. ethernet)    */  assert(packet);    if (port == 0) {    /*     * input from net device     */    grid_hdr *gh = (grid_hdr *) (packet->data() + sizeof(click_ether));    switch (gh->type) {    case grid_hdr::GRID_NBR_ENCAP:    case grid_hdr::GRID_LOC_REPLY:    case grid_hdr::GRID_ROUTE_PROBE:    case grid_hdr::GRID_ROUTE_REPLY:      {	/* 	* try to either receive the packet or forward it	*/	struct grid_nbr_encap *encap = (grid_nbr_encap *) (packet->data() + sizeof(click_ether) + gh->hdr_len);	IPAddress dest_ip(encap->dst_ip);#if NOISY 	click_chatter("lr %s: got %s packet for %s; I am %s; agi=%s, is_gw = %d\n",		      id().cc(),		      grid_hdr::type_string(gh->type).cc(),		      dest_ip.s().cc(), 		      _ipaddr.s().cc(),		      _any_gateway_ip.s().cc(),		      is_gw() ? 1 : 0);#endif	// is the packet for us?	if ((dest_ip == _ipaddr) ||	    (dest_ip == _any_gateway_ip && is_gw())) {	  // is it IP data?  If so, send it to IP input path.	  if (gh->type == grid_hdr::GRID_NBR_ENCAP) {#if NOISY	    click_chatter("%s: got an IP packet for us %s",			  id().cc(),			  dest_ip.s().cc());#endif	    packet->pull(sizeof(click_ether) + gh->hdr_len + sizeof(grid_nbr_encap));	    notify_route_cbs(packet, dest_ip, GRCB::SendToIP, 0, 0);	    output(1).push(packet);	  }	  else	    click_chatter("%s: got %s packet for us, but don't know how to handle it",			  id().cc(), grid_hdr::type_string(gh->type).cc());	} 	else {	  // packet is not for us, try to forward it!	  forward_grid_packet(packet, encap->dst_ip);	}      }      break;    default:      click_chatter("%s: received unexpected Grid packet type: %s", 		    id().cc(), grid_hdr::type_string(gh->type).cc());      notify_route_cbs(packet, 0, GRCB::Drop, GRCB::UnknownType, 0);      output(3).push(packet);    }  }  else {    /*     * input from higher level protocol -- expects IP packets     * annotated with dst IP address.     */    assert(port == 1);    // check to see is the desired dest is our neighbor    IPAddress dst = packet->dst_ip_anno();#if NOISY    click_chatter("lr %s: got packet for %s; I am %s; agi=%s, is_gw=%d\n",		  id().cc(),		  dst.s().cc(), 		  _ipaddr.s().cc(),		  _any_gateway_ip.s().cc(),		  is_gw() ? 1 : 0);#endif    if (dst == _any_gateway_ip && is_gw()) {      packet->kill();    } else if (dst == _ipaddr) {      click_chatter("%s: got IP packet from us for our address; looping it back.  Check the configuration.", id().cc());      output(1).push(packet);    } else {      // encapsulate packet with grid hdr and try to send it out      WritablePacket *new_packet = packet->push(sizeof(click_ether) + sizeof(grid_hdr) + sizeof(grid_nbr_encap));      memset(new_packet->data(), 0, sizeof(click_ether) + sizeof(grid_hdr) + sizeof(grid_nbr_encap));      struct click_ether *eh = (click_ether *) new_packet->data();      eh->ether_type = htons(ETHERTYPE_GRID);      struct grid_hdr *gh = (grid_hdr *) (new_packet->data() + sizeof(click_ether));      gh->hdr_len = sizeof(grid_hdr);      gh->total_len = new_packet->length() - sizeof(click_ether); // encapsulate everything we get, don't look inside it for length info      gh->total_len = htons(gh->total_len);      gh->type = grid_hdr::GRID_NBR_ENCAP;      /* FixSrcLoc will see that the gh->ip and gh->tx_ip fields are         the same, and will fill in gh->loc, etc. */      // gh->tx_ip is set in forward_grid_packet()      gh->ip = _ipaddr;             struct grid_nbr_encap *encap = (grid_nbr_encap *) (new_packet->data() + sizeof(click_ether) + sizeof(grid_hdr));      encap->hops_travelled = 0;      encap->dst_ip = dst;#ifndef SMALL_GRID_HEADERS      encap->dst_loc_good = false;#endif      forward_grid_packet(new_packet, dst);    }  }}voidLookupLocalGridRoute::add_handlers(){  add_default_handlers(true);}boolLookupLocalGridRoute::get_next_hop(IPAddress dest_ip, EtherAddress *dest_eth, 				   IPAddress *next_hop_ip, unsigned char *next_hop_interface) const{  assert(dest_eth != 0);  GridGenericRouteTable::RouteEntry rte;  bool found_route;  if (dest_ip == _any_gateway_ip) {        found_route = _rtes->current_gateway(rte);          // what if we are being asked to forward a grid packet to an    // internet host, but we have no local routes to a gateway?    // drop here?        // i guess we could do a loc query for a gateway...  seems a little    // sketchy to me though.  } else {    found_route = _rtes->get_one_entry(dest_ip, rte);  }    /* did we have a route? */  if (found_route && rte.good()) {    *dest_eth = rte.next_hop_eth;    *next_hop_ip = rte.next_hop_ip;    *next_hop_interface = rte.next_hop_interface;    return true;  }  return false;}voidLookupLocalGridRoute::forward_grid_packet(Packet *xp, IPAddress dest_ip){  WritablePacket *packet = xp->uniqueify();  /*   * packet must have a MAC hdr, grid_hdr, and a grid_nbr_encap hdr on   * it.  This function will update the hop count, transmitter ip and   * loc (us) and dst/src MAC addresses.  Sender ip and loc info will   * not be touched, so if we are originating the packet, those have   * to be setup before calling this function.  Similarly, the   * destination ip and loc info must be set by whoever (or whatever   * element) originates the packet.  The originator should probably   * set the nb->dst_loc_good to false, so that if we don't find a   * local route the loc querier will know to lookup the destination   * location before using geographic forwarding.   */  if (_rtes == 0) {    // no GridRouteTable next-hop table in configuration    click_chatter("%s: can't forward packet for %s; there is no routing table, trying geographic forwarding", id().cc(), dest_ip.s().cc());    notify_route_cbs(packet, dest_ip, GRCB::FallbackToGF, 0, 0);    output(2).push(packet);    return;  }  struct grid_nbr_encap *encap = (grid_nbr_encap *) (packet->data() + sizeof(click_ether) + sizeof(grid_hdr));  EtherAddress next_hop_eth;  IPAddress next_hop_ip;  unsigned char next_hop_interface = 0;  bool found_next_hop = get_next_hop(dest_ip, &next_hop_eth, &next_hop_ip, &next_hop_interface);  if (found_next_hop) {    struct click_ether *eh = (click_ether *) packet->data();    memcpy(eh->ether_shost, _ethaddr.data(), 6);    memcpy(eh->ether_dhost, next_hop_eth.data(), 6);    struct grid_hdr *gh = (grid_hdr *) (packet->data() + sizeof(click_ether));    gh->tx_ip = _ipaddr;    encap->hops_travelled++;    // leave src location update to FixSrcLoc element    int sig = 0;    int qual = 0;    struct timeval tv = { 0, 0 };#ifdef CLICK_USERLEVEL    if (_link_tracker)      _link_tracker->get_stat(next_hop_ip, sig, qual, tv);#endif    unsigned int data2 = (qual << 16) | ((-sig) & 0xFFff);    notify_route_cbs(packet, dest_ip, GRCB::ForwardDSDV, next_hop_ip, data2);    SET_PAINT_ANNO(packet, next_hop_interface);    output(0).push(packet);  }  else {#if NOISY    click_chatter("%s: unable to forward packet for %s with local routing, trying geographic routing", id().cc(), dest_ip.s().cc());#endif        // logging    notify_route_cbs(packet, dest_ip, GRCB::FallbackToGF, 0, 0);    if (_log)      _log->log_no_route(packet, Timestamp::now());    output(2).push(packet);  }}CLICK_ENDDECLSEXPORT_ELEMENT(LookupLocalGridRoute)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -