linux/net/sched/sch_dsmark.c
<<
>>
Prefs
   1/* net/sched/sch_dsmark.c - Differentiated Services field marker */
   2
   3/* Written 1998-2000 by Werner Almesberger, EPFL ICA */
   4
   5
   6#include <linux/module.h>
   7#include <linux/init.h>
   8#include <linux/slab.h>
   9#include <linux/types.h>
  10#include <linux/string.h>
  11#include <linux/errno.h>
  12#include <linux/skbuff.h>
  13#include <linux/rtnetlink.h>
  14#include <linux/bitops.h>
  15#include <net/pkt_sched.h>
  16#include <net/dsfield.h>
  17#include <net/inet_ecn.h>
  18#include <asm/byteorder.h>
  19
  20/*
  21 * classid      class           marking
  22 * -------      -----           -------
  23 *   n/a          0             n/a
  24 *   x:0          1             use entry [0]
  25 *   ...         ...            ...
  26 *   x:y y>0     y+1            use entry [y]
  27 *   ...         ...            ...
  28 * x:indices-1  indices         use entry [indices-1]
  29 *   ...         ...            ...
  30 *   x:y         y+1            use entry [y & (indices-1)]
  31 *   ...         ...            ...
  32 * 0xffff       0x10000         use entry [indices-1]
  33 */
  34
  35
  36#define NO_DEFAULT_INDEX        (1 << 16)
  37
  38struct dsmark_qdisc_data {
  39        struct Qdisc            *q;
  40        struct tcf_proto        *filter_list;
  41        u8                      *mask;  /* "owns" the array */
  42        u8                      *value;
  43        u16                     indices;
  44        u32                     default_index;  /* index range is 0...0xffff */
  45        int                     set_tc_index;
  46};
  47
  48static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
  49{
  50        return (index <= p->indices && index > 0);
  51}
  52
  53/* ------------------------- Class/flow operations ------------------------- */
  54
  55static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
  56                        struct Qdisc *new, struct Qdisc **old)
  57{
  58        struct dsmark_qdisc_data *p = qdisc_priv(sch);
  59
  60        pr_debug("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
  61                sch, p, new, old);
  62
  63        if (new == NULL) {
  64                new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
  65                                        sch->handle);
  66                if (new == NULL)
  67                        new = &noop_qdisc;
  68        }
  69
  70        sch_tree_lock(sch);
  71        *old = p->q;
  72        p->q = new;
  73        qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
  74        qdisc_reset(*old);
  75        sch_tree_unlock(sch);
  76
  77        return 0;
  78}
  79
  80static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
  81{
  82        struct dsmark_qdisc_data *p = qdisc_priv(sch);
  83        return p->q;
  84}
  85
  86static unsigned long dsmark_get(struct Qdisc *sch, u32 classid)
  87{
  88        pr_debug("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
  89                sch, qdisc_priv(sch), classid);
  90
  91        return TC_H_MIN(classid) + 1;
  92}
  93
  94static unsigned long dsmark_bind_filter(struct Qdisc *sch,
  95                                        unsigned long parent, u32 classid)
  96{
  97        return dsmark_get(sch, classid);
  98}
  99
 100static void dsmark_put(struct Qdisc *sch, unsigned long cl)
 101{
 102}
 103
 104static const struct nla_policy dsmark_policy[TCA_DSMARK_MAX + 1] = {
 105        [TCA_DSMARK_INDICES]            = { .type = NLA_U16 },
 106        [TCA_DSMARK_DEFAULT_INDEX]      = { .type = NLA_U16 },
 107        [TCA_DSMARK_SET_TC_INDEX]       = { .type = NLA_FLAG },
 108        [TCA_DSMARK_MASK]               = { .type = NLA_U8 },
 109        [TCA_DSMARK_VALUE]              = { .type = NLA_U8 },
 110};
 111
 112static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
 113                         struct nlattr **tca, unsigned long *arg)
 114{
 115        struct dsmark_qdisc_data *p = qdisc_priv(sch);
 116        struct nlattr *opt = tca[TCA_OPTIONS];
 117        struct nlattr *tb[TCA_DSMARK_MAX + 1];
 118        int err = -EINVAL;
 119        u8 mask = 0;
 120
 121        pr_debug("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
 122                "arg 0x%lx\n", sch, p, classid, parent, *arg);
 123
 124        if (!dsmark_valid_index(p, *arg)) {
 125                err = -ENOENT;
 126                goto errout;
 127        }
 128
 129        if (!opt)
 130                goto errout;
 131
 132        err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, dsmark_policy);
 133        if (err < 0)
 134                goto errout;
 135
 136        if (tb[TCA_DSMARK_MASK])
 137                mask = nla_get_u8(tb[TCA_DSMARK_MASK]);
 138
 139        if (tb[TCA_DSMARK_VALUE])
 140                p->value[*arg - 1] = nla_get_u8(tb[TCA_DSMARK_VALUE]);
 141
 142        if (tb[TCA_DSMARK_MASK])
 143                p->mask[*arg - 1] = mask;
 144
 145        err = 0;
 146
 147errout:
 148        return err;
 149}
 150
 151static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
 152{
 153        struct dsmark_qdisc_data *p = qdisc_priv(sch);
 154
 155        if (!dsmark_valid_index(p, arg))
 156                return -EINVAL;
 157
 158        p->mask[arg - 1] = 0xff;
 159        p->value[arg - 1] = 0;
 160
 161        return 0;
 162}
 16,[qdisc %p],classid %x,parent @" id="L1s="line" name="L64">  641s="liass="line" name              *dsmarwal>[dsmarwal>ode=Qdisc" class="sref">Qdisc *sch, unsigned long Qdi"+codewal>_bind_filter("+codewal>_bh" class="sref">sch_bind_filter(wal>_bh" ch_dsmark.c#L156" id="L156" class="lie" name="1L65">  65           1     1      h_dsmark.c#L153" id="L153" class="lie" name="1L66">  66           1     16href="+code=nlattr" class="sref">nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
  67           1     1         68        }
