#include <linux/rtnetlink.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <net/net_namespace.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <linux/tc_act/tc_mirred.h>
return 0;
}
-static int tcf_mirred_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
+ [TCA_MIRRED_PARMS] = { .len = sizeof(struct tc_mirred) },
+};
+
+static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
struct tc_action *a, int ovr, int bind)
{
- struct rtattr *tb[TCA_MIRRED_MAX];
+ struct nlattr *tb[TCA_MIRRED_MAX + 1];
struct tc_mirred *parm;
struct tcf_mirred *m;
struct tcf_common *pc;
struct net_device *dev = NULL;
- int ret = 0;
+ int ret = 0, err;
int ok_push = 0;
- if (rta == NULL || rtattr_parse_nested(tb, TCA_MIRRED_MAX, rta) < 0)
+ if (nla == NULL)
return -EINVAL;
- if (tb[TCA_MIRRED_PARMS-1] == NULL ||
- RTA_PAYLOAD(tb[TCA_MIRRED_PARMS-1]) < sizeof(*parm))
+ err = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[TCA_MIRRED_PARMS] == NULL)
return -EINVAL;
- parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
+ parm = nla_data(tb[TCA_MIRRED_PARMS]);
if (parm->ifindex) {
- dev = __dev_get_by_index(parm->ifindex);
+ dev = __dev_get_by_index(&init_net, parm->ifindex);
if (dev == NULL)
return -ENODEV;
switch (dev->type) {
return TC_ACT_SHOT;
}
- skb2 = skb_clone(skb, GFP_ATOMIC);
+ skb2 = skb_act_clone(skb, GFP_ATOMIC);
if (skb2 == NULL)
goto bad_mirred;
if (m->tcfm_eaction != TCA_EGRESS_MIRROR &&
opt.bindcnt = m->tcf_bindcnt - bind;
opt.eaction = m->tcfm_eaction;
opt.ifindex = m->tcfm_ifindex;
- RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
+ NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(m->tcf_tm.expires);
- RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
+ NLA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
return skb->len;
-rtattr_failure:
+nla_put_failure:
nlmsg_trim(skb, b);
return -1;
}