Skip to content

L3IP Interface Implementation #8739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions features/lwipstack/LWIPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,60 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
#endif //LWIP_ETHERNET
}


nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetworkStack::Interface **interface_out)
{
#if LWIP_L3IP
Interface *interface = new (std::nothrow) Interface();
if (!interface) {
return NSAPI_ERROR_NO_MEMORY;
}
interface->l3ip = &l3ip;
interface->memory_manager = &memory_manager;
interface->ppp = false;



// interface->netif.hwaddr_len = 0; should we set?

if (!netif_add(&interface->netif,
#if LWIP_IPV4
0, 0, 0,
#endif
interface, &LWIP::Interface::emac_if_init, ip_input)) {
return NSAPI_ERROR_DEVICE_ERROR;
}

if (default_if) {
netif_set_default(&interface->netif);
default_interface = interface;
}

netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq);
netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq);

*interface_out = interface;


//lwip_add_random_seed(seed); to do?

return NSAPI_ERROR_OK;

#else
return NSAPI_ERROR_UNSUPPORTED;

#endif //LWIP_L3IP
}

nsapi_error_t LWIP::remove_l3ip_interface(OnboardNetworkStack::Interface **interface_out)
{
#if LWIP_L3IP
return NSAPI_ERROR_OK;
#else
return NSAPI_ERROR_UNSUPPORTED;

#endif //LWIP_L3IP
}
/* Internal API to preserve existing PPP functionality - revise to better match mbed_ipstak_add_ethernet_interface later */
nsapi_error_t LWIP::_add_ppp_interface(void *hw, bool default_if, nsapi_ip_stack_t stack, LWIP::Interface **interface_out)
{
Expand Down
166 changes: 166 additions & 0 deletions features/lwipstack/LWIPInterfaceL3IP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright (c) 2018 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "lwip/tcpip.h"
#include "lwip/tcp.h"
#include "lwip/ip.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "netsocket/nsapi_types.h"
#include "netsocket/L3IP.h"

#include "LWIPStack.h"

#if LWIP_L3IP

err_t LWIP::Interface::l3ip_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
{
/* Increase reference counter since lwip stores handle to pbuf and frees
it after output */
pbuf_ref(p);

LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
bool ret = mbed_if->l3ip->link_out(p);
return ret ? ERR_OK : ERR_IF;
}

void LWIP::Interface::l3ip_input(net_stack_mem_buf_t *buf)
{
struct pbuf *p = static_cast<struct pbuf *>(buf);

/* pass all packets to IP stack input */
if (netif.input(p, &netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("Emac LWIP: IP input error\n"));

pbuf_free(p);
}
}

void LWIP::Interface::l3ip_state_change(bool up)
{
if (up) {
tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, &netif, 1);
} else {
tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, &netif, 1);
}
}

#if LWIP_IGMP

#include "lwip/igmp.h"
/**
* IPv4 address filtering setup.
*
* \param[in] netif the lwip network interface structure
* \param[in] group IPv4 group to modify
* \param[in] action
* \return ERR_OK or error code
*/
err_t LWIP::Interface::l3ip_multicast_ipv4_filter(struct netif *netif, const ip4_addr_t *group, enum netif_mac_filter_action action)
{
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
SocketAddress addr(&group, NSAPI_IPv6);
switch (action) {
case NETIF_ADD_MAC_FILTER: {
mbed_if->l3ip->add_ipv4_multicast_group(addr.get_ip_address());
return ERR_OK;
}
case NETIF_DEL_MAC_FILTER:
mbed_if->l3ip->remove_ipv4_multicast_group(addr.get_ip_address());
return ERR_OK;
default:
return ERR_ARG;
}

}
#endif

#if LWIP_IPV6_MLD

#include "lwip/mld6.h"
/**
* IPv6 address filtering setup.
*
* \param[in] netif the lwip network interface structure
* \param[in] group IPv6 group to modify
* \param[in] action
* \return ERR_OK or error code
*/
err_t LWIP::Interface::l3ip_multicast_ipv6_filter(struct netif *netif, const ip6_addr_t *group, enum netif_mac_filter_action action)
{
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
SocketAddress addr(&group, NSAPI_IPv6);
switch (action) {
case NETIF_ADD_MAC_FILTER: {

mbed_if->l3ip->add_ipv6_multicast_group(addr.get_ip_address());
return ERR_OK;
}
case NETIF_DEL_MAC_FILTER:
mbed_if->l3ip->remove_ipv6_multicast_group(addr.get_ip_address());
return ERR_OK;
default:
return ERR_ARG;
}

}
#endif

err_t LWIP::Interface::l3ip_if_init(struct netif *netif)
{
int err = ERR_OK;
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);

