- 论坛徽章:
- 0
|
楼主,QoS子系统中,有一个action就是mirror,不知道是不是拿来实现你这个功能的
- static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
- struct tcf_result *res)
- {
- struct tcf_mirred *m = a->priv;
- struct net_device *dev;
- struct sk_buff *skb2 = NULL;
- u32 at = G_TC_AT(skb->tc_verd);
- spin_lock(&m->tcf_lock);
- dev = m->tcfm_dev;
- m->tcf_tm.lastuse = jiffies;
- if (!(dev->flags&IFF_UP) ) {
- if (net_ratelimit())
- printk("mirred to Houston: device %s is gone!\n",
- dev->name);
- bad_mirred:
- if (skb2 != NULL)
- kfree_skb(skb2);
- m->tcf_qstats.overlimits++;
- m->tcf_bstats.bytes += qdisc_pkt_len(skb);
- m->tcf_bstats.packets++;
- spin_unlock(&m->tcf_lock);
- /* should we be asking for packet to be dropped?
- * may make sense for redirect case only
- */
- return TC_ACT_SHOT;
- }
- skb2 = skb_act_clone(skb, GFP_ATOMIC);
- if (skb2 == NULL)
- goto bad_mirred;
- if (m->tcfm_eaction != TCA_EGRESS_MIRROR &&
- m->tcfm_eaction != TCA_EGRESS_REDIR) {
- if (net_ratelimit())
- printk("tcf_mirred unknown action %d\n",
- m->tcfm_eaction);
- goto bad_mirred;
- }
- m->tcf_bstats.bytes += qdisc_pkt_len(skb2);
- m->tcf_bstats.packets++;
- if (!(at & AT_EGRESS))
- if (m->tcfm_ok_push)
- skb_push(skb2, skb2->dev->hard_header_len);
- /* mirror is always swallowed */
- if (m->tcfm_eaction != TCA_EGRESS_MIRROR)
- skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
- skb2->dev = dev;
- skb2->iif = skb->dev->ifindex;
- dev_queue_xmit(skb2);
- spin_unlock(&m->tcf_lock);
- return m->tcf_action;
- }
复制代码 |
|