checkpoint before changing pq structure to be a sockbuf for downq
authorKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Wed, 23 May 1990 06:46:31 +0000 (22:46 -0800)
committerKeith Sklower <sklower@ucbvax.Berkeley.EDU>
Wed, 23 May 1990 06:46:31 +0000 (22:46 -0800)
and only retaining up method

SCCS-vsn: sys/netccitt/pk_input.c 7.3
SCCS-vsn: sys/netccitt/pk_output.c 7.3
SCCS-vsn: sys/netccitt/pk_subr.c 7.4
SCCS-vsn: sys/netccitt/pk_usrreq.c 7.5
SCCS-vsn: sys/netccitt/if_x25subr.c 7.4
SCCS-vsn: sys/netccitt/pk_var.h 7.4
SCCS-vsn: sys/netccitt/x25.h 7.4

usr/src/sys/netccitt/if_x25subr.c
usr/src/sys/netccitt/pk_input.c
usr/src/sys/netccitt/pk_output.c
usr/src/sys/netccitt/pk_subr.c
usr/src/sys/netccitt/pk_usrreq.c
usr/src/sys/netccitt/pk_var.h
usr/src/sys/netccitt/x25.h

index 8181e82..eb54226 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)if_x25subr.c        7.3 (Berkeley) %G%
+ *     @(#)if_x25subr.c        7.4 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -56,8 +56,8 @@ struct        sockaddr *dst;
 register struct        rtentry *rt;
 {
        register struct mbuf *m;
 register struct        rtentry *rt;
 {
        register struct mbuf *m;
-       struct rtextension_x25 *rtx;
-       struct pq *pq;
+       register struct rtextension_x25 *rtx;
+       register struct pq *pq;
        struct pklcd *lcp;
        struct x25_ifaddr *ia;
        struct mbuf    *prev;
        struct pklcd *lcp;
        struct x25_ifaddr *ia;
        struct mbuf    *prev;
@@ -96,10 +96,10 @@ register struct     rtentry *rt;
        if (rtx->rtx_lcd == 0) {
                int x25_ifinput();
 
        if (rtx->rtx_lcd == 0) {
                int x25_ifinput();
 
-               m = m_getclr(M_DONTWAIT, MT_PCB);
-               if (m == 0)
+               lcp = pk_attach((struct socket *)0);
+               if (lcp == 0)
                        senderr(ENOBUFS);
                        senderr(ENOBUFS);
-               rtx->rtx_lcd = lcp = mtod(m, struct pklcd *);
+               rtx->rtx_lcd = lcp;
                rtx->rtx_rt = rt;
                rtx->rtx_ia = ia;
                lcp->lcd_upq.pq_next = (caddr_t)rtx;
                rtx->rtx_rt = rt;
                rtx->rtx_ia = ia;
                lcp->lcd_upq.pq_next = (caddr_t)rtx;
@@ -155,7 +155,8 @@ register struct     rtentry *rt;
        case XRS_FREE:
                lcp->lcd_downq.pq_data = m;
                lcp->lcd_pkcb = &(rtx->rtx_ia->ia_pkcb);
        case XRS_FREE:
                lcp->lcd_downq.pq_data = m;
                lcp->lcd_pkcb = &(rtx->rtx_ia->ia_pkcb);
-               pk_connect(lcp, rt->rt_gateway);
+               pk_connect(lcp, (struct mbuf *)0,
+                               (struct sockaddr_x25 *)rt->rt_gateway);
                break;
                /* FALLTHROUGH */
        default:
                break;
                /* FALLTHROUGH */
        default:
@@ -385,7 +386,7 @@ struct sockaddr *dst;
 
        case caseof(XRS_RESOLVING, RTM_CHANGE):
                lcp->lcd_pkcb = &(ia->ia_pkcb);
 
        case caseof(XRS_RESOLVING, RTM_CHANGE):
                lcp->lcd_pkcb = &(ia->ia_pkcb);
-               pk_connect(lcp, nam);
+               pk_connect(lcp, (struct mbuf *)0, sa);
                break;
        }
        if (rt->rt_ifp->if_type == IFT_DDN)
                break;
        }
        if (rt->rt_ifp->if_type == IFT_DDN)
index e293d7d..361905c 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pk_input.c  7.2 (Berkeley) %G%
+ *     @(#)pk_input.c  7.3 (Berkeley) %G%
  */
 
 #include "../h/param.h"
  */
 
 #include "../h/param.h"
 #include "../netccitt/pk.h"
 #include "../netccitt/pk_var.h"
 
 #include "../netccitt/pk.h"
 #include "../netccitt/pk_var.h"
 
-struct pkcb *
-pk_newlink (xcp)
-struct x25config *xcp;
-{
-       register struct pkcb *pkp;
-       register struct mbuf *m;
-       register struct pklcd *lcp;
-       register struct protosw *pp;
-       register unsigned size;
-
-       if (xcp -> xc_ntnlen <= 0 || xcp -> xc_ntnlen > sizeof (xcp -> xc_ntn) * 2)
-               return ((struct pkcb *)0);
-#ifdef BSD4_3
-       pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0);
-#else
-       pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto);
-#endif
-       if (pp == 0 || pp -> pr_output == 0) {
-               pk_message (0, xcp, "link level protosw error");
-               return ((struct pkcb *)0);
-       }
-
-       /*
-        * Allocate a network control block structure
-        */
-
-       size = sizeof (struct pkcb) + xcp->xc_maxlcn * sizeof (struct pklcd *);
-#ifdef sun
-       if (xcp -> xc_maxlcn < 1 || size > mclbytes) {
-#else
-       if (xcp -> xc_maxlcn < 1 || size > CLBYTES) {
-#endif
-               pk_message (0, xcp, "invalid maxlcn");
-               return ((struct pkcb *)0);
-       }
-       m = m_get (M_DONTWAIT, MT_PCB);
-       if (m == 0)
-               return ((struct pkcb *)0);
-       if (size > MLEN) {
-#ifdef sun
-               if (mclget (m) == 0) {
-                       m_freem (m);
-                       return ((struct pkcb *)0);
-               }
-#else
-#ifdef BSD4_3
-               MCLGET (m);
-               if (m -> m_len != CLBYTES) {
-                       (void) m_free (m);
-                       return ((struct pkcb *)0);
-               }
-#else
-               register struct mbuf *p;
-
-               MCLGET (p, 1);
-               if (p == 0) {
-                       m_freem (m);
-                       return ((struct pkcb *)0);
-               }
-               m -> m_off = (int)p - (int)m;
-#endif
-#endif
-       }
-       pkp = mtod (m, struct pkcb *);
-       bzero ((caddr_t)pkp, size);
-
-       /*
-        * Allocate a logical channel descriptor for lcn 0
-        */
-
-       m = m_getclr (M_DONTWAIT, MT_PCB);
-       if (m == 0) {
-               m_freem (dtom (pkp));
-               return ((struct pkcb *)0);
-       }
-       lcp = mtod (m, struct pklcd *);
-       lcp -> lcd_state = READY;
-       lcp -> lcd_pkp = pkp;
-       pkp -> pk_chan[0] = lcp;
-
-       pkp -> pk_output = pp -> pr_output;
-       pkp -> pk_xcp = xcp;
-       pkp -> pk_state = DTE_WAITING;
-       pkp -> pk_maxlcn = xcp -> xc_maxlcn;
-       pkp -> pk_next = pkcbhead;
-       pkcbhead = pkp;
-
-       /*
-        * set defaults
-        */
-
-       if (xcp -> xc_pwsize == 0)
-               xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
-       if (xcp -> xc_psize == 0)
-               xcp -> xc_psize = X25_PS128;
-       return (pkp);
-}
-
 /* 
  *  This procedure is called by the link level whenever the link
  *  becomes operational, is reset, or when the link goes down. 
  */
 
 /* 
  *  This procedure is called by the link level whenever the link
  *  becomes operational, is reset, or when the link goes down. 
  */
 
-pk_ctlinput (code, xcp)
-struct x25config *xcp;
+pk_ctlinput (code, pkp)
+register struct pkcb *pkp;
 {
 {
-       register struct pkcb *pkp;
-
-       for (pkp = pkcbhead; pkp; pkp = pkp -> pk_next)
-               if (pkp -> pk_xcp == xcp)
-                       break;
 
 
-       if (pkp == 0 && (pkp = pk_newlink (xcp)) == 0)
+       if (pkp == 0)
                return (EINVAL);
                return (EINVAL);
-
        switch (code) {
        case PRC_LINKUP: 
                if (pkp -> pk_state == DTE_WAITING)
        switch (code) {
        case PRC_LINKUP: 
                if (pkp -> pk_state == DTE_WAITING)
@@ -557,10 +453,10 @@ incoming_call (pkp, xp, len)
 struct pkcb *pkp;
 struct x25_packet *xp;
 {
 struct pkcb *pkp;
 struct x25_packet *xp;
 {
-       register struct pklcd *lcp, *l;
+       register struct pklcd *lcp = 0, *l;
        register struct sockaddr_x25 *sa;
        register struct x25_calladdr *a;
        register struct sockaddr_x25 *sa;
        register struct x25_calladdr *a;
-       register struct socket *so;
+       register struct socket *so = 0;
        struct mbuf *m;
        register int l1, l2;
        char *e, *errstr = "server unavailable";
        struct mbuf *m;
        register int l1, l2;
        char *e, *errstr = "server unavailable";
@@ -616,8 +512,12 @@ struct x25_packet *xp;
                        errstr = "incoming collect call refused";
                        break;
                }
                        errstr = "incoming collect call refused";
                        break;
                }
-               so = sonewconn (l -> lcd_so);
-               if (so == NULL) {
+               if (l -> lcd_so) {
+                       if (so = sonewconn (l -> lcd_so, SO_ISCONNETED))
+                                   lcp = (struct pklcd *) so -> so_pcb;
+               } else 
+                       lcp = pk_attach((struct socket *) 0);
+               if (lcp == 0) {
                        /*
                         * Insufficient space or too many unaccepted
                         * connections.  Just throw the call away.
                        /*
                         * Insufficient space or too many unaccepted
                         * connections.  Just throw the call away.
@@ -625,7 +525,7 @@ struct x25_packet *xp;
                        errstr = "server malfunction";
                        break;
                }
                        errstr = "server malfunction";
                        break;
                }
-               lcp = (struct pklcd *) so -> so_pcb;
+               lcp -> lcd_upq.pq_put = lcp -> lcd_upq.pq_put;
                lcp -> lcd_lcn = lcn;
                lcp -> lcd_state = RECEIVED_CALL;
                lcp -> lcd_craddr = sa;
                lcp -> lcd_lcn = lcn;
                lcp -> lcd_state = RECEIVED_CALL;
                lcp -> lcd_craddr = sa;
@@ -634,7 +534,8 @@ struct x25_packet *xp;
                pk_assoc (pkp, lcp, sa);
                lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
                pk_output (lcp);
                pk_assoc (pkp, lcp, sa);
                lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
                pk_output (lcp);
-               soisconnected (so);
+               if (so)
+                       soisconnected (so);
                return;
        }
 
                return;
        }
 
index 5399b36..0059aa3 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pk_output.c 7.2 (Berkeley) %G%
+ *     @(#)pk_output.c 7.3 (Berkeley) %G%
  */
 
 #include "../h/param.h"
  */
 
 #include "../h/param.h"
@@ -144,7 +144,7 @@ register struct pklcd *lcp;
                pk_trace (pkp -> pk_xcp, xp, "P-Out");
 
                /* Pass the packet on down to the link layer */
                pk_trace (pkp -> pk_xcp, xp, "P-Out");
 
                /* Pass the packet on down to the link layer */
-               (*pkp -> pk_output) (m, pkp -> pk_xcp);
+               (*pkp -> pk_lloutput) (m, pkp -> pk_xcp);
        }
 }
 
        }
 }
 
@@ -168,8 +168,14 @@ struct pklcd *lcp;
                                lcp -> lcd_reset_condition)
                        return (NULL);
 
                                lcp -> lcd_reset_condition)
                        return (NULL);
 
-               if (so == 0)
-                       return (NULL);
+               if (so == 0) {
+                       if ((m = lcp->lcd_downq.pq_data) == 0)
+                               return (NULL);
+                       lcp->lcd_downq.pq_data = m->m_nextpkt;
+                       lcp->lcd_downq.pq_space += m->m_pkthdr.len;
+                       m->m_nextpkt = 0;
+                               return (m);
+               }
 
                if ((m = so -> so_snd.sb_mb) == 0)
                        return (NULL);
 
                if ((m = so -> so_snd.sb_mb) == 0)
                        return (NULL);
@@ -177,22 +183,11 @@ struct pklcd *lcp;
                n = m;
                while (n) {
                        sbfree (&so -> so_snd, n);
                n = m;
                while (n) {
                        sbfree (&so -> so_snd, n);
-#ifndef BSD4_3
-                       if ((int) n -> m_act == 1)
-                               break;
-#endif
                        n = n -> m_next;
                }
 
                        n = n -> m_next;
                }
 
-#ifdef BSD4_3
                so->so_snd.sb_mb = m->m_act;
                m->m_act = 0;
                so->so_snd.sb_mb = m->m_act;
                m->m_act = 0;
-#else
-               if (n) {
-                       so -> so_snd.sb_mb = n -> m_next;
-                       n -> m_next = 0;
-               }
-#endif
        }
 
        return (m);
        }
 
        return (m);
index c141b6a..cbd2728 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pk_subr.c   7.3 (Berkeley) %G%
+ *     @(#)pk_subr.c   7.4 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -22,6 +22,8 @@
 #include "time.h"
 #include "kernel.h"
 
 #include "time.h"
 #include "kernel.h"
 
+#include "../net/if.h"
+
 #include "x25.h"
 #include "pk.h"
 #include "pk_var.h"
 #include "x25.h"
 #include "pk.h"
 #include "pk_var.h"
@@ -39,31 +41,32 @@ struct      x25_packet *pk_template ();
  *
  */
 
  *
  */
 
+struct pklcd *
 pk_attach (so)
 struct socket *so;
 {
        register struct pklcd *lcp;
 pk_attach (so)
 struct socket *so;
 {
        register struct pklcd *lcp;
-       register struct mbuf *m;
-       register int error;
-
-       if (error = soreserve (so, pk_sendspace, pk_recvspace))
-               return (error);
-
-       /* Hopefully we can remove this when SEQ_PKT is available (4.3?) */
-       so -> so_snd.sb_mbmax = pk_sendspace;
+       register int error = ENOBUFS;
 
 
-       if ((m = m_getclr (M_DONTWAIT, MT_PCB)) == 0)
-               return (ENOBUFS);
-       lcp = mtod (m, struct pklcd *);
-       so -> so_pcb = (caddr_t) lcp;
-       lcp -> lcd_so = so;
-
-       if (so -> so_options & SO_ACCEPTCONN)
-               lcp -> lcd_state = LISTEN;
-       else
-               lcp -> lcd_state = READY;
+       MALLOC(lcp, struct pklcd *, sizeof(*lcp), M_PCB, M_NOWAIT);
+       if (lcp) {
+               bzero((caddr_t)lcp, sizeof(*lcp));
+               if (so) {
+                       error = soreserve (so, pk_sendspace, pk_recvspace);
+                       so -> so_snd.sb_mbmax = pk_sendspace;
+                       lcp -> lcd_so = so;
+                       if (so -> so_options & SO_ACCEPTCONN)
+                               lcp -> lcd_state = LISTEN;
+                       else
+                               lcp -> lcd_state = READY;
+               }
 
 
-       return (0);
+       }
+       if (so) {
+               so -> so_pcb = (caddr_t) lcp;
+               so -> so_error = error;
+       }
+       return (lcp);
 }
 
 /* 
 }
 
 /* 
@@ -211,7 +214,6 @@ int restart_cause;
  *  This procedure frees up the Logical Channel Descripter.
  */
 
  *  This procedure frees up the Logical Channel Descripter.
  */
 
-static
 pk_freelcd (lcp)
 register struct pklcd *lcp;
 {
 pk_freelcd (lcp)
 register struct pklcd *lcp;
 {
@@ -221,16 +223,10 @@ register struct pklcd *lcp;
        if (lcp -> lcd_template)
                m_freem (dtom (lcp -> lcd_template));
 
        if (lcp -> lcd_template)
                m_freem (dtom (lcp -> lcd_template));
 
-       if (lcp -> lcd_craddr)
-               m_freem (dtom (lcp -> lcd_craddr));
-
-       if (lcp -> lcd_ceaddr)
-               m_freem (dtom (lcp -> lcd_ceaddr));
-
        if (lcp -> lcd_lcn > 0)
                lcp -> lcd_pkp -> pk_chan[lcp -> lcd_lcn] = NULL;
 
        if (lcp -> lcd_lcn > 0)
                lcp -> lcd_pkp -> pk_chan[lcp -> lcd_lcn] = NULL;
 
-       m_freem (dtom (lcp));
+       free((caddr_t)lcp, M_PCB);
 }
 
 
 }
 
 
@@ -244,10 +240,10 @@ pk_bind (lcp, nam)
 struct pklcd *lcp;
 struct mbuf *nam;
 {
 struct pklcd *lcp;
 struct mbuf *nam;
 {
-       register struct sockaddr_x25 *sa;
        register struct pkcb *pkp;
        register struct mbuf *m;
        register struct pklcd *pp;
        register struct pkcb *pkp;
        register struct mbuf *m;
        register struct pklcd *pp;
+       register struct sockaddr_x25 *sa;
 
        if (nam == NULL)
                return (EADDRNOTAVAIL);
 
        if (nam == NULL)
                return (EADDRNOTAVAIL);
@@ -275,9 +271,8 @@ struct mbuf *nam;
                        min (pp->lcd_ceaddr->x25_udlen, sa->x25_udlen)) == 0)
                        return (EADDRINUSE);
 
                        min (pp->lcd_ceaddr->x25_udlen, sa->x25_udlen)) == 0)
                        return (EADDRINUSE);
 
-       if ((m = m_copy (nam, 0, (int)M_COPYALL)) == 0)
-               return (ENOBUFS);
-       lcp -> lcd_ceaddr = mtod (m, struct sockaddr_x25 *);
+       lcp -> lcd_laddr = *sa;
+       lcp -> lcd_ceaddr = &lcp -> lcd_laddr;
        return (0);
 }
 
        return (0);
 }
 
