nic_router: free MAC on session-creation exception

If a MAC address was once allocated for a downlink and during the further
creation of the downlink an exception caused the creation to be aborted, the
NIC router didn't free the MAC address again.

Ref 
This commit is contained in:
Martin Stein 2019-10-15 12:43:17 +02:00 committed by Christian Helmuth
parent ebcca179ed
commit 58247737fd

@ -163,13 +163,33 @@ Session_component *Net::Root::_create_session(char const *args)
/* create new session object behind session env in the RAM block */
try {
Session_label const label { label_from_args(args) };
return construct_at<Session_component>(
(void*)((addr_t)ram_ptr + sizeof(Session_env)),
session_env,
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0),
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0),
_timer, _mac_alloc.alloc(), _router_mac, label,
_interfaces, _config(), ram_ds);
Mac_address const mac { _mac_alloc.alloc() };
try {
Session_component *x = construct_at<Session_component>(
(void*)((addr_t)ram_ptr + sizeof(Session_env)),
session_env,
Arg_string::find_arg(args, "tx_buf_size").ulong_value(0),
Arg_string::find_arg(args, "rx_buf_size").ulong_value(0),
_timer, mac, _router_mac, label, _interfaces,
_config(), ram_ds);
return x;
}
catch (Out_of_ram) {
_mac_alloc.free(mac);
Session_env session_env_stack { session_env };
session_env_stack.detach(ram_ptr);
session_env_stack.free(ram_ds);
_invalid_downlink("NIC session RAM quota");
throw Insufficient_ram_quota();
}
catch (Out_of_caps) {
_mac_alloc.free(mac);
Session_env session_env_stack { session_env };
session_env_stack.detach(ram_ptr);
session_env_stack.free(ram_ds);
_invalid_downlink("NIC session CAP quota");
throw Insufficient_cap_quota();
}
}
catch (Mac_allocator::Alloc_failed) {
Session_env session_env_stack { session_env };
@ -178,20 +198,6 @@ Session_component *Net::Root::_create_session(char const *args)
_invalid_downlink("failed to allocate MAC address");
throw Service_denied();
}
catch (Out_of_ram) {
Session_env session_env_stack { session_env };
session_env_stack.detach(ram_ptr);
session_env_stack.free(ram_ds);
_invalid_downlink("NIC session RAM quota");
throw Insufficient_ram_quota();
}
catch (Out_of_caps) {
Session_env session_env_stack { session_env };
session_env_stack.detach(ram_ptr);
session_env_stack.free(ram_ds);
_invalid_downlink("NIC session CAP quota");
throw Insufficient_cap_quota();
}
}
catch (Region_map::Invalid_dataspace) {
session_env_stack.free(ram_ds);