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:
@@ -66,6 +66,8 @@ struct net_datalink_module_info {
|
|||||||
status_t (*control)(struct net_domain *domain, int32 option, void *value,
|
status_t (*control)(struct net_domain *domain, int32 option, void *value,
|
||||||
size_t *_length);
|
size_t *_length);
|
||||||
status_t (*send_data)(struct net_route *route, struct net_buffer *buffer);
|
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,
|
const struct sockaddr *address,
|
||||||
|
|||||||
@@ -1353,34 +1353,20 @@ ipv4_send_data(net_protocol *_protocol, net_buffer *buffer)
|
|||||||
|
|
||||||
TRACE_SK(protocol, "SendData(%p [%ld bytes])", buffer, buffer->size);
|
TRACE_SK(protocol, "SendData(%p [%ld bytes])", buffer, buffer->size);
|
||||||
|
|
||||||
if (protocol) {
|
if (protocol && (protocol->flags & IP_FLAG_HEADER_INCLUDED)) {
|
||||||
if (protocol->flags & IP_FLAG_HEADER_INCLUDED) {
|
if (buffer->size < sizeof(ipv4_header))
|
||||||
if (buffer->size < sizeof(ipv4_header))
|
return EINVAL;
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
sockaddr_in *source = (sockaddr_in *)&buffer->source;
|
sockaddr_in *source = (sockaddr_in *)&buffer->source;
|
||||||
sockaddr_in *destination = (sockaddr_in *)&buffer->destination;
|
sockaddr_in *destination = (sockaddr_in *)&buffer->destination;
|
||||||
|
|
||||||
fill_sockaddr_in(source, *NetBufferField<in_addr_t,
|
fill_sockaddr_in(source, *NetBufferField<in_addr_t,
|
||||||
offsetof(ipv4_header, source)>(buffer));
|
offsetof(ipv4_header, source)>(buffer));
|
||||||
fill_sockaddr_in(destination, *NetBufferField<in_addr_t,
|
fill_sockaddr_in(destination, *NetBufferField<in_addr_t,
|
||||||
offsetof(ipv4_header, destination)>(buffer));
|
offsetof(ipv4_header, destination)>(buffer));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
net_route *route = NULL;
|
return sDatalinkModule->send_datagram(protocol, sDomain, buffer);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -911,10 +911,7 @@ UdpEndpoint::SendData(net_buffer *buffer)
|
|||||||
{
|
{
|
||||||
TRACE_EP("SendData(%p [%lu bytes])", buffer, buffer->size);
|
TRACE_EP("SendData(%p [%lu bytes])", buffer, buffer->size);
|
||||||
|
|
||||||
// This will call into IPv4 which will do all of the obtaining
|
return gDatalinkModule->send_datagram(this, NULL, buffer);
|
||||||
// routes and other datagram related dirty work and eventually
|
|
||||||
// call back into our send_routed_data.
|
|
||||||
return next->module->send_data(next, buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
Tests if \a address is a local address in the domain.
|
||||||
\param _interface will be set to the interface belonging to that address
|
\param _interface will be set to the interface belonging to that address
|
||||||
@@ -784,6 +808,7 @@ net_datalink_module_info gNetDatalinkModule = {
|
|||||||
|
|
||||||
datalink_control,
|
datalink_control,
|
||||||
datalink_send_data,
|
datalink_send_data,
|
||||||
|
datalink_send_datagram,
|
||||||
datalink_is_local_address,
|
datalink_is_local_address,
|
||||||
datalink_get_interface,
|
datalink_get_interface,
|
||||||
datalink_get_interface_with_address,
|
datalink_get_interface_with_address,
|
||||||
|
|||||||
Reference in New Issue
Block a user