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); }
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 }