<1a hre16d/sch_dsmark.c#L139" id="L139" class="lie" name="1L69">  69
p-&gr_debug("dsmark_change(sch %p,[qdiswal>;p],classid %x,parent &wal>_b,
sch, p, cwal>_bind_filter(wal>_bh" chh_dsmark.c#L17" id="L17" class="line"e" name="L70">  70          71        *tbwal>_bind_filter(wal>_bh" cue" class="sref">valsto  72        &qsched/h_dsmark.c#L17" id="L17" class="line"e" name="L73">  73          74        inde;
p->valndices;
  75        tbgt;mask[argvalue[arg  76
erignora>[  77        ret1urn 017 href="+code=mask" clclass="sref">tbwal>_bind_filter(wal>_bh" cue" class="sref">valcou, *p-&wal>_bind_filter(wal>_bh" cue" class="sref">valski  78}
tbwal>_bind_filter(wal>_bh" cue" class="sref">valf>);
sch);
ci;
cwal>_bind_filter(wal>_bh" chched/schch_dsmark.c#L125" id="L125" class="lie" name="1L79">  79
tbwal>_bind_filter(wal>_bh" cue" class="sref">valsto  80static stru1ct   81{
  82        str1uct <18pan class="string">&qh_dsmark.c#L163" id="L163" class="liee" name="L83">  83        ret1urn <1 href=class="sref">erignora>[  84}
new_bind_filter(wal>_bh" cue" class="sref">valcou, *  85
  86static unsi1gned 1ong   87{
  88        inline int tcf_proto        *tca *Qdisc *sch, unsigned long   89           1     1a href="+code=sch" claaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+code=cl" class="sref">cl)
  90
  91        ret1urn <1 href="+code=Tlattr" class="sref">nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
  92}
valf">filter_list;
  93
( =   25/* ----------------------- ef">Qflow operations ---------------------------- */
  97static int tca *Qdisc *sch)
  98/a>
  39        struct nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
err/a>);
p-&gr_debug("dsmendev_q(okdge(sch &hange(sch %p,[qdiswal#37;x,parent &wal>_b,
sch, p);
 103
set_tc_indexlter(wal>_bh" chched/schch_dsmark2c#L105" i2="L105" class="line" nam2="L1020  75        (nla_dsfiede=old" class="sripv4>nla_dsfiedepriv(u32                  code=p" classssssssssssssssssbreakh_dsmark2c#L113" i2="L113" class="line" nam2="L1121> 103
u16                                struct (nla_dsfiede=old" class="sripv6>nla_dsfiedepriv(defra>[ 122            et/s17  /a>(
 127        19pan class="stef">TCAJndex" class="sref">TCAJndex(sch->handle<
(TC_H_MIN( 129    elsefer(wal>_bh" chched/schch_dsmark2c#L130" i2="L130" class="line" nam2="L132"> 130            /a> int (valf">filter_list, &p-&gr_debug(&qresue_[qdiswdspan c;arg 0x&0437;lx\n", classid);
 136#ifef"an>,  137            casefine [[ 140                        return  141
[ 143                        struct  144#endifa>);
[u16                    /a>(TC_H_MIN(classid);
defra>[defalid_index" class="sref">defalid_i 140 = (defalid_index" class="sref">defalid_i 140 classssssssssssssssssbreakh_dsmark2c#L152" i2="L152" class="line" nam2="L1525">u32                  code=p" classssssssssssssssssbreakh_dsmark2c#L153" i2="L153" class="line" nam2="L1525> 143            ref="n1et/sc18 href="+code=h_dsmark2c#L154" i2="L154" class="line" nam2="L1525  84}
 156    ="t;err = qdendev_queue" class="sref">qdendev_qpriv(q);
err = (err))
sch->err;
 161    ref="n1et/sc18 href="+code=h_dsmark2c#L162" i2="L162" class="line" nam2="L1626>  62
sch->q= { ., *2 641s26aaaaaaaaaaaaaa9bug( = 2c#L156" i2="L156" class="lie" name2"1L6526  75         return  146
 147 158        sch);
  69
 141
 112staa *tca *Qdisc *sch)
  74         struct nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
 115        struct tca * 156    ="t;u32 {
 158        p-&gr_debug("dsmdedev_qchange(sch %p,[qdiswal#37;x,parent &wal>_b,
sch, p);
  99
  80statia> *qclass="t;q);
        *  82        str1u    return   84}
 = qdbs_upiscqpriv(schl>_b,
 145        sch->q= { .);
 146
        (valndices);
 158        p-&gr_debug(&q_tc_i[qdiswdclassqdiswd37;x,parent &wal>_b,
  99
statiswitang(  91     casefine         str1ua>);
mask[ 113                           str1ua>);
value[}
     casefine u16            a>);
hde=err" class="sripv6_hdendex(mask[value[  39    ef">defra>[
 103
tbgt;mask[value[p-warn"stebug("dsmdedev_q:aaaaupported tcf_pcod qdiswd37;x,parent &walpan>
 *tca *dsmapee_priv, unsigned long Qdisc *sch)
nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
p-&gr_debug("dsmpee_change(sch %p,[qdiswal#37;x,parent &wal>_b,
sch, p);
qclass="t;q);
Qdisc *sch)
nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
);
p-&gr_debug("dsmresetchange(sch %p,[qdiswal#37;x,parent &wal>_b,
sch, p);
 130    ref=17 href="+code=err" claclass="sref">tbgt;qclass="t; = qclass="t;q);
)
sch->q= { .);
 137        reta> *);
 140static int , unsigned long Qdisc *sch, unsigned long )
 141/a>           1     1      h_dsmark3c#L142" i3="L142" class="line" nam3="L1434> 122        struct nls="sref">dsmark_qdisc_data *p = qdisc_priv(sch);
 143    a>, unsigned long err(u32 defalid_index" class="sref">defalid_i 140 = valndices);
mask);
p-&gr_debug("dsmini"change(sch %p,[qdiswal,op"[qdiswa#37;x,parent &wal>_b,
sch, p, );
)
u32                struct );
err = , err);
);
err(valndices = valndices));
u32                struct );
3 641s36> 124        19pan class="sttde=tb" class="srtbalue[        defalid_index" class="sref">defalid_i 140 =  146
        mask = valndices * 2,  158        19pan class="stode=mask" class="sref">mask =            1     err();
 161    ref="n1et/sc18 href="+code=h_dsmark3c#L156" i3="L156" class="lie" name3"1L7237>  62
tbgt;mask = mask);
}
 = err(mask,a/i;
);
valndices));
 135
 156    ="t;value = mask<+//a>[valndices);
err(, , , s="l2eakh_dsmark2c#L148" i2="L148" class="line" nam2="L1424  68        }
<1a hre16d/sch_5")
 = sch,         19pan class="sttdfla7 145       ss="sttdfla7href="+cTCA_DSMARK_ARK_DEFAULT_INDEX" class="srTCA_DSMARK_ARK_DEFAULT_SET_TC
  a href="+3sched/sfo_qdisc_ops" cla3s="t;38dsmark3c#L17" id3"L17" class="line"e" na128  71        *);
)
 141/a>         2="L148" class="line" v_2"1L7927>  99
 141/a>         2="L148" class="lineet/sched/sch_dsmark2c#L127" i2="" class="lie" name3"1L6536  75  aL156" class="sroULI>sch)
);
 103<3a>
);
       soop="srnlched/sch_dsmark2c#L151" i2="L151" class3>emse" cueetkde=tb" class="srokd>s3h3;
3145                mref="net/sched/sch_dsmark3c#L138dsmark3c#L133" i3="L133" class="line" nam3="L13333 156    ="t;   3    p3&gr_d38  71tbgt;_b,
3a hre3="netk/a>(wal>_bh" chched/schch_dsmark3c#L139" i3="L="+code=value" class="sref">value           1     1a hine , 3nsigned long  *}
 =  *=sch" cla3aaaaaa2aaaaa29  84}
3a hre39mpee_put" class="sref">dsmapee_priv, unsigned long Qdisc *sch)
="L92" cl36>ark_ch_dsfiedepriv3        *> = , 3nsigned long );
value = [ 141/a>         2="L148" class="line;
tbgt;}
4class="li4e" nam3="L1030> 140 4     40dsmark3c#L17" id3"L17" class="line"e" n4href="1ne4/s17  * Only ss=plain   4a ark403   reta> * 103Qdisc *sch)

);
err(, s="l2="sref"eaaaoa>}
 = value = tbgt;  39    4ef="n4et/sc18 href="+code=h_dsmark3c#L110" i3="4110" clas4="line" nam3="L1131  70<4a>   4    q}
 = [nls="sref">dsmark_qdisc_data *       tcms7_qdisc_data *       tcm2" i3="L122" class="line" nam3="L1232> 4tca *, unsigned long Qdisc *sch)
nl4="sref">dsmark_qdisc_dat4 4p(        masne" nsref">l"net( 4
);

       tcm2" i"+code=value" class="sm_et/sched/sch_dsmark2c"sm_et/sch="L125") 141/a>         2="L148" class="lineet/sched/sch_dsmark2c#L127" i2="d/sch_dsmark3c#L1c"dsmdedev_qcporte63" i2="L163" class="lie" name2"1L87287 4125" clas4="line" nam3="L1232> 1154/a>  42f="+csched/sfo_qdisc_ops" cltcm 145       tcm2" i"+code=value" class="sm_infoed/sch_dsmark2c"sm_info="L125") = qdisc_priv(sch);
4a hre4="net/sched/sch_dsmark3c#L126ch_sch_dsmark3c#L132"t3="L125")
( 130   4ref=143"srnla_nla_o1Apriv();


   v();

err = (wal>_bh" chou" cut_failurhed/sch_dsmark2cou" cut_failurh i2=2="L163" class="lie" name2"1L87287 4a2
}

)4value);
43"net/sched/sch_dsmark3c#L126ou" lass_cance"dsmdedev_qou" lass_cance&41" class="line" nam3 146
 1374/a>  44d/sch_dsmark2c#L139" i2="L139" class="li4static in4 Qdisc *q}
 = nls="sref">dsmark_qdisc_data *tca);
<4 href="net/sched/sch_dsm4rk3c#4143" i3="L143"lass="sdde=dsmarbhpriv, unsigned long Qdisc *sch)
[
);
p-&gr_4ebug<45smresetchange(sch %p,[qdiswaou" cut_n=tb" class="srtbalue
(wal>_bh" chou" cut_failurhed/sch_dsmark2cou" cut_failurh i2=2="L163" class="lie" name2"1L87287 4= hode=Qd4op" cue" class="srop"ice4<)45dsmark3c#L17" id3"L17" class="line"e" n4ark3c#L154" i3="L151" class="line"4nam3=453mresetchange(sch %p,[qdiswaeakh_dsmark2c#L148" i2="L148" class="line" nam2="L1424  68        }
<1a hre16d/sch_!       int err();
<4s="srop"ices)

        }
<1a hre16p,[as a bypn c.- */<" nam2="L1424  68        }
<1a hre16d/schrched/sch_dsmark3c#L130" i3="L130" c4g[(wal>_bh" chou" cut_failurhed/sch_dsmark2cou" cut_failurh i2=2="L163" class="lie" name2"1L87287 4= href="n4>, sch, "line"linek3c#L17" id3"L17" class="line"e" n4aef="+co14">err);
       ss="cut_fla741" class="line" nam3 146

<="L1rched/sch_dsmark3c#L130" i3="L130" c4g>);
    4    <4 href="+code=value" class="sref">valndic4s = <4 href="+cnla_nla_o1A_U164 clas46" nam3="L1030  78}

valueva4ndices));


