]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/ipfw/altq.c
bhyvectl(8): Normalize the man page date
[FreeBSD/FreeBSD.git] / sbin / ipfw / altq.c
1 /*-
2  * Copyright (c) 2002-2003 Luigi Rizzo
3  * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
4  * Copyright (c) 1994 Ugen J.S.Antsilevich
5  *
6  * Idea and grammar partially left from:
7  * Copyright (c) 1993 Daniel Boulet
8  *
9  * Redistribution and use in source forms, with and without modification,
10  * are permitted provided that this entire comment appears intact.
11  *
12  * Redistribution in binary form may occur without any restrictions.
13  * Obviously, it would be nice if you gave credit where credit is due
14  * but requiring it would be too onerous.
15  *
16  * This software is provided ``AS IS'' without any warranties of any kind.
17  *
18  * NEW command line interface for IP firewall facility
19  *
20  * $FreeBSD$
21  *
22  * altq interface
23  */
24
25 #define PFIOC_USE_LATEST
26
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <sys/sockio.h>
30
31 #include "ipfw2.h"
32
33 #include <err.h>
34 #include <errno.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sysexits.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include <net/if.h>             /* IFNAMSIZ */
43 #include <net/pfvar.h>
44 #include <netinet/in.h> /* in_addr */
45 #include <netinet/ip_fw.h>
46
47 /*
48  * Map between current altq queue id numbers and names.
49  */
50 static TAILQ_HEAD(, pf_altq) altq_entries =
51         TAILQ_HEAD_INITIALIZER(altq_entries);
52
53 void
54 altq_set_enabled(int enabled)
55 {
56         int pffd;
57
58         pffd = open("/dev/pf", O_RDWR);
59         if (pffd == -1)
60                 err(EX_UNAVAILABLE,
61                     "altq support opening pf(4) control device");
62         if (enabled) {
63                 if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
64                         err(EX_UNAVAILABLE, "enabling altq");
65         } else {
66                 if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
67                         err(EX_UNAVAILABLE, "disabling altq");
68         }
69         close(pffd);
70 }
71
72 static void
73 altq_fetch(void)
74 {
75         struct pfioc_altq pfioc;
76         struct pf_altq *altq;
77         int pffd;
78         unsigned int mnr;
79         static int altq_fetched = 0;
80
81         if (altq_fetched)
82                 return;
83         altq_fetched = 1;
84         pffd = open("/dev/pf", O_RDONLY);
85         if (pffd == -1) {
86                 warn("altq support opening pf(4) control device");
87                 return;
88         }
89         bzero(&pfioc, sizeof(pfioc));
90         pfioc.version = PFIOC_ALTQ_VERSION;
91         if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
92                 warn("altq support getting queue list");
93                 close(pffd);
94                 return;
95         }
96         mnr = pfioc.nr;
97         for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
98                 if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
99                         if (errno == EBUSY)
100                                 break;
101                         warn("altq support getting queue list");
102                         close(pffd);
103                         return;
104                 }
105                 if (pfioc.altq.qid == 0)
106                         continue;
107                 altq = safe_calloc(1, sizeof(*altq));
108                 *altq = pfioc.altq;
109                 TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
110         }
111         close(pffd);
112 }
113
114 u_int32_t
115 altq_name_to_qid(const char *name)
116 {
117         struct pf_altq *altq;
118
119         altq_fetch();
120         TAILQ_FOREACH(altq, &altq_entries, entries)
121                 if (strcmp(name, altq->qname) == 0)
122                         break;
123         if (altq == NULL)
124                 errx(EX_DATAERR, "altq has no queue named `%s'", name);
125         return altq->qid;
126 }
127
128 static const char *
129 altq_qid_to_name(u_int32_t qid)
130 {
131         struct pf_altq *altq;
132
133         altq_fetch();
134         TAILQ_FOREACH(altq, &altq_entries, entries)
135                 if (qid == altq->qid)
136                         break;
137         if (altq == NULL)
138                 return NULL;
139         return altq->qname;
140 }
141
142 void
143 print_altq_cmd(struct buf_pr *bp, const ipfw_insn_altq *altqptr)
144 {
145         if (altqptr) {
146                 const char *qname;
147
148                 qname = altq_qid_to_name(altqptr->qid);
149                 if (qname == NULL)
150                         bprintf(bp, " altq ?<%u>", altqptr->qid);
151                 else
152                         bprintf(bp, " altq %s", qname);
153         }
154 }