Skip to content

Commit 7560447

Browse files
committed
functions to initialize queueing, and add queues
1 parent bebe621 commit 7560447

5 files changed

Lines changed: 219 additions & 6 deletions

File tree

sys/net/npf/files.npf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ file net/npf/npf_alg_icmp.c npf
5050

5151
# Interfaces
5252
file net/npf/if_npflog.c npf
53+
54+
# queues
55+
file net/npf/npf_altq.c npf

sys/net/npf/npf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ struct npfioc_altq {
330330
#define IOC_NPF_RULE _IOWR('N', 107, nvlist_ref_t)
331331
#define IOC_NPF_CONN_LOOKUP _IOWR('N', 108, nvlist_ref_t)
332332
#define IOC_NPF_TABLE_REPLACE _IOWR('N', 109, nvlist_ref_t)
333-
#define IOC_NPF_BEGIN_ALTQ _IO('N', 112)
333+
#define IOC_NPF_BEGIN_ALTQ _IO('N', 112)
334334
#define IOC_NPF_ADD_ALTQ _IOWR('N', 110, struct npfioc_altq)
335335
#define IOC_NPF_GET_ALTQS _IOWR('N', 111, struct npfioc_altq)
336336

sys/net/npf/npf_altq.c

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
#ifdef _KERNEL_OPT
2+
#include "opt_altq.h"
3+
#include "opt_inet.h"
4+
#endif
5+
6+
#include <sys/systm.h>
7+
#include <sys/pool.h>
8+
#include <altq/altq.h>
9+
#include "npf.h"
10+
11+
#ifdef ALTQ
12+
13+
TAILQ_HEAD(npf_tags, npf_tagname) npf_tags = TAILQ_HEAD_INITIALIZER(npf_tags),
14+
npf_qids = TAILQ_HEAD_INITIALIZER(npf_qids);
15+
16+
void tag_unref(struct npf_tags *, u_int16_t);
17+
uint16_t npftagname2tag(struct npf_tags *, char *);
18+
19+
struct npf_altqqueue *npf_altqs_active;
20+
struct npf_altqqueue *npf_altqs_inactive;
21+
struct npf_altqqueue npf_altqs[2];
22+
23+
struct pool npf_altq_pl;
24+
int npf_altq_loaded = 0;
25+
26+
/* npf interface to start altq */
27+
void
28+
npf_altq_init(void)
29+
{
30+
pool_init(&npf_altq_pl, sizeof(struct npf_altq), 0, 0, 0, "npfaltqpl",
31+
&pool_allocator_nointr, IPL_NONE);
32+
TAILQ_INIT(&npf_altqs[0]);
33+
TAILQ_INIT(&npf_altqs[1]);
34+
npf_altqs_active = &npf_altqs[0];
35+
npf_altqs_inactive = &npf_altqs[1];
36+
}
37+
38+
int
39+
npf_begin_altq(void)
40+
{
41+
struct npf_altq *altq;
42+
int error = 0;
43+
/* Purge the old altq list */
44+
while ((altq = TAILQ_FIRST(npf_altqs_inactive)) != NULL) {
45+
TAILQ_REMOVE(npf_altqs_inactive, altq, entries);
46+
if (altq->qname[0] == 0) {
47+
/* detach and destroy the discipline */
48+
if ((error = altq_remove(altq)) != 0)
49+
return error;
50+
} else
51+
npf_qid_unref(altq->qid);
52+
pool_put(&npf_altq_pl, altq);
53+
}
54+
55+
return 0;
56+
}
57+
58+
void
59+
npf_qid_unref(u_int32_t qid)
60+
{
61+
tag_unref(&npf_qids, (u_int16_t)qid);
62+
}
63+
64+
void
65+
tag_unref(struct npf_tags *head, u_int16_t tag)
66+
{
67+
struct npf_tagname *p, *next;
68+
if (tag == 0)
69+
return;
70+
for (p = TAILQ_FIRST(head); p != NULL; p = next) {
71+
next = TAILQ_NEXT(p, entries);
72+
if (tag == p->tag) {
73+
if (--p->ref == 0) {
74+
TAILQ_REMOVE(head, p, entries);
75+
free(p, M_TEMP);
76+
}
77+
break;
78+
}
79+
}
80+
}
81+
82+
int
83+
npf_add_altq(void *data)
84+
{
85+
struct npfioc_altq *paa = (struct npfioc_altq *)data;
86+
struct npf_altq *altq, *a;
87+
int error;
88+
89+
altq = pool_get(&npf_altq_pl, PR_NOWAIT);
90+
if (altq == NULL) {
91+
error = ENOMEM;
92+
return error;
93+
}
94+
memcpy(altq, &paa->altq, sizeof(*altq));
95+
/*
96+
* if this is for a queue, find the discipline and
97+
* copy the necessary fields
98+
*/
99+
if (altq->qname[0] != 0) {
100+
if ((altq->qid = npf_qname2qid(altq->qname)) == 0) {
101+
error = EBUSY;
102+
pool_put(&npf_altq_pl, altq);
103+
return error;
104+
}
105+
TAILQ_FOREACH(a, npf_altqs_inactive, entries) {
106+
if (strncmp(a->ifname, altq->ifname,
107+
IFNAMSIZ) == 0 && a->qname[0] == 0) {
108+
altq->altq_disc = a->altq_disc;
109+
break;
110+
}
111+
}
112+
}
113+
error = altq_add(altq);
114+
if (error) {
115+
pool_put(&npf_altq_pl, altq);
116+
return error;
117+
}
118+
TAILQ_INSERT_TAIL(npf_altqs_inactive, altq, entries);
119+
memcpy(&paa->altq, altq, sizeof(paa->altq));
120+
121+
if (!npf_altq_loaded)
122+
npf_altq_loaded = 1;
123+
return 0;
124+
}
125+
126+
u_int32_t
127+
npf_qname2qid(char *qname)
128+
{
129+
return ((u_int32_t)npftagname2tag(&npf_qids, qname));
130+
}
131+
132+
u_int16_t
133+
npftagname2tag(struct npf_tags *head, char *tagname)
134+
{
135+
struct npf_tagname *tag, *p = NULL;
136+
u_int16_t new_tagid = 1;
137+
TAILQ_FOREACH(tag, head, entries)
138+
if (strcmp(tagname, tag->name) == 0) {
139+
tag->ref++;
140+
return (tag->tag);
141+
}
142+
/*
143+
* to avoid fragmentation, we do a linear search from the beginning
144+
* and take the first free slot we find. if there is none or the list
145+
* is empty, append a new entry at the end.
146+
*/
147+
/* new entry */
148+
if (!TAILQ_EMPTY(head))
149+
for (p = TAILQ_FIRST(head); p != NULL &&
150+
p->tag == new_tagid; p = TAILQ_NEXT(p, entries))
151+
new_tagid = p->tag + 1;
152+
if (new_tagid > TAGID_MAX)
153+
return 0;
154+
/* allocate and fill new struct npf_tagname */
155+
tag = malloc(sizeof(*tag),
156+
M_TEMP, M_NOWAIT);
157+
if (tag == NULL)
158+
return 0;
159+
memset(tag, 0, sizeof(*tag));
160+
strlcpy(tag->name, tagname, sizeof(tag->name));
161+
tag->tag = new_tagid;
162+
tag->ref++;
163+
if (p != NULL) /* insert new entry before p */
164+
TAILQ_INSERT_BEFORE(p, tag, entries);
165+
else /* either list empty or no free slot in between */
166+
TAILQ_INSERT_TAIL(head, tag, entries);
167+
return (tag->tag);
168+
}
169+
170+
int
171+
npf_get_altqs(void *data)
172+
{
173+
struct npfioc_altq *paa = (struct npfioc_altq *)data;
174+
struct npf_altq *altq;
175+
paa->nr = 0;
176+
TAILQ_FOREACH(altq, npf_altqs_active, entries)
177+
paa->nr++;
178+
return 0 ;
179+
}
180+
181+
#endif /* ALTQ */

sys/net/npf/npf_altq.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,24 @@ struct npf_altq {
105105
u_int32_t qid; /* return value */
106106
};
107107

108+
struct npf_tag {
109+
uint16_t tag; /* tag id */
110+
};
111+
112+
struct npf_tagname {
113+
TAILQ_ENTRY(npf_tagname) entries;
114+
char name[NPF_TAG_NAME_SIZE];
115+
uint16_t tag;
116+
int ref;
117+
};
118+
108119
TAILQ_HEAD(npf_altqqueue, npf_altq);
109120

110-
extern int npf_get_altqs(void *);
111-
extern void npf_altq_init(void);
112-
extern int npf_begin_altq(void);
113-
extern int npf_add_altq(void *);
121+
extern int npf_get_altqs(void *);
122+
extern void npf_altq_init(void);
123+
extern int npf_begin_altq(void);
124+
extern int npf_add_altq(void *);
125+
void npf_qid_unref(uint32_t);
126+
extern uint32_t npf_qname2qid(char *);
114127

115128
#endif /* NPF_ALTQ_H_ */

sys/net/npf/npf_os.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
* NPF main: dynamic load/initialisation and unload routines.
3232
*/
3333

34+
#ifdef _KERNEL_OPT
35+
#include "opt_altq.h"
36+
#include "opt_inet.h"
37+
#endif
38+
3439
#ifdef _KERNEL
3540
#include <sys/cdefs.h>
3641
__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.21 2021/01/27 17:39:13 christos Exp $");
@@ -274,7 +279,18 @@ npf_dev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
274279
return npfctl_table(npf, data);
275280
case IOC_NPF_STATS:
276281
return npf_stats_export(npf, data);
277-
282+
#ifdef ALTQ
283+
case IOC_NPF_ADD_ALTQ:
284+
return npf_add_altq(data);
285+
case IOC_NPF_GET_ALTQS:
286+
return npf_get_altqs(data);
287+
case IOC_NPF_BEGIN_ALTQ:
288+
/* initialize all queueing components on the first attempt */
289+
if (!npf_altq_loaded) {
290+
npf_altq_init();
291+
}
292+
return npf_begin_altq();
293+
#endif /* ALTQ */
278294
case IOC_NPF_LOAD:
279295
case IOC_NPF_SAVE:
280296
case IOC_NPF_RULE:

0 commit comments

Comments
 (0)