1/*-
2 * Copyright (c) 1996 Charles D. Cranor and Washington University.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by Charles D. Cranor and
16 *      Washington University.
17 * 4. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $NetBSD: natm_pcb.c,v 1.4 1996/11/09 03:26:27 chuck Exp $
32 */
33
34/*
35 * atm_pcb.c: manage atm protocol control blocks and keep IP and NATM
36 * from trying to use each other's VCs.
37 */
38
39#include "opt_ddb.h"
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD$");
43
44#include <sys/param.h>
45#include <sys/kernel.h>
46#include <sys/lock.h>
47#include <sys/malloc.h>
48#include <sys/mutex.h>
49#include <sys/systm.h>
50#include <sys/socket.h>
51#include <sys/socketvar.h>
52
53#include <net/if.h>
54#include <net/if_var.h>		/* XXX: db_show_natm() */
55
56#include <netinet/in.h>
57
58#include <netnatm/natm.h>
59
60#include <ddb/ddb.h>
61
62struct npcblist natm_pcbs;
63
64/*
65 * npcb_alloc: allocate a npcb [in the free state]
66 */
67struct natmpcb *
68npcb_alloc(int wait)
69
70{
71	struct natmpcb *npcb;
72
73	npcb = malloc(sizeof(*npcb), M_PCB, wait | M_ZERO);
74	if (npcb != NULL)
75		npcb->npcb_flags = NPCB_FREE;
76	return (npcb);
77}
78
79
80/*
81 * npcb_free: free a npcb
82 */
83void
84npcb_free(struct natmpcb *npcb, int op)
85{
86
87	NATM_LOCK_ASSERT();
88
89	if ((npcb->npcb_flags & NPCB_FREE) == 0) {
90		LIST_REMOVE(npcb, pcblist);
91		npcb->npcb_flags = NPCB_FREE;
92	}
93	if (op == NPCB_DESTROY) {
94		if (npcb->npcb_inq) {
95			npcb->npcb_flags = NPCB_DRAIN;	/* flag for distruct. */
96		} else {
97			free(npcb, M_PCB);		/* kill it! */
98		}
99	}
100}
101
102
103/*
104 * npcb_add: add or remove npcb from main list
105 *   returns npcb if ok
106 */
107struct natmpcb *
108npcb_add(struct natmpcb *npcb, struct ifnet *ifp, u_int16_t vci, u_int8_t vpi)
109{
110	struct natmpcb *cpcb = NULL;		/* current pcb */
111
112	NATM_LOCK_ASSERT();
113
114	/*
115	 * lookup required
116	 */
117	LIST_FOREACH(cpcb, &natm_pcbs, pcblist)
118		if (ifp == cpcb->npcb_ifp && vci == cpcb->npcb_vci &&
119		    vpi == cpcb->npcb_vpi)
120			break;
121
122	/*
123	 * add & something already there?
124	 */
125	if (cpcb) {
126		cpcb = NULL;
127		goto done;			/* fail */
128	}
129
130	/*
131	 * need to allocate a pcb?
132	 */
133	if (npcb == NULL) {
134		/* could be called from lower half */
135		cpcb = npcb_alloc(M_NOWAIT);
136		if (cpcb == NULL)
137			goto done;			/* fail */
138	} else {
139		cpcb = npcb;
140	}
141
142	cpcb->npcb_ifp = ifp;
143	cpcb->ipaddr.s_addr = 0;
144	cpcb->npcb_vci = vci;
145	cpcb->npcb_vpi = vpi;
146	cpcb->npcb_flags = NPCB_CONNECTED;
147
148	LIST_INSERT_HEAD(&natm_pcbs, cpcb, pcblist);
149
150done:
151	return (cpcb);
152}
153
154#ifdef DDB
155DB_SHOW_COMMAND(natm, db_show_natm)
156{
157	struct natmpcb *cpcb;
158
159	db_printf("npcb dump:\n");
160	LIST_FOREACH(cpcb, &natm_pcbs, pcblist) {
161		db_printf("if=%s, vci=%d, vpi=%d, IP=0x%x, sock=%p, "
162		    "flags=0x%x, inq=%d\n", cpcb->npcb_ifp->if_xname,
163		    cpcb->npcb_vci, cpcb->npcb_vpi, cpcb->ipaddr.s_addr,
164		    cpcb->npcb_socket, cpcb->npcb_flags, cpcb->npcb_inq);
165	}
166}
167#endif
168