From 145a45a7c0f4809cd70751e7fc63c8fe5a1d09d2 Mon Sep 17 00:00:00 2001
From: Sylvain Rochet <gradator@gradator.net>
Date: Wed, 18 Mar 2015 20:51:53 +0100
Subject: [PATCH] PPP, PPPoS, improved tcpip input path

New input type TCPIP_MSG_INPKT_PPPOS. Removed the netif input pointer usage
which was actually broken by design. Fixed bug #44565.
---
 src/api/tcpip.c               | 57 +++++++++++++++++++++++++++++++++++++------
 src/include/lwip/tcpip.h      |  7 ++++++
 src/include/netif/ppp/pppos.h |  9 +++++++
 src/netif/ppp/pppos.c         | 10 ++------
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/src/api/tcpip.c b/src/api/tcpip.c
index 9dc30c8..b11b1b0 100644
--- a/src/api/tcpip.c
+++ b/src/api/tcpip.c
@@ -49,6 +49,7 @@
 #include "lwip/ip.h"
 #include "netif/etharp.h"
 #include "netif/ppp/pppoe.h"
+#include "netif/ppp/pppos.h"
 
 #define TCPIP_MSG_VAR_REF(name)     API_VAR_REF(name)
 #define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
@@ -114,13 +115,6 @@ tcpip_thread(void *arg)
         ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
       } else
 #endif /* LWIP_ETHERNET */
-#if PPPOS_SUPPORT
-      if (((msg->msg.inp.netif->flags & NETIF_FLAG_BROADCAST) == 0)
-            && msg->msg.inp.netif->input
-            && (msg->msg.inp.netif->input != tcpip_input)) {
-        msg->msg.inp.netif->input(msg->msg.inp.p, msg->msg.inp.netif);
-      } else
-#endif /* PPPOS_SUPPORT */
 #if LWIP_IPV6
       if (((*(u8_t*)(msg->msg.inp.p->payload)) & 0xf0) == 0x60) {
           ip6_input(msg->msg.inp.p, msg->msg.inp.netif);
@@ -133,6 +127,13 @@ tcpip_thread(void *arg)
       break;
 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
 
+#if PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED
+    case TCPIP_MSG_INPKT_PPPOS:
+      pppos_input_sys(msg->msg.inp.p, msg->msg.inp.netif);
+      memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+      break;
+#endif /* PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED*/
+
 #if LWIP_NETIF_API
     case TCPIP_MSG_NETIFAPI:
       LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
@@ -231,6 +232,48 @@ tcpip_input(struct pbuf *p, struct netif *inp)
 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
 }
 
+#if PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED
+/**
+ * Pass a received packet to tcpip_thread for input processing
+ *
+ * @param p the received packet, p->payload pointing to the Ethernet header or
+ *          to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
+ *          NETIF_FLAG_ETHERNET flags)
+ * @param inp the network interface on which the packet was received
+ */
+err_t
+tcpip_pppos_input(struct pbuf *p, struct netif *inp)
+{
+#if LWIP_TCPIP_CORE_LOCKING_INPUT
+  err_t ret;
+  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_pppos_input: PACKET %p/%p\n", (void *)p, (void *)inp));
+  LOCK_TCPIP_CORE();
+  ret = pppos_input_sys(p, inp);
+  UNLOCK_TCPIP_CORE();
+  return ret;
+#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+  struct tcpip_msg *msg;
+
+  if (!sys_mbox_valid(&mbox)) {
+    return ERR_VAL;
+  }
+  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
+  if (msg == NULL) {
+    return ERR_MEM;
+  }
+
+  msg->type = TCPIP_MSG_INPKT_PPPOS;
+  msg->msg.inp.p = p;
+  msg->msg.inp.netif = inp;
+  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
+    memp_free(MEMP_TCPIP_MSG_INPKT, msg);
+    return ERR_MEM;
+  }
+  return ERR_OK;
+#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
+}
+#endif /* PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED */
+
 /**
  * Call a specific function in the thread context of
  * tcpip_thread for easy access synchronization.
diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h
index c6fe103..cadccd9 100644
--- a/src/include/lwip/tcpip.h
+++ b/src/include/lwip/tcpip.h
@@ -143,6 +143,10 @@ err_t tcpip_apimsg(struct api_msg *apimsg);
 
 err_t tcpip_input(struct pbuf *p, struct netif *inp);
 
+#if PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED
+err_t tcpip_pppos_input(struct pbuf *p, struct netif *inp);
+#endif /* PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED */
+
 #if LWIP_NETIF_API
 err_t tcpip_netifapi(struct netifapi_msg *netifapimsg);
 #if LWIP_TCPIP_CORE_LOCKING