mbed_if->l3ip->set_memory_manager(*mbed_if->memory_manager);
mbed_if->l3ip->set_link_input_cb(mbed::callback(mbed_if, &LWIP::Interface::l3ip_input));
mbed_if->l3ip->set_link_state_cb(mbed::callback(mbed_if, &LWIP::Interface::l3ip_state_change));

/* Interface capabilities */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET;

if (!mbed_if->l3ip->power_up()) {
err = ERR_IF;
}

netif->mtu = mbed_if->l3ip->get_mtu_size();
mbed_if->l3ip->get_ifname(netif->name, NSAPI_INTERFACE_NAME_SIZE);

#if LWIP_IPV4
netif->output = &LWIP::Interface::l3ip_output;
#if LWIP_IGMP
netif->igmp_mac_filter = &LWIP::Interface::l3ip_multicast_ipv4_filter;
netif->flags |= NETIF_FLAG_IGMP;
#endif /* LWIP_IGMP */
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
//netif->output_ip6 = ethip6_output;//to be done
#if LWIP_IPV6_MLD
netif->mld_mac_filter = &LWIP::Interface::l3ip_multicast_ipv6_filter;
netif->flags |= NETIF_FLAG_MLD6;
#else
// Would need to enable all multicasts here - no API in fsl_enet to do that
#error "IPv6 multicasts won't be received if LWIP_IPV6_MLD is disabled, breaking the system"
#endif
#endif

netif->linkoutput = NULL;

return err;
}

#endif

30 changes: 15 additions & 15 deletions features/lwipstack/LWIPMemoryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "pbuf.h"
#include "LWIPMemoryManager.h"

emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
net_stack_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
{
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
if (pbuf == NULL) {
Expand All @@ -25,10 +25,10 @@ emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)

align_memory(pbuf, align);

return static_cast<emac_mem_buf_t *>(pbuf);
return static_cast<net_stack_mem_buf_t *>(pbuf);
}

emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
net_stack_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
{
uint32_t total_align = count_total_align(size, align);

Expand All @@ -39,7 +39,7 @@ emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)

align_memory(pbuf, align);

return static_cast<emac_mem_buf_t *>(pbuf);
return static_cast<net_stack_mem_buf_t *>(pbuf);
}

uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
Expand All @@ -48,56 +48,56 @@ uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
return alloc_unit;
}

void LWIPMemoryManager::free(emac_mem_buf_t *buf)
void LWIPMemoryManager::free(net_stack_mem_buf_t *buf)
{
pbuf_free(static_cast<struct pbuf *>(buf));
}

uint32_t LWIPMemoryManager::get_total_len(const emac_mem_buf_t *buf) const
uint32_t LWIPMemoryManager::get_total_len(const net_stack_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->tot_len;
}

void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf)
void LWIPMemoryManager::copy(net_stack_mem_buf_t *to_buf, const net_stack_mem_buf_t *from_buf)
{
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
}

void LWIPMemoryManager::copy_to_buf(emac_mem_buf_t *to_buf, const void *ptr, uint32_t len)
void LWIPMemoryManager::copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len)
{
pbuf_take(static_cast<struct pbuf *>(to_buf), ptr, len);
}

uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const emac_mem_buf_t *from_buf) const
uint32_t LWIPMemoryManager::copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const
{
return pbuf_copy_partial(static_cast<const struct pbuf *>(from_buf), ptr, len, 0);
}

void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
void LWIPMemoryManager::cat(net_stack_mem_buf_t *to_buf, net_stack_mem_buf_t *cat_buf)
{
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));
}

emac_mem_buf_t *LWIPMemoryManager::get_next(const emac_mem_buf_t *buf) const
net_stack_mem_buf_t *LWIPMemoryManager::get_next(const net_stack_mem_buf_t *buf) const
{
if (!buf) {
return NULL;
}
struct pbuf *next = (static_cast<const struct pbuf *>(buf))->next;
return static_cast<emac_mem_buf_t *>(next);
return static_cast<net_stack_mem_buf_t *>(next);
}

void *LWIPMemoryManager::get_ptr(const emac_mem_buf_t *buf) const
void *LWIPMemoryManager::get_ptr(const net_stack_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->payload;
}

uint32_t LWIPMemoryManager::get_len(const emac_mem_buf_t *buf) const
uint32_t LWIPMemoryManager::get_len(const net_stack_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->len;
}

void LWIPMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len)
void LWIPMemoryManager::set_len(net_stack_mem_buf_t *buf, uint32_t len)
{
struct pbuf *pbuf = static_cast<struct pbuf *>(buf);
pbuf->len = len;
Expand Down
Loading