altq.c revision 302408
1251607Sdim/* 2251607Sdim * Copyright (c) 2002-2003 Luigi Rizzo 3251607Sdim * Copyright (c) 1996 Alex Nash, Paul Traina, Poul-Henning Kamp 4251607Sdim * Copyright (c) 1994 Ugen J.S.Antsilevich 5251607Sdim * 6251607Sdim * Idea and grammar partially left from: 7251607Sdim * Copyright (c) 1993 Daniel Boulet 8251607Sdim * 9251607Sdim * Redistribution and use in source forms, with and without modification, 10251607Sdim * are permitted provided that this entire comment appears intact. 11251607Sdim * 12251607Sdim * Redistribution in binary form may occur without any restrictions. 13251607Sdim * Obviously, it would be nice if you gave credit where credit is due 14251607Sdim * but requiring it would be too onerous. 15251607Sdim * 16251607Sdim * This software is provided ``AS IS'' without any warranties of any kind. 17251607Sdim * 18251607Sdim * NEW command line interface for IP firewall facility 19251607Sdim * 20251607Sdim * $FreeBSD: stable/11/sbin/ipfw/altq.c 270424 2014-08-23 17:37:18Z melifaro $ 21251607Sdim * 22251607Sdim * altq interface 23251607Sdim */ 24251607Sdim 25251607Sdim#include <sys/types.h> 26251607Sdim#include <sys/socket.h> 27251607Sdim#include <sys/sockio.h> 28251607Sdim 29251607Sdim#include "ipfw2.h" 30251607Sdim 31251607Sdim#include <err.h> 32251607Sdim#include <errno.h> 33251607Sdim#include <stdio.h> 34251607Sdim#include <stdlib.h> 35251607Sdim#include <string.h> 36251607Sdim#include <sysexits.h> 37251607Sdim#include <unistd.h> 38251607Sdim#include <fcntl.h> 39251607Sdim 40251607Sdim#include <net/if.h> /* IFNAMSIZ */ 41251607Sdim#include <net/pfvar.h> 42251607Sdim#include <netinet/in.h> /* in_addr */ 43251607Sdim#include <netinet/ip_fw.h> 44251607Sdim 45251607Sdim/* 46251607Sdim * Map between current altq queue id numbers and names. 47251607Sdim */ 48251607Sdimstatic TAILQ_HEAD(, pf_altq) altq_entries = 49251607Sdim TAILQ_HEAD_INITIALIZER(altq_entries); 50251607Sdim 51251607Sdimvoid 52251607Sdimaltq_set_enabled(int enabled) 53251607Sdim{ 54251607Sdim int pffd; 55251607Sdim 56251607Sdim pffd = open("/dev/pf", O_RDWR); 57251607Sdim if (pffd == -1) 58251607Sdim err(EX_UNAVAILABLE, 59251607Sdim "altq support opening pf(4) control device"); 60251607Sdim if (enabled) { 61251607Sdim if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) 62251607Sdim err(EX_UNAVAILABLE, "enabling altq"); 63251607Sdim } else { 64251607Sdim if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) 65251607Sdim err(EX_UNAVAILABLE, "disabling altq"); 66251607Sdim } 67251607Sdim close(pffd); 68251607Sdim} 69251607Sdim 70251607Sdimstatic void 71251607Sdimaltq_fetch(void) 72251607Sdim{ 73251607Sdim struct pfioc_altq pfioc; 74251607Sdim struct pf_altq *altq; 75251607Sdim int pffd; 76251607Sdim unsigned int mnr; 77251607Sdim static int altq_fetched = 0; 78251607Sdim 79251607Sdim if (altq_fetched) 80251607Sdim return; 81251607Sdim altq_fetched = 1; 82251607Sdim pffd = open("/dev/pf", O_RDONLY); 83251607Sdim if (pffd == -1) { 84251607Sdim warn("altq support opening pf(4) control device"); 85251607Sdim return; 86251607Sdim } 87251607Sdim bzero(&pfioc, sizeof(pfioc)); 88251607Sdim if (ioctl(pffd, DIOCGETALTQS, &pfioc) != 0) { 89251607Sdim warn("altq support getting queue list"); 90251607Sdim close(pffd); 91251607Sdim return; 92251607Sdim } 93251607Sdim mnr = pfioc.nr; 94251607Sdim for (pfioc.nr = 0; pfioc.nr < mnr; pfioc.nr++) { 95251607Sdim if (ioctl(pffd, DIOCGETALTQ, &pfioc) != 0) { 96251607Sdim if (errno == EBUSY) 97251607Sdim break; 98251607Sdim warn("altq support getting queue list"); 99251607Sdim close(pffd); 100251607Sdim return; 101251607Sdim } 102251607Sdim if (pfioc.altq.qid == 0) 103251607Sdim continue; 104251607Sdim altq = safe_calloc(1, sizeof(*altq)); 105251607Sdim *altq = pfioc.altq; 106251607Sdim TAILQ_INSERT_TAIL(&altq_entries, altq, entries); 107251607Sdim } 108251607Sdim close(pffd); 109251607Sdim} 110251607Sdim 111251607Sdimu_int32_t 112251607Sdimaltq_name_to_qid(const char *name) 113251607Sdim{ 114 struct pf_altq *altq; 115 116 altq_fetch(); 117 TAILQ_FOREACH(altq, &altq_entries, entries) 118 if (strcmp(name, altq->qname) == 0) 119 break; 120 if (altq == NULL) 121 errx(EX_DATAERR, "altq has no queue named `%s'", name); 122 return altq->qid; 123} 124 125static const char * 126altq_qid_to_name(u_int32_t qid) 127{ 128 struct pf_altq *altq; 129 130 altq_fetch(); 131 TAILQ_FOREACH(altq, &altq_entries, entries) 132 if (qid == altq->qid) 133 break; 134 if (altq == NULL) 135 return NULL; 136 return altq->qname; 137} 138 139void 140print_altq_cmd(struct buf_pr *bp, ipfw_insn_altq *altqptr) 141{ 142 if (altqptr) { 143 const char *qname; 144 145 qname = altq_qid_to_name(altqptr->qid); 146 if (qname == NULL) 147 bprintf(bp, " altq ?<%u>", altqptr->qid); 148 else 149 bprintf(bp, " altq %s", qname); 150 } 151} 152