@@ -313,20 +308,24 @@ register struct sockaddr_x25 *sa;
        lcp -> lcd_stime = time.tv_sec;
 }
 
        lcp -> lcd_stime = time.tv_sec;
 }
 
-pk_connect (lcp, nam)
+pk_connect (lcp, nam, sa)
 register struct pklcd *lcp;
 register struct pklcd *lcp;
+register struct sockaddr_x25 *sa;
 struct mbuf *nam;
 {
        register struct pkcb *pkp;
 struct mbuf *nam;
 {
        register struct pkcb *pkp;
-       register struct sockaddr_x25 *sa;
        register struct mbuf *m;
        register struct mbuf *m;
+       register struct ifnet *ifp;
 
 
-       if (checksockaddr (nam))
-               return (EINVAL);
-       sa = mtod (nam, struct sockaddr_x25 *);
+       if (sa == 0) {
+               if (checksockaddr (nam))
+                       return (EINVAL);
+               sa = mtod (nam, struct sockaddr_x25 *);
+       }
        if (sa -> x25_addr[0] == '\0')
                return (EDESTADDRREQ);
        if (sa -> x25_addr[0] == '\0')
                return (EDESTADDRREQ);
-       for (pkp = pkcbhead; ; pkp = pkp->pk_next) {
+       if (lcp->lcd_pkp == 0)
+           for (pkp = pkcbhead; ; pkp = pkp->pk_next) {
                if (pkp == 0)
                        return (ENETUNREACH);
                /*
                if (pkp == 0)
                        return (ENETUNREACH);
                /*
@@ -343,16 +342,14 @@ struct mbuf *nam;
                return (ENETDOWN);
        if ((lcp -> lcd_lcn = pk_getlcn (pkp)) == 0)
                return (EMFILE);
                return (ENETDOWN);
        if ((lcp -> lcd_lcn = pk_getlcn (pkp)) == 0)
                return (EMFILE);
-       if ((m = m_copy (nam, 0, (int)M_COPYALL)) == 0)
-               return (ENOBUFS);
-       lcp -> lcd_ceaddr = mtod (m, struct sockaddr_x25 *);
+       lcp -> lcd_faddr = *sa;
+       lcp -> lcd_ceaddr = & lcp->lcd_faddr;
        pk_assoc (pkp, lcp, lcp -> lcd_ceaddr);
        if (lcp -> so)
                soisconnecting (lcp -> lcd_so);
        lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL);
        pk_assoc (pkp, lcp, lcp -> lcd_ceaddr);
        if (lcp -> so)
                soisconnecting (lcp -> lcd_so);
        lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL);
-       pk_callrequest (lcp, m, pkp -> pk_xcp);
-       pk_output (lcp);
-       return (0);
+       pk_callrequest (lcp, lcp -> lcd_ceaddr, pkp -> pk_xcp);
+       return (*pkp -> pk_start)(lcp);
 }
 
 /* 
 }
 
 /* 
@@ -360,13 +357,12 @@ struct mbuf *nam;
  *  address, facilities fields and the user data field.
  */
 
  *  address, facilities fields and the user data field.
  */
 
-pk_callrequest (lcp, nam, xcp)
+pk_callrequest (lcp, sa, xcp)
 struct pklcd *lcp;
 struct pklcd *lcp;
-struct mbuf *nam;
+register struct sockaddr_x25 *sa;
 register struct x25config *xcp;
 {
        register struct x25_calladdr *a;
 register struct x25config *xcp;
 {
        register struct x25_calladdr *a;
-       register struct sockaddr_x25 *sa = mtod (nam, struct sockaddr_x25 *);
        register struct mbuf *m = dtom (lcp -> lcd_template);
        unsigned posn = 0;
        octet *cp;
        register struct mbuf *m = dtom (lcp -> lcd_template);
        unsigned posn = 0;
        octet *cp;
index fa2bc25..dd1147d 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pk_usrreq.c 7.4 (Berkeley) %G%
+ *     @(#)pk_usrreq.c 7.5 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -125,7 +125,7 @@ struct mbuf *control;
        case PRU_CONNECT: 
                if (nam -> m_len == sizeof (struct x25_sockaddr))
                        old_to_new (nam);
        case PRU_CONNECT: 
                if (nam -> m_len == sizeof (struct x25_sockaddr))
                        old_to_new (nam);
-               error = pk_connect (lcp, nam);
+               error = pk_connect (lcp, nam, (struct sockaddr_25 *)0);
                break;
 
        /* 
                break;
 
        /* 
@@ -252,6 +252,21 @@ release:
        return (error);
 }
 
        return (error);
 }
 
+/* 
+ * If you want to use UBC X.25 level 3 in conjunction with some
+ * other X.25 level 2 driver, have the ifp->if_ioctl routine
+ * assign pk_start to pkp -> pk_start when called with SIOCSIFCONF_X25.
+ */
+/* ARGSUSED */
+pk_start (lcp)
+register struct pklcd *lcp;
+{
+       extern int pk_send();
+
+       lcp -> lcp_downq.pq_put = pk_send;
+       return (pk_output(lcp));
+}
+
 /*ARGSUSED*/
 pk_control (so, cmd, data, ifp)
 struct socket *so;
 /*ARGSUSED*/
 pk_control (so, cmd, data, ifp)
 struct socket *so;
@@ -262,6 +277,7 @@ register struct ifnet *ifp;
        register struct ifreq_x25 *ifr = (struct ifreq_x25 *)data;
        register struct ifaddr *ifa = 0;
        register struct x25_ifaddr *ia = 0;
        register struct ifreq_x25 *ifr = (struct ifreq_x25 *)data;
        register struct ifaddr *ifa = 0;
        register struct x25_ifaddr *ia = 0;
+       struct pklcd *dev_lcp = 0;
        int error, s;
        unsigned n;
 
        int error, s;
        unsigned n;
 
@@ -290,10 +306,10 @@ register struct ifnet *ifp;
                if (ifa == (struct ifaddr *)0) {
                        register struct mbuf *m;
 
                if (ifa == (struct ifaddr *)0) {
                        register struct mbuf *m;
 
-                       m = m_getclr(M_WAIT, MT_IFADDR);
-                       if (m == (struct mbuf *)NULL)
+                       MALLOC(ia, struct x25_ifaddr *, sizeof (*ia),
+                               M_IFADDR, M_WAITOK);
+                       if (ia == 0)
                                return (ENOBUFS);
                                return (ENOBUFS);
-                       ia = mtod(m, struct x25_ifaddr *);
                        if (ifa = ifp->if_addrlist) {
                                for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
                                        ;
                        if (ifa = ifp->if_addrlist) {
                                for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
                                        ;
@@ -310,17 +326,25 @@ register struct ifnet *ifp;
                }
                ia->ia_xcp = &(ifr->ifr_xc);
                if (ia->ia_chan && (ia->ia_maxlcn != ia->xcp->xc_maxlcn)) {
                }
                ia->ia_xcp = &(ifr->ifr_xc);
                if (ia->ia_chan && (ia->ia_maxlcn != ia->xcp->xc_maxlcn)) {
+                       pk_restart(&ia->ia_pkp, X25_RESTART_NETWORK_CONGESTION);
+                       dev_lcp = ia->ia_chan[0];
                        free((caddr_t)ia->ia_chan, M_IFADDR);
                        free((caddr_t)ia->ia_chan, M_IFADDR);
-                       ia->ia_ia_chan = 0;
+                       ia->ia_chan = 0;
                }
                }
-               n = ia->ia_maxlcn * sizeof(struct pklcd *);
-               if (ia->ia_chan == 0)
+               if (ia->ia_chan == 0) {
+                       n = ia->ia_maxlcn * sizeof(struct pklcd *);
                        ia->ia_chan = (struct pklcd **) malloc(n, M_IFADDR);
                        ia->ia_chan = (struct pklcd **) malloc(n, M_IFADDR);
-               if (ia->ia_chan)
-                       bzero((caddr_t)ia->ia_chan, n);
-               else {
-                       ia->ia_xcp = &ia->ia_xc;
-                       return (ENOBUFS);
+                       if (ia->ia_chan) {
+                               bzero((caddr_t)ia->ia_chan, n);
+                               if (dev_lcp == 0)
+                                       dev_lcp = pk_attach((struct socket *)0);
+                               ia->ia_chan = dev_lcp;
+                       } else {
+                               if (dev_lcp)
+                                       pk_close(dev_lcp);
+                               ia->ia_xcp = &ia->ia_xc;
+                               return (ENOBUFS);
+                       }
                }
                /*
                 * Give the interface a chance to initialize if this
                }
                /*
                 * Give the interface a chance to initialize if this
@@ -459,8 +483,10 @@ register struct mbuf *m;
                m_freem (m0);
                return (EMSGSIZE);
        }
                m_freem (m0);
                return (EMSGSIZE);
        }
-
-       sbappendrecord (&lcp -> lcd_so -> so_snd, m0);
+       if (lcp -> lcd_so)
+               sbappendrecord (&lcp -> lcd_so -> so_snd, m0);
+       else
+               pq_appendrecord (&lcp -> lcd_downq, m0);
        lcp -> lcd_template = 0;
        lcp -> lcd_txcnt++;
        pk_output (lcp);
        lcp -> lcd_template = 0;
        lcp -> lcd_txcnt++;
        pk_output (lcp);
index 38ba899..f831fe6 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)pk_var.h    7.3 (Berkeley) %G%
+ *     @(#)pk_var.h    7.4 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -56,14 +56,16 @@ struct pklcd {
        char    lcd_flags;              /* copy of sockaddr_x25 op_flags */
        struct  x25_packet *lcd_template;/* Address of current packet */
        struct  socket *lcd_so;         /* Socket addr for connection */
        char    lcd_flags;              /* copy of sockaddr_x25 op_flags */
        struct  x25_packet *lcd_template;/* Address of current packet */
        struct  socket *lcd_so;         /* Socket addr for connection */
-       struct  sockaddr_x25 *lcd_craddr;/* Calling address */
-       struct  sockaddr_x25 *lcd_ceaddr;/* Called address */
+       struct  sockaddr_x25 *lcd_craddr;/* Calling address pointer */
+       struct  sockaddr_x25 *lcd_ceaddr;/* Called address pointer */
        time_t  lcd_stime;              /* time circuit established */
        long    lcd_txcnt;              /* Data packet transmit count */
        long    lcd_rxcnt;              /* Data packet receive count */
        short   lcd_intrcnt;            /* Interrupt packet transmit count */
        struct  pklcd *lcd_listen;      /* Next lcd on listen queue */
        time_t  lcd_stime;              /* time circuit established */
        long    lcd_txcnt;              /* Data packet transmit count */
        long    lcd_rxcnt;              /* Data packet receive count */
        short   lcd_intrcnt;            /* Interrupt packet transmit count */
        struct  pklcd *lcd_listen;      /* Next lcd on listen queue */
-       struct  pkcb *lcd_pkp;          /* network this lcd is attached to */
+       struct  pkcb *lcd_pkp;          /* Network this lcd is attached to */
+       struct  sockaddr_x25 lcd_faddr  /* Remote Address (Calling) */
+       struct  sockaddr_x25 lcd_laddr  /* Local Address (Called) */
 };
 
 #define X25_DG_CIRCUIT 0x10            /* lcd_flag: used for datagrams */
 };
 
 #define X25_DG_CIRCUIT 0x10            /* lcd_flag: used for datagrams */
@@ -77,9 +79,10 @@ struct pklcd {
 struct pkcb {
        struct  pkcb *pk_next;
        struct  x25_ifaddr *pk_ia;      /* backpointer to ifaddr */
 struct pkcb {
        struct  pkcb *pk_next;
        struct  x25_ifaddr *pk_ia;      /* backpointer to ifaddr */
-       short   pk_state;               /* packet level status */
-       int     (*pk_output) ();        /* link level output procedure */
+       int     (*pk_lloutput) ();      /* link level output procedure */
+       int     (*pk_start) ();         /* connect, confirm method */
        struct  x25config *pk_xcp;      /* network specific configuration */
        struct  x25config *pk_xcp;      /* network specific configuration */
+       short   pk_state;               /* packet level status */
        struct  x25config pk_xc;        /* network specific configuration */
        struct  pklcd **pk_chan;        /* actual size == xc_maxlcn+1 */
 #define        pk_maxlcn pk_xc.xc_maxlcn       /* local copy of xc_maxlcn */
        struct  x25config pk_xc;        /* network specific configuration */
        struct  pklcd **pk_chan;        /* actual size == xc_maxlcn+1 */
 #define        pk_maxlcn pk_xc.xc_maxlcn       /* local copy of xc_maxlcn */
@@ -130,6 +133,7 @@ struct rtextension_x25 {
 #ifdef KERNEL
 struct pkcb *pkcbhead;         /* head of linked list of networks */
 struct pklcd *pk_listenhead;
 #ifdef KERNEL
 struct pkcb *pkcbhead;         /* head of linked list of networks */
 struct pklcd *pk_listenhead;
+struct pklcd *pk_attach();
 
 char   *pk_name[], *pk_state[];
 int    pk_t20, pk_t21, pk_t22, pk_t23;
 
 char   *pk_name[], *pk_state[];
 int    pk_t20, pk_t21, pk_t22, pk_t23;
index b1ffc11..fc418a4 100644 (file)
@@ -9,7 +9,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)x25.h       7.3 (Berkeley) %G%
+ *     @(#)x25.h       7.4 (Berkeley) %G%
  */
 
 #ifdef KERNEL
  */
 
 #ifdef KERNEL