[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fix mbuf exhaustion when flooding under ppp-on-demand




Since I don't use PPP myself, could some kind soul out there test
these two patches (one on /sys/net/if_ppp.c, and the other in a couple
of files in /usr/src/usr.sbin/pppd/). Before you recompile pppd, you
need to copy /sys/net/ppp_defs.h to /usr/include/net/ppp_defs.h (this
assumes you're running -current -- if not, get a recent copy of
ppp_defs.h, a couple of changes have been made in the last few days).
I'd appreciate it if you could test this under normal ppp on demand,
and then with a ping flood.
Cheers,
-Angelos


--- snip ---
Index: if_ppp.c
===================================================================
RCS file: /cvs/src/sys/net/if_ppp.c,v
retrieving revision 1.13
diff -c -r1.13 if_ppp.c
*** if_ppp.c	1998/07/01 21:02:23	1.13
--- if_ppp.c	1998/07/04 01:58:29
***************
*** 758,766 ****
       * Put the packet on the appropriate queue.
       */
      s = splsoftnet();
!     if ((mode == NPMODE_QUEUE) ||
! 	(mode == NPMODE_KEEPLAST)) /* XXX Fix eventually */ {
! 	/* XXX we should limit the number of packets on this queue */
  	*sc->sc_npqtail = m0;
  	m0->m_nextpkt = NULL;
  	sc->sc_npqtail = &m0->m_nextpkt;
--- 758,774 ----
       * Put the packet on the appropriate queue.
       */
      s = splsoftnet();
!     if (mode == NPMODE_KEEPLAST) {
! 	while (sc->sc_npqueue) {   /* Discard already queued packets */
! 	    m = sc->sc_npqueue->m_nextpkt;
! 	    m_freem(sc->sc_npqueue);
! 	    sc->sc_npqueue = m;
! 	}
! 	
! 	sc->sc_npqueue = m0;       /* Put new packet in queue */
! 	m0->m_nextpkt = NULL;
! 	sc->sc_npqtail = &m0->m_nextpkt;
!     } else if (mode == NPMODE_QUEUE) {
  	*sc->sc_npqtail = m0;
  	m0->m_nextpkt = NULL;
  	sc->sc_npqtail = &m0->m_nextpkt;
***************
*** 798,804 ****
  ppp_requeue(sc)
      struct ppp_softc *sc;
  {
!     struct mbuf *m, **mpp;
      struct ifqueue *ifq;
      enum NPmode mode;
  
--- 806,812 ----
  ppp_requeue(sc)
      struct ppp_softc *sc;
  {
!     struct mbuf *m, **mpp, *m2;
      struct ifqueue *ifq;
      enum NPmode mode;
  
***************
*** 832,839 ****
  	    *mpp = m->m_nextpkt;
  	    m_freem(m);
  	    break;
  
! 	case NPMODE_KEEPLAST:	/* XXX Fix eventually */
  	case NPMODE_QUEUE:
  	    mpp = &m->m_nextpkt;
  	    break;
--- 840,855 ----
  	    *mpp = m->m_nextpkt;
  	    m_freem(m);
  	    break;
+ 
+ 	case NPMODE_KEEPLAST:
+ 	    while (sc->sc_npqueue) {
+ 		m2 = sc->sc_npqueue->m_nextpkt;
+ 		m_freem(sc->sc_npqueue);
+ 		sc->sc_npqueue = m2;
+ 	    }
  
! 	    sc->sc_npqueue = m;
! 	    /* Fall through */
  	case NPMODE_QUEUE:
  	    mpp = &m->m_nextpkt;
  	    break;
--- snip ---

--- snip ---
Index: demand.c
===================================================================
RCS file: /cvs/src/usr.sbin/pppd/demand.c,v
retrieving revision 1.5
diff -c -r1.5 demand.c
*** demand.c	1998/01/17 20:30:21	1.5
--- demand.c	1998/07/04 01:58:08
***************
*** 125,130 ****
--- 125,145 ----
  }
  
  /*
+  * demand_keeplast - set each network protocol to keep the last packet received
+  */
+ void
+ demand_keeplast()
+ {
+     int i;
+     struct protent *protp;
+     
+     for (i = 0; (protp = protocols[i]) != NULL; ++i)
+         if (protp->enabled_flag && protp->demand_conf != NULL)
+             sifnpmode(0, protp->protocol & ~0x8000, NPMODE_KEEPLAST);
+     get_loop_output();
+ }
+ 
+ /*
   * demand_discard - set each network protocol to discard packets
   * with an error.
   */
Index: ipcp.c
===================================================================
RCS file: /cvs/src/usr.sbin/pppd/ipcp.c,v
retrieving revision 1.6
diff -c -r1.6 ipcp.c
*** ipcp.c	1998/05/08 04:52:23	1.6
--- ipcp.c	1998/07/04 01:58:11
***************
*** 1114,1120 ****
  	return 0;
      if (!sifup(u))
  	return 0;
!     if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
  	return 0;
      if (wo->default_route)
  	if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
--- 1114,1120 ----
  	return 0;
      if (!sifup(u))
  	return 0;
!     if (!sifnpmode(u, PPP_IP, NPMODE_KEEPLAST))
  	return 0;
      if (wo->default_route)
  	if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/pppd/main.c,v
retrieving revision 1.22
diff -c -r1.22 main.c
*** main.c	1998/05/08 04:52:27	1.22
--- main.c	1998/07/04 01:58:14
***************
*** 415,421 ****
  	    /*
  	     * Now we want to bring up the link.
  	     */
! 	    demand_block();
  	    syslog(LOG_INFO, "Starting link");
  	}
  
--- 415,421 ----
  	    /*
  	     * Now we want to bring up the link.
  	     */
! 	    demand_keeplast();
  	    syslog(LOG_INFO, "Starting link");
  	}
  
Index: pppd.h
===================================================================
RCS file: /cvs/src/usr.sbin/pppd/pppd.h,v
retrieving revision 1.9
diff -c -r1.9 pppd.h
*** pppd.h	1998/05/08 04:52:32	1.9
--- pppd.h	1998/07/04 01:58:15
***************
*** 235,240 ****
--- 235,241 ----
  /* Procedures exported from demand.c */
  void demand_conf __P((void));	/* config interface(s) for demand-dial */
  void demand_block __P((void));	/* set all NPs to queue up packets */
+ void demand_keeplast __P((void)); /* set all NPs to keep last packet received */
  void demand_unblock __P((void)); /* set all NPs to pass packets */
  void demand_discard __P((void)); /* set all NPs to discard packets */
  void demand_rexmit __P((int));	/* retransmit saved frames for an NP */
--- snip ---