Unix Technical Forum

Re: [patch] pfctl: allow multiple tags in "tagged" statement

This is a discussion on Re: [patch] pfctl: allow multiple tags in "tagged" statement within the mailing.openbsd.tech forums, part of the OpenBSD category; --> Of course actually including the diff is a better idea... * Daniel Hartmeier (daniel@benzedrine.cx) wrote: > > which matches ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 08:33 AM
Pierre-Yves Ritschard
 
Posts: n/a
Default Re: [patch] pfctl: allow multiple tags in "tagged" statement

Of course actually including the diff is a better idea...

* Daniel Hartmeier (daniel@benzedrine.cx) wrote:
>
> which matches every packet. So you might want to add
>
> | not matchtag {
> filter_opts.match_tags = $2;
> filter_opts.match_tag_not = $1;
> if ($1 && $2->tail != $2) {
> yyerror("tag list negation matches all");
> YYERROR;
> }
> }
>
> or at least explain it in the man page


Hi, sorry for the delay, I broke my arm.
Good point regarding negation, I fixed it and also modified the man page
anyway to reflect the code change.

If it is deemed necessary similar changes can be done for nat-rules and
rdr-rules.
Index: sbin/pfctl/parse.y
================================================== =================
RCS file: /space/release/cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.496
diff -u -r1.496 parse.y
--- sbin/pfctl/parse.y 6 Apr 2006 21:54:56 -0000 1.496
+++ sbin/pfctl/parse.y 18 Apr 2006 13:39:05 -0000
@@ -117,6 +117,12 @@
struct node_icmp *tail;
};

+struct node_matchtag {
+ char tagname[PF_TAG_NAME_SIZE];
+ struct node_matchtag *next;
+ struct node_matchtag *tail;
+};
+
enum { PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
@@ -197,7 +203,7 @@
char *label;
struct node_qassign queues;
char *tag;
- char *match_tag;
+ struct node_matchtag *match_tags;
u_int8_t match_tag_not;
} filter_opts;

@@ -276,7 +282,7 @@
struct node_proto *, struct node_os*, struct node_host *,
struct node_port *, struct node_host *, struct node_port *,
struct node_uid *, struct node_gid *, struct node_icmp *,
- const char *);
+ struct node_matchtag *, const char *);
int expand_altq(struct pf_altq *, struct node_if *, struct node_queue *,
struct node_queue_bw bwspec, struct node_queue_opt *);
int expand_queue(struct pf_altq *, struct node_if *, struct node_queue *,
@@ -386,6 +392,7 @@
struct table_opts table_opts;
struct pool_opts pool_opts;
struct node_hfsc_opts hfsc_opts;
+ struct node_matchtag *matchtag_opts;
} v;
int lineno;
} YYSTYPE;
@@ -456,6 +463,7 @@
%type <v.scrub_opts> scrub_opts scrub_opt scrub_opts_l
%type <v.table_opts> table_opts table_opt table_opts_l
%type <v.pool_opts> pool_opts pool_opt pool_opts_l
+%type <v.matchtag_opts> matchtag matchtag_list matchtag_item
%type <v.tagged> tagged
%%

@@ -616,13 +624,6 @@
r.af = $5;
r.prob = $8.prob;

- if ($8.match_tag)
- if (strlcpy(r.match_tagname, $8.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
r.match_tag_not = $8.match_tag_not;

decide_address_family($7.src.host, &r.af);
@@ -630,7 +631,7 @@

expand_rule(&r, $4, NULL, $6, $7.src_os,
$7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
- 0, 0, 0, $2);
+ 0, 0, 0, $8.match_tags, $2);
free($2);
}
| NATANCHOR string interface af proto fromto {
@@ -650,7 +651,7 @@

expand_rule(&r, $3, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
- 0, 0, 0, $2);
+ 0, 0, 0, 0, $2);
free($2);
}
| RDRANCHOR string interface af proto fromto {
@@ -691,7 +692,7 @@

expand_rule(&r, $3, NULL, $5, $6.src_os,
$6.src.host, $6.src.port, $6.dst.host, $6.dst.port,
- 0, 0, 0, $2);
+ 0, 0, 0, 0, $2);
free($2);
}
| BINATANCHOR string interface af proto fromto {
@@ -803,7 +804,7 @@

expand_rule(&r, $4, NULL, $6, $7.src_os,
$7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
- NULL, NULL, NULL, "");
+ NULL, NULL, NULL, NULL, "");
}
;

