diff --git a/headers/private/net/net_datalink.h b/headers/private/net/net_datalink.h index 2b007a0454..868575a2cb 100644 --- a/headers/private/net/net_datalink.h +++ b/headers/private/net/net_datalink.h @@ -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, diff --git a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp index 9cccfe1771..fae5d02148 100644 --- a/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp +++ b/src/add-ons/kernel/network/protocols/ipv4/ipv4.cpp @@ -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(buffer)); - fill_sockaddr_in(destination, *NetBufferField(buffer)); - } + fill_sockaddr_in(source, *NetBufferField(buffer)); + fill_sockaddr_in(destination, *NetBufferField(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); } diff --git a/src/add-ons/kernel/network/protocols/udp/udp.cpp b/src/add-ons/kernel/network/protocols/udp/udp.cpp index 9d3e59a82b..0d44470bfe 100644 --- a/src/add-ons/kernel/network/protocols/udp/udp.cpp +++ b/src/add-ons/kernel/network/protocols/udp/udp.cpp @@ -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); } diff --git a/src/add-ons/kernel/network/stack/datalink.cpp b/src/add-ons/kernel/network/stack/datalink.cpp index 178583f745..e823d01156 100644 --- a/src/add-ons/kernel/network/stack/datalink.cpp +++ b/src/add-ons/kernel/network/stack/datalink.cpp @@ -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,