mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
nic_router: fix use of outdated ARP-cache entries
When a NIC session is destructed at the router, we have to remove all ARP cache entries that match the MAC address of that session. Otherwise the outdated entries might be re-applied later, leading to wrong destination MAC addresses in routed packets. Fixes #2637
This commit is contained in:
parent
0423eb4499
commit
6575df84c5
@ -13,6 +13,8 @@
|
||||
|
||||
/* local includes */
|
||||
#include <arp_cache.h>
|
||||
#include <domain.h>
|
||||
#include <configuration.h>
|
||||
|
||||
using namespace Net;
|
||||
using namespace Genode;
|
||||
@ -48,6 +50,11 @@ Arp_cache_entry::find_by_ip(Ipv4_address const &ip) const
|
||||
return entry->find_by_ip(ip);
|
||||
}
|
||||
|
||||
void Arp_cache_entry::print(Output &output) const
|
||||
{
|
||||
Genode::print(output, _ip, " > ", _mac);
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Arp_cache **
|
||||
@ -55,9 +62,15 @@ Arp_cache_entry::find_by_ip(Ipv4_address const &ip) const
|
||||
|
||||
void Arp_cache::new_entry(Ipv4_address const &ip, Mac_address const &mac)
|
||||
{
|
||||
if (_entries[_curr].constructed()) { remove(&(*_entries[_curr])); }
|
||||
if (_entries[_curr].constructed()) {
|
||||
remove(&(*_entries[_curr]));
|
||||
}
|
||||
_entries[_curr].construct(ip, mac);
|
||||
insert(&(*_entries[_curr]));
|
||||
Arp_cache_entry &entry = *_entries[_curr];
|
||||
insert(&entry);
|
||||
if (_domain.config().verbose()) {
|
||||
log("[", _domain, "] new ARP entry ", entry);
|
||||
}
|
||||
if (_curr < NR_OF_ENTRIES - 1) {
|
||||
_curr++;
|
||||
} else {
|
||||
@ -73,3 +86,22 @@ Arp_cache_entry const &Arp_cache::find_by_ip(Ipv4_address const &ip) const
|
||||
|
||||
return first()->find_by_ip(ip);
|
||||
}
|
||||
|
||||
|
||||
void Arp_cache::destroy_entries_with_mac(Mac_address const &mac)
|
||||
{
|
||||
for (unsigned curr = 0; curr < NR_OF_ENTRIES; curr++) {
|
||||
try {
|
||||
Arp_cache_entry &entry = *_entries[curr];
|
||||
if (entry.mac() != mac) {
|
||||
continue;
|
||||
}
|
||||
if (_domain.config().verbose()) {
|
||||
log("[", _domain, "] destroy ARP entry ", entry);
|
||||
}
|
||||
remove(&entry);
|
||||
_entries[curr].destruct();
|
||||
|
||||
} catch (Arp_cache_entry_slot::Deref_unconstructed_object) { }
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
namespace Net {
|
||||
|
||||
class Domain;
|
||||
class Arp_cache;
|
||||
class Arp_cache_entry;
|
||||
using Arp_cache_entry_slot = Genode::Constructible<Arp_cache_entry>;
|
||||
@ -56,6 +57,14 @@ class Net::Arp_cache_entry : public Genode::Avl_node<Arp_cache_entry>
|
||||
***************/
|
||||
|
||||
Mac_address const &mac() const { return _mac; }
|
||||
Ipv4_address const &ip() const { return _ip; }
|
||||
|
||||
|
||||
/*********
|
||||
** log **
|
||||
*********/
|
||||
|
||||
void print(Genode::Output &output) const;
|
||||
};
|
||||
|
||||
|
||||
@ -68,16 +77,21 @@ class Net::Arp_cache : public Genode::Avl_tree<Arp_cache_entry>
|
||||
NR_OF_ENTRIES = ENTRIES_SIZE / sizeof(Arp_cache_entry),
|
||||
};
|
||||
|
||||
Arp_cache_entry_slot _entries[NR_OF_ENTRIES];
|
||||
bool _init = true;
|
||||
unsigned _curr = 0;
|
||||
Domain const &_domain;
|
||||
Arp_cache_entry_slot _entries[NR_OF_ENTRIES];
|
||||
bool _init = true;
|
||||
unsigned _curr = 0;
|
||||
|
||||
public:
|
||||
|
||||
struct No_match : Genode::Exception { };
|
||||
|
||||
Arp_cache(Domain const &domain) : _domain(domain) { }
|
||||
|
||||
void new_entry(Ipv4_address const &ip, Mac_address const &mac);
|
||||
|
||||
void destroy_entries_with_mac(Mac_address const &mac);
|
||||
|
||||
Arp_cache_entry const &find_by_ip(Ipv4_address const &ip) const;
|
||||
};
|
||||
|
||||
|
@ -98,7 +98,7 @@ class Net::Domain : public Domain_base
|
||||
unsigned long _interface_cnt { 0 };
|
||||
Pointer<Dhcp_server> _dhcp_server { };
|
||||
Genode::Reconstructible<Ipv4_config> _ip_config;
|
||||
Arp_cache _arp_cache { };
|
||||
Arp_cache _arp_cache { *this };
|
||||
Arp_waiter_list _foreign_arp_waiters { };
|
||||
Link_side_tree _tcp_links { };
|
||||
Link_side_tree _udp_links { };
|
||||
|
@ -1022,6 +1022,8 @@ Interface::~Interface()
|
||||
_dhcp_allocations.remove(allocation);
|
||||
_destroy_dhcp_allocation(*allocation);
|
||||
}
|
||||
/* dissolve ARP cache entries with the MAC address of this interface */
|
||||
_domain.arp_cache().destroy_entries_with_mac(_mac);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user