introduced datalink's send_datagram to perform route and source address selection and dispatch the datagram to appropriate domain/protocol.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20714 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-04-15 22:11:12 +00:00
parent f106e0650e
commit 1408d1f0ce
4 changed files with 40 additions and 30 deletions

View File

@ -66,10 +66,12 @@ struct net_datalink_module_info {
status_t (*control)(struct net_domain *domain, int32 option, void *value,
size_t *_length);
status_t (*send_data)(struct net_route *route, struct net_buffer *buffer);
status_t (*send_datagram)(struct net_protocol *protocol,
struct net_domain *domain, struct net_buffer *buffer);
bool (*is_local_address)(struct net_domain *domain,
bool (*is_local_address)(struct net_domain *domain,
const struct sockaddr *address,
net_interface **_interface,
net_interface **_interface,
uint32 *_matchedType);
net_interface *(*get_interface)(struct net_domain *domain, uint32 index);
net_interface *(*get_interface_with_address)(struct net_domain *domain,

View File

@ -1353,34 +1353,20 @@ ipv4_send_data(net_protocol *_protocol, net_buffer *buffer)
TRACE_SK(protocol, "SendData(%p [%ld bytes])", buffer, buffer->size);
if (protocol) {
if (protocol->flags & IP_FLAG_HEADER_INCLUDED) {
if (buffer->size < sizeof(ipv4_header))
return EINVAL;
if (protocol && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) {
if (buffer->size < sizeof(ipv4_header))
return EINVAL;
sockaddr_in *source = (sockaddr_in *)&buffer->source;
sockaddr_in *destination = (sockaddr_in *)&buffer->destination;
sockaddr_in *source = (sockaddr_in *)&buffer->source;
sockaddr_in *destination = (sockaddr_in *)&buffer->destination;
fill_sockaddr_in(source, *NetBufferField<in_addr_t,
offsetof(ipv4_header, source)>(buffer));
fill_sockaddr_in(destination, *NetBufferField<in_addr_t,
offsetof(ipv4_header, destination)>(buffer));
}
fill_sockaddr_in(source, *NetBufferField<in_addr_t,
offsetof(ipv4_header, source)>(buffer));
fill_sockaddr_in(destination, *NetBufferField<in_addr_t,
offsetof(ipv4_header, destination)>(buffer));
}
net_route *route = NULL;
status_t status = sDatalinkModule->get_buffer_route(sDomain, buffer,
&route);
if (status >= B_OK) {
if (protocol)
status = protocol->socket->first_protocol->module->send_routed_data(
protocol->socket->first_protocol, route, buffer);
else
status = ipv4_send_routed_data(NULL, route, buffer);
sDatalinkModule->put_route(sDomain, route);
}
return status;
return sDatalinkModule->send_datagram(protocol, sDomain, buffer);
}

View File

@ -911,10 +911,7 @@ UdpEndpoint::SendData(net_buffer *buffer)
{
TRACE_EP("SendData(%p [%lu bytes])", buffer, buffer->size);
// This will call into IPv4 which will do all of the obtaining
// routes and other datagram related dirty work and eventually
// call back into our send_routed_data.
return next->module->send_data(next, buffer);
return gDatalinkModule->send_datagram(this, NULL, buffer);
}

View File

@ -362,6 +362,30 @@ datalink_send_data(struct net_route *route, net_buffer *buffer)
}
status_t
datalink_send_datagram(net_protocol *protocol, net_domain *domain,
net_buffer *buffer)
{
if (protocol == NULL && domain == NULL)
return B_BAD_VALUE;
net_protocol_module_info *module = protocol ? protocol->module
: domain->module;
if (domain == NULL)
domain = protocol->module->get_domain(protocol);
net_route *route = NULL;
status_t status = get_buffer_route(domain, buffer, &route);
if (status < B_OK)
return status;
status = module->send_routed_data(protocol, route, buffer);
put_route(domain, route);
return status;
}
/*!
Tests if \a address is a local address in the domain.
\param _interface will be set to the interface belonging to that address
@ -784,6 +808,7 @@ net_datalink_module_info gNetDatalinkModule = {
datalink_control,
datalink_send_data,
datalink_send_datagram,
datalink_is_local_address,
datalink_get_interface,
datalink_get_interface_with_address,