summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/altq/altq_cbq.h2
-rw-r--r--sys/net/altq/altq_hfsc.h2
-rw-r--r--sys/net/if.h2
-rw-r--r--sys/net/if_bridge.c16
-rw-r--r--sys/net/if_ethersubr.c6
-rw-r--r--sys/net/if_pflog.h4
-rw-r--r--sys/net/if_pfsync.h3
-rw-r--r--sys/net/pfil.c147
-rw-r--r--sys/net/pfil.h7
-rw-r--r--sys/net/pfvar.h87
10 files changed, 261 insertions, 15 deletions
diff --git a/sys/net/altq/altq_cbq.h b/sys/net/altq/altq_cbq.h
index 51e7cf9..68559e2 100644
--- a/sys/net/altq/altq_cbq.h
+++ b/sys/net/altq/altq_cbq.h
@@ -190,7 +190,7 @@ struct cbq_getstats {
#define CBQ_TIMEOUT 10
#define CBQ_LS_TIMEOUT (20 * hz / 1000)
-#define CBQ_MAX_CLASSES 256
+#define CBQ_MAX_CLASSES 2048
#ifdef ALTQ3_COMPAT
#define CBQ_MAX_FILTERS 256
diff --git a/sys/net/altq/altq_hfsc.h b/sys/net/altq/altq_hfsc.h
index de5e89b..78521f8 100644
--- a/sys/net/altq/altq_hfsc.h
+++ b/sys/net/altq/altq_hfsc.h
@@ -51,7 +51,7 @@ struct service_curve {
/* special class handles */
#define HFSC_NULLCLASS_HANDLE 0
-#define HFSC_MAX_CLASSES 64
+#define HFSC_MAX_CLASSES 2048
/* hfsc class flags */
#define HFCF_RED 0x0001 /* use RED */
diff --git a/sys/net/if.h b/sys/net/if.h
index 98ae0a8..5da596a 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -249,7 +249,7 @@ struct if_data {
#define IFCAP_CANTCHANGE (IFCAP_NETMAP)
-#define IFQ_MAXLEN 50
+#define IFQ_MAXLEN 128
#define IFNET_SLOWHZ 1 /* granularity is 1 second */
/*
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 4fe5e67..d1df805 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -864,6 +864,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
BRIDGE_LOCK(sc);
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
+ if (bif->bif_ifp->if_type == IFT_GIF)
+ continue;
if (bif->bif_ifp->if_mtu != ifr->ifr_mtu) {
log(LOG_NOTICE, "%s: invalid MTU: %u(%s)"
" != %d\n", sc->sc_ifp->if_xname,
@@ -1155,12 +1157,14 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
}
#endif
/* Allow the first Ethernet member to define the MTU */
- if (LIST_EMPTY(&sc->sc_iflist))
- sc->sc_ifp->if_mtu = ifs->if_mtu;
- else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
- if_printf(sc->sc_ifp, "invalid MTU: %u(%s) != %u\n",
- ifs->if_mtu, ifs->if_xname, sc->sc_ifp->if_mtu);
- return (EINVAL);
+ if (ifs->if_type != IFT_GIF) {
+ if (LIST_EMPTY(&sc->sc_iflist))
+ sc->sc_ifp->if_mtu = ifs->if_mtu;
+ else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
+ if_printf(sc->sc_ifp, "invalid MTU: %u(%s) != %u\n",
+ ifs->if_mtu, ifs->if_xname, sc->sc_ifp->if_mtu);
+ return (EINVAL);
+ }
}
bif = malloc(sizeof(*bif), M_DEVBUF, M_NOWAIT|M_ZERO);
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 82c8b3a..27f4411 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -87,6 +87,8 @@ CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN);
VNET_DEFINE(struct pfil_head, link_pfil_hook); /* Packet filter hooks */
+SYSCTL_DECL(_net_link);
+
/* netgraph node hooks for ng_ether(4) */
void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m);
@@ -702,6 +704,9 @@ vnet_ether_init(__unused void *arg)
if ((i = pfil_head_register(&V_link_pfil_hook)) != 0)
printf("%s: WARNING: unable to register pfil link hook, "
"error %d\n", __func__, i);
+ else
+ pfil_head_export_sysctl(&V_link_pfil_hook,
+ SYSCTL_STATIC_CHILDREN(_net_link));
#ifdef VIMAGE
netisr_register_vnet(&ether_nh);
#endif
@@ -972,7 +977,6 @@ ether_reassign(struct ifnet *ifp, struct vnet *new_vnet, char *unused __unused)
}
#endif
-SYSCTL_DECL(_net_link);
SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
#if 0
diff --git a/sys/net/if_pflog.h b/sys/net/if_pflog.h
index 0faeb7d..326b551 100644
--- a/sys/net/if_pflog.h
+++ b/sys/net/if_pflog.h
@@ -40,10 +40,14 @@ struct pfloghdr {
char ruleset[PFLOG_RULESET_NAME_SIZE];
u_int32_t rulenr;
u_int32_t subrulenr;
+#ifdef PF_USER_INFO
uid_t uid;
pid_t pid;
uid_t rule_uid;
pid_t rule_pid;
+#else
+ u_int32_t ridentifier;
+#endif
u_int8_t dir;
u_int8_t pad[3];
};
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
index 5c4ba63..74be9b7 100644
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -235,6 +235,9 @@ struct pfsyncreq {
char pfsyncr_syncdev[IFNAMSIZ];
struct in_addr pfsyncr_syncpeer;
int pfsyncr_maxupdates;
+#define PFSYNCF_OK 0x00000001
+#define PFSYNCF_DEFER 0x00000002
+#define PFSYNCF_PUSH 0x00000004
int pfsyncr_defer;
};
diff --git a/sys/net/pfil.c b/sys/net/pfil.c
index 248d183..94a95ac 100644
--- a/sys/net/pfil.c
+++ b/sys/net/pfil.c
@@ -34,6 +34,7 @@
#include <sys/errno.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/sbuf.h>
#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -79,7 +80,7 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
for (pfh = pfil_chain_get(dir, ph); pfh != NULL;
pfh = TAILQ_NEXT(pfh, pfil_chain)) {
- if (pfh->pfil_func != NULL) {
+ if (!(pfh->pfil_flags & PFIL_DISABLED) && pfh->pfil_func != NULL) {
rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir,
inp);
if (rv != 0 || m == NULL)
@@ -212,6 +213,140 @@ pfil_head_unregister(struct pfil_head *ph)
return (0);
}
+static int
+pfil_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct rm_priotracker rmpt;
+ struct pfil_head *ph;
+ struct packet_filter_hook *pfh, *pfhtmp;
+ struct sbuf *sb;
+ pfil_chain_t npfl, *pfl;
+ char *new_order, *elm, *parse;
+ int i = 0, err = 0, hintlen, reqlen;
+
+ hintlen = 0;
+
+ ph = (struct pfil_head *)arg1;
+ if (ph == NULL || !PFIL_HOOKED(ph)) {
+ err = SYSCTL_OUT(req, "", 2);
+ return (err);
+ }
+
+ if (arg2 == PFIL_IN)
+ pfl = &ph->ph_in;
+ else
+ pfl = &ph->ph_out;
+
+ if (TAILQ_EMPTY(pfl)) {
+ err = SYSCTL_OUT(req, "", 2);
+ return (err);
+ }
+
+ /*
+ * NOTE: This is needed to avoid witness(4) warnings.
+ */
+ PFIL_RLOCK(ph, &rmpt);
+ TAILQ_FOREACH(pfh, pfl, pfil_chain) {
+ if (pfh->pfil_name != NULL)
+ hintlen = strlen(pfh->pfil_name);
+ else
+ hintlen += 2;
+ }
+ PFIL_RUNLOCK(ph, &rmpt);
+
+ sb = sbuf_new(NULL, NULL, hintlen + 1, SBUF_AUTOEXTEND);
+ if (sb == NULL)
+ return (EINVAL);
+
+ PFIL_RLOCK(ph, &rmpt);
+ TAILQ_FOREACH(pfh, pfl, pfil_chain) {
+ if (i > 0)
+ sbuf_printf(sb, ", ");
+ if (pfh->pfil_name != NULL)
+ sbuf_printf(sb, "%s%s", pfh->pfil_name,
+ pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
+ else
+ sbuf_printf(sb, "%s%s", "NA",
+ pfh->pfil_flags & PFIL_DISABLED ? "*" : "");
+ i++;
+ }
+ PFIL_RUNLOCK(ph, &rmpt);
+
+ sbuf_finish(sb);
+
+ /* hint for sensible write buffer sizes */
+ hintlen = sbuf_len(sb) + i * 2;
+ err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
+ sbuf_delete(sb);
+
+ if (err || !req->newptr)
+ return (err);
+
+ if ((reqlen = req->newlen - req->newidx) > hintlen)
+ return (E2BIG);
+ new_order = malloc(reqlen + 1, M_TEMP, M_WAITOK|M_ZERO);
+
+ err = SYSCTL_IN(req, new_order, reqlen);
+ if (err)
+ goto error;
+ new_order[reqlen] = '\0'; /* Just in case */
+ parse = new_order;
+
+ TAILQ_INIT(&npfl);
+ PFIL_WLOCK(ph);
+ while ((elm = strsep(&parse, " \t,")) != NULL) {
+ if (*elm == '\0')
+ continue;
+ TAILQ_FOREACH_SAFE(pfh, pfl, pfil_chain, pfhtmp) {
+ if (pfh->pfil_name != NULL) {
+ if (!strcmp(pfh->pfil_name, elm)) {
+ TAILQ_REMOVE(pfl, pfh, pfil_chain);
+ TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
+ pfh->pfil_flags &= ~PFIL_DISABLED;
+ break;
+ }
+ } else {
+ if (!strcmp(elm, "NA")) {
+ TAILQ_REMOVE(pfl, pfh, pfil_chain);
+ TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
+ pfh->pfil_flags &= ~PFIL_DISABLED;
+ break;
+ }
+ }
+ }
+ }
+
+ TAILQ_FOREACH_SAFE(pfh, pfl, pfil_chain, pfhtmp) {
+ pfh->pfil_flags |= PFIL_DISABLED;
+ TAILQ_REMOVE(pfl, pfh, pfil_chain);
+ TAILQ_INSERT_TAIL(&npfl, pfh, pfil_chain);
+ }
+
+ TAILQ_CONCAT(pfl, &npfl, pfil_chain);
+
+error:
+ PFIL_WUNLOCK(ph);
+ free(new_order, M_TEMP);
+ return (err);
+}
+
+void
+pfil_head_export_sysctl(struct pfil_head *ph, struct sysctl_oid_list *parent)
+{
+ struct sysctl_oid *root;
+
+ root = SYSCTL_ADD_NODE(&ph->ph_clist, parent, OID_AUTO, "pfil",
+ CTLFLAG_RW, 0, "pfil(9) management");
+ SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+ "inbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+ (void *)ph, PFIL_IN, pfil_sysctl_handler, "A",
+ "Inbound filter hooks");
+ SYSCTL_ADD_PROC((void *)&ph->ph_clist, SYSCTL_CHILDREN(root), OID_AUTO,
+ "outbound", CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_SECURE3,
+ (void *)ph, PFIL_OUT, pfil_sysctl_handler, "A",
+ "Outbound filter hooks");
+}
+
/*
* pfil_head_get() returns the pfil_head for a given key/dlt.
*/
@@ -239,6 +374,12 @@ pfil_head_get(int type, u_long val)
int
pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
{
+ return (pfil_add_named_hook(func, arg, NULL, flags, ph));
+}
+
+int
+pfil_add_named_hook(pfil_func_t func, void *arg, char *name, int flags, struct pfil_head *ph)
+{
struct packet_filter_hook *pfh1 = NULL;
struct packet_filter_hook *pfh2 = NULL;
int err;
@@ -263,6 +404,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
if (flags & PFIL_IN) {
pfh1->pfil_func = func;
pfh1->pfil_arg = arg;
+ pfh1->pfil_name = name;
+ pfh1->pfil_flags &= ~PFIL_DISABLED;
err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
if (err)
goto locked_error;
@@ -271,6 +414,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
if (flags & PFIL_OUT) {
pfh2->pfil_func = func;
pfh2->pfil_arg = arg;
+ pfh2->pfil_name = name;
+ pfh2->pfil_flags &= ~PFIL_DISABLED;
err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
if (err) {
if (flags & PFIL_IN)
diff --git a/sys/net/pfil.h b/sys/net/pfil.h
index c9a1b65..ff260ce 100644
--- a/sys/net/pfil.h
+++ b/sys/net/pfil.h
@@ -38,6 +38,7 @@
#include <sys/_mutex.h>
#include <sys/lock.h>
#include <sys/rmlock.h>
+#include <sys/sysctl.h>
struct mbuf;
struct ifnet;
@@ -55,11 +56,14 @@ struct packet_filter_hook {
TAILQ_ENTRY(packet_filter_hook) pfil_chain;
pfil_func_t pfil_func;
void *pfil_arg;
+ int pfil_flags;
+ char *pfil_name;
};
#define PFIL_IN 0x00000001
#define PFIL_OUT 0x00000002
#define PFIL_WAITOK 0x00000004
+#define PFIL_DISABLED 0x00000008
#define PFIL_ALL (PFIL_IN|PFIL_OUT)
typedef TAILQ_HEAD(pfil_chain, packet_filter_hook) pfil_chain_t;
@@ -85,6 +89,7 @@ struct pfil_head {
struct rmlock ph_lock; /* Private lock storage */
int flags;
#endif
+ struct sysctl_ctx_list ph_clist;
union {
u_long phu_val;
void *phu_ptr;
@@ -96,7 +101,9 @@ struct pfil_head {
/* Public functions for pfil hook management by packet filters. */
struct pfil_head *pfil_head_get(int, u_long);
+void pfil_head_export_sysctl(struct pfil_head *, struct sysctl_oid_list *);
int pfil_add_hook(pfil_func_t, void *, int, struct pfil_head *);
+int pfil_add_named_hook(pfil_func_t, void *, char *, int, struct pfil_head *);
int pfil_remove_hook(pfil_func_t, void *, int, struct pfil_head *);
#define PFIL_HOOKED(p) ((p)->ph_nhooks > 0)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index ed23eb5..a6c95ac 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -329,6 +329,14 @@ struct pf_rule_gid {
u_int8_t op;
};
+struct pf_rule_ieee8021q_pcp {
+ u_int8_t pcp[2];
+ u_int8_t op;
+#define SETPCP_VALID 0x80 /* Set if PCP value in field is valid. */
+#define SETPCP_PCP_MASK 0x07 /* Mask to retrieve pcp if SETPCP_VALID. */
+ u_int8_t setpcp;
+};
+
struct pf_rule_addr {
struct pf_addr_wrap addr;
u_int16_t port[2];
@@ -468,6 +476,13 @@ struct pf_osfp_ioctl {
int fp_getnum; /* DIOCOSFPGET number */
};
+struct pf_rule_actions {
+ u_int16_t qid;
+ u_int16_t pqid;
+ u_int32_t pdnpipe;
+ u_int32_t dnpipe;
+ u_int8_t flags;
+};
union pf_rule_ptr {
struct pf_rule *ptr;
@@ -491,6 +506,7 @@ struct pf_rule {
union pf_rule_ptr skip[PF_SKIP_COUNT];
#define PF_RULE_LABEL_SIZE 64
char label[PF_RULE_LABEL_SIZE];
+ char schedule[PF_RULE_LABEL_SIZE];
char ifname[IFNAMSIZ];
char qname[PF_QNAME_SIZE];
char pqname[PF_QNAME_SIZE];
@@ -523,12 +539,21 @@ struct pf_rule {
u_int32_t limit;
u_int32_t seconds;
} max_src_conn_rate;
- u_int32_t qid;
- u_int32_t pqid;
+ u_int16_t qid;
+ u_int16_t pqid;
+ u_int32_t dnpipe;
+ u_int32_t pdnpipe;
+#define PFRULE_DN_IS_PIPE 0x00000010
+#define PFRULE_DN_IS_QUEUE 0x00000020
+ u_int32_t free_flags;
u_int32_t rt_listid;
u_int32_t nr;
u_int32_t prob;
+#ifdef PF_USER_INFO
uid_t cuid;
+#else
+ u_int32_t cuid;
+#endif
pid_t cpid;
counter_u64_t states_cur;
@@ -569,6 +594,29 @@ struct pf_rule {
u_int8_t allow_opts;
u_int8_t rt;
u_int8_t return_ttl;
+
+#ifndef DSCP_EF
+/* Copied from altq_cdnr.h */
+/* diffserve code points */
+#define DSCP_MASK 0xfc
+#define DSCP_CUMASK 0x03
+#define DSCP_VA 0xb0
+#define DSCP_EF 0xb8
+#define DSCP_AF11 0x28
+#define DSCP_AF12 0x30
+#define DSCP_AF13 0x38
+#define DSCP_AF21 0x48
+#define DSCP_AF22 0x50
+#define DSCP_AF23 0x58
+#define DSCP_AF31 0x68
+#define DSCP_AF32 0x70
+#define DSCP_AF33 0x78
+#define DSCP_AF41 0x88
+#define DSCP_AF42 0x90
+#define DSCP_AF43 0x98
+#define AF_CLASSMASK 0xe0
+#define AF_DROPPRECMASK 0x18
+#endif
u_int8_t tos;
u_int8_t set_tos;
u_int8_t anchor_relative;
@@ -583,6 +631,8 @@ struct pf_rule {
u_int16_t port;
} divert;
+ struct pf_rule_ieee8021q_pcp ieee8021q_pcp;
+
uint64_t u_states_cur;
uint64_t u_states_tot;
uint64_t u_src_nodes;
@@ -605,6 +655,13 @@ struct pf_rule {
#define PFRULE_REASSEMBLE_TCP 0x1000
#define PFRULE_SET_TOS 0x2000
+/* rule flags for TOS or DSCP differentiation */
+#define PFRULE_TOS 0x2000
+#define PFRULE_DSCP 0x4000
+
+/* rule flags for handling ALTQ hashing required by certain disciplines */
+#define PFRULE_ALTQ_HASH 0x8000
+
/* rule flags again */
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
@@ -709,7 +766,13 @@ struct pf_state {
u_int64_t id;
u_int32_t creatorid;
u_int8_t direction;
- u_int8_t pad[3];
+ u_int8_t pad[2];
+ u_int8_t local_flags;
+#define PFSTATE_DIVERT_ALTQ 0x10
+#define PFSTATE_DIVERT_DNCOOKIE 0x20
+#define PFSTATE_DIVERT_ACTION 0x40
+#define PFSTATE_DIVERT_TAG 0x80
+#define PFSTATE_DIVERT_MASK 0xFF00
u_int refs;
TAILQ_ENTRY(pf_state) sync_list;
@@ -731,7 +794,12 @@ struct pf_state {
u_int32_t creation;
u_int32_t expire;
u_int32_t pfsync_time;
+ u_int16_t qid;
+ u_int16_t pqid;
+ u_int32_t pdnpipe;
+ u_int32_t dnpipe;
u_int16_t tag;
+ u_int16_t divert_cookie;
u_int8_t log;
u_int8_t state_flags;
#define PFSTATE_ALLOWOPTS 0x01
@@ -744,7 +812,7 @@ struct pf_state {
/* XXX */
u_int8_t sync_updates;
- u_int8_t _tail[3];
+ u_int8_t _tail;
};
/*
@@ -1080,11 +1148,13 @@ struct pfi_kif {
#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
struct pf_pdesc {
+#ifdef PF_USER_INFO
struct {
int done;
uid_t uid;
gid_t gid;
} lookup;
+#endif
u_int64_t tot_len; /* Make Mickey money */
union {
struct tcphdr *tcp;
@@ -1102,6 +1172,7 @@ struct pf_pdesc {
u_int16_t *sport;
u_int16_t *dport;
struct pf_mtag *pf_mtag;
+ struct pf_rule_actions act;
u_int32_t p_len; /* total length of payload */
@@ -1253,6 +1324,11 @@ struct pfioc_state_kill {
u_int psk_killed;
};
+struct pfioc_schedule_kill {
+ int numberkilled;
+ char schedule[PF_RULE_LABEL_SIZE];
+};
+
struct pfioc_states {
int ps_len;
union {
@@ -1437,6 +1513,7 @@ struct pf_ifspeed {
u_int32_t baudrate;
};
#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed)
+#define DIOCKILLSCHEDULE _IOWR('D', 96, struct pfioc_schedule_kill)
#ifdef _KERNEL
LIST_HEAD(pf_src_node_list, pf_src_node);
@@ -1595,6 +1672,8 @@ int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
int pf_match_addr_range(struct pf_addr *, struct pf_addr *,
struct pf_addr *, sa_family_t);
int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
+int pf_match_ieee8021q_pcp(u_int8_t, u_int8_t, u_int8_t, struct mbuf *);
+int pf_ieee8021q_setpcp(struct mbuf *m, struct pf_rule *r);
void pf_normalize_init(void);
void pf_normalize_cleanup(void);
OpenPOWER on IntegriCloud