The patch is extending the rules, so i dont see how it could behave differently
The original set of percentage is still strange so you have a point. Unless they expect this behavior (they still end with the good 100% rules) isn't it possible to round robin this ? with relayd or something else ? On Tue, Sep 17, 2013 at 3:42 PM, Dave Anderson <d...@daveanderson.com>wrote: > On Tue, 17 Sep 2013, Ivan Popovski wrote: > > >Hi > > > >I've been asked, by net admin, to implement pf.conf simplification for > >divert-to rule. Reason is that divert-to is written to support only one > >port per line and because of that there are situations where admins > >must write lot of lines only because different ports. After looking at > >pfctl/parse.y I've found that patch (for 5.3) would be trivial and > >wouldn't break anything, ie. works for one port and port range at the > >same time. > > > >Please let me know if there is interest for this and ofc if something > >needs to be fixed. > > > >Here is an example. > > > >Now: > > > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42240 modulate state probability 20% > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42241 modulate state probability 20% > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42242 modulate state probability 20% > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42243 modulate state probability 20% > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42244 modulate state > > This appears to be intended to divide connections equally among five > ports, but (given that the probability applies only to the packets which > actually reach the rule) doesn't it actually divide them as 20%, 16%, > 12.8%, 10.24%, 40.96%? To get an (approximately) equal distribution I > think you'd need to use probabilities 20%, 25%, 33%, 50%. > > If using a port range were to implicitly divide connections equally > among those ports, this problem would go away. But that's not what your > patch does. > > Dave > > >After patching: > > > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42240:42243 modulate state probability 20% > >pass in quick inet proto tcp from 192.168.1.0/24 to any port 21 > divert-to 127.0.0.1 port 42244 modulate state > > > >Patch: > > > >Index: parse.y > >=================================================================== > >RCS file: /cvs/src/sbin/pfctl/parse.y,v > >retrieving revision 1.621 > >diff -u -r1.621 parse.y > >--- parse.y 16 Jan 2013 01:49:20 -0000 1.621 > >+++ parse.y 17 Sep 2013 15:45:20 -0000 > >@@ -261,7 +261,7 @@ > > u_int8_t set_prio[2]; > > struct { > > struct node_host *addr; > >- u_int16_t port; > >+ u_int16_t port, port_top; > > } divert, divert_packet; > > struct redirspec nat; > > struct redirspec rdr; > >@@ -475,7 +475,7 @@ > > %type <v.i> sourcetrack flush unaryop statelock > > %type <v.b> action > > %type <v.b> flags flag blockspec prio > >-%type <v.range> portplain portstar portrange > >+%type <v.range> portstar portrange > > %type <v.hashkey> hashkey > > %type <v.proto> proto proto_list proto_item > > %type <v.number> protoval > >@@ -2078,6 +2078,28 @@ > > r.divert.addr = > > $8.divert.addr->addr.v.a.addr; > > } > >+ if ($8.divert.port_top && > >+ $8.divert.port_top < r.divert.port) { > >+ yyerror("invalid divert port > range: " > >+ "%u:%u", ntohs(r.divert.port), > >+ ntohs($8.divert.port_top)); > >+ YYERROR; > >+ } > >+ > >+#define NHS_LT(x, y) (ntohs(x) < ntohs(y)) > >+#define NHS_INC(x) x = htons(ntohs(x) + 1) > >+ while(NHS_LT(r.divert.port, > >+ $8.divert.port_top)) { > >+ expand_rule(&r, 1, $4, &$8.nat, > &$8.rdr, > >+ &$8.rroute, $6, $7.src_os, > >+ $7.src.host, $7.src.port, > >+ $7.dst.host, $7.dst.port, > >+ $8.uid, $8.gid, $8.rcv, > >+ $8.icmpspec, ""); > >+ NHS_INC(r.divert.port); > >+ } > >+#undef NHS_INC > >+#undef NHS_LT > > } > > r.divert_packet.port = $8.divert_packet.port; > > > >@@ -2197,7 +2219,7 @@ > > } > > filter_opts.rtableid = $2; > > } > >- | DIVERTTO STRING PORT portplain { > >+ | DIVERTTO STRING PORT portrange { > > if ((filter_opts.divert.addr = host($2)) == NULL) { > > yyerror("could not parse divert address: > %s", > > $2); > >@@ -2210,6 +2232,7 @@ > > yyerror("invalid divert port: %u", > ntohs($4.a)); > > YYERROR; > > } > >+ filter_opts.divert.port_top = $4.b; > > } > > | DIVERTREPLY { > > filter_opts.divert.port = 1; /* some random > value */ > >@@ -3073,15 +3096,6 @@ > > $$->op = $2; > > $$->next = NULL; > > $$->tail = $$; > >- } > >- ; > >- > >-portplain : numberstring { > >- if (parseport($1, &$$, 0) == -1) { > >- free($1); > >- YYERROR; > >- } > >- free($1); > > } > > ; > > > > > > > > -- > Dave Anderson > <d...@daveanderson.com> > > > -- --------------------------------------------------------------------------------------------------------------------- () ascii ribbon campaign - against html e-mail /\