mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 06:28:27 -04:00
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),
|
||||
#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
|
||||
};
|
||||
|
||||
@ -129,8 +143,19 @@ void AP_Networking::init()
|
||||
}
|
||||
#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::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);
|
||||
}
|
||||
#endif
|
||||
@ -158,6 +183,13 @@ void AP_Networking::init()
|
||||
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();
|
||||
|
||||
GCS_SEND_TEXT(MAV_SEVERITY_INFO,"NET: Initialized");
|
||||
|
@ -26,6 +26,7 @@ class AP_Networking
|
||||
public:
|
||||
friend class AP_Networking_Backend;
|
||||
friend class AP_Networking_ChibiOS;
|
||||
friend class AP_Networking_PPP;
|
||||
friend class AP_Vehicle;
|
||||
friend class Networking_Periph;
|
||||
|
||||
@ -149,6 +150,13 @@ public:
|
||||
|
||||
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:
|
||||
static AP_Networking *singleton;
|
||||
|
||||
@ -172,10 +180,18 @@ private:
|
||||
AP_Int32 tests;
|
||||
AP_Networking_IPV4 test_ipaddr{AP_NETWORKING_TEST_IP};
|
||||
#endif
|
||||
|
||||
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||
AP_Networking_IPV4 remote_ppp_ip{AP_NETWORKING_REMOTE_PPP_IP};
|
||||
#endif
|
||||
} param;
|
||||
|
||||
AP_Networking_Backend *backend;
|
||||
|
||||
#if AP_NETWORKING_PPP_GATEWAY_ENABLED
|
||||
AP_Networking_Backend *backend_PPP;
|
||||
#endif
|
||||
|
||||
HAL_Semaphore sem;
|
||||
|
||||
enum class NetworkPortType {
|
||||
|
@ -119,3 +119,17 @@
|
||||
#ifndef AP_NETWORKING_SENDFILE_BUFSIZE
|
||||
#define AP_NETWORKING_SENDFILE_BUFSIZE (64*512)
|
||||
#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) {
|
||||
case PPPERR_NONE:
|
||||
// got new addresses for the link
|
||||
driver.activeSettings.ip = ntohl(netif_ip4_addr(pppif)->addr);
|
||||
driver.activeSettings.gw = ntohl(netif_ip4_gw(pppif)->addr);
|
||||
driver.activeSettings.nm = ntohl(netif_ip4_netmask(pppif)->addr);
|
||||
driver.activeSettings.last_change_ms = AP_HAL::millis();
|
||||
#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.gw = ntohl(netif_ip4_gw(pppif)->addr);
|
||||
driver.activeSettings.nm = ntohl(netif_ip4_netmask(pppif)->addr);
|
||||
driver.activeSettings.last_change_ms = AP_HAL::millis();
|
||||
}
|
||||
break;
|
||||
|
||||
case PPPERR_OPEN:
|
||||
@ -94,10 +101,13 @@ bool AP_Networking_PPP::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialise TCP/IP thread
|
||||
LWIP_TCPIP_LOCK();
|
||||
tcpip_init(NULL, NULL);
|
||||
LWIP_TCPIP_UNLOCK();
|
||||
const bool ethernet_gateway = frontend.option_is_set(AP_Networking::OPTION::PPP_ETHERNET_GATEWAY);
|
||||
if (!ethernet_gateway) {
|
||||
// initialise TCP/IP thread
|
||||
LWIP_TCPIP_LOCK();
|
||||
tcpip_init(NULL, NULL);
|
||||
LWIP_TCPIP_UNLOCK();
|
||||
}
|
||||
|
||||
hal.scheduler->delay(100);
|
||||
|
||||
@ -127,9 +137,14 @@ void AP_Networking_PPP::ppp_loop(void)
|
||||
while (!hal.scheduler->is_system_initialized()) {
|
||||
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
|
||||
uart->begin(0);
|
||||
uart->begin(AP::serialmanager().find_baudrate(AP_SerialManager::SerialProtocol_PPP, 0));
|
||||
uart->set_unbuffered_writes(true);
|
||||
|
||||
while (true) {
|
||||
@ -137,9 +152,63 @@ void AP_Networking_PPP::ppp_loop(void)
|
||||
|
||||
// connect and set as default route
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
#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();
|
||||
|
||||
need_restart = false;
|
||||
|
@ -74,7 +74,6 @@ extern "C"
|
||||
#define LWIP_ICMP LWIP_IPV4
|
||||
|
||||
#define LWIP_SNMP LWIP_UDP
|
||||
#define MIB2_STATS LWIP_SNMP
|
||||
#ifdef LWIP_HAVE_MBEDTLS
|
||||
#define LWIP_SNMP_V3 (LWIP_SNMP)
|
||||
#endif
|
||||
@ -255,6 +254,7 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
#define LWIP_ARP 1
|
||||
#define ARP_TABLE_SIZE 10
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_PROXYARP_SUPPORT 1
|
||||
|
||||
|
||||
/* ---------- 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. */
|
||||
#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
|
||||
* if they both deal with IP fragments */
|
||||
#define IP_REASSEMBLY 1
|
||||
@ -302,22 +308,8 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
|
||||
/* ---------- Statistics options ---------- */
|
||||
|
||||
#define LWIP_STATS 1
|
||||
#define LWIP_STATS_DISPLAY 1
|
||||
|
||||
#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 */
|
||||
#define LWIP_STATS 0
|
||||
#define LWIP_STATS_DISPLAY 0
|
||||
|
||||
/* ---------- NETBIOS options ---------- */
|
||||
#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 CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
|
||||
#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) */
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
Loading…
Reference in New Issue
Block a user