@@ -945,7 +946,7 @@
if (h != NULL)
expand_rule(&r, j, NULL, NULL, NULL, h,
NULL, NULL, NULL, NULL, NULL,
- NULL, "");
+ NULL, NULL, "");

if ((i->ifa_flags & IFF_LOOPBACK) == 0) {
bzero(&r, sizeof(r));
@@ -964,7 +965,7 @@
if (h != NULL)
expand_rule(&r, NULL, NULL,
NULL, NULL, h, NULL, NULL,
- NULL, NULL, NULL, NULL, "");
+ NULL, NULL, NULL, NULL, NULL, "");
} else
free(hh);
}
@@ -1536,13 +1537,6 @@
PF_TAG_NAME_SIZE - 1);
YYERROR;
}
- if ($9.match_tag)
- if (strlcpy(r.match_tagname, $9.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
r.match_tag_not = $9.match_tag_not;
if (rule_label(&r, $9.label))
YYERROR;
@@ -1833,7 +1827,7 @@

expand_rule(&r, $4, $5.host, $7, $8.src_os,
$8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
- $9.uid, $9.gid, $9.icmpspec, "");
+ $9.uid, $9.gid, $9.icmpspec, $9.match_tags, "");
}
;

@@ -1919,9 +1913,13 @@
| TAG string {
filter_opts.tag = $2;
}
- | not TAGGED string {
- filter_opts.match_tag = $3;
+ | not matchtag {
+ filter_opts.match_tags = $2;
filter_opts.match_tag_not = $1;
+ if ($1 && ($2 != $2->tail)) {
+ yyerror("cannot negate tag list");
+ YYERROR;
+ }
}
| PROBABILITY STRING {
char *e;
@@ -1947,6 +1945,38 @@
}
;

+matchtag : TAGGED matchtag_item {
+ $$ = $2;
+ }
+ | TAGGED '{' matchtag_list '}' {
+ $$ = $3;
+ }
+ ;
+
+matchtag_list : matchtag_item { $$ = $1; }
+ | matchtag_list comma matchtag_item {
+ $1->tail->next = $3;
+ $1->tail = $3;
+ $$ = $1;
+ }
+ ;
+
+matchtag_item : STRING {
+ $$ = calloc(1, sizeof (struct node_matchtag));
+ if ($$ == NULL)
+ err(1, "matchtag_item: calloc");
+ if ((strlcpy($$->tagname,$1,PF_TAG_NAME_SIZE)) >=
+ PF_TAG_NAME_SIZE) {
+ yyerror("tag too long, max %u chars",
+ PF_TAG_NAME_SIZE - 1);
+ YYERROR;
+ }
+ free($1);
+ $$->next = NULL;
+ $$->tail = $$;
+ }
+ ;
+
action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
| BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; }
;
@@ -3385,7 +3415,7 @@

