<commit_before>/** @file
 * @brief LLDP related functions
 */

/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(net_lldp, CONFIG_NET_LLDP_LOG_LEVEL);

#include <errno.h>
#include <stdlib.h>

#include <net/net_core.h>
#include <net/ethernet.h>
#include <net/net_mgmt.h>
#include <net/lldp.h>

static struct net_mgmt_event_callback cb;

/* Have only one timer in order to save memory */
static struct k_delayed_work lldp_tx_timer;

/* Track currently active timers */
static sys_slist_t lldp_ifaces;

#define BUF_ALLOC_TIMEOUT K_MSEC(50)

static int lldp_find(struct ethernet_context *ctx, struct net_if *iface)
{
	int i, found = -1;

	for (i = 0; i < ARRAY_SIZE(ctx->lldp); i++) {
		if (ctx->lldp[i].iface == iface) {
			return i;
		}

		if (found < 0 && ctx->lldp[i].iface == NULL) {
			found = i;
		}
	}

	if (found >= 0) {
		ctx->lldp[found].iface = iface;
		return found;
	}

	return -ENOENT;
}

static void lldp_submit_work(u32_t timeout)
{
	if (!k_delayed_work_remaining_get(&lldp_tx_timer) ||
	    timeout < k_delayed_work_remaining_get(&lldp_tx_timer)) {
		k_delayed_work_cancel(&lldp_tx_timer);
		k_delayed_work_submit(&lldp_tx_timer, K_MSEC(timeout));

		NET_DBG("Next wakeup in %d ms",
			k_delayed_work_remaining_get(&lldp_tx_timer));
	}
}

static bool lldp_check_timeout(s64_t start, u32_t time, s64_t timeout)
{
	start += time;
	start = abs(start);

	if (start > timeout) {
		return false;
	}

	return true;
}

static bool lldp_timedout(struct ethernet_lldp *lldp, s64_t timeout)
{
	return lldp_check_timeout(lldp->tx_timer_start,
				  lldp->tx_timer_timeout,
				  timeout);
}

