Loading net/sched/sch_dsmark.c +88 −86 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ #endif #define PRIV(sch) qdisc_priv(sch) #define PRIV(sch) ((struct dsmark_qdisc_data *) qdisc_priv(sch)) /* Loading @@ -55,10 +55,10 @@ struct dsmark_qdisc_data { struct Qdisc *q; struct tcf_proto *filter_list; __u8 *mask; /* "owns" the array */ __u8 *value; __u16 indices; __u32 default_index; /* index range is 0...0xffff */ u8 *mask; /* "owns" the array */ u8 *value; u16 indices; u32 default_index; /* index range is 0...0xffff */ int set_tc_index; }; Loading @@ -80,14 +80,13 @@ static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index) /* ------------------------- Class/flow operations ------------------------- */ static int dsmark_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { struct dsmark_qdisc_data *p = PRIV(sch); DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, old); DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n", sch, p, new, old); if (new == NULL) { new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); Loading @@ -97,43 +96,36 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg, sch_tree_lock(sch); *old = xchg(&p->q, new); if (*old) qdisc_reset(*old); sch->q.qlen = 0; sch_tree_unlock(sch); /* @@@ move up ? */ sch_tree_unlock(sch); return 0; } static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg) { struct dsmark_qdisc_data *p = PRIV(sch); return p->q; return PRIV(sch)->q; } static unsigned long dsmark_get(struct Qdisc *sch, u32 classid) { struct dsmark_qdisc_data *p __attribute__((unused)) = PRIV(sch); DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n", sch, PRIV(sch), classid); DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",sch,p,classid); return TC_H_MIN(classid) + 1; } static unsigned long dsmark_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { return dsmark_get(sch, classid); } static void dsmark_put(struct Qdisc *sch, unsigned long cl) { } static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, struct rtattr **tca, unsigned long *arg) { Loading Loading @@ -173,22 +165,25 @@ static int dsmark_delete(struct Qdisc *sch,unsigned long arg) { struct dsmark_qdisc_data *p = PRIV(sch); if (!arg || arg > p->indices) if (!dsmark_valid_index(p, arg)) return -EINVAL; p->mask[arg-1] = 0xff; p->value[arg-1] = 0; return 0; } static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) { struct dsmark_qdisc_data *p = PRIV(sch); int i; DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker); if (walker->stop) return; for (i = 0; i < p->indices; i++) { if (p->mask[i] == 0xff && !p->value[i]) goto ignore; Loading @@ -203,26 +198,20 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) } } static struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl) { struct dsmark_qdisc_data *p = PRIV(sch); return &p->filter_list; return &PRIV(sch)->filter_list; } /* --------------------------- Qdisc operations ---------------------------- */ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct tcf_result res; int result; int ret = NET_XMIT_POLICED; int err; D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); if (p->set_tc_index) { /* FIXME: Safe with non-linear skbs? --RR */ switch (skb->protocol) { Loading @@ -239,17 +228,21 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) break; }; } result = TC_POLICE_OK; /* be nice to gcc */ if (TC_H_MAJ(skb->priority) == sch->handle) { if (TC_H_MAJ(skb->priority) == sch->handle) skb->tc_index = TC_H_MIN(skb->priority); } else { result = tc_classify(skb,p->filter_list,&res); else { struct tcf_result res; int result = tc_classify(skb, p->filter_list, &res); D2PRINTK("result %d class 0x%04x\n", result, res.classid); switch (result) { #ifdef CONFIG_NET_CLS_POLICE case TC_POLICE_SHOT: kfree_skb(skb); break; sch->qstats.drops++; return NET_XMIT_POLICED; #if 0 case TC_POLICE_RECLASSIFY: /* FIXME: what to do here ??? */ Loading @@ -266,43 +259,45 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) break; }; } if ( #ifdef CONFIG_NET_CLS_POLICE result == TC_POLICE_SHOT || #endif ((ret = p->q->enqueue(skb,p->q)) != 0)) { err = p->q->enqueue(skb,p->q); if (err != NET_XMIT_SUCCESS) { sch->qstats.drops++; return ret; return err; } sch->bstats.bytes += skb->len; sch->bstats.packets++; sch->q.qlen++; return ret; } return NET_XMIT_SUCCESS; } static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct sk_buff *skb; int index; u32 index; D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p); skb = p->q->ops->dequeue(p->q); if (!skb) if (skb == NULL) return NULL; sch->q.qlen--; index = skb->tc_index & (p->indices - 1); D2PRINTK("index %d->%d\n", skb->tc_index, index); switch (skb->protocol) { case __constant_htons(ETH_P_IP): ipv4_change_dsfield(skb->nh.iph, p->mask[index],p->value[index]); ipv4_change_dsfield(skb->nh.iph, p->mask[index], p->value[index]); break; case __constant_htons(ETH_P_IPV6): ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index],p->value[index]); ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index], p->value[index]); break; default: /* Loading @@ -316,25 +311,28 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) htons(skb->protocol)); break; }; return skb; } static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch) { int ret; struct dsmark_qdisc_data *p = PRIV(sch); int err; D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); if ((ret = p->q->ops->requeue(skb, p->q)) == 0) { sch->q.qlen++; sch->qstats.requeues++; return 0; } err = p->q->ops->requeue(skb, p->q); if (err != NET_XMIT_SUCCESS) { sch->qstats.drops++; return ret; return err; } sch->q.qlen++; sch->qstats.requeues++; return NET_XMIT_SUCCESS; } static unsigned int dsmark_drop(struct Qdisc *sch) { Loading @@ -342,15 +340,17 @@ static unsigned int dsmark_drop(struct Qdisc *sch) unsigned int len; DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p); if (!p->q->ops->drop) return 0; if (!(len = p->q->ops->drop(p->q))) if (p->q->ops->drop == NULL) return 0; len = p->q->ops->drop(p->q); if (len) sch->q.qlen--; return len; } static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) { struct dsmark_qdisc_data *p = PRIV(sch); Loading Loading @@ -400,7 +400,6 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) return err; } static void dsmark_reset(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); Loading @@ -410,23 +409,23 @@ static void dsmark_reset(struct Qdisc *sch) sch->q.qlen = 0; } static void dsmark_destroy(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct tcf_proto *tp; DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); while (p->filter_list) { tp = p->filter_list; p->filter_list = tp->next; tcf_destroy(tp); } qdisc_destroy(p->q); kfree(p->mask); } static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { Loading Loading @@ -505,10 +504,13 @@ static int __init dsmark_module_init(void) { return register_qdisc(&dsmark_qdisc_ops); } static void __exit dsmark_module_exit(void) { unregister_qdisc(&dsmark_qdisc_ops); } module_init(dsmark_module_init) module_exit(dsmark_module_exit) MODULE_LICENSE("GPL"); Loading
net/sched/sch_dsmark.c +88 −86 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ #endif #define PRIV(sch) qdisc_priv(sch) #define PRIV(sch) ((struct dsmark_qdisc_data *) qdisc_priv(sch)) /* Loading @@ -55,10 +55,10 @@ struct dsmark_qdisc_data { struct Qdisc *q; struct tcf_proto *filter_list; __u8 *mask; /* "owns" the array */ __u8 *value; __u16 indices; __u32 default_index; /* index range is 0...0xffff */ u8 *mask; /* "owns" the array */ u8 *value; u16 indices; u32 default_index; /* index range is 0...0xffff */ int set_tc_index; }; Loading @@ -80,14 +80,13 @@ static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index) /* ------------------------- Class/flow operations ------------------------- */ static int dsmark_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { struct dsmark_qdisc_data *p = PRIV(sch); DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, old); DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n", sch, p, new, old); if (new == NULL) { new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); Loading @@ -97,43 +96,36 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg, sch_tree_lock(sch); *old = xchg(&p->q, new); if (*old) qdisc_reset(*old); sch->q.qlen = 0; sch_tree_unlock(sch); /* @@@ move up ? */ sch_tree_unlock(sch); return 0; } static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg) { struct dsmark_qdisc_data *p = PRIV(sch); return p->q; return PRIV(sch)->q; } static unsigned long dsmark_get(struct Qdisc *sch, u32 classid) { struct dsmark_qdisc_data *p __attribute__((unused)) = PRIV(sch); DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n", sch, PRIV(sch), classid); DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",sch,p,classid); return TC_H_MIN(classid) + 1; } static unsigned long dsmark_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { return dsmark_get(sch, classid); } static void dsmark_put(struct Qdisc *sch, unsigned long cl) { } static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, struct rtattr **tca, unsigned long *arg) { Loading Loading @@ -173,22 +165,25 @@ static int dsmark_delete(struct Qdisc *sch,unsigned long arg) { struct dsmark_qdisc_data *p = PRIV(sch); if (!arg || arg > p->indices) if (!dsmark_valid_index(p, arg)) return -EINVAL; p->mask[arg-1] = 0xff; p->value[arg-1] = 0; return 0; } static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) { struct dsmark_qdisc_data *p = PRIV(sch); int i; DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker); if (walker->stop) return; for (i = 0; i < p->indices; i++) { if (p->mask[i] == 0xff && !p->value[i]) goto ignore; Loading @@ -203,26 +198,20 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) } } static struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl) { struct dsmark_qdisc_data *p = PRIV(sch); return &p->filter_list; return &PRIV(sch)->filter_list; } /* --------------------------- Qdisc operations ---------------------------- */ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct tcf_result res; int result; int ret = NET_XMIT_POLICED; int err; D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); if (p->set_tc_index) { /* FIXME: Safe with non-linear skbs? --RR */ switch (skb->protocol) { Loading @@ -239,17 +228,21 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) break; }; } result = TC_POLICE_OK; /* be nice to gcc */ if (TC_H_MAJ(skb->priority) == sch->handle) { if (TC_H_MAJ(skb->priority) == sch->handle) skb->tc_index = TC_H_MIN(skb->priority); } else { result = tc_classify(skb,p->filter_list,&res); else { struct tcf_result res; int result = tc_classify(skb, p->filter_list, &res); D2PRINTK("result %d class 0x%04x\n", result, res.classid); switch (result) { #ifdef CONFIG_NET_CLS_POLICE case TC_POLICE_SHOT: kfree_skb(skb); break; sch->qstats.drops++; return NET_XMIT_POLICED; #if 0 case TC_POLICE_RECLASSIFY: /* FIXME: what to do here ??? */ Loading @@ -266,43 +259,45 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) break; }; } if ( #ifdef CONFIG_NET_CLS_POLICE result == TC_POLICE_SHOT || #endif ((ret = p->q->enqueue(skb,p->q)) != 0)) { err = p->q->enqueue(skb,p->q); if (err != NET_XMIT_SUCCESS) { sch->qstats.drops++; return ret; return err; } sch->bstats.bytes += skb->len; sch->bstats.packets++; sch->q.qlen++; return ret; } return NET_XMIT_SUCCESS; } static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct sk_buff *skb; int index; u32 index; D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p); skb = p->q->ops->dequeue(p->q); if (!skb) if (skb == NULL) return NULL; sch->q.qlen--; index = skb->tc_index & (p->indices - 1); D2PRINTK("index %d->%d\n", skb->tc_index, index); switch (skb->protocol) { case __constant_htons(ETH_P_IP): ipv4_change_dsfield(skb->nh.iph, p->mask[index],p->value[index]); ipv4_change_dsfield(skb->nh.iph, p->mask[index], p->value[index]); break; case __constant_htons(ETH_P_IPV6): ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index],p->value[index]); ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index], p->value[index]); break; default: /* Loading @@ -316,25 +311,28 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) htons(skb->protocol)); break; }; return skb; } static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch) { int ret; struct dsmark_qdisc_data *p = PRIV(sch); int err; D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); if ((ret = p->q->ops->requeue(skb, p->q)) == 0) { sch->q.qlen++; sch->qstats.requeues++; return 0; } err = p->q->ops->requeue(skb, p->q); if (err != NET_XMIT_SUCCESS) { sch->qstats.drops++; return ret; return err; } sch->q.qlen++; sch->qstats.requeues++; return NET_XMIT_SUCCESS; } static unsigned int dsmark_drop(struct Qdisc *sch) { Loading @@ -342,15 +340,17 @@ static unsigned int dsmark_drop(struct Qdisc *sch) unsigned int len; DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p); if (!p->q->ops->drop) return 0; if (!(len = p->q->ops->drop(p->q))) if (p->q->ops->drop == NULL) return 0; len = p->q->ops->drop(p->q); if (len) sch->q.qlen--; return len; } static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) { struct dsmark_qdisc_data *p = PRIV(sch); Loading Loading @@ -400,7 +400,6 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) return err; } static void dsmark_reset(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); Loading @@ -410,23 +409,23 @@ static void dsmark_reset(struct Qdisc *sch) sch->q.qlen = 0; } static void dsmark_destroy(struct Qdisc *sch) { struct dsmark_qdisc_data *p = PRIV(sch); struct tcf_proto *tp; DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); while (p->filter_list) { tp = p->filter_list; p->filter_list = tp->next; tcf_destroy(tp); } qdisc_destroy(p->q); kfree(p->mask); } static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { Loading Loading @@ -505,10 +504,13 @@ static int __init dsmark_module_init(void) { return register_qdisc(&dsmark_qdisc_ops); } static void __exit dsmark_module_exit(void) { unregister_qdisc(&dsmark_qdisc_ops); } module_init(dsmark_module_init) module_exit(dsmark_module_exit) MODULE_LICENSE("GPL");