Пример #1
0
static int sender_iface(struct net_if *iface, struct net_pkt *pkt)
{
	if (!pkt->frags) {
		DBG("No data to send!\n");
		return -ENODATA;
	}

	if (test_started) {
		struct net_if_test *data = iface->dev->driver_data;

		DBG("Sending at iface %d %p\n", net_if_get_by_iface(iface),
		    iface);

		if (net_pkt_iface(pkt) != iface) {
			DBG("Invalid interface %p, expecting %p\n",
				 net_pkt_iface(pkt), iface);
			test_failed = true;
		}

		if (net_if_get_by_iface(iface) != data->idx) {
			DBG("Invalid interface %d index, expecting %d\n",
				 data->idx, net_if_get_by_iface(iface));
			test_failed = true;
		}
	}

	net_pkt_unref(pkt);

	k_sem_give(&wait_data);

	return 0;
}
Пример #2
0
static inline enum net_verdict process_data(struct net_pkt *pkt,
					    bool is_loopback)
{
	int ret;
	bool locally_routed = false;

#if defined(CONFIG_NET_IPV6_FRAGMENT)
	/* If the packet is routed back to us when we have reassembled
	 * an IPv6 packet, then do not pass it to L2 as the packet does
	 * not have link layer headers in it.
	 */
	if (net_pkt_ipv6_fragment_start(pkt)) {
		locally_routed = true;
	}
#endif

	/* If there is no data, then drop the packet. */
	if (!pkt->frags) {
		NET_DBG("Corrupted packet (frags %p)", pkt->frags);
		net_stats_update_processing_error();

		return NET_DROP;
	}

	if (!is_loopback && !locally_routed) {
		ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
		if (ret != NET_CONTINUE) {
			if (ret == NET_DROP) {
				NET_DBG("Packet %p discarded by L2", pkt);
				net_stats_update_processing_error();
			}

			return ret;
		}
	}

	/* IP version and header length. */
	switch (NET_IPV6_HDR(pkt)->vtc & 0xf0) {
#if defined(CONFIG_NET_IPV6)
	case 0x60:
		net_stats_update_ipv6_recv();
		net_pkt_set_family(pkt, PF_INET6);
		return net_ipv6_process_pkt(pkt);
#endif
#if defined(CONFIG_NET_IPV4)
	case 0x40:
		net_stats_update_ipv4_recv();
		net_pkt_set_family(pkt, PF_INET);
		return net_ipv4_process_pkt(pkt);
#endif
	}

	NET_DBG("Unknown IP family packet (0x%x)",
		NET_IPV6_HDR(pkt)->vtc & 0xf0);
	net_stats_update_ip_errors_protoerr();
	net_stats_update_ip_errors_vhlerr();

	return NET_DROP;
}
Пример #3
0
static int loopback_send(struct device *dev, struct net_pkt *pkt)
{
	struct net_pkt *cloned;
	int res;

	ARG_UNUSED(dev);

	if (!pkt->frags) {
		LOG_ERR("No data to send");
		return -ENODATA;
	}

	/* We need to swap the IP addresses because otherwise
	 * the packet will be dropped.
	 */

	if (net_pkt_family(pkt) == AF_INET6) {
		struct in6_addr addr;

		net_ipaddr_copy(&addr, &NET_IPV6_HDR(pkt)->src);
		net_ipaddr_copy(&NET_IPV6_HDR(pkt)->src,
				&NET_IPV6_HDR(pkt)->dst);
		net_ipaddr_copy(&NET_IPV6_HDR(pkt)->dst, &addr);
	} else {
		struct in_addr addr;

		net_ipaddr_copy(&addr, &NET_IPV4_HDR(pkt)->src);
		net_ipaddr_copy(&NET_IPV4_HDR(pkt)->src,
				&NET_IPV4_HDR(pkt)->dst);
		net_ipaddr_copy(&NET_IPV4_HDR(pkt)->dst, &addr);
	}

	/* We should simulate normal driver meaning that if the packet is
	 * properly sent (which is always in this driver), then the packet
	 * must be dropped. This is very much needed for TCP packets where
	 * the packet is reference counted in various stages of sending.
	 */
	cloned = net_pkt_clone(pkt, K_MSEC(100));
	if (!cloned) {
		res = -ENOMEM;
		goto out;
	}

	res = net_recv_data(net_pkt_iface(cloned), cloned);
	if (res < 0) {
		LOG_ERR("Data receive failed.");
	}

out:
	/* Let the receiving thread run now */
	k_yield();

	return res;
}
Пример #4
0
/* Called when data needs to be sent to network */
int net_send_data(struct net_pkt *pkt)
{
	int status;

	if (!pkt || !pkt->frags) {
		return -ENODATA;
	}

	if (!net_pkt_iface(pkt)) {
		return -EINVAL;
	}

#if defined(CONFIG_NET_STATISTICS)
	switch (net_pkt_family(pkt)) {
	case AF_INET:
		net_stats_update_ipv4_sent();
		break;
	case AF_INET6:
		net_stats_update_ipv6_sent();
		break;
	}
#endif

	status = check_ip_addr(pkt);
	if (status < 0) {
		return status;
	} else if (status > 0) {
		/* Packet is destined back to us so send it directly
		 * to RX processing.
		 */
		NET_DBG("Loopback pkt %p back to us", pkt);
		processing_data(pkt, true);
		return 0;
	}

	if (net_if_send_data(net_pkt_iface(pkt), pkt) == NET_DROP) {
		return -EIO;
	}

	return 0;
}
Пример #5
0
static int eth_send(struct device *dev, struct net_pkt *pkt)
{
	struct eth_context *ctx = dev->driver_data;
	int count = net_pkt_get_len(pkt);
	int ret;

	ret = net_pkt_read(pkt, ctx->send, count);
	if (ret) {
		return ret;
	}

	update_gptp(net_pkt_iface(pkt), pkt, true);

	LOG_DBG("Send pkt %p len %d", pkt, count);

	ret = eth_write_data(ctx->dev_fd, ctx->send, count);
	if (ret < 0) {
		LOG_DBG("Cannot send pkt %p (%d)", pkt, ret);
	}

	return ret < 0 ? ret : 0;
}
Пример #6
0
struct net_pkt *net_ipv4_create(struct net_context *context,
				struct net_pkt *pkt,
				const struct in_addr *src,
				const struct in_addr *dst)
{
	NET_ASSERT(((struct sockaddr_in_ptr *)&context->local)->sin_addr);

	if (!src) {
		src = ((struct sockaddr_in_ptr *)&context->local)->sin_addr;
	}

	if (net_is_ipv4_addr_unspecified(src)
	    || net_is_ipv4_addr_mcast(src)) {
		src = &net_pkt_iface(pkt)->ipv4.unicast[0].address.in_addr;
	}

	return net_ipv4_create_raw(pkt,
				   src,
				   dst,
				   net_context_get_iface(context),
				   net_context_get_ip_proto(context));
}