[LARTC] Qdisc stops responding
Naturally I forgot to attach the code, as I was rushing to get to lunch. R.harper p.s why do my messages end up as a reply to someone else's message in the archive? _ Log på MSN Messenger direkte fra nettet http://webmessenger.msn.com/ /* Flow based Qdisc scheduler */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LATENCY 10 #define LIMIT 50 #define HASH_SIZE 20 #define FLOW_LIFETIME (10*HZ) /* Protects conntrack->proto.tcp*/ //static DECLARE_RWLOCK(tcp_lock); struct flow_sched_data { u32 latency; u32 limit; u32 qlen; struct sk_buff_head qs[HASH_SIZE]; u32 is_used[HASH_SIZE]; psched_time_t last_pkt_sent[HASH_SIZE]; psched_time_t next_send_time[HASH_SIZE]; psched_time_t interval[HASH_SIZE]; struct timer_list remove_timer[HASH_SIZE]; struct timer_list timer; struct sk_buff_head fasttrack; }; static __inline__ u32 get_hash(struct sk_buff *skb) { if (skb->protocol == __constant_htons(ETH_P_IP) ){ struct iphdr *iph = skb->nh.iph; if (iph->protocol == 6){ struct tcphdr *tcph = (void *)iph + (iph->ihl*4); return jhash_3words(iph->saddr^iph->protocol, iph->daddr, (tcph->dest << 16 | tcph->source), 0x543298ff); } else{ return jhash_3words(iph->saddr, iph->daddr, iph->protocol, 0x543298ff); } } return 0; } static __inline__ short flow_hash(struct sk_buff *skb, struct Qdisc *sch) { int i = 0; u32 hash; short index; struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; struct flow_sched_data *q = qdisc_priv(sch); ct = ip_conntrack_get(skb, &ctinfo); //if (ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED) hash = get_hash(skb); index = hash % HASH_SIZE; if (q->is_used[index] == hash){ //printk("Correct flow found, hash: %u, index: %i \n", hash, index); //Found correct flow return index; } else if (q->is_used[index] == 0){ psched_time_t next_send; PSCHED_GET_TIME(next_send); //bucket unused, lets use this one printk("New flow, hash: %u, index: %i \n", hash, index); q->is_used[index] = hash; //seting the dequeue time! //READ_LOCK(&tcp_lock); //q->next_send_time[index] = PSCHED_TADD(next_send, PSCHED_JIFFIE2US(ct->proto.tcp.rate)); //READ_UNLOCK(&tcp_lock); q->next_send_time[index] = PSCHED_TADD(next_send, q->interval[index]); return index; } else{ //Must search the whole table to see if this is an //established connection, for(i = 0; i < HASH_SIZE; i++){ if (q->is_used[(index+i)%HASH_SIZE] == hash){ //found the right slot in the table; return (index+i)%HASH_SIZE; } } //Ok didn't find an established connection //This *must* be a new connection for(i = 0; i < HASH_SIZE; i++){ if (q->is_used[(index+i)%HASH_SIZE] == 0){ psched_time_t next_send; PSCHED_GET_TIME(next_send); //found unused slot in the hash table. q->is_used[(index+i)%HASH_SIZE] = hash; //READ_LOCK(&tcp_lock); //q->next_send_time[(index+i)%HASH_SIZE] = PSCHED_TADD(next_send, PSCHED_JIFFIE2US(ct->proto.tcp.rate)); //READ_UNLOCK(&tcp_lock); q->next_send_time[(index+i)%HASH_SIZE] = PSCHED_TADD(next_send, q->interval[(index+i)%HASH_SIZE]); return (index+i)%HASH_SIZE; } } //Nothing found, strange! //Must be an error printk(KERN_WARNING "No hash bucket found!\n"); return -1; } } static __inline__ int flow_is_valid(struct sk_buff *skb){ struct iphdr *iph = skb->nh.iph; enum ip_conntrack_info ctinfo; struct tcphdr *tcph = (void *)iph + (iph->ihl*4); if (skb->protocol != __constant_htons(ETH_P_IP) ) return 0; if (iph->protocol != IPPROTO_TCP) return 0; ip_conntrack_get(skb, &ctinfo); if (!tcph->ack) return 0; if (ctinfo != IP_CT_ESTABLISHED) return 0; return 1; } static int flow_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct flow_sched_data *q = qdisc_priv(sch); short hash; if (flow_is_valid(skb) == 1) hash = flow_hash(skb, sch); else hash = 0; if (!skb->nfmark) goto drop; if (q->qlen && sch->q.qlen >= q->qlen){ printk("Dropping packet, queue full\n"); goto drop; } if (hash == -1) goto drop; //printk("flow_enqueue hash %u skb=%p @%lu\n", hash, skb, jiffies); //printk("qs len pre: %i \n", q->qs[hash].qlen); __skb_queue_tail(&q->qs[hash], skb); //printk("qs len post: %i \n", q->qs[hash].qlen); q->remove_timer[hash].expires = jiffies + FLOW_LIFETIME; add_timer(&q->remove_timer[hash]); if (++sch->q.qlen < q->limit-1){ sch->stats.bytes += skb->len; sch->stats.packets++; return NET_XMIT_SUCCESS; } drop: sch->stats.drops++; kfree_skb(skb); r
[LARTC] Qdisc stops responding
Hello lartc I wrote a scheduling qdisc that works on a per-flow basis. It dequeue packets according to a flow interval. But as it turns out there is a problem with it. The qdisc loads just fine and is working correctly. The problem is that if the qdisc is removed and loaded again, it stops responding. By that I mean it stops to enqueue packets to the underlying Qdisc. "tc -d qdisc show" shows that the packets get backloged in the qdisc and never leave. I was hoping that someone has the time so take a quick look at the *bad* code and see if you can spot an obvious error. I know the code is probably not up to your standards since this is my first qdisc, and my pet hamster did all the coding;) Hoping for response R.harper _ Undgå pop-ups med MSN Toolbar - http://toolbar.msn.dk hent den gratis! ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc
[LARTC] Ingress rate
Hello I'm doing some qdisc programming and I want to get/read the current ingress rate from a kernel module I was wondering what is the most convenient of achieving this My idea is to load the ingress qdisc and the police filter if necessary. and modify the source to export a structure or function so I can read the ingress rate. How does this sound? Is there a simpler way? With regards R.Harper _ Log på MSN Messenger direkte fra nettet http://webmessenger.msn.com/ ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc
[LARTC] recording packet sent time
Hello I am writing a qdisc scheduler (called fb in the diagram) that does certain packet delaying and other stuff. (for egress traffic) root (htb/tbf) | --- cl1 cl2| tbf || cl3cl4 || *fb* fifo Now I need to record the time when packets leaves the system. I can't do it in fb since the packet *may* experience buffering delay in higher level token bucket. I was wondering what are my options for such an implementation? Is it a good option to write a qdisc for this task that will be used as a root qdisc? (every packet does travel through it, right?) Or is there a better location for this code, (or perhaps this is already done somewhere?) (it should be safe to assume that there will be not significat buffering delay in the physical device, since the rate will be much lower then the device an handle) With regards R.Harper _ Få alle de nye og sjove ikoner med MSN Messenger http://messenger.msn.dk/ ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc
Re: [LARTC] Internal Qdisc
TBF provides traffic shaping by the Token Bucket theory, while SFQ makes sure(actually just hints) swap packets in different sessions so that no particular session will hang around for a long time. Yes I know the difference between TBF and SFQ. I was trying to ask about the programming/architectural difference between creating a *internal Qdisc* for buffering (like TBF does) and then using q->qdisc->enqueue(skb, q->qdisc) etc. commands for queueing ... or just use the qdisc "provided"? __skb_enqueue(skb, skq->q) etc commands for queueing But thanks for your reply Regards R.Harper R Harper wrote: > Hell > I'm new to Qdisc programming and I was wondering, what is the difference > between using an internal Qdisc (like e.g. TBF does) vs. not using > internal Qdisc (like e.g. SFQ does)? > > Can someone give me a quick rundown of pro and cons? > > with regards > R.harper > > _ > Undg pop-ups med MSN Toolbar - http://toolbar.msn.dk hent den gratis! > > ___ > LARTC mailing list > LARTC@mailman.ds9a.nl > http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc > _ Få alle de nye og sjove ikoner med MSN Messenger http://messenger.msn.dk/ ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc
[LARTC] Internal Qdisc
Hell I'm new to Qdisc programming and I was wondering, what is the difference between using an internal Qdisc (like e.g. TBF does) vs. not using internal Qdisc (like e.g. SFQ does)? Can someone give me a quick rundown of pro and cons? with regards R.harper _ Undgå pop-ups med MSN Toolbar - http://toolbar.msn.dk hent den gratis! ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc
[LARTC] TCQ_F_THROTTLED question
Hello Can someone explane to me how the TCQ_F_THROTTLED flag and the watchdog function used in tbf and htb works? To be more specific, (reading tbf code) if there are not enough tokens, a watchdog timer will be "started" and the TCQ_F_THROTTLED flag set. But what happens then the time is up? where is the code reentered? What does the flag "really" mean? If someone could take a moment to answer these question it would be great, or point to documentation or disscussion (if one exists) With regards R.harper _ Find det, du søger på MSN Søg http://search.msn.dk ___ LARTC mailing list LARTC@mailman.ds9a.nl http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc