altq.c revision 189394
1228753Smm/*
2228753Smm * Copyright (c) 2002-2003 Luigi Rizzo
3228753Smm * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp
4228753Smm * Copyright (c) 1994 Ugen J.S.Antsilevich
5228753Smm *
6228753Smm * Idea and grammar partially left from:
7228753Smm * Copyright (c) 1993 Daniel Boulet
8228753Smm *
9228753Smm * Redistribution and use in source forms, with and without modification,
10228753Smm * are permitted provided that this entire comment appears intact.
11228753Smm *
12228753Smm * Redistribution in binary form may occur without any restrictions.
13228753Smm * Obviously, it would be nice if you gave credit where credit is due
14228753Smm * but requiring it would be too onerous.
15228753Smm *
16228753Smm * This software is provided ``AS IS'' without any warranties of any kind.
17228753Smm *
18228753Smm * NEW command line interface for IP firewall facility
19228753Smm *
20228753Smm * $FreeBSD: head/sbin/ipfw/altq.c 189394 2009-03-05 08:01:19Z luigi $
21228753Smm *
22228753Smm * altq interface
23228753Smm */
24228753Smm
25228753Smm#include <sys/types.h>
26228763Smm#include <sys/socket.h>
27228753Smm#include <sys/sockio.h>
28228753Smm
29228753Smm#include "ipfw2.h"
30228753Smm
31228753Smm#include <err.h>
32228753Smm#include <errno.h>
33228753Smm#include <stdio.h>
34228753Smm#include <stdlib.h>
35228753Smm#include <string.h>
36228753Smm#include <sysexits.h>
37228753Smm#include <unistd.h>
38228753Smm#include <fcntl.h>
39228753Smm
40228753Smm#include <net/if.h>		/* IFNAMSIZ */
41228753Smm#include <net/pfvar.h>
42228753Smm#include <netinet/ip_fw.h>
43228753Smm
44228753Smm/*
45228753Smm * Map between current altq queue id numbers and names.
46228753Smm */
47228753Smmstatic TAILQ_HEAD(, pf_altq) altq_entries =
48228753Smm	TAILQ_HEAD_INITIALIZER(altq_entries);
49228753Smm
50228753Smmvoid
51228753Smmaltq_set_enabled(int enabled)
52228753Smm{
53228753Smm	int pffd;
54228753Smm
55228753Smm	pffd = open("/dev/pf", O_RDWR);
56228753Smm	if (pffd == -1)
57228753Smm		err(EX_UNAVAILABLE,
58228753Smm		    "altq support opening pf(4) control device");
59228753Smm	if (enabled) {
60228753Smm		if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST)
61228753Smm			err(EX_UNAVAILABLE, "enabling altq");
62228753Smm	} else {
63228753Smm		if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT)
64228753Smm			err(EX_UNAVAILABLE, "disabling altq");
65228753Smm	}
66228753Smm	close(pffd);
67228753Smm}
68228753Smm
69228753Smmstatic void
70228753Smmaltq_fetch(void)
71228753Smm{
72228753Smm	struct pfioc_altq pfioc;
73228753Smm	struct pf_altq *altq;
74228753Smm	int pffd;
75228753Smm	unsigned int mnr;
76228753Smm	static int altq_fetched = 0;
77228753Smm
78228753Smm	if (altq_fetched)
79228753Smm		return;
80228753Smm	altq_fetched = 1;
81228753Smm	pffd = open("/dev/pf", O_RDONLY);
82228753Smm	if (pffd == -1) {
83228753Smm		warn("altq support opening pf(4) control device");
84228753Smm		return;
85228753Smm	}
86228753Smm	bzero(&pfioc, sizeof(pfioc));
87228753Smm	if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) {
88228753Smm		warn("altq support getting queue list");
89228753Smm		close(pffd);
90228753Smm		return;
91228753Smm	}
92228753Smm	mnr = pfioc.nr;
93228753Smm	for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) {
94228753Smm		if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) {
95228753Smm			if (errno == EBUSY)
96228753Smm				break;
97228753Smm			warn("altq support getting queue list");
98228753Smm			close(pffd);
99228753Smm			return;
100228753Smm		}
101228753Smm		if (pfioc.altq.qid == 0)
102228753Smm			continue;
103228753Smm		altq = safe_calloc(1, sizeof(*altq));
104228753Smm		*altq = pfioc.altq;
105228753Smm		TAILQ_INSERT_TAIL(&altq_entries, altq, entries);
106228753Smm	}
107228753Smm	close(pffd);
108228753Smm}
109228753Smm
110228753Smmu_int32_t
111228753Smmaltq_name_to_qid(const char *name)
112228753Smm{
113228753Smm	struct pf_altq *altq;
114228753Smm
115228753Smm	altq_fetch();
116228753Smm	TAILQ_FOREACH(altq, &altq_entries, entries)
117228753Smm		if (strcmp(name, altq->qname) == 0)
118228753Smm			break;
119228753Smm	if (altq == NULL)
120228753Smm		errx(EX_DATAERR, "altq has no queue named `%s'", name);
121228753Smm	return altq->qid;
122228753Smm}
123228753Smm
124228753Smmstatic const char *
125228753Smmaltq_qid_to_name(u_int32_t qid)
126228753Smm{
127228753Smm	struct pf_altq *altq;
128228753Smm
129228753Smm	altq_fetch();
130228753Smm	TAILQ_FOREACH(altq, &altq_entries, entries)
131228753Smm		if (qid == altq->qid)
132228753Smm			break;
133228753Smm	if (altq == NULL)
134228753Smm		return NULL;
135228753Smm	return altq->qname;
136228753Smm}
137228753Smm
138228753Smmvoid
139228753Smmprint_altq_cmd(ipfw_insn_altq *altqptr)
140228753Smm{
141228753Smm        if (altqptr) {
142228753Smm                const char *qname;
143228753Smm
144228753Smm                qname = altq_qid_to_name(altqptr->qid);
145228753Smm                if (qname == NULL)
146228753Smm                        printf(" altq ?<%u>", altqptr->qid);
147228753Smm                else
148228753Smm                        printf(" altq %s", qname);
149228753Smm        }
150228753Smm}
151228753Smm