Hi! Some time ago I faced a problem in limiting traffic on host with multiple uplinks. Since all the stuff worked nice seemed that there will be no problems. But then I realized that P2P users are smart enough to bypass limits as sfq doesn't give fair sharing in this case (thousands of connections from one user versus few from the other). I tried IMQ but it's instability in my configuration was painfull. So I made something like that: 1. i use IPMARK patch for the iptables to mark all the connections in P2P related class depending on source IP (i use SNAT), 2. modified ESFQ to create hash depending on FWMARK instead of src ip 3. and it worked. So I have uplink policy based on source ip in snat-ed environment without using IMQ. I'm looking for the opinions, cause I may be wrong in this. Patch for the files below, cause it's short diff -urN ./orig/pkt_sched.h ./patched/pkt_sched.h --- ./orig/pkt_sched.h 2004-02-26 09:27:54.000000000 +0100 +++ ./patched/pkt_sched.h 2004-01-07 21:23:58.000000000 +0100 @@ -162,6 +162,7 @@ TCA_SFQ_HASH_CLASSIC, TCA_SFQ_HASH_DST, TCA_SFQ_HASH_SRC, + TCA_SFQ_HASH_FWMARK, }; diff -urN ./orig/q_esfq.c ./patched/q_esfq.c --- ./orig/q_esfq.c 2004-02-26 09:28:10.000000000 +0100 +++ ./patched/q_esfq.c 2004-01-07 22:08:04.000000000 +0100 @@ -30,7 +30,7 @@ { fprintf(stderr, "Usage: ... esfq [ perturb SECS ] [ quantum BYTES ] [ depth FLOWS ]\n\t[ divisor HASHBITS ] [ limit PKTS ] [ hash HASHTYPE]\n"); fprintf(stderr,"Where: \n"); - fprintf(stderr,"HASHTYPE := { classic | src | dst }\n"); + fprintf(stderr,"HASHTYPE := { classic | src | dst | fwmark }\n"); } #define usage() return(-1) @@ -95,6 +95,9 @@ } else if(strcmp(*argv,"src") == 0) { opt.hash_kind= TCA_SFQ_HASH_SRC; + } else + if(strcmp(*argv,"fwmark") == 0) { + opt.hash_kind= TCA_SFQ_HASH_FWMARK; } else { fprintf(stderr, "Illegal \"hash\"\n"); explain(); @@ -148,6 +151,9 @@ case TCA_SFQ_HASH_SRC: fprintf(f,"src"); break; + case TCA_SFQ_HASH_FWMARK: + fprintf(f,"fw"); + break; default: fprintf(f,"Unknown"); } diff -urN ./orig/sch_esfq.c ./patched/sch_esfq.c --- ./orig/sch_esfq.c 2004-02-26 09:27:54.000000000 +0100 +++ ./patched/sch_esfq.c 2004-01-07 21:39:24.000000000 +0100 @@ -117,6 +117,7 @@ { u32 h, h2; u32 hs; + u32 nfm; switch (skb->protocol) { case __constant_htons(ETH_P_IP): @@ -124,6 +125,7 @@ struct iphdr *iph = skb->nh.iph; h = iph->daddr; hs = iph->saddr; + nfm = skb -> nfmark; h2 = hs^iph->protocol; if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && (iph->protocol == IPPROTO_TCP || @@ -137,6 +139,7 @@ struct ipv6hdr *iph = skb->nh.ipv6h; h = iph->daddr.s6_addr32[3]; hs = iph->saddr.s6_addr32[3]; + nfm = skb->nfmark; h2 = hs^iph->nexthdr; if (iph->nexthdr == IPPROTO_TCP || iph->nexthdr == IPPROTO_UDP || @@ -148,6 +151,7 @@ h = (u32)(unsigned long)skb->dst; hs = (u32)(unsigned long)skb->sk; h2 = hs^skb->protocol; + nfm = skb->nfmark; } switch(q->hash_kind) { @@ -157,6 +161,8 @@ return esfq_hash_u32(q,h); case TCA_SFQ_HASH_SRC: return esfq_hash_u32(q,hs); + case TCA_SFQ_HASH_FWMARK: + return esfq_hash_u32(q,nfm); default: if (net_ratelimit()) printk(KERN_DEBUG "esfq unknown hash method, fallback to classic\n"); -- Greetings, Robert mailto:rkurjata@xxxxxxxxxxxxx _______________________________________________ LARTC mailing list / LARTC@xxxxxxxxxxxxxxx http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/