diff --git a/net/arp.hh b/net/arp.hh index 3e45c399bb..7abdb5fcd5 100644 --- a/net/arp.hh +++ b/net/arp.hh @@ -194,10 +194,6 @@ arp_for::learn(l2addr hwaddr, l3addr paddr) { template unsigned arp_for::forward(packet& p, size_t off) { - auto ah = p.get_header(off); - if (ntoh(ah->oper) == op_reply) { - return std::numeric_limits::max(); // broadcast reply - } return engine.cpu_id(); } @@ -216,7 +212,7 @@ arp_for::received(packet p) { case op_request: return handle_request(&h); case op_reply: - learn(h.sender_hwaddr, h.sender_paddr); + arp_learn(h.sender_hwaddr, h.sender_paddr); return make_ready_future<>(); default: return make_ready_future<>(); diff --git a/net/ip.hh b/net/ip.hh index fd10e50528..72508cbdc2 100644 --- a/net/ip.hh +++ b/net/ip.hh @@ -249,6 +249,9 @@ public: void register_l4(proto_type id, ip_protocol* handler); net::hw_features hw_features() { return _netif->hw_features(); } static bool needs_frag(packet& p, ip_protocol_num proto_num, net::hw_features hw_features); + void learn(ethernet_address l2, ipv4_address l3) { + _arp.learn(l2, l3); + } }; template @@ -312,6 +315,8 @@ struct l4connid::connid_hash : private std::hash, private st } }; +void arp_learn(ethernet_address l2, ipv4_address l3); + } #endif /* IP_HH_ */ diff --git a/net/native-stack.cc b/net/native-stack.cc index 518f6a553f..d103cf4242 100644 --- a/net/native-stack.cc +++ b/net/native-stack.cc @@ -111,6 +111,9 @@ public: return ready_promise.get_future(); } virtual bool has_per_core_namespace() override { return true; }; + void arp_learn(ethernet_address l2, ipv4_address l3) { + _inet.learn(l2, l3); + } friend class native_server_socket_impl; }; @@ -228,6 +231,16 @@ future<> native_network_stack::initialize() { }); } +void arp_learn(ethernet_address l2, ipv4_address l3) +{ + for (unsigned i = 0; i < smp::count; i++) { + smp::submit_to(i, [l2, l3] { + auto & ns = static_cast(engine.net()); + ns.arp_learn(l2, l3); + }); + } +} + void create_native_stack(boost::program_options::variables_map opts, std::shared_ptr dev) { native_network_stack::ready_promise.set_value(std::unique_ptr(std::make_unique(opts, std::move(dev)))); }