diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/Kconfig | 38 | ||||
-rw-r--r-- | net/sched/act_api.c | 15 | ||||
-rw-r--r-- | net/sched/cls_api.c | 2 | ||||
-rw-r--r-- | net/sched/em_meta.c | 62 | ||||
-rw-r--r-- | net/sched/em_text.c | 3 | ||||
-rw-r--r-- | net/sched/gact.c | 2 | ||||
-rw-r--r-- | net/sched/ipt.c | 2 | ||||
-rw-r--r-- | net/sched/mirred.c | 2 | ||||
-rw-r--r-- | net/sched/pedit.c | 2 | ||||
-rw-r--r-- | net/sched/police.c | 3 | ||||
-rw-r--r-- | net/sched/sch_api.c | 6 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 24 | ||||
-rw-r--r-- | net/sched/sch_red.c | 2 | ||||
-rw-r--r-- | net/sched/simple.c | 2 |
14 files changed, 86 insertions, 79 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 7bac249258e3..45d3bc0812c8 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -1,6 +1,43 @@ # # Traffic control configuration. # + +menuconfig NET_SCHED + bool "QoS and/or fair queueing" + ---help--- + When the kernel has several packets to send out over a network + device, it has to decide which ones to send first, which ones to + delay, and which ones to drop. This is the job of the packet + scheduler, and several different algorithms for how to do this + "fairly" have been proposed. + + If you say N here, you will get the standard packet scheduler, which + is a FIFO (first come, first served). If you say Y here, you will be + able to choose from among several alternative algorithms which can + then be attached to different network devices. This is useful for + example if some of your network devices are real time devices that + need a certain minimum data flow rate, or if you need to limit the + maximum data flow rate for traffic which matches specified criteria. + This code is considered to be experimental. + + To administer these schedulers, you'll need the user-level utilities + from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. + That package also contains some documentation; for more, check out + <http://snafu.freedom.org/linux2.2/iproute-notes.html>. + + This Quality of Service (QoS) support will enable you to use + Differentiated Services (diffserv) and Resource Reservation Protocol + (RSVP) on your Linux router if you also say Y to "QoS support", + "Packet classifier API" and to some classifiers below. Documentation + and software is at <http://diffserv.sourceforge.net/>. + + If you say Y here and to "/proc file system" below, you will be able + to read status information about packet schedulers from the file + /proc/net/psched. + + The available schedulers are listed in the following questions; you + can say Y to as many as you like. If unsure, say N now. + choice prompt "Packet scheduler clock source" depends on NET_SCHED @@ -454,6 +491,7 @@ config NET_EMATCH_TEXT depends on NET_EMATCH select TEXTSEARCH select TEXTSEARCH_KMP + select TEXTSEARCH_BM select TEXTSEARCH_FSM ---help--- Say Y here if you want to be ablt to classify packets based on diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 249c61936ea0..8aebe8f6d271 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -165,7 +165,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action *act, while ((a = act) != NULL) { repeat: if (a->ops && a->ops->act) { - ret = a->ops->act(&skb, a); + ret = a->ops->act(&skb, a, res); if (TC_MUNGED & skb->tc_verd) { /* copied already, allow trampling */ skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); @@ -179,11 +179,6 @@ repeat: act = a->next; } exec_done: - if (skb->tc_classid > 0) { - res->classid = skb->tc_classid; - res->class = 0; - skb->tc_classid = 0; - } return ret; } @@ -598,7 +593,7 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh->nlmsg_flags |= NLM_F_ROOT; module_put(a->ops->owner); kfree(a); - err = rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); if (err > 0) return 0; @@ -661,7 +656,7 @@ tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) /* now do the delete */ tcf_action_destroy(head, 0); - ret = rtnetlink_send(skb, pid, RTMGRP_TC, + ret = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); if (ret > 0) return 0; @@ -703,9 +698,9 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, x->rta_len = skb->tail - (u8*)x; nlh->nlmsg_len = skb->tail - b; - NETLINK_CB(skb).dst_groups = RTMGRP_TC; + NETLINK_CB(skb).dst_group = RTNLGRP_TC; - err = rtnetlink_send(skb, pid, RTMGRP_TC, flags&NLM_F_ECHO); + err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO); if (err > 0) err = 0; return err; diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 3b5714ef4d1a..b4d89fbb3782 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -367,7 +367,7 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, return -EINVAL; } - return rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); } struct tcf_dump_args diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 53d98f8d3d80..00eae5f9a01a 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -27,17 +27,17 @@ * lvalue rvalue * +-----------+ +-----------+ * | type: INT | | type: INT | - * def | id: INDEV | | id: VALUE | + * def | id: DEV | | id: VALUE | * | data: | | data: 3 | * +-----------+ +-----------+ * | | - * ---> meta_ops[INT][INDEV](...) | + * ---> meta_ops[INT][DEV](...) | * | | * ----------- | * V V * +-----------+ +-----------+ * | type: INT | | type: INT | - * obj | id: INDEV | | id: VALUE | + * obj | id: DEV | | id: VALUE | * | data: 2 |<--data got filled out | data: 3 | * +-----------+ +-----------+ * | | @@ -170,26 +170,6 @@ META_COLLECTOR(var_dev) *err = var_dev(skb->dev, dst); } -META_COLLECTOR(int_indev) -{ - *err = int_dev(skb->input_dev, dst); -} - -META_COLLECTOR(var_indev) -{ - *err = var_dev(skb->input_dev, dst); -} - -META_COLLECTOR(int_realdev) -{ - *err = int_dev(skb->real_dev, dst); -} - -META_COLLECTOR(var_realdev) -{ - *err = var_dev(skb->real_dev, dst); -} - /************************************************************************** * skb attributes **************************************************************************/ @@ -229,12 +209,14 @@ META_COLLECTOR(int_maclen) * Netfilter **************************************************************************/ -#ifdef CONFIG_NETFILTER META_COLLECTOR(int_nfmark) { +#ifdef CONFIG_NETFILTER dst->value = skb->nfmark; -} +#else + dst->value = 0; #endif +} /************************************************************************** * Traffic Control @@ -245,31 +227,21 @@ META_COLLECTOR(int_tcindex) dst->value = skb->tc_index; } -#ifdef CONFIG_NET_CLS_ACT -META_COLLECTOR(int_tcverd) -{ - dst->value = skb->tc_verd; -} - -META_COLLECTOR(int_tcclassid) -{ - dst->value = skb->tc_classid; -} -#endif - /************************************************************************** * Routing **************************************************************************/ -#ifdef CONFIG_NET_CLS_ROUTE META_COLLECTOR(int_rtclassid) { if (unlikely(skb->dst == NULL)) *err = -1; else +#ifdef CONFIG_NET_CLS_ROUTE dst->value = skb->dst->tclassid; -} +#else + dst->value = 0; #endif +} META_COLLECTOR(int_rtiif) { @@ -505,8 +477,6 @@ struct meta_ops static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [TCF_META_TYPE_VAR] = { [META_ID(DEV)] = META_FUNC(var_dev), - [META_ID(INDEV)] = META_FUNC(var_indev), - [META_ID(REALDEV)] = META_FUNC(var_realdev), [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if), }, [TCF_META_TYPE_INT] = { @@ -515,25 +485,15 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1), [META_ID(LOADAVG_2)] = META_FUNC(int_loadavg_2), [META_ID(DEV)] = META_FUNC(int_dev), - [META_ID(INDEV)] = META_FUNC(int_indev), - [META_ID(REALDEV)] = META_FUNC(int_realdev), [META_ID(PRIORITY)] = META_FUNC(int_priority), [META_ID(PROTOCOL)] = META_FUNC(int_protocol), [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), [META_ID(PKTLEN)] = META_FUNC(int_pktlen), [META_ID(DATALEN)] = META_FUNC(int_datalen), [META_ID(MACLEN)] = META_FUNC(int_maclen), -#ifdef CONFIG_NETFILTER [META_ID(NFMARK)] = META_FUNC(int_nfmark), -#endif [META_ID(TCINDEX)] = META_FUNC(int_tcindex), -#ifdef CONFIG_NET_CLS_ACT - [META_ID(TCVERDICT)] = META_FUNC(int_tcverd), - [META_ID(TCCLASSID)] = META_FUNC(int_tcclassid), -#endif -#ifdef CONFIG_NET_CLS_ROUTE [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), -#endif [META_ID(RTIIF)] = META_FUNC(int_rtiif), [META_ID(SK_FAMILY)] = META_FUNC(int_sk_family), [META_ID(SK_STATE)] = META_FUNC(int_sk_state), diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 873840d8d072..77beabc91fa3 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c @@ -55,9 +55,6 @@ static int em_text_change(struct tcf_proto *tp, void *data, int len, struct ts_config *ts_conf; int flags = 0; - printk("Configuring text: %s from %d:%d to %d:%d len %d\n", conf->algo, conf->from_offset, - conf->from_layer, conf->to_offset, conf->to_layer, conf->pattern_len); - if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len)) return -EINVAL; diff --git a/net/sched/gact.c b/net/sched/gact.c index a811c89fef7f..d1c6d542912a 100644 --- a/net/sched/gact.c +++ b/net/sched/gact.c @@ -135,7 +135,7 @@ tcf_gact_cleanup(struct tc_action *a, int bind) } static int -tcf_gact(struct sk_buff **pskb, struct tc_action *a) +tcf_gact(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res) { struct tcf_gact *p = PRIV(a, gact); struct sk_buff *skb = *pskb; diff --git a/net/sched/ipt.c b/net/sched/ipt.c index b114d994d523..f50136eed211 100644 --- a/net/sched/ipt.c +++ b/net/sched/ipt.c @@ -201,7 +201,7 @@ tcf_ipt_cleanup(struct tc_action *a, int bind) } static int -tcf_ipt(struct sk_buff **pskb, struct tc_action *a) +tcf_ipt(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res) { int ret = 0, result = 0; struct tcf_ipt *p = PRIV(a, ipt); diff --git a/net/sched/mirred.c b/net/sched/mirred.c index f309ce336803..20d06916dc0b 100644 --- a/net/sched/mirred.c +++ b/net/sched/mirred.c @@ -158,7 +158,7 @@ tcf_mirred_cleanup(struct tc_action *a, int bind) } static int -tcf_mirred(struct sk_buff **pskb, struct tc_action *a) +tcf_mirred(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res) { struct tcf_mirred *p = PRIV(a, mirred); struct net_device *dev; diff --git a/net/sched/pedit.c b/net/sched/pedit.c index 678be6a645fb..767d24f4610e 100644 --- a/net/sched/pedit.c +++ b/net/sched/pedit.c @@ -130,7 +130,7 @@ tcf_pedit_cleanup(struct tc_action *a, int bind) } static int -tcf_pedit(struct sk_buff **pskb, struct tc_action *a) +tcf_pedit(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res) { struct tcf_pedit *p = PRIV(a, pedit); struct sk_buff *skb = *pskb; diff --git a/net/sched/police.c b/net/sched/police.c index c03545faf523..eb39fb2f39b6 100644 --- a/net/sched/police.c +++ b/net/sched/police.c @@ -284,7 +284,8 @@ static int tcf_act_police_cleanup(struct tc_action *a, int bind) return 0; } -static int tcf_act_police(struct sk_buff **pskb, struct tc_action *a) +static int tcf_act_police(struct sk_buff **pskb, struct tc_action *a, + struct tcf_result *res) { psched_time_t now; struct sk_buff *skb = *pskb; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b9a069af4a02..31570b9a6e9a 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -816,7 +816,7 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, } if (skb->len) - return rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); err_out: kfree_skb(skb); @@ -1040,7 +1040,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, return -EINVAL; } - return rtnetlink_send(skb, pid, RTMGRP_TC, n->nlmsg_flags&NLM_F_ECHO); + return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); } struct qdisc_dump_args @@ -1194,7 +1194,7 @@ EXPORT_SYMBOL(psched_time_base); * with 32-bit get_cycles(). Safe up to 4GHz CPU. */ static void psched_tick(unsigned long); -static struct timer_list psched_timer = TIMER_INITIALIZER(psched_tick, 0, 0); +static DEFINE_TIMER(psched_timer, psched_tick, 0, 0); static void psched_tick(unsigned long dummy) { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 73e218e646ac..99ceb91f0150 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -238,6 +238,20 @@ static void dev_watchdog_down(struct net_device *dev) spin_unlock_bh(&dev->xmit_lock); } +void netif_carrier_on(struct net_device *dev) +{ + if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) + linkwatch_fire_event(dev); + if (netif_running(dev)) + __netdev_watchdog_up(dev); +} + +void netif_carrier_off(struct net_device *dev) +{ + if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) + linkwatch_fire_event(dev); +} + /* "NOOP" scheduler: the best scheduler, recommended for all interfaces under all circumstances. It is difficult to invent anything faster or cheaper. @@ -331,11 +345,10 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc) int prio; struct sk_buff_head *list = qdisc_priv(qdisc); - for (prio = 0; prio < PFIFO_FAST_BANDS; prio++, list++) { - struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list); - if (skb) { + for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) { + if (!skb_queue_empty(list + prio)) { qdisc->q.qlen--; - return skb; + return __qdisc_dequeue_head(qdisc, list + prio); } } @@ -439,6 +452,7 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) if (!ops->init || ops->init(sch, NULL) == 0) return sch; + qdisc_destroy(sch); errout: return NULL; } @@ -600,6 +614,8 @@ void dev_shutdown(struct net_device *dev) } EXPORT_SYMBOL(__netdev_watchdog_up); +EXPORT_SYMBOL(netif_carrier_on); +EXPORT_SYMBOL(netif_carrier_off); EXPORT_SYMBOL(noop_qdisc); EXPORT_SYMBOL(noop_qdisc_ops); EXPORT_SYMBOL(qdisc_create_dflt); diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 664d0e47374f..7845d045eec4 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -385,7 +385,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt) memcpy(q->Stab, RTA_DATA(tb[TCA_RED_STAB-1]), 256); q->qcount = -1; - if (skb_queue_len(&sch->q) == 0) + if (skb_queue_empty(&sch->q)) PSCHED_SET_PASTPERFECT(q->qidlestart); sch_tree_unlock(sch); return 0; diff --git a/net/sched/simple.c b/net/sched/simple.c index 3ab4c675ab5d..8a6ae4f491e8 100644 --- a/net/sched/simple.c +++ b/net/sched/simple.c @@ -44,7 +44,7 @@ static DEFINE_RWLOCK(simp_lock); #include <net/pkt_act.h> #include <net/act_generic.h> -static int tcf_simp(struct sk_buff **pskb, struct tc_action *a) +static int tcf_simp(struct sk_buff **pskb, struct tc_action *a, struct tcf_result *res) { struct sk_buff *skb = *pskb; struct tcf_defact *p = PRIV(a, defact); |