Convert netipx to use queue(9) doubly-linked lists instead of home-brew
linked lists for ipxpcb's.
This commit is contained in:
parent
79e0f8f5c4
commit
a369265a70
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1995, Mike Mitchell
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -84,8 +85,11 @@ const union ipx_host ipx_broadhost = { .s_host[0] = 0xffff,
|
||||
struct ipxstat ipxstat;
|
||||
struct sockaddr_ipx ipx_netmask, ipx_hostmask;
|
||||
|
||||
struct ipxpcb ipxpcb;
|
||||
struct ipxpcb ipxrawpcb;
|
||||
/*
|
||||
* IPX protocol control block (pcb) lists.
|
||||
*/
|
||||
struct ipxpcbhead ipxpcb_list;
|
||||
struct ipxpcbhead ipxrawpcb_list;
|
||||
|
||||
static int ipxqmaxlen = IFQ_MAXLEN;
|
||||
static struct ifqueue ipxintrq;
|
||||
@ -106,8 +110,9 @@ ipx_init()
|
||||
{
|
||||
|
||||
read_random(&ipx_pexseq, sizeof ipx_pexseq);
|
||||
ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb;
|
||||
ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb;
|
||||
|
||||
LIST_INIT(&ipxpcb_list);
|
||||
LIST_INIT(&ipxrawpcb_list);
|
||||
|
||||
ipx_netmask.sipx_len = 6;
|
||||
ipx_netmask.sipx_addr.x_net = ipx_broadnet;
|
||||
@ -152,8 +157,7 @@ ipxintr(struct mbuf *m)
|
||||
/*
|
||||
* Give any raw listeners a crack at the packet
|
||||
*/
|
||||
for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb;
|
||||
ipxp = ipxp->ipxp_next) {
|
||||
LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) {
|
||||
struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL);
|
||||
if (m1 != NULL)
|
||||
ipx_input(m1, ipxp);
|
||||
@ -466,8 +470,7 @@ struct ifnet *ifp;
|
||||
/*
|
||||
* Give any raw listeners a crack at the packet
|
||||
*/
|
||||
for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb;
|
||||
ipxp = ipxp->ipxp_next) {
|
||||
LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) {
|
||||
struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL);
|
||||
if (m0 != NULL) {
|
||||
register struct ipx *ipx;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1995, Mike Mitchell
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -56,7 +57,7 @@ static struct ipx_addr zeroipx_addr;
|
||||
int
|
||||
ipx_pcballoc(so, head, td)
|
||||
struct socket *so;
|
||||
struct ipxpcb *head;
|
||||
struct ipxpcbhead *head;
|
||||
struct thread *td;
|
||||
{
|
||||
register struct ipxpcb *ipxp;
|
||||
@ -67,7 +68,7 @@ ipx_pcballoc(so, head, td)
|
||||
ipxp->ipxp_socket = so;
|
||||
if (ipxcksum)
|
||||
ipxp->ipxp_flags |= IPXP_CHECKSUM;
|
||||
insque(ipxp, head);
|
||||
LIST_INSERT_HEAD(head, ipxp, ipxp_list);
|
||||
so->so_pcb = (caddr_t)ipxp;
|
||||
return (0);
|
||||
}
|
||||
@ -274,7 +275,7 @@ ipx_pcbdetach(ipxp)
|
||||
sotryfree(so);
|
||||
if (ipxp->ipxp_route.ro_rt != NULL)
|
||||
rtfree(ipxp->ipxp_route.ro_rt);
|
||||
remque(ipxp);
|
||||
LIST_REMOVE(ipxp, ipxp_list);
|
||||
FREE(ipxp, M_PCB);
|
||||
}
|
||||
|
||||
@ -319,7 +320,7 @@ ipx_pcblookup(faddr, lport, wildp)
|
||||
u_short fport;
|
||||
|
||||
fport = faddr->x_port;
|
||||
for (ipxp = (&ipxpcb)->ipxp_next; ipxp != (&ipxpcb); ipxp = ipxp->ipxp_next) {
|
||||
LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) {
|
||||
if (ipxp->ipxp_lport != lport)
|
||||
continue;
|
||||
wildcard = 0;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1995, Mike Mitchell
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -43,9 +44,7 @@
|
||||
* IPX protocol interface control block.
|
||||
*/
|
||||
struct ipxpcb {
|
||||
struct ipxpcb *ipxp_next; /* doubly linked list */
|
||||
struct ipxpcb *ipxp_prev;
|
||||
struct ipxpcb *ipxp_head;
|
||||
LIST_ENTRY(ipxpcb) ipxp_list;
|
||||
struct socket *ipxp_socket; /* back pointer to socket */
|
||||
struct ipx_addr ipxp_faddr; /* destination address */
|
||||
struct ipx_addr ipxp_laddr; /* socket's address */
|
||||
@ -57,6 +56,13 @@ struct ipxpcb {
|
||||
u_char ipxp_rpt; /* last received packet type by ipx_input() */
|
||||
};
|
||||
|
||||
/*
|
||||
* Additional IPX pcb-related types and variables.
|
||||
*/
|
||||
LIST_HEAD(ipxpcbhead, ipxpcb);
|
||||
extern struct ipxpcbhead ipxpcb_list;
|
||||
extern struct ipxpcbhead ipxrawpcb_list;
|
||||
|
||||
/* possible flags */
|
||||
|
||||
#define IPXP_IN_ABORT 0x1 /* calling abort through socket */
|
||||
@ -81,7 +87,7 @@ struct ipxpcb {
|
||||
#ifdef _KERNEL
|
||||
extern struct ipxpcb ipxpcb; /* head of list */
|
||||
|
||||
int ipx_pcballoc(struct socket *so, struct ipxpcb *head,
|
||||
int ipx_pcballoc(struct socket *so, struct ipxpcbhead *head,
|
||||
struct thread *p);
|
||||
int ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam,
|
||||
struct thread *p);
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1995, Mike Mitchell
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -455,7 +456,7 @@ ipx_attach(so, proto, td)
|
||||
if (ipxp != NULL)
|
||||
return (EINVAL);
|
||||
s = splnet();
|
||||
error = ipx_pcballoc(so, &ipxpcb, td);
|
||||
error = ipx_pcballoc(so, &ipxpcb_list, td);
|
||||
splx(s);
|
||||
if (error == 0)
|
||||
error = soreserve(so, ipxsendspace, ipxrecvspace);
|
||||
@ -616,7 +617,7 @@ ripx_attach(so, proto, td)
|
||||
if (td != NULL && (error = suser(td)) != 0)
|
||||
return (error);
|
||||
s = splnet();
|
||||
error = ipx_pcballoc(so, &ipxrawpcb, td);
|
||||
error = ipx_pcballoc(so, &ipxrawpcb_list, td);
|
||||
splx(s);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -66,7 +66,6 @@ SYSCTL_DECL(_net_ipx_ipx);
|
||||
extern int ipxcksum;
|
||||
extern long ipx_pexseq;
|
||||
extern struct ipxstat ipxstat;
|
||||
extern struct ipxpcb ipxrawpcb;
|
||||
extern struct pr_usrreqs ipx_usrreqs;
|
||||
extern struct pr_usrreqs ripx_usrreqs;
|
||||
extern struct sockaddr_ipx ipx_netmask;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Robert N. M. Watson
|
||||
* Copyright (c) 1995, Mike Mitchell
|
||||
* Copyright (c) 1984, 1985, 1986, 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -1310,7 +1311,7 @@ spx_attach(so, proto, td)
|
||||
if (ipxp != NULL)
|
||||
return (EISCONN);
|
||||
s = splnet();
|
||||
error = ipx_pcballoc(so, &ipxpcb, td);
|
||||
error = ipx_pcballoc(so, &ipxpcb_list, td);
|
||||
if (error)
|
||||
goto spx_attach_end;
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
@ -1731,9 +1732,7 @@ spx_fasttimo()
|
||||
register struct spxpcb *cb;
|
||||
int s = splnet();
|
||||
|
||||
ipxp = ipxpcb.ipxp_next;
|
||||
if (ipxp != NULL)
|
||||
for (; ipxp != &ipxpcb; ipxp = ipxp->ipxp_next)
|
||||
LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) {
|
||||
if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) != NULL &&
|
||||
(cb->s_flags & SF_DELACK)) {
|
||||
cb->s_flags &= ~SF_DELACK;
|
||||
@ -1741,6 +1740,8 @@ spx_fasttimo()
|
||||
spxstat.spxs_delack++;
|
||||
spx_output(cb, (struct mbuf *)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
}
|
||||
|
||||
@ -1752,36 +1753,32 @@ spx_fasttimo()
|
||||
void
|
||||
spx_slowtimo()
|
||||
{
|
||||
register struct ipxpcb *ip, *ipnxt;
|
||||
register struct ipxpcb *ip, *ip_temp;
|
||||
register struct spxpcb *cb;
|
||||
int s = splnet();
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Search through tcb's and update active timers.
|
||||
* Search through tcb's and update active timers. Note that timers
|
||||
* may free the ipxpcb, so be sure to handle that case.
|
||||
*/
|
||||
ip = ipxpcb.ipxp_next;
|
||||
if (ip == NULL) {
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
while (ip != &ipxpcb) {
|
||||
LIST_FOREACH_SAFE(ip, &ipxpcb_list, ipxp_list, ip_temp) {
|
||||
cb = ipxtospxpcb(ip);
|
||||
ipnxt = ip->ipxp_next;
|
||||
if (cb == NULL)
|
||||
goto tpgone;
|
||||
continue;
|
||||
for (i = 0; i < SPXT_NTIMERS; i++) {
|
||||
if (cb->s_timer[i] && --cb->s_timer[i] == 0) {
|
||||
spx_timers(cb, i);
|
||||
if (ipnxt->ipxp_prev != ip)
|
||||
goto tpgone;
|
||||
/*
|
||||
* spx_timers() returns (NULL) if it free'd
|
||||
* the pcb.
|
||||
*/
|
||||
if (spx_timers(cb, i) == NULL)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cb->s_idle++;
|
||||
if (cb->s_rtt)
|
||||
cb->s_rtt++;
|
||||
tpgone:
|
||||
ip = ipnxt;
|
||||
}
|
||||
spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */
|
||||
splx(s);
|
||||
|
Loading…
Reference in New Issue
Block a user