static int lldp_send(struct ethernet_lldp *lldp)
{
	static const struct net_eth_addr lldp_multicast_eth_addr = {
		{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
	};
	int ret = 0;
	struct net_pkt *pkt;
	size_t len;

	if (!lldp->lldpdu) {
		/* The ethernet driver has not set the lldpdu pointer */
		NET_DBG("The LLDPDU is not set for lldp %p", lldp);
		ret = -EINVAL;
		goto out;
	}

	if (lldp->optional_du && lldp->optional_len) {
		len = sizeof(struct net_lldpdu) + lldp->optional_len;
	} else {
		len = sizeof(struct net_lldpdu);
	}

	pkt = net_pkt_alloc_with_buffer(lldp->iface, len, AF_UNSPEC, 0,
					BUF_ALLOC_TIMEOUT);
	if (!pkt) {
		ret = -ENOMEM;
		goto out;
	}

	if (net_pkt_write(pkt, (u8_t *)lldp->lldpdu,
			  sizeof(struct net_lldpdu))) {
		net_pkt_unref(pkt);
		ret = -ENOMEM;
		goto out;
	}

	if (lldp->optional_du && lldp->optional_len) {
		if (!net_pkt_write(pkt, (u8_t *)lldp->optional_du,
				   lldp->optional_len)) {
			net_pkt_unref(pkt);
			ret = -ENOMEM;
			goto out;
		}
	}

	if (IS_ENABLED(CONFIG_NET_LLDP_END_LLDPDU_TLV_ENABLED)) {
		u16_t tlv_end = htons(NET_LLDP_END_LLDPDU_VALUE);

		if (!net_pkt_write(pkt, (u8_t *)&tlv_end, sizeof(tlv_end))) {
			net_pkt_unref(pkt);
			ret = -ENOMEM;
			goto out;
		}
	}<commit_msg>net: lldp: Sent LLDP packet was missing proper net_pkt type<commit_after>/** @file
 * @brief LLDP related functions
 */

/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <logging/log.h>
LOG_MODULE_REGISTER(net_lldp, CONFIG_NET_LLDP_LOG_LEVEL);

#include <errno.h>
#include <stdlib.h>

#include <net/net_core.h>
#include <net/ethernet.h>
#include <net/net_mgmt.h>
#include <net/lldp.h>

static struct net_mgmt_event_callback cb;

/* Have only one timer in order to save memory */
static struct k_delayed_work lldp_tx_timer;

/* Track currently active timers */
static sys_slist_t lldp_ifaces;

#define BUF_ALLOC_TIMEOUT K_MSEC(50)

static int lldp_find(struct ethernet_context *ctx, struct net_if *iface)
{
	int i, found = -1;

	for (i = 0; i < ARRAY_SIZE(ctx->lldp); i++) {
		if (ctx->lldp[i].iface == iface) {
			return i;
		}

		if (found < 0 && ctx->lldp[i].iface == NULL) {
			found = i;
		}
	}

	if (found >= 0) {
		ctx->lldp[found].iface = iface;
		return found;
	}

	return -ENOENT;
}

static void lldp_submit_work(u32_t timeout)
{
	if (!k_delayed_work_remaining_get(&lldp_tx_timer) ||
	    timeout < k_delayed_work_remaining_get(&lldp_tx_timer)) {
		k_delayed_work_cancel(&lldp_tx_timer);
		k_delayed_work_submit(&lldp_tx_timer, K_MSEC(timeout));

		NET_DBG("Next wakeup in %d ms",
			k_delayed_work_remaining_get(&lldp_tx_timer));
	}
}

static bool lldp_check_timeout(s64_t start, u32_t time, s64_t timeout)
{
	start += time;
	start = abs(start);

	if (start > timeout) {
		return false;
	}

	return true;
}

static bool lldp_timedout(struct ethernet_lldp *lldp, s64_t timeout)
{
	return lldp_check_timeout(lldp->tx_timer_start,
				  lldp->tx_timer_timeout,
				  timeout);
}

static int lldp_send(struct ethernet_lldp *lldp)
{
	static const struct net_eth_addr lldp_multicast_eth_addr = {
		{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
	};
	int ret = 0;
	struct net_pkt *pkt;
	size_t len;

	if (!lldp->lldpdu) {
		/* The ethernet driver has not set the lldpdu pointer */
		NET_DBG("The LLDPDU is not set for lldp %p", lldp);
		ret = -EINVAL;
		goto out;
	}

	if (lldp->optional_du && lldp->optional_len) {
		len = sizeof(struct net_lldpdu) + lldp->optional_len;
	} else {
		len = sizeof(struct net_lldpdu);
	}

	pkt = net_pkt_alloc_with_buffer(lldp->iface, len, AF_UNSPEC, 0,
					BUF_ALLOC_TIMEOUT);
	if (!pkt) {
		ret = -ENOMEM;
		goto out;
	}

	net_pkt_set_lldp(pkt, true);

	if (net_pkt_write(pkt, (u8_t *)lldp->lldpdu,
			  sizeof(struct net_lldpdu))) {
		net_pkt_unref(pkt);
		ret = -ENOMEM;
		goto out;
	}

	if (lldp->optional_du && lldp->optional_len) {
		if (!net_pkt_write(pkt, (u8_t *)lldp->optional_du,
				   lldp->optional_len)) {
			net_pkt_unref(pkt);
			ret = -ENOMEM;
			goto out;
		}
	}

	if (IS_ENABLED(CONFIG_NET_LLDP_END_LLDPDU_TLV_ENABLED)) {
		u16_t tlv_end = htons(NET_LLDP_END_LLDPDU_VALUE);

		if (!net_pkt_write(pkt, (u8_t *)&tlv_end, sizeof(tlv_end))) {
			net_pkt_unref(pkt);
			ret = -ENOMEM;
			goto out;
		}
	}
{'fraction_non_alphanumeric': 0.13279270146984287, 'fraction_numerical': 0.015205271160669031, 'mean_word_length': 4.138888888888889, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1346748', 'n_tokens_mistral': 2781, 'n_tokens_neox': 2624, 'n_words': 515}