LXR scrip/net <./) <._plug.c ion p> typ/e="tex typbody class="func" type="tex ravigatt.tdclass="e="ti> top t.t> /">LXR //script> net ">net net <./) "> <./) net <./) <._plug.c"> <._plug.c t/sp u t!-- -- //script> 8/net <./) <._plug.c gatypimggfx/favicon.png" typlef /css" alt="<< a r gat( dy a:'GET="net <./) <._plug.c"r=ghr();"idd gatypsp ufid="ver_ans; } gatytypsns; }edInd="v"fid="v"f on, f( d="up= ee_versGET ncok 's/lxrng-funcs.js"> <' 'scrip' '' 'net <./) <._plug.c');" typop'GET''; }el"v4.9.11" ga v4.9.11 gatyp/spaT typ/form typa gaty href="../linux+v3.6.10/net/sched/sch_plug.c"> gatypimg src="../.static/gfx/right.png" alt=">>"> p/spaT pspaT class="lxr_search"> ga
gatypinput typel"hidden" namel"navtarget" '; }el""> gatypinput typel"text" namel"search" idl"search"> gatypbuttET'typel"submit">Search gatyPrefs typ/a> p/spaT gaty yp/div gaty ypform ac'GET="ajax+*" method="post" onsubmit="return false;"> pinput typel"hidden" namel"ajax_lookup" idl"ajax_lookup" '; }el""> gaty yp/form gaty ypdiv class="headingbottEm"> pdiv idl"file_contents"
y y1p/a>pspaT class="comment">/*p/spaT  y y2p/a>pspaT class="comment"> * sch_plug.c Queue traffic until aT explicit release commandp/spaT  y y3p/a>pspaT class="comment"> *p/spaT  y y4p/a>pspaT class="comment"> *             This program is free software; you caT redistribute it and/orp/spaT  y y5p/a>pspaT class="comment"> *             modify it under the terms of the GNU General Public Licensep/spaT  y y6p/a>pspaT class="comment"> *             as published by the Free Software Founda'GET; either versGETp/spaT  y y7p/a>pspaT class="comment"> *             2 of the License, or (at your op'GET) any later versGET.p/spaT  y y8p/a>pspaT class="comment"> *p/spaT  y y9p/a>pspaT class="comment"> * There are two ways to use this qdisc:p/spaT  y 10pspaT class="comment"> * 1. A simple "instantaneous" plug/unplug opera'GET, by issuing aT alterna'Gngp/spaT  y 11p/a>pspaT class="comment"> *    sequence of TCQ_PLUG_BUFFER & TCQ_PLUG_RELEASE_INDEFINITE commands.p/spaT  y 12p/a>pspaT class="comment"> *p/spaT  y 13p/a>pspaT class="comment"> * 2. For network output buffering (a.k.a output commit) func'GETality.p/spaT  y 14p/a>pspaT class="comment"> *    Output commit property is commonly used by applica'GETs using checkpointp/spaT  y 15p/a>pspaT class="comment"> *    based fault-tolerance to ensure that the checkpoint from which a systemp/spaT  y 16p/a>pspaT class="comment"> *    is being restored is consistent w.r.t outside world.p/spaT  y 17p/a>pspaT class="comment"> *p/spaT  y 18p/a>pspaT class="comment"> *    Consider for e.g. Remus - a Virtual Machine checkpointing system,p/spaT  y 19p/a>pspaT class="comment"> *    wherein a VM is checkpointed, say every 50ms. The checkpoint is replica'edp/spaT  y 20pspaT class="comment"> *    asynchronously to the backup host, while the VM continues executing thep/spaT  y 21p/a>pspaT class="comment"> *    next epoch speculatively.p/spaT  y 22p/a>pspaT class="comment"> *p/spaT  y 23p/a>pspaT class="comment"> *    The following is a typical sequence of output buffer opera'GETs:p/spaT  y 24p/a>pspaT class="comment"> *       1.At epoch i, start_buffer(i)p/spaT  y 25p/a>pspaT class="comment"> *       2. At end of epoch i (i.e. after 50ms):p/spaT  y 26p/a>pspaT class="comment"> *          2.1 Stop VM and take checkpoint(i).p/spaT  y 27p/a>pspaT class="comment"> *          2.2 start_buffer(i+1) and Resume VMp/spaT  y 28p/a>pspaT class="comment"> *    y y3. While speculatively executing epoch(i+1), asynchronously replica'ep/spaT  y 29p/a>pspaT class="comment"> *          checkpoint(i) to backup host.p/spaT  y 30pspaT class="comment"> *    y y4. When checkpoint_ack(i) is received from backup, release_buffer(i)p/spaT  y 31p/a>pspaT class="comment"> *    Thus, this Qdisc would receive the following sequence of commands:p/spaT  y 32p/a>pspaT class="comment"> *       TCQ_PLUG_BUFFER (epoch i)p/spaT  y 33p/a>pspaT class="comment"> *       .. TCQ_PLUG_BUFFER (epoch i+1)p/spaT  y 34p/a>pspaT class="comment"> *       ....TCQ_PLUG_RELEASE_ONE (epoch i)p/spaT  y 35p/a>pspaT class="comment"> *       ......TCQ_PLUG_BUFFER (epoch i+2)p/spaT  y 36p/a>pspaT class="comment"> *       ........p/spaT  y 37p/a>pspaT class="comment"> */p/spaT  y 38p/a> y 39p/a>#include <linux/module.hp/a>> y 40p/a>#include <linux/types.hp/a>> y 41p/a>#include <linux/kernel.hp/a>> y 42p/a>#include <linux/errno.hp/a>> y 43p/a>#include <linux/netdevice.hp/a>> y 44p/a>#include <linux/skbuff.hp/a>> y 45p/a>#include <net/pkt_sched.hp/a>> y 46p/a> y 47p/a>pspaT class="comment">/*p/spaT  y 48p/a>pspaT class="comment"> * Sta'e of the queue, when used for network output buffering:p/spaT  y 49p/a>pspaT class="comment"> *p/spaT  y 50pspaT class="comment"> *    y yyyyyyyyyyyplug(i+1) yyyyyyyyyyyplug(i) yyyyyyyyyheadp/spaT  y 51p/a>pspaT class="comment"> * ------------------+--------------------+---------------->p/spaT  y 52p/a>pspaT class="comment"> *                   |                    |p/spaT  y 53p/a>pspaT class="comment"> *                   |                    |p/spaT  y 54p/a>pspaT class="comment"> * pkts_current_epoch| pkts_last_epoch    |pkts_to_releasep/spaT  y 55p/a>pspaT class="comment"> * ----------------->|<--------+--------->|+--------------->p/spaT  y 56p/a>pspaT class="comment"> *                   v                    vp/spaT  y 57p/a>pspaT class="comment"> *p/spaT  y 58p/a>pspaT class="comment"> */p/spaT  y 59p/a> y 60structypa href="+code=plug_sched_data" class="sref">plug_sched_data { y 61p/a>        pspaT class="comment">/* If true, the dequeue func'GET releases all packetsp/spaT  y 62p/a>pspaT class="comment">         * from head to end of the queue. The queue turns intop/spaT  y 63p/a>pspaT class="comment">         * a pass-through queue for newly arriving packets.p/spaT  y 64p/a>pspaT class="comment">         */p/spaT  y 65p/a>        pa href="+code=bool" class="sref">boolp/a> pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a>; y 66p/a> y 67p/a>        pspaT class="comment">/* Queue Limit in bytes */p/spaT  y 68p/a>        pa href="+code=u32" class="sref">u32p/a> pa href="+code=limit" class="sref">limitp/a>; y 69p/a> y 70p/a>        pspaT class="comment">/* Number of packets (output) from the current speculativelyp/spaT  y 71p/a>pspaT class="comment">         * executing epoch.p/spaT  y 72p/a>pspaT class="comment">         */p/spaT  y 73p/a>        pa href="+code=u32" class="sref">u32p/a> pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a>; y 74p/a> y 75p/a>        pspaT class="comment">/* Number of packets corresponding to the recently finishedp/spaT  y 76p/a>pspaT class="comment">         * epoch. These will be released when we receive ap/spaT  y 77p/a>pspaT class="comment">         * TCQ_PLUG_RELEASE_ONE command. This command is typicallyp/spaT  y 78p/a>pspaT class="comment">         * issued after committing a checkpoint at the target.p/spaT  y 79p/a>pspaT class="comment">         */p/spaT  y 80p/a>        pa href="+code=u32" class="sref">u32p/a> pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a>; y 81p/a> y 82p/a>        pspaT class="comment">/*p/spaT  y 83p/a>pspaT class="comment">         * Number of packets from the head of the queue, that caTp/spaT  y 84p/a>pspaT class="comment">         * be released (committed checkpoint).p/spaT  y 85p/a>pspaT class="comment">         */p/spaT  y 86p/a>        pa href="+code=u32" class="sref">u32p/a> pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a>; y 87p/a>}; y 88p/a> y 89static intypa href="+code=plug_enqueue" class="sref">plug_enqueue(structypa href="+code=sk_buff" class="sref">sk_buffp/a> *pa href="+code=skb" class="sref">skbp/a>, structypa href="+code=Qdisc" class="sref">Qdiscp/a> *pa href="+code=sch" class="sref">schp/a>) y 90p/a>{ y 91p/a>        structypa href="+code=plug_sched_data" class="sref">plug_sched_data *pa href="+code=q" class="sref">q =ypa href="+code=qdisc_priv" class="sref">qdisc_priv(pa href="+code=sch" class="sref">schp/a>); y 92p/a> y 93p/a>        if (pa href="+code=likely" class="sref">likelyp/a>(pa href="+code=sch" class="sref">schp/a>->pa href="+code=qstats" class="sref">qstatsp/a>.pa href="+code=backlog" class="sref">backlogp/a> +ypa href="+code=skb" class="sref">skbp/a>->pa href="+code=len" class="sref">lenp/a> <=ypa href="+code=q" class="sref">q->pa href="+code=limit" class="sref">limitp/a>)) { y 94p/a>                if (!pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a>) y 95p/a>                        pa href="+code=q" class="sref">q->pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a>++; y 96p/a>                return pa href="+code=qdisc_enqueue_tail" class="sref">qdisc_enqueue_tailp/a>(pa href="+code=skb" class="sref">skbp/a>, pa href="+code=sch" class="sref">schp/a>); y 97p/a>        } y 98p/a> y 99p/a>        return pa href="+code=qdisc_reshape_fail" class="sref">qdisc_reshape_failp/a>(pa href="+code=skb" class="sref">skbp/a>, pa href="+code=sch" class="sref">schp/a>); y100p/a>} y101p/a> y102static structypa href="+code=sk_buff" class="sref">sk_buffp/a> *pa href="+code=plug_dequeue" class="sref">plug_dequeue(structypa href="+code=Qdisc" class="sref">Qdiscp/a> *pa href="+code=sch" class="sref">schp/a>) y103p/a>{ y104p/a>        structypa href="+code=plug_sched_data" class="sref">plug_sched_data *pa href="+code=q" class="sref">q =ypa href="+code=qdisc_priv" class="sref">qdisc_priv(pa href="+code=sch" class="sref">schp/a>); y105p/a> y106p/a>        if (pa href="+code=qdisc_is_throttled" class="sref">qdisc_is_throttled(pa href="+code=sch" class="sref">schp/a>)) y107p/a>                return pa href="+code=NULL" class="sref">NULLp/a>; y108p/a> y109p/a>        if (!pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a>) { y110p/a>                if (!pa href="+code=q" class="sref">q->pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a>) { y111p/a>                        pspaT class="comment">/* No more packets to dequeue. Block the queuep/spaT  y112p/a>pspaT class="comment">                         * and wait for the next release command.p/spaT  y113p/a>pspaT class="comment">                         */p/spaT  y114p/a>                        pa href="+code=qdisc_throttled" class="sref">qdisc_throttled(pa href="+code=sch" class="sref">schp/a>); y115p/a>                        return pa href="+code=NULL" class="sref">NULLp/a>; y116p/a>                } y117p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a>--; y118p/a>        } y119p/a> y120p/a>        return pa href="+code=qdisc_dequeue_head" class="sref">qdisc_dequeue_head(pa href="+code=sch" class="sref">schp/a>); y121p/a>} y122p/a> y123p/a>static intypa href="+code=plug_init" class="sref">plug_init(structypa href="+code=Qdisc" class="sref">Qdiscp/a> *pa href="+code=sch" class="sref">schp/a>, structypa href="+code=nlattr" class="sref">nlattrp/a> *pa href="+code=opt" class="sref">optp/a>) y124p/a>{ y125p/a>        structypa href="+code=plug_sched_data" class="sref">plug_sched_data *pa href="+code=q" class="sref">q =ypa href="+code=qdisc_priv" class="sref">qdisc_priv(pa href="+code=sch" class="sref">schp/a>); y126p/a> y127p/a>        pa href="+code=q" class="sref">q->pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a> =y0; y128p/a>        pa href="+code=q" class="sref">q->pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a> =y0; y129p/a>        pa href="+code=q" class="sref">q->pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a> =y0; y130p/a>        pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a> =ypa href="+code=false" class="sref">falsep/a>; y131p/a> y132p/a>        if (pa href="+code=opt" class="sref">optp/a> ==ypa href="+code=NULL" class="sref">NULLp/a>) { y133p/a>                pspaT class="comment">/* We will set a default limit of 100 pkts (~150kB)p/spaT  y134p/a>pspaT class="comment">                 * in case tx_queue_len is not available. Thep/spaT  y135p/a>pspaT class="comment">                 * default '; }e is completely arbitrary.p/spaT  y136p/a>pspaT class="comment">                 */p/spaT  y137p/a>                pa href="+code=u32" class="sref">u32p/a> pa href="+code=pkt_limit" class="sref">pkt_limit =ypa href="+code=qdisc_dev" class="sref">qdisc_dev(pa href="+code=sch" class="sref">schp/a>)->pa href="+code=tx_queue_len" class="sref">tx_queue_len ? : 100; y138p/a>                pa href="+code=q" class="sref">q->pa href="+code=limit" class="sref">limitp/a> =ypa href="+code=pkt_limit" class="sref">pkt_limit *ypa href="+code=psched_mtu" class="sref">psched_mtu(pa href="+code=qdisc_dev" class="sref">qdisc_dev(pa href="+code=sch" class="sref">schp/a>)); y139p/a>        } else { y140p/a>                structypa href="+code=tc_plug_qopt" class="sref">tc_plug_qopt *pa href="+code=ctl" class="sref">ctlp/a> =ypa href="+code=nla_data" class="sref">nla_data(pa href="+code=opt" class="sref">optp/a>); y141p/a> y142p/a>                if (pa href="+code=nla_len" class="sref">nla_len(pa href="+code=opt" class="sref">optp/a>) < sizeof(*pa href="+code=ctl" class="sref">ctlp/a>)) y143p/a>                        return -pa href="+code=EINVAL" class="sref">EINVALp/a>; y144p/a> y145p/a>                pa href="+code=q" class="sref">q->pa href="+code=limit" class="sref">limitp/a> =ypa href="+code=ctl" class="sref">ctlp/a>->pa href="+code=limit" class="sref">limitp/a>; y146p/a>        } y147p/a> y148p/a>        pa href="+code=qdisc_throttled" class="sref">qdisc_throttled(pa href="+code=sch" class="sref">schp/a>); y149p/a>        return 0; y150p/a>} y151p/a> y152p/a>pspaT class="comment">/* Receives 4 types of messages:p/spaT  y153p/a>pspaT class="comment"> * TCQ_PLUG_BUFFER: Inset a plug into the queue andp/spaT  y154p/a>pspaT class="comment"> *  buffer any incoming packetsp/spaT  y155p/a>pspaT class="comment"> * TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue headp/spaT  y156p/a>pspaT class="comment"> *   to beginning of the next plug.p/spaT  y157p/a>pspaT class="comment"> * TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.p/spaT  y158p/a>pspaT class="comment"> *   Stop buffering packets until the next TCQ_PLUG_BUFFERp/spaT  y159p/a>pspaT class="comment"> *   command is received (just ac' as a pass-thru queue).p/spaT  y160pspaT class="comment"> * TCQ_PLUG_LIMIT: Increase/decrease queue sizep/spaT  y161p/a>pspaT class="comment"> */p/spaT  y162static intypa href="+code=plug_change" class="sref">plug_change(structypa href="+code=Qdisc" class="sref">Qdiscp/a> *pa href="+code=sch" class="sref">schp/a>, structypa href="+code=nlattr" class="sref">nlattrp/a> *pa href="+code=opt" class="sref">optp/a>) y163p/a>{ y164p/a>        structypa href="+code=plug_sched_data" class="sref">plug_sched_data *pa href="+code=q" class="sref">q =ypa href="+code=qdisc_priv" class="sref">qdisc_priv(pa href="+code=sch" class="sref">schp/a>); y165p/a>        structypa href="+code=tc_plug_qopt" class="sref">tc_plug_qopt *pa href="+code=msg" class="sref">msgp/a>; y166p/a> y167p/a>        if (pa href="+code=opt" class="sref">optp/a> ==ypa href="+code=NULL" class="sref">NULLp/a>) y168p/a>                return -pa href="+code=EINVAL" class="sref">EINVALp/a>; y169p/a> y170p/a>        pa href="+code=msg" class="sref">msgp/a> =ypa href="+code=nla_data" class="sref">nla_data(pa href="+code=opt" class="sref">optp/a>); y171p/a>        if (pa href="+code=nla_len" class="sref">nla_len(pa href="+code=opt" class="sref">optp/a>) < sizeof(*pa href="+code=msg" class="sref">msgp/a>)) y172p/a>                return -pa href="+code=EINVAL" class="sref">EINVALp/a>; y173p/a> y174p/a>        switch (pa href="+code=msg" class="sref">msgp/a>->pa href="+code=ac'GET" class="sref">ac'GETp/a>) { y175p/a>        case pa href="+code=TCQ_PLUG_BUFFER" class="sref">TCQ_PLUG_BUFFERp/a>: y176p/a>                pspaT class="comment">/* Save size of the current buffer */p/spaT  y177p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a> =ypa href="+code=q" class="sref">q->pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a>; y178p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a> =y0; y179p/a>                if (pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a>) y180p/a>                        pa href="+code=qdisc_throttled" class="sref">qdisc_throttled(pa href="+code=sch" class="sref">schp/a>); y181p/a>                pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a> =ypa href="+code=false" class="sref">falsep/a>; y182p/a>                break; y183p/a>        case pa href="+code=TCQ_PLUG_RELEASE_ONE" class="sref">TCQ_PLUG_RELEASE_ONEp/a>: y184p/a>                pspaT class="comment">/* Add packets from the last complete buffer to thep/spaT  y185p/a>pspaT class="comment">                 * packets to be released set.p/spaT  y186p/a>pspaT class="comment">                 */p/spaT  y187p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a> +=ypa href="+code=q" class="sref">q->pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a>; y188p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a> =y0; y189p/a>                pa href="+code=qdisc_unthrottled" class="sref">qdisc_unthrottled(pa href="+code=sch" class="sref">schp/a>); y190p/a>                pa href="+code=netif_schedule_queue" class="sref">netif_schedule_queue(pa href="+code=sch" class="sref">schp/a>->pa href="+code=dev_queue" class="sref">dev_queuep/a>); y191p/a>                break; y192p/a>        case pa href="+code=TCQ_PLUG_RELEASE_INDEFINITE" class="sref">TCQ_PLUG_RELEASE_INDEFINITEp/a>: y193p/a>                pa href="+code=q" class="sref">q->pa href="+code=unplug_indefinite" class="sref">unplug_indefinitep/a> =ypa href="+code=true" class="sref">truep/a>; y194p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_to_release" class="sref">pkts_to_releasep/a> =y0; y195p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_last_epoch" class="sref">pkts_last_epochp/a> =y0; y196p/a>                pa href="+code=q" class="sref">q->pa href="+code=pkts_current_epoch" class="sref">pkts_current_epochp/a> =y0; y197p/a>                pa href="+code=qdisc_unthrottled" class="sref">qdisc_unthrottled(pa href="+code=sch" class="sref">schp/a>); y198p/a>                pa href="+code=netif_schedule_queue" class="sref">netif_schedule_queue(pa href="+code=sch" class="sref">schp/a>->pa href="+code=dev_queue" class="sref">dev_queuep/a>); y199p/a>                break; y200p/a>        case pa href="+code=TCQ_PLUG_LIMIT" class="sref">TCQ_PLUG_LIMITp/a>: y201p/a>                pspaT class="comment">/* Limit is supplied in bytes */p/spaT  y202p/a>                pa href="+code=q" class="sref">q->pa href="+code=limit" class="sref">limitp/a> =ypa href="+code=msg" class="sref">msgp/a>->pa href="+code=limit" class="sref">limitp/a>; y203p/a>                break; y204p/a>        default: y205p/a>                return -pa href="+code=EINVAL" class="sref">EINVALp/a>; y206p/a>        } y207p/a> y208p/a>        return 0; y209p/a>} y210p/a> y211p/a>static structypa href="+code=Qdisc_ops" class="sref">Qdisc_opsp/a> pa href="+code=plug_qdisc_ops" class="sref">plug_qdisc_opsp/a> pa href="+code=__read_mostly" class="sref">__read_mostlyp/a> =y{ y212p/a>        .pa href="+code=id" class="sref">idp/a>          =       pspaT class="string">"plug"p/spaT , y213p/a>        .pa href="+code=priv_size" class="sref">priv_sizep/a>   =       sizeof(structypa href="+code=plug_sched_data" class="sref">plug_sched_data), y214p/a>        .pa href="+code=enqueue" class="sref">enqueue     =       pa href="+code=plug_enqueue" class="sref">plug_enqueue, y215p/a>        .pa href="+code=dequeue" class="sref">dequeue     =       pa href="+code=plug_dequeue" class="sref">plug_dequeue, y216p/a>        .pa href="+code=peek" class="sref">peekp/a>        =       pa href="+code=qdisc_peek_head" class="sref">qdisc_peek_head, y217p/a>        .pa href="+code=init" class="sref">init        =       pa href="+code=plug_init" class="sref">plug_init, y218p/a>        .pa href="+code=change" class="sref">change      =       pa href="+code=plug_change" class="sref">plug_change, y219p/a>        .pa href="+code=owner" class="sref">ownerp/a>       =       pa href="+code=THIS_MODULE" class="sref">THIS_MODULE, y220p/a>}; y221p/a> y222static intypa href="+code=__init" class="sref">__init pa href="+code=plug_module_init" class="sref">plug_module_init(void) y223p/a>{ y224p/a>        return pa href="+code=register_qdisc" class="sref">register_qdisc(&pa href="+code=plug_qdisc_ops" class="sref">plug_qdisc_opsp/a>); y225p/a>} y226p/a> y227p/a>static voidypa href="+code=__exit" class="sref">__exit pa href="+code=plug_module_exit" class="sref">plug_module_exit(void) y228p/a>{ y229p/a>        pa href="+code=unregister_qdisc" class="sref">unregister_qdisc(&pa href="+code=plug_qdisc_ops" class="sref">plug_qdisc_opsp/a>); y230p/a>} y231p/a>pa href="+code=module_init" class="sref">module_init(pa href="+code=plug_module_init" class="sref">plug_module_init) y232p/a>pa href="+code=module_exit" class="sref">module_exit(pa href="+code=plug_module_exit" class="sref">plug_module_exit) y233p/a>pa href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE(pspaT class="string">"GPL"p/spaT ); y234p/a>p/pre>p/di<>

)p/di<>

"L234" class="line" namel"Ljt6noo;pa">
top/original LXR software by buff/sch_plughttp://sourceforge..c#Lprojects/lxa">LXR is sunet"net/lxa@lgt; .nonet/.ass="lin" namel"Ljt6subnoo;pa">
lxa.lgt; .no kindly hrefedeby /sch_plughttp://www.redpill-lgtpro.no">Redpill Lgtpro ASnet/