void dev_init_scheduler(struct net_device *dev) { qdisc_lock_tree(dev); dev->qdisc = &noop_qdisc; dev->qdisc_sleeping = &noop_qdisc; INIT_LIST_HEAD(&dev->qdisc_list); qdisc_unlock_tree(dev); dev_watchdog_init(dev); }
void dev_shutdown(struct net_device *dev) { struct Qdisc *qdisc; qdisc_lock_tree(dev); qdisc = dev->qdisc_sleeping; dev->qdisc = &noop_qdisc; dev->qdisc_sleeping = &noop_qdisc; qdisc_destroy(qdisc); #if defined(CONFIG_NET_SCH_INGRESS) || defined(CONFIG_NET_SCH_INGRESS_MODULE) if ((qdisc = dev->qdisc_ingress) != NULL) { dev->qdisc_ingress = NULL; qdisc_destroy(qdisc); } #endif BUG_TRAP(!timer_pending(&dev->watchdog_timer)); qdisc_unlock_tree(dev); }
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { struct rtattr **tca; struct tcmsg *t; u32 protocol; u32 prio; u32 nprio; u32 parent; struct net_device *dev; struct Qdisc *q; struct tcf_proto **back, **chain; struct tcf_proto *tp; struct tcf_proto_ops *tp_ops; struct Qdisc_class_ops *cops; unsigned long cl; unsigned long fh; int err; replay: tca = arg; t = NLMSG_DATA(n); protocol = TC_H_MIN(t->tcm_info); prio = TC_H_MAJ(t->tcm_info); nprio = prio; parent = t->tcm_parent; cl = 0; if (prio == 0) { /* If no priority is given, user wants we allocated it. */ if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE)) return -ENOENT; prio = TC_H_MAKE(0x80000000U,0U); } /* Find head of filter chain. */ /* Find link */ if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL) return -ENODEV; /* Find qdisc */ if (!parent) { q = dev->qdisc_sleeping; parent = q->handle; } else if ((q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent))) == NULL) return -EINVAL; /* Is it classful? */ if ((cops = q->ops->cl_ops) == NULL) return -EINVAL; /* Do we search for filter, attached to class? */ if (TC_H_MIN(parent)) { cl = cops->get(q, parent); if (cl == 0) return -ENOENT; } /* And the last stroke */ chain = cops->tcf_chain(q, cl); err = -EINVAL; if (chain == NULL) goto errout; /* Check the chain for existence of proto-tcf with this priority */ for (back = chain; (tp=*back) != NULL; back = &tp->next) { if (tp->prio >= prio) { if (tp->prio == prio) { if (!nprio || (tp->protocol != protocol && protocol)) goto errout; } else tp = NULL; break; } } if (tp == NULL) { /* Proto-tcf does not exist, create new one */ if (tca[TCA_KIND-1] == NULL || !protocol) goto errout; err = -ENOENT; if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE)) goto errout; /* Create new proto tcf */ err = -ENOBUFS; if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL) goto errout; err = -EINVAL; tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]); if (tp_ops == NULL) { #ifdef CONFIG_KMOD struct rtattr *kind = tca[TCA_KIND-1]; char name[IFNAMSIZ]; if (kind != NULL && rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { rtnl_unlock(); request_module("cls_%s", name); rtnl_lock(); tp_ops = tcf_proto_lookup_ops(kind); /* We dropped the RTNL semaphore in order to * perform the module load. So, even if we * succeeded in loading the module we have to * replay the request. We indicate this using * -EAGAIN. */ if (tp_ops != NULL) { module_put(tp_ops->owner); err = -EAGAIN; } } #endif kfree(tp); goto errout; } memset(tp, 0, sizeof(*tp)); tp->ops = tp_ops; tp->protocol = protocol; tp->prio = nprio ? : tcf_auto_prio(*back); tp->q = q; tp->classify = tp_ops->classify; tp->classid = parent; if ((err = tp_ops->init(tp)) != 0) { module_put(tp_ops->owner); kfree(tp); goto errout; } qdisc_lock_tree(dev); tp->next = *back; *back = tp; qdisc_unlock_tree(dev); } else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))