@@ -178,6 +182,9 @@ enum tcpip_msg_type {
   TCPIP_MSG_API,
 #endif /* LWIP_NETCONN || LWIP_SOCKET */
   TCPIP_MSG_INPKT,
+#if PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED
+  TCPIP_MSG_INPKT_PPPOS,
+#endif /* PPPOS_SUPPORT && !PPP_INPROC_MULTITHREADED */
 #if LWIP_NETIF_API
   TCPIP_MSG_NETIFAPI,
 #endif /* LWIP_NETIF_API */
diff --git a/src/include/netif/ppp/pppos.h b/src/include/netif/ppp/pppos.h
index 16263d0..761f7c6 100644
--- a/src/include/netif/ppp/pppos.h
+++ b/src/include/netif/ppp/pppos.h
@@ -112,5 +112,14 @@ err_t pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l);
 /* PPP over Serial: this is the input function to be called for received data. */
 void pppos_input(ppp_pcb *ppp, u8_t* data, int len);
 
+
+/*
+ * Functions called from lwIP
+ * DO NOT CALL FROM lwIP USER APPLICATION.
+ */
+#if !NO_SYS && !PPP_INPROC_MULTITHREADED
+err_t pppos_input_sys(struct pbuf *p, struct netif *inp);
+#endif /* !NO_SYS && !PPP_INPROC_MULTITHREADED */
+
 #endif /* PPPOS_H */
 #endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */
diff --git a/src/netif/ppp/pppos.c b/src/netif/ppp/pppos.c
index 13a47f2..06a72c6 100644
--- a/src/netif/ppp/pppos.c
+++ b/src/netif/ppp/pppos.c
@@ -70,9 +70,6 @@ static err_t pppos_netif_input(ppp_pcb *ppp, void *ctx, struct pbuf *p, u16_t pr
 #endif /* VJ_SUPPORT */
 
 /* Prototypes for procedures local to this file. */
-#if !NO_SYS && !PPP_INPROC_MULTITHREADED
-static err_t pppos_input_sys(struct pbuf *p, struct netif *inp);
-#endif /* !NO_SYS && !PPP_INPROC_MULTITHREADED */
 #if PPP_INPROC_MULTITHREADED
 static void pppos_input_callback(void *arg);
 #endif /* PPP_INPROC_MULTITHREADED */
@@ -205,9 +202,6 @@ ppp_pcb *pppos_create(struct netif *pppif, sio_fd_t fd,
 
   pppos->ppp = ppp;
   pppos->fd = fd;
-#if !NO_SYS && !PPP_INPROC_MULTITHREADED
-  ppp->netif->input = pppos_input_sys;
-#endif /* !NO_SYS && !PPP_INPROC_MULTITHREADED */
   ppp_link_set_callbacks(ppp, &pppos_callbacks, pppos);
   return ppp;
 }
@@ -499,11 +493,11 @@ pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l)
     cur += n->len;
   }
 
-  return tcpip_input(p, ppp_netif(ppp));
+  return tcpip_pppos_input(p, ppp_netif(ppp));
 }
 
 /* called from TCPIP thread */
-static err_t pppos_input_sys(struct pbuf *p, struct netif *inp) {
+err_t pppos_input_sys(struct pbuf *p, struct netif *inp) {
   ppp_pcb *ppp = (ppp_pcb*)inp->state;
   struct pbuf *n;
 
-- 
2.1.4