expand_rule(&r, $2, $8 == NULL ? NULL : $8->host, $4,
$5.src_os, $5.src.host, $5.src.port, $5.dst.host,
- $5.dst.port, 0, 0, 0, "");
+ $5.dst.port, 0, 0, 0, 0, "");
free($8);
}
;
@@ -4362,14 +4392,13 @@
struct node_host *src_hosts, struct node_port *src_ports,
struct node_host *dst_hosts, struct node_port *dst_ports,
struct node_uid *uids, struct node_gid *gids, struct node_icmp *icmp_types,
- const char *anchor_call)
+ struct node_matchtag *match_tags, const char *anchor_call)
{
sa_family_t af = r->af;
int added = 0, error = 0;
char ifname[IF_NAMESIZE];
char label[PF_RULE_LABEL_SIZE];
char tagname[PF_TAG_NAME_SIZE];
- char match_tagname[PF_TAG_NAME_SIZE];
struct pf_pooladdr *pa;
struct node_host *h;
u_int8_t flags, flagset, keep_state;
@@ -4378,9 +4407,6 @@
errx(1, "expand_rule: strlcpy");
if (strlcpy(tagname, r->tagname, sizeof(tagname)) >= sizeof(tagname))
errx(1, "expand_rule: strlcpy");
- if (strlcpy(match_tagname, r->match_tagname, sizeof(match_tagname)) >=
- sizeof(match_tagname))
- errx(1, "expand_rule: strlcpy");
flags = r->flags;
flagset = r->flagset;
keep_state = r->keep_state;
@@ -4395,6 +4421,7 @@
LOOP_THROUGH(struct node_port, dst_port, dst_ports,
LOOP_THROUGH(struct node_uid, uid, uids,
LOOP_THROUGH(struct node_gid, gid, gids,
+ LOOP_THROUGH(struct node_matchtag, match_tag, match_tags,

r->af = af;
/* for link-local IPv6 address, interface must match up */
@@ -4430,7 +4457,9 @@
if (strlcpy(r->tagname, tagname, sizeof(r->tagname)) >=
sizeof(r->tagname))
errx(1, "expand_rule: strlcpy");
- if (strlcpy(r->match_tagname, match_tagname,
+ if (!match_tag->tagname)
+ errx(1, "expand_rule: no tagname");
+ if (strlcpy(r->match_tagname, match_tag->tagname,
sizeof(r->match_tagname)) >= sizeof(r->match_tagname))
errx(1, "expand_rule: strlcpy");
expand_label(r->label, PF_RULE_LABEL_SIZE, r->ifname, r->af,
@@ -4519,7 +4548,7 @@
added++;
}

- ))))))))));
+ )))))))))));

FREE_LIST(struct node_if, interfaces);
FREE_LIST(struct node_proto, protos);
@@ -4532,6 +4561,7 @@
FREE_LIST(struct node_gid, gids);
FREE_LIST(struct node_icmp, icmp_types);
FREE_LIST(struct node_host, rpool_hosts);
+ FREE_LIST(struct node_matchtag, match_tags);

if (!added)
yyerror("rule expands to no valid combination");
Index: share/man/man5/pf.conf.5
================================================== =================
RCS file: /space/release/cvs/src/share/man/man5/pf.conf.5,v
retrieving revision 1.342
diff -u -r1.342 pf.conf.5
--- share/man/man5/pf.conf.5 14 Mar 2006 11:09:44 -0000 1.342
+++ share/man/man5/pf.conf.5 27 Apr 2006 12:24:36 -0000
@@ -1584,15 +1584,16 @@
.Ar binat
rules in addition to filter rules.
Tags take the same macros as labels (see above).
-.It Ar tagged <string>
+.It Ar tagged <string> | { <string>, <string> }
Used with filter or translation rules to specify that packets must already
-be tagged with the given tag in order to match the rule.
-Inverse tag matching can also be done
+be tagged with any of the given tags in order to match the rule.
+If only one tag is given, inverse tag matching can also be done
by specifying the
.Cm !\&
operator before the
.Ar tagged
-keyword.
+keyword. A list of tags cannot be negated as it would expand to a useless
+rule.
.It Ar probability <number>
A probability attribute can be attached to a rule, with a value set between
0 and 1, bounds not included.
@@ -2654,6 +2655,7 @@
"max-mss" number | "random-id" | "reassemble tcp" |
fragmentation | "allow-opts" |
"label" string | "tag" string | [ ! ] "tagged" string |
+ "tagged" "{" string [ [ "," ] string ] "}" |
"queue" ( string | "(" string [ [ "," ] string ] ")" ) |
"probability" number"%"

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 02:39 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com