Пример #1
0
Inet4::Inet4(hw::Nic& nic)
  : ip4_addr_(IP4::INADDR_ANY),
    netmask_(IP4::INADDR_ANY),
    router_(IP4::INADDR_ANY),
    dns_server(IP4::INADDR_ANY),
    nic_(nic), eth_(nic), arp_(*this), ip4_(*this),
    icmp_(*this), udp_(*this), tcp_(*this), dns(*this),
    bufstore_(nic.bufstore()), MTU_(nic.MTU())
{
  INFO("Inet4","Bringing up a IPv4 stack");
  Ensures(sizeof(IP4::addr) == 4);

  /** Upstream delegates */
  auto eth_bottom(upstream::from<Ethernet,&Ethernet::bottom>(eth_));
  auto arp_bottom(upstream::from<Arp,&Arp::bottom>(arp_));
  auto ip4_bottom(upstream::from<IP4,&IP4::bottom>(ip4_));
  auto icmp4_bottom(upstream::from<ICMPv4,&ICMPv4::bottom>(icmp_));
  auto udp4_bottom(upstream::from<UDP,&UDP::bottom>(udp_));
  auto tcp_bottom(upstream::from<TCP,&TCP::bottom>(tcp_));

  /** Upstream wiring  */
  // Packets available
  nic.on_transmit_queue_available(
    transmit_avail_delg::from<Inet4, &Inet4::process_sendq>(*this));

  // Phys -> Eth (Later, this will be passed through router)
  nic.set_linklayer_out(eth_bottom);

  // Eth -> Arp
  eth_.set_arp_handler(arp_bottom);

  // Eth -> IP4
  eth_.set_ip4_handler(ip4_bottom);

  // IP4 -> ICMP
  ip4_.set_icmp_handler(icmp4_bottom);

  // IP4 -> UDP
  ip4_.set_udp_handler(udp4_bottom);

  // IP4 -> TCP
  ip4_.set_tcp_handler(tcp_bottom);

  /** Downstream delegates */
  // retreive drivers delegate virtually, instead of setting it to a virtual call
  auto phys_top(nic.get_physical_out());
  //auto phys_top(downstream
  //              ::from<hw::Nic,&hw::Nic::transmit>(nic));
  auto eth_top(downstream
               ::from<Ethernet,&Ethernet::transmit>(eth_));
  auto arp_top(downstream
               ::from<Arp,&Arp::transmit>(arp_));
  auto ip4_top(downstream
               ::from<IP4,&IP4::transmit>(ip4_));

  /** Downstream wiring. */

  // ICMP -> IP4
  icmp_.set_network_out(ip4_top);

  // UDP4 -> IP4
  udp_.set_network_out(ip4_top);

  // TCP -> IP4
  tcp_.set_network_out(ip4_top);

  // IP4 -> Arp
  ip4_.set_linklayer_out(arp_top);

  // Arp -> Eth
  arp_.set_linklayer_out(eth_top);

  // Eth -> Phys
  assert(phys_top);
  eth_.set_physical_out(phys_top);
}
Пример #2
0
Inet::Inet(hw::Nic& nic)
  : ip4_addr_(IP4::ADDR_ANY),
    netmask_(IP4::ADDR_ANY),
    gateway_(IP4::ADDR_ANY),
    dns_server_(IP4::ADDR_ANY),
    nic_(nic), arp_(*this), ip4_(*this), ip6_(*this),
    icmp_(*this), icmp6_(*this), udp_(*this), tcp_(*this), dns_(*this),
    domain_name_{},
    MTU_(nic.MTU())
{
  static_assert(sizeof(IP4::addr) == 4, "IPv4 addresses must be 32-bits");

  /** SMP related **/
  this->cpu_id = SMP::cpu_id();
  INFO("Inet", "Bringing up %s on CPU %d",
        ifname().c_str(), this->get_cpu_id());

  /** Upstream delegates */
  auto arp_bottom(upstream{arp_, &Arp::receive});
  auto ip4_bottom(upstream_ip{ip4_, &IP4::receive});
  auto ip6_bottom(upstream_ip{ip6_, &IP6::receive});
  auto icmp4_bottom(upstream{icmp_, &ICMPv4::receive});
  auto icmp6_bottom(upstream{icmp6_, &ICMPv6::receive});
  auto udp4_bottom(upstream{udp_, &UDP::receive});
  auto tcp_bottom(upstream{tcp_, &TCP::receive});
  auto tcp6_bottom(upstream{tcp_, &TCP::receive6});

  /** Upstream wiring  */
  // Packets available
  nic.on_transmit_queue_available({this, &Inet::process_sendq});

  // Link -> Arp
  nic_.set_arp_upstream(arp_bottom);

  // Link -> IP4
  nic_.set_ip4_upstream(ip4_bottom);

  // Link -> IP6
  nic_.set_ip6_upstream(ip6_bottom);

  // IP4 -> ICMP
  ip4_.set_icmp_handler(icmp4_bottom);

  // IP6 -> ICMP6
  ip6_.set_icmp_handler(icmp6_bottom);

  // IP4 -> UDP
  ip4_.set_udp_handler(udp4_bottom);

  // IP4 -> TCP
  ip4_.set_tcp_handler(tcp_bottom);

  // IP6 -> TCP
  ip6_.set_tcp_handler(tcp6_bottom);

  /** Downstream delegates */
  auto link_top(nic_.create_link_downstream());
  auto arp_top(IP4::downstream_arp{arp_, &Arp::transmit});
  auto ndp_top(IP6::downstream_ndp{icmp6_, &ICMPv6::ndp_transmit});
  auto ip4_top(downstream{ip4_, &IP4::transmit});
  auto ip6_top(downstream{ip6_, &IP6::transmit});

  /** Downstream wiring. */

  // ICMP -> IP4
  icmp_.set_network_out(ip4_top);

  // ICMPv6 -> IP6
  icmp6_.set_network_out(ip6_top);

  // UDP4 -> IP4
  udp_.set_network_out(ip4_top);

  // TCP -> IP4
  tcp_.set_network_out(ip4_top);

  // TCP -> IP6
  tcp_.set_network_out6(ip6_top);

  // IP4 -> Arp
  ip4_.set_linklayer_out(arp_top);

  // IP6 -> Ndp
  ip6_.set_linklayer_out(ndp_top);

  // NDP -> Link
  icmp6_.set_ndp_linklayer_out(link_top);

  // UDP6 -> IP6
  // udp6->set_network_out(ip6_top);
  // TCP6 -> IP6
  // tcp6->set_network_out(ip6_top);

  // Arp -> Link
  assert(link_top);
  arp_.set_linklayer_out(link_top);

#ifndef INCLUDEOS_SINGLE_THREADED
  // move this nework stack automatically
  // to the current CPU if its not 0
  if (SMP::cpu_id() != 0) {
    this->move_to_this_cpu();
  }
#endif
}