I need some help with my idea about PF. I want to implement idea based
on freebsd's ipfw "mask dst-ip" feature.

Lets assume that we have some altq rules like this:
altq on $if cbq bandwidth 100Mb queue { std, ..., pq }
  queue ...
  queue pq bandwidth ... priority 1 cbq { pq_1, pq_2, pq_3,...}
    queue pq_1 bandwidth 256K
    queue pq_2 bandwidth 256K
    queue pq_3 bandwidth 256K
...
And some filter rule like this:
pass out on $if ... from any to 192.168.0.0/24 ... queue pq

So, assume that we want to assign all packets passed that rule to one
of _subqueues_ of "pq" queue. Not to "pq" itself. That assignment must
be based on packet's destination IP address, so packets to 192.168.0.1
must be assigned to "pq_1" queue, packets to 192.168.0.2 - to "pq_2",
and so on.

I "implement" that idea (my diff is totally wrong, but it only have to
show my idea). I started with imagination that instead of assigning
rule's queue tag to packet I try to find some subqueue of rule's
queue.
(On example above, instead of assigning "pq" queue for packet to
192.168.0.1 I seek for "pq_1" queue.)

Again, my "implementation" is very ugly, it's becouse I'm not very
familiar with PF code yet. Here is the diff:
Index: pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.634.2.1
diff -u pf.c
--- pf.c        11 Apr 2009 23:43:40 -0000      1.634.2.1
+++ pf.c        29 May 2009 17:55:29 -0000
@@ -5287,8 +5287,30 @@
        if (action == PF_PASS && r->qid) {
                if (pqid || (pd.tos & IPTOS_LOWDELAY))
                        m->m_pkthdr.pf.qid = r->pqid;
-               else
-                       m->m_pkthdr.pf.qid = r->qid;
+               else {
+                       /* m->m_pkthdr.pf.qid = r->qid; */
+                       char qname[PF_TAG_NAME_SIZE],
qsubname[PF_TAG_NAME_SIZE];
+                       u_int32_t i_pkt_dstip, i_rule_dstnet, i_diff;
+                       struct pf_tagname *tag;
+                       /* packet's dst IP ==> u_int32_t */
+                       i_pkt_dstip = ntohl(pd.dst->pfa.v4.s_addr);
+                       /* rule's dst (net) IP  ==> u_int32_t */
+                       i_rule_dstnet = ntohl(r->dst.addr.va.addr.s_addr);
+                       i_diff = i_pkt_dstip - i_rule_dstnet;
+                       /* get rule's queue name by queue tag id */
+                       tag2tagname(&pf_tags, r->qid, qname);
+                       /* create sub-queue name on packet's dst IP basis */
+                       if (snprintf(qsubname, sizeof(qsubname),
"%s_%u", qname, i_diff) == -1)
+                               panic("Can't create subqueue name");
+                       /* get tag of that queue */
+                       TAILQ_FOREACH(tag, &pf_tags, entries)
+                               if (strcmp(qsubname, tag->name) == 0) {
+                                       /* assign packet to this sub-queue */
+                                       m->m_pkthdr.pf.qid = tag->tag;
+                                       break;
+                               }
+
+               }
                /* add hints for ecn */
                m->m_pkthdr.pf.hdr = h;
        }

Yes, yes, it's totally wrong implemented, it uses structure members
wrong, it uses "not existing here" variables etc, of cause. Pls, don't
kick me much, I just want to discuss the idea at first.

So, at first, is the idea in general acceptable?
-- 
antonvm

Reply via email to