blob: 3700ac4279a7851da875d57e777b376c08165a96 [file] [log] [blame]
/*
* Copyright (c) 2020 DENX Software Engineering GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_dsa_lldp_sample, CONFIG_NET_DSA_LOG_LEVEL);
#include <zephyr/net/dsa.h>
#include "main.h"
static void iface_cb(struct net_if *iface, void *user_data)
{
struct ud *ifaces = user_data;
if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return;
}
if (net_eth_get_hw_capabilities(iface) & ETHERNET_DSA_MASTER_PORT) {
if (ifaces->master == NULL) {
ifaces->master = iface;
/* Get slave interfaces */
for (int i = 0; i < ARRAY_SIZE(ifaces->lan); i++) {
struct net_if *slave = dsa_get_slave_port(iface, i);
if (slave == NULL) {
LOG_ERR("Slave interface %d not found.", i);
break;
}
ifaces->lan[i] = slave;
}
return;
}
}
}
static const uint8_t eth_filter_l2_addr_base[][6] = {
/* MAC address of other device - for filtering testing */
{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }
};
enum net_verdict dsa_ll_addr_switch_cb(struct net_if *iface,
struct net_pkt *pkt)
{
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
struct net_linkaddr lladst;
net_pkt_cursor_init(pkt);
lladst.len = sizeof(hdr->dst.addr);
lladst.addr = &hdr->dst.addr[0];
/*
* Pass packet to lan1..3 when matching one from
* check_ll_ether_addr table
*/
if (check_ll_ether_addr(lladst.addr, &eth_filter_l2_addr_base[0][0])) {
return 1;
}
return 0;
}
int start_slave_port_packet_socket(struct net_if *iface,
struct instance_data *pd)
{
struct sockaddr_ll dst;
int ret;
pd->sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
if (pd->sock < 0) {
LOG_ERR("Failed to create RAW socket : %d", errno);
return -errno;
}
dst.sll_ifindex = net_if_get_by_iface(iface);
dst.sll_family = AF_PACKET;
ret = bind(pd->sock, (const struct sockaddr *)&dst,
sizeof(struct sockaddr_ll));
if (ret < 0) {
LOG_ERR("Failed to bind packet socket : %d", errno);
return -errno;
}
return 0;
}
struct ud ifaces;
static int init_dsa_ports(void)
{
uint8_t tbl_buf[8];
/* Initialize interfaces - read them to ifaces */
(void)memset(&ifaces, 0, sizeof(ifaces));
net_if_foreach(iface_cb, &ifaces);
/*
* Set static table to forward LLDP protocol packets
* to master port.
*/
dsa_switch_set_mac_table_entry(ifaces.lan[0],
&eth_filter_l2_addr_base[0][0],
BIT(4), 0, 0);
dsa_switch_get_mac_table_entry(ifaces.lan[0], tbl_buf, 0);
LOG_INF("DSA static MAC address table entry [%d]:", 0);
LOG_INF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
tbl_buf[7], tbl_buf[6], tbl_buf[5], tbl_buf[4],
tbl_buf[3], tbl_buf[2], tbl_buf[1], tbl_buf[0]);
return 0;
}
void main(void)
{
init_dsa_ports();
LOG_INF("DSA ports init - OK");
}