AP_Networking: added option for PPP<->ethernet bridge
when NET_OPTIONS is set to enable PPP bridging both an ethernet and a PPP link will be brought up, with IP forwarding making the PPP remote endpoint available on the ethernet LAN
This commit is contained in:
parent
5414416230
commit
39a1fc9dbd
@ -86,6 +86,20 @@ const AP_Param::GroupInfo AP_Networking::var_info[] = {
|
|||||||
AP_SUBGROUPINFO(param.test_ipaddr, "TEST_IP", 8, AP_Networking, AP_Networking_IPV4),
|
AP_SUBGROUPINFO(param.test_ipaddr, "TEST_IP", 8, AP_Networking, AP_Networking_IPV4),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @Param: OPTIONS
|
||||||
|
// @DisplayName: Networking options
|
||||||
|
// @Description: Networking options
|
||||||
|
// @Bitmask: 0:EnablePPP Ethernet gateway
|
||||||
|
// @RebootRequired: True
|
||||||
|
// @User: Advanced
|
||||||
|
AP_GROUPINFO("OPTIONS", 9, AP_Networking, param.options, 0),
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
// @Group: REMPPP_IP
|
||||||
|
// @Path: AP_Networking_address.cpp
|
||||||
|
AP_SUBGROUPINFO(param.remote_ppp_ip, "REMPPP_IP", 10, AP_Networking, AP_Networking_IPV4),
|
||||||
|
#endif
|
||||||
|
|
||||||
AP_GROUPEND
|
AP_GROUPEND
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -129,8 +143,19 @@ void AP_Networking::init()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
if (option_is_set(OPTION::PPP_ETHERNET_GATEWAY)) {
|
||||||
|
/*
|
||||||
|
when we are a PPP/Ethernet gateway we bring up the ethernet first
|
||||||
|
*/
|
||||||
|
backend = new AP_Networking_ChibiOS(*this);
|
||||||
|
backend_PPP = new AP_Networking_PPP(*this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if AP_NETWORKING_BACKEND_PPP
|
#if AP_NETWORKING_BACKEND_PPP
|
||||||
if (AP::serialmanager().have_serial(AP_SerialManager::SerialProtocol_PPP, 0)) {
|
if (backend == nullptr && AP::serialmanager().have_serial(AP_SerialManager::SerialProtocol_PPP, 0)) {
|
||||||
backend = new AP_Networking_PPP(*this);
|
backend = new AP_Networking_PPP(*this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -158,6 +183,13 @@ void AP_Networking::init()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
if (backend_PPP != nullptr && !backend_PPP->init()) {
|
||||||
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "NET: backend_PPP init failed");
|
||||||
|
backend_PPP = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
announce_address_changes();
|
announce_address_changes();
|
||||||
|
|
||||||
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"NET: Initialized");
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"NET: Initialized");
|
||||||
|
@ -26,6 +26,7 @@ class AP_Networking
|
|||||||
public:
|
public:
|
||||||
friend class AP_Networking_Backend;
|
friend class AP_Networking_Backend;
|
||||||
friend class AP_Networking_ChibiOS;
|
friend class AP_Networking_ChibiOS;
|
||||||
|
friend class AP_Networking_PPP;
|
||||||
friend class AP_Vehicle;
|
friend class AP_Vehicle;
|
||||||
friend class Networking_Periph;
|
friend class Networking_Periph;
|
||||||
|
|
||||||
@ -149,6 +150,13 @@ public:
|
|||||||
|
|
||||||
static const struct AP_Param::GroupInfo var_info[];
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
|
|
||||||
|
enum class OPTION {
|
||||||
|
PPP_ETHERNET_GATEWAY=(1U<<0),
|
||||||
|
};
|
||||||
|
bool option_is_set(OPTION option) const {
|
||||||
|
return (param.options.get() & int32_t(option)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static AP_Networking *singleton;
|
static AP_Networking *singleton;
|
||||||
|
|
||||||
@ -172,10 +180,18 @@ private:
|
|||||||
AP_Int32 tests;
|
AP_Int32 tests;
|
||||||
AP_Networking_IPV4 test_ipaddr{AP_NETWORKING_TEST_IP};
|
AP_Networking_IPV4 test_ipaddr{AP_NETWORKING_TEST_IP};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
AP_Networking_IPV4 remote_ppp_ip{AP_NETWORKING_REMOTE_PPP_IP};
|
||||||
|
#endif
|
||||||
} param;
|
} param;
|
||||||
|
|
||||||
AP_Networking_Backend *backend;
|
AP_Networking_Backend *backend;
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
AP_Networking_Backend *backend_PPP;
|
||||||
|
#endif
|
||||||
|
|
||||||
HAL_Semaphore sem;
|
HAL_Semaphore sem;
|
||||||
|
|
||||||
enum class NetworkPortType {
|
enum class NetworkPortType {
|
||||||
|
@ -119,3 +119,17 @@
|
|||||||
#ifndef AP_NETWORKING_SENDFILE_BUFSIZE
|
#ifndef AP_NETWORKING_SENDFILE_BUFSIZE
|
||||||
#define AP_NETWORKING_SENDFILE_BUFSIZE (64*512)
|
#define AP_NETWORKING_SENDFILE_BUFSIZE (64*512)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
#define AP_NETWORKING_PPP_GATEWAY_ENABLED (AP_NETWORKING_BACKEND_CHIBIOS && AP_NETWORKING_BACKEND_PPP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
the IP address given to the remote end of the PPP link when running
|
||||||
|
as a PPP<->ethernet gateway. If this is on the same subnet as the
|
||||||
|
ethernet interface IP then proxyarp will be used
|
||||||
|
*/
|
||||||
|
#ifndef AP_NETWORKING_REMOTE_PPP_IP
|
||||||
|
#define AP_NETWORKING_REMOTE_PPP_IP "0.0.0.0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -57,10 +57,17 @@ void AP_Networking_PPP::ppp_status_callback(struct ppp_pcb_s *pcb, int code, voi
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case PPPERR_NONE:
|
case PPPERR_NONE:
|
||||||
// got new addresses for the link
|
// got new addresses for the link
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
if (driver.frontend.option_is_set(AP_Networking::OPTION::PPP_ETHERNET_GATEWAY)) {
|
||||||
|
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "PPP: got addresses");
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
driver.activeSettings.ip = ntohl(netif_ip4_addr(pppif)->addr);
|
driver.activeSettings.ip = ntohl(netif_ip4_addr(pppif)->addr);
|
||||||
driver.activeSettings.gw = ntohl(netif_ip4_gw(pppif)->addr);
|
driver.activeSettings.gw = ntohl(netif_ip4_gw(pppif)->addr);
|
||||||
driver.activeSettings.nm = ntohl(netif_ip4_netmask(pppif)->addr);
|
driver.activeSettings.nm = ntohl(netif_ip4_netmask(pppif)->addr);
|
||||||
driver.activeSettings.last_change_ms = AP_HAL::millis();
|
driver.activeSettings.last_change_ms = AP_HAL::millis();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPPERR_OPEN:
|
case PPPERR_OPEN:
|
||||||
@ -94,10 +101,13 @@ bool AP_Networking_PPP::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool ethernet_gateway = frontend.option_is_set(AP_Networking::OPTION::PPP_ETHERNET_GATEWAY);
|
||||||
|
if (!ethernet_gateway) {
|
||||||
// initialise TCP/IP thread
|
// initialise TCP/IP thread
|
||||||
LWIP_TCPIP_LOCK();
|
LWIP_TCPIP_LOCK();
|
||||||
tcpip_init(NULL, NULL);
|
tcpip_init(NULL, NULL);
|
||||||
LWIP_TCPIP_UNLOCK();
|
LWIP_TCPIP_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
hal.scheduler->delay(100);
|
hal.scheduler->delay(100);
|
||||||
|
|
||||||
@ -127,9 +137,14 @@ void AP_Networking_PPP::ppp_loop(void)
|
|||||||
while (!hal.scheduler->is_system_initialized()) {
|
while (!hal.scheduler->is_system_initialized()) {
|
||||||
hal.scheduler->delay_microseconds(1000);
|
hal.scheduler->delay_microseconds(1000);
|
||||||
}
|
}
|
||||||
|
const bool ppp_gateway = frontend.option_is_set(AP_Networking::OPTION::PPP_ETHERNET_GATEWAY);
|
||||||
|
if (ppp_gateway) {
|
||||||
|
// wait for the ethernet interface to be up
|
||||||
|
AP::network().startup_wait();
|
||||||
|
}
|
||||||
|
|
||||||
// ensure this thread owns the uart
|
// ensure this thread owns the uart
|
||||||
uart->begin(0);
|
uart->begin(AP::serialmanager().find_baudrate(AP_SerialManager::SerialProtocol_PPP, 0));
|
||||||
uart->set_unbuffered_writes(true);
|
uart->set_unbuffered_writes(true);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -137,9 +152,63 @@ void AP_Networking_PPP::ppp_loop(void)
|
|||||||
|
|
||||||
// connect and set as default route
|
// connect and set as default route
|
||||||
LWIP_TCPIP_LOCK();
|
LWIP_TCPIP_LOCK();
|
||||||
|
|
||||||
|
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
if (ppp_gateway) {
|
||||||
|
/*
|
||||||
|
when bridging setup the ppp interface with the same IP
|
||||||
|
as the ethernet interface, and set the remote IP address
|
||||||
|
as the local address + 1
|
||||||
|
*/
|
||||||
|
ip4_addr_t our_ip, his_ip;
|
||||||
|
const uint32_t ip = frontend.get_ip_active();
|
||||||
|
uint32_t rem_ip = frontend.param.remote_ppp_ip.get_uint32();
|
||||||
|
if (rem_ip == 0) {
|
||||||
|
// use ethernet IP +1 by default
|
||||||
|
rem_ip = ip+1;
|
||||||
|
}
|
||||||
|
our_ip.addr = htonl(ip);
|
||||||
|
his_ip.addr = htonl(rem_ip);
|
||||||
|
ppp_set_ipcp_ouraddr(ppp, &our_ip);
|
||||||
|
ppp_set_ipcp_hisaddr(ppp, &his_ip);
|
||||||
|
if (netif_list != nullptr) {
|
||||||
|
const uint32_t nmask = frontend.get_netmask_param();
|
||||||
|
if ((ip & nmask) == (rem_ip & nmask)) {
|
||||||
|
// remote PPP IP is on the same subnet as the
|
||||||
|
// local ethernet IP, so enable proxyarp to avoid
|
||||||
|
// users having to setup routes in all devices
|
||||||
|
netif_set_proxyarp(netif_list, &his_ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to the remote end
|
||||||
ppp_connect(ppp, 0);
|
ppp_connect(ppp, 0);
|
||||||
|
|
||||||
|
if (ppp_gateway) {
|
||||||
|
extern struct netif *netif_list;
|
||||||
|
/*
|
||||||
|
when we are setup as a PPP gateway we want the pppif to be
|
||||||
|
first in the list so routing works if it is on the same
|
||||||
|
subnet
|
||||||
|
*/
|
||||||
|
if (netif_list != nullptr &&
|
||||||
|
netif_list->next != nullptr &&
|
||||||
|
netif_list->next->next == pppif) {
|
||||||
|
netif_list->next->next = nullptr;
|
||||||
|
pppif->next = netif_list;
|
||||||
|
netif_list = pppif;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
netif_set_default(pppif);
|
netif_set_default(pppif);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// normal PPP link, connect to the remote end and set as the
|
||||||
|
// default route
|
||||||
|
ppp_connect(ppp, 0);
|
||||||
|
netif_set_default(pppif);
|
||||||
|
#endif // AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||||
|
|
||||||
LWIP_TCPIP_UNLOCK();
|
LWIP_TCPIP_UNLOCK();
|
||||||
|
|
||||||
need_restart = false;
|
need_restart = false;
|
||||||
|
@ -74,7 +74,6 @@ extern "C"
|
|||||||
#define LWIP_ICMP LWIP_IPV4
|
#define LWIP_ICMP LWIP_IPV4
|
||||||
|
|
||||||
#define LWIP_SNMP LWIP_UDP
|
#define LWIP_SNMP LWIP_UDP
|
||||||
#define MIB2_STATS LWIP_SNMP
|
|
||||||
#ifdef LWIP_HAVE_MBEDTLS
|
#ifdef LWIP_HAVE_MBEDTLS
|
||||||
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
||||||
#endif
|
#endif
|
||||||
@ -255,6 +254,7 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#define LWIP_ARP 1
|
#define LWIP_ARP 1
|
||||||
#define ARP_TABLE_SIZE 10
|
#define ARP_TABLE_SIZE 10
|
||||||
#define ARP_QUEUEING 1
|
#define ARP_QUEUEING 1
|
||||||
|
#define ARP_PROXYARP_SUPPORT 1
|
||||||
|
|
||||||
|
|
||||||
/* ---------- IP options ---------- */
|
/* ---------- IP options ---------- */
|
||||||
@ -263,6 +263,12 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
on a device with only one network interface, define this to 0. */
|
on a device with only one network interface, define this to 0. */
|
||||||
#define IP_FORWARD 1
|
#define IP_FORWARD 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
extra header space when forwarding for adding the ethernet header
|
||||||
|
*/
|
||||||
|
#define PBUF_LINK_HLEN 16
|
||||||
|
|
||||||
|
|
||||||
/* IP reassembly and segmentation.These are orthogonal even
|
/* IP reassembly and segmentation.These are orthogonal even
|
||||||
* if they both deal with IP fragments */
|
* if they both deal with IP fragments */
|
||||||
#define IP_REASSEMBLY 1
|
#define IP_REASSEMBLY 1
|
||||||
@ -302,22 +308,8 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
|
|
||||||
/* ---------- Statistics options ---------- */
|
/* ---------- Statistics options ---------- */
|
||||||
|
|
||||||
#define LWIP_STATS 1
|
#define LWIP_STATS 0
|
||||||
#define LWIP_STATS_DISPLAY 1
|
#define LWIP_STATS_DISPLAY 0
|
||||||
|
|
||||||
#if LWIP_STATS
|
|
||||||
#define LINK_STATS 1
|
|
||||||
#define IP_STATS 1
|
|
||||||
#define ICMP_STATS 1
|
|
||||||
#define IGMP_STATS 1
|
|
||||||
#define IPFRAG_STATS 1
|
|
||||||
#define UDP_STATS 1
|
|
||||||
#define TCP_STATS 1
|
|
||||||
#define MEM_STATS 1
|
|
||||||
#define MEMP_STATS 1
|
|
||||||
#define PBUF_STATS 1
|
|
||||||
#define SYS_STATS 1
|
|
||||||
#endif /* LWIP_STATS */
|
|
||||||
|
|
||||||
/* ---------- NETBIOS options ---------- */
|
/* ---------- NETBIOS options ---------- */
|
||||||
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
|
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
|
||||||
@ -343,7 +335,10 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
|
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
|
||||||
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
||||||
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
|
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
|
||||||
#define VJ_SUPPORT 1 /* Set > 0 for VJ header compression. */
|
/*
|
||||||
|
VJ support disabled due to bugs with IP forwarding
|
||||||
|
*/
|
||||||
|
#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */
|
||||||
#define MD5_SUPPORT 0 /* Set > 0 for MD5 (see also CHAP) */
|
#define MD5_SUPPORT 0 /* Set > 0 for MD5 (see also CHAP) */
|
||||||
|
|
||||||
#endif /* PPP_SUPPORT */
|
#endif /* PPP_SUPPORT */
|
||||||
|
Loading…
Reference in New Issue
Block a user