1
|
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
|
2
|
index 99c26c0..90e0959 100644
|
3
|
--- a/sbin/pfctl/parse.y
|
4
|
+++ b/sbin/pfctl/parse.y
|
5
|
@@ -215,6 +215,7 @@ struct filter_opts {
|
6
|
#define FOM_TOS 0x04
|
7
|
#define FOM_KEEP 0x08
|
8
|
#define FOM_SRCTRACK 0x10
|
9
|
+#define FOM_DSCP 0x20
|
10
|
struct node_uid *uid;
|
11
|
struct node_gid *gid;
|
12
|
struct {
|
13
|
@@ -225,6 +226,7 @@ struct filter_opts {
|
14
|
} flags;
|
15
|
struct node_icmp *icmpspec;
|
16
|
u_int32_t tos;
|
17
|
+ u_int32_t dscp;
|
18
|
u_int32_t prob;
|
19
|
struct {
|
20
|
int action;
|
21
|
@@ -440,7 +442,7 @@ int parseport(char *, struct range *r, int);
|
22
|
%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
|
23
|
%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
|
24
|
%token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
|
25
|
-%token NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DROP TABLE
|
26
|
+%token NOROUTE URPFFAILED FRAGMENT USER GROUP MAXMSS MAXIMUM TTL TOS DSCP DROP TABLE
|
27
|
%token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
|
28
|
%token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY RANDOMID
|
29
|
%token REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
|
30
|
@@ -458,7 +460,7 @@ int parseport(char *, struct range *r, int);
|
31
|
%token <v.i> PORTBINARY
|
32
|
%type <v.interface> interface if_list if_item_not if_item
|
33
|
%type <v.number> number icmptype icmp6type uid gid
|
34
|
-%type <v.number> tos not yesno
|
35
|
+%type <v.number> tos dscp not yesno
|
36
|
%type <v.probability> probability
|
37
|
%type <v.i> no dir af fragcache optimizer
|
38
|
%type <v.i> sourcetrack flush unaryop statelock
|
39
|
@@ -1928,7 +1930,14 @@ pfrule : action dir logquick interface route af proto fromto
|
40
|
#endif
|
41
|
}
|
42
|
|
43
|
- r.tos = $9.tos;
|
44
|
+ if ($9.tos) {
|
45
|
+ r.tos = $9.tos;
|
46
|
+ r.rule_flag |= PFRULE_TOS;
|
47
|
+ }
|
48
|
+ if ($9.dscp) {
|
49
|
+ r.tos = $9.dscp;
|
50
|
+ r.rule_flag |= PFRULE_DSCP;
|
51
|
+ }
|
52
|
r.keep_state = $9.keep.action;
|
53
|
o = $9.keep.options;
|
54
|
|
55
|
@@ -2306,6 +2315,14 @@ filter_opt : USER uids {
|
56
|
filter_opts.marker |= FOM_TOS;
|
57
|
filter_opts.tos = $2;
|
58
|
}
|
59
|
+ | dscp {
|
60
|
+ if (filter_opts.marker & FOM_DSCP) {
|
61
|
+ yyerror("dscp cannot be redefined");
|
62
|
+ YYERROR;
|
63
|
+ }
|
64
|
+ filter_opts.marker |= FOM_DSCP;
|
65
|
+ filter_opts.dscp = $1;
|
66
|
+ }
|
67
|
| keep {
|
68
|
if (filter_opts.marker & FOM_KEEP) {
|
69
|
yyerror("modulate or keep cannot be redefined");
|
70
|
@@ -3398,6 +3415,48 @@ tos : STRING {
|
71
|
}
|
72
|
;
|
73
|
|
74
|
+dscp : DSCP STRING {
|
75
|
+ if (!strcmp($2, "EF"))
|
76
|
+ $$ = DSCP_EF;
|
77
|
+ else if (!strcmp($2, "VA"))
|
78
|
+ $$ = DSCP_VA;
|
79
|
+ else if (!strcmp($2, "af11"))
|
80
|
+ $$ = DSCP_AF11;
|
81
|
+ else if (!strcmp($2, "af12"))
|
82
|
+ $$ = DSCP_AF12;
|
83
|
+ else if (!strcmp($2, "af13"))
|
84
|
+ $$ = DSCP_AF13;
|
85
|
+ else if (!strcmp($2, "af21"))
|
86
|
+ $$ = DSCP_AF21;
|
87
|
+ else if (!strcmp($2, "af22"))
|
88
|
+ $$ = DSCP_AF22;
|
89
|
+ else if (!strcmp($2, "af23"))
|
90
|
+ $$ = DSCP_AF23;
|
91
|
+ else if (!strcmp($2, "af31"))
|
92
|
+ $$ = DSCP_AF31;
|
93
|
+ else if (!strcmp($2, "af32"))
|
94
|
+ $$ = DSCP_AF32;
|
95
|
+ else if (!strcmp($2, "af33"))
|
96
|
+ $$ = DSCP_AF33;
|
97
|
+ else if (!strcmp($2, "af41"))
|
98
|
+ $$ = DSCP_AF41;
|
99
|
+ else if (!strcmp($2, "af42"))
|
100
|
+ $$ = DSCP_AF42;
|
101
|
+ else if (!strcmp($2, "af43"))
|
102
|
+ $$ = DSCP_AF43;
|
103
|
+ else if ($2[0] == '0' && $2[1] == 'x')
|
104
|
+ $$ = strtoul($2, NULL, 16) * 4;
|
105
|
+ else
|
106
|
+ $$ = strtoul($2, NULL, 10) * 4;
|
107
|
+ if (!$$ || $$ > 255) {
|
108
|
+ yyerror("illegal dscp value %s", $2);
|
109
|
+ free($2);
|
110
|
+ YYERROR;
|
111
|
+ }
|
112
|
+ free($2);
|
113
|
+ }
|
114
|
+ ;
|
115
|
+
|
116
|
sourcetrack : SOURCETRACK { $$ = PF_SRCTRACK; }
|
117
|
| SOURCETRACK GLOBAL { $$ = PF_SRCTRACK_GLOBAL; }
|
118
|
| SOURCETRACK RULE { $$ = PF_SRCTRACK_RULE; }
|
119
|
@@ -4440,6 +4497,10 @@ filter_consistent(struct pf_rule *r, int anchor_call)
|
120
|
"synproxy state or modulate state");
|
121
|
problems++;
|
122
|
}
|
123
|
+ if ((r->rule_flag & PFRULE_TOS) && (r->rule_flag & PFRULE_DSCP)) {
|
124
|
+ yyerror("tos and dscp cannot be used together");
|
125
|
+ problems++;
|
126
|
+ }
|
127
|
return (-problems);
|
128
|
}
|
129
|
|
130
|
@@ -5234,6 +5295,7 @@ lookup(char *s)
|
131
|
{ "divert-to", DIVERTTO},
|
132
|
{ "drop", DROP},
|
133
|
{ "drop-ovl", FRAGDROP},
|
134
|
+ { "dscp", DSCP},
|
135
|
{ "dup-to", DUPTO},
|
136
|
{ "fastroute", FASTROUTE},
|
137
|
{ "file", FILENAME},
|
138
|
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
|
139
|
index f248995..544bc22 100644
|
140
|
--- a/sbin/pfctl/pfctl_parser.c
|
141
|
+++ b/sbin/pfctl/pfctl_parser.c
|
142
|
@@ -847,8 +847,10 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose, int numeric)
|
143
|
printf(" code %u", r->code-1);
|
144
|
}
|
145
|
}
|
146
|
- if (r->tos)
|
147
|
- printf(" tos 0x%2.2x", r->tos);
|
148
|
+ if (r->tos && (r->rule_flag & PFRULE_TOS))
|
149
|
+ printf(" tos 0x%2.2x", r->tos);
|
150
|
+ if (r->tos && (r->rule_flag & PFRULE_DSCP))
|
151
|
+ printf(" dscp 0x%2.2x", r->tos & DSCP_MASK);
|
152
|
if (!r->keep_state && r->action == PF_PASS && !anchor_call[0])
|
153
|
printf(" no state");
|
154
|
else if (r->keep_state == PF_STATE_NORMAL)
|
155
|
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
|
156
|
index c16591b..8ac2659 100644
|
157
|
--- a/sys/net/pfvar.h
|
158
|
+++ b/sys/net/pfvar.h
|
159
|
@@ -643,6 +643,29 @@ struct pf_rule {
|
160
|
u_int8_t allow_opts;
|
161
|
u_int8_t rt;
|
162
|
u_int8_t return_ttl;
|
163
|
+
|
164
|
+#ifndef DSCP_EF
|
165
|
+/* Copied from altq_cdnr.h */
|
166
|
+/* diffserve code points */
|
167
|
+#define DSCP_MASK 0xfc
|
168
|
+#define DSCP_CUMASK 0x03
|
169
|
+#define DSCP_VA 0xb0
|
170
|
+#define DSCP_EF 0xb8
|
171
|
+#define DSCP_AF11 0x28
|
172
|
+#define DSCP_AF12 0x30
|
173
|
+#define DSCP_AF13 0x38
|
174
|
+#define DSCP_AF21 0x48
|
175
|
+#define DSCP_AF22 0x50
|
176
|
+#define DSCP_AF23 0x58
|
177
|
+#define DSCP_AF31 0x68
|
178
|
+#define DSCP_AF32 0x70
|
179
|
+#define DSCP_AF33 0x78
|
180
|
+#define DSCP_AF41 0x88
|
181
|
+#define DSCP_AF42 0x90
|
182
|
+#define DSCP_AF43 0x98
|
183
|
+#define AF_CLASSMASK 0xe0
|
184
|
+#define AF_DROPPRECMASK 0x18
|
185
|
+#endif
|
186
|
u_int8_t tos;
|
187
|
u_int8_t set_tos;
|
188
|
u_int8_t anchor_relative;
|
189
|
@@ -677,6 +699,13 @@ struct pf_rule {
|
190
|
#define PFRULE_REASSEMBLE_TCP 0x1000
|
191
|
#define PFRULE_SET_TOS 0x2000
|
192
|
|
193
|
+/* rule flags for TOS or DSCP differentiation */
|
194
|
+#define PFRULE_TOS 0x2000
|
195
|
+#define PFRULE_DSCP 0x4000
|
196
|
+
|
197
|
+/* rule flags for handling ALTQ hashing required by certain disciplines */
|
198
|
+#define PFRULE_ALTQ_HASH 0x8000
|
199
|
+
|
200
|
/* rule flags again */
|
201
|
#define PFRULE_IFBOUND 0x00010000 /* if-bound */
|
202
|
#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
|
203
|
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
|
204
|
index 2de8c40..5786066b 100644
|
205
|
--- a/sys/netpfil/pf/pf.c
|
206
|
+++ b/sys/netpfil/pf/pf.c
|
207
|
@@ -3216,8 +3216,11 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
|
208
|
/* icmp only. type always 0 in other cases */
|
209
|
else if (r->code && r->code != icmpcode + 1)
|
210
|
r = TAILQ_NEXT(r, entries);
|
211
|
- else if (r->tos && !(r->tos == pd->tos))
|
212
|
- r = TAILQ_NEXT(r, entries);
|
213
|
+ else if ((r->rule_flag & PFRULE_TOS) && r->tos && !(r->tos == pd->tos))
|
214
|
+ r = TAILQ_NEXT(r, entries);
|
215
|
+ else if ((r->rule_flag & PFRULE_DSCP) && r->tos &&
|
216
|
+ !(r->tos == (pd->tos & DSCP_MASK)))
|
217
|
+ r = TAILQ_NEXT(r, entries);
|
218
|
else if (r->rule_flag & PFRULE_FRAGMENT)
|
219
|
r = TAILQ_NEXT(r, entries);
|
220
|
else if (pd->proto == IPPROTO_TCP &&
|
221
|
@@ -3655,6 +3658,9 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
|
222
|
r = r->skip[PF_SKIP_DST_ADDR].ptr;
|
223
|
else if (r->tos && !(r->tos == pd->tos))
|
224
|
r = TAILQ_NEXT(r, entries);
|
225
|
+ else if ((r->rule_flag & PFRULE_DSCP) && r->tos &&
|
226
|
+ !(r->tos == (pd->tos & DSCP_MASK)))
|
227
|
+ r = TAILQ_NEXT(r, entries);
|
228
|
else if (r->os_fingerprint != PF_OSFP_ANY)
|
229
|
r = TAILQ_NEXT(r, entries);
|
230
|
else if (pd->proto == IPPROTO_UDP &&
|