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