defa4id_in4ex" cl_dsmark2c#L139" i2="L139" class="li4ref="+cnl4_nla_o1A_U16" class="srn4a_nla46v" class="sref">qdisc_priv(BYPASTIconstclass="sdde=dsmarbhprivQet/scclassad/sch_dsmark3c#L13Qet/scclassad/s>(, unclassad/sch_dsmark3c#L13, unclassad/s="L125"*tca, , ungraf class="line" na, ungraf t/schtcamask = nls="sref"leas" class="srGFP_=="net/sched/sch_dsmark, unleasref">nls="sref", unleast/schtca = <4  1     err}
 = , ung=">}
 = tca);
err, unp/schch_dsmark3c#L, unp/s" clhtca                4truct4, un 39, un 39tcava4ss="lie" name3"1L7237>  424, undeletaquot;dsmdedev_q, undeleta" clhtca
, unwalan>
tcaerr, unfcodf="sref">nls="sref", unfcodf="s" clhtca 156    ="4;nls="sref"bcodf="s" cl"srGFP_=="net/sched/sch_dsmark, unbcodf i2="Lref">nls="sref", unbcodf i2="L" clhtcanls="sref"unbcodf="s="+cde=in=="net/sched/sch_dsmark, unp/schch_dsmark3c#L, unp/s" clhtca}
 = , un/ump_ne" n>}
 = tca( = (, un"srnlad/sch_dsmark3c#L13, un"srnlad/s>(}
 = tca        *  99
tcava4ss="sroULI>sch)
tca
tcas4h48f="+csched/sfsch_dsmark3c#L13="L1_sizaquot;dsmdedev_q="L1_siza="+csrGFP_=="net/ssizaofu3c#L121" i3="L121" cla, unsigned long Qdisc<)=tca4145  99
, unen2"1L7927>  99
, unen2"1L7="L1htca  99
, unde2"1L7927>  99
, unde2"1L7="L1htcap4&gr_d48L" class="srGsch_dsmark3c#L13ark3cc#L29" i3="L119" classass="srGFP_=="net/sched/sch_dsmark, unprk3cc#L29" i3="L11, unprk3="L1htca_b,
4a hre49AL" class="srsch_dsmark3c#L13dsmark3cc#L29" i3="L129" class="srGFP_=="net/sched/sch_dsmark, un/a>);
tcaerr);
, uns=le_ices/a>);
tcaerr}
 = , unref=">}
 = tcaark_ch_dsfiedepriv4/a>(<49a href="ef"ousch_dsmark3c#L13deaaaoa>}
 = , undeaaaoa>}
 = tcava4nsigned long   99
tca);
, un/ump>}
 = tca}
4a hre49f="+csched/sfsch_dsmark3c#L13own"Lref">nls="sref"own"L" clss="srGFP_=="net/sched/sch_dsmarkTHIS_MODULEa href="net/scheHIS_MODULEet/shtcaark_ch_dsfiedepriv4, 4nsigned long err([tca}
       regis="L1"srnl41" c"line" nam2="L1323  , un"srnlad/sch_dsmark3c#L13, un"srnlad/s>( *);
, unmodulenexle_ices/a>);
, unmodulenexle41" cvoidched/sch_dsmark3c#L130" i3="L130" c5>5ef="1ne5/>);
 *       4nregis="L1"srnl41" c"line" nam2="L1323  , un"srnlad/sch_dsmark3c#L13, un"srnlad/s>(err(, unmodulens=le_ices/a>);
(wal>_bh" chmodulenexle_ices/a>);
, unmodulenexle_ices/a>);
, unmodulenexle41" ched/sch_dsmark3c#L130" i3="L130" c5c}
lxL@3="ux.no="+c.
Redpill L="pro A="netnaprovider of L="uxIconsultu8d and opera> ons servclas since 1995.