unsigned int            datalen;
        u16                     matchid;
        u16                     flags;
+       struct net              *net;
 };
 
 static inline int tcf_em_is_container(struct tcf_ematch *em)
 struct tcf_ematch_ops {
        int                     kind;
        int                     datalen;
-       int                     (*change)(struct tcf_proto *, void *,
+       int                     (*change)(struct net *net, void *,
                                          int, struct tcf_ematch *);
        int                     (*match)(struct sk_buff *, struct tcf_ematch *,
                                         struct tcf_pkt_info *);
-       void                    (*destroy)(struct tcf_proto *,
-                                          struct tcf_ematch *);
+       void                    (*destroy)(struct tcf_ematch *);
        int                     (*dump)(struct sk_buff *, struct tcf_ematch *);
        struct module           *owner;
        struct list_head        link;
 void tcf_em_unregister(struct tcf_ematch_ops *);
 int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
                         struct tcf_ematch_tree *);
-void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
+void tcf_em_tree_destroy(struct tcf_ematch_tree *);
 int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
 int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
                        struct tcf_pkt_info *);
 };
 
 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
-#define tcf_em_tree_destroy(tp, t) do { (void)(t); } while(0)
+#define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
 #define tcf_em_tree_dump(skb, t, tlv) (0)
 #define tcf_em_tree_change(tp, dst, src) do { } while(0)
 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
 
 
        tcf_unbind_filter(tp, &f->res);
        tcf_exts_destroy(&f->exts);
-       tcf_em_tree_destroy(tp, &f->ematches);
+       tcf_em_tree_destroy(&f->ematches);
        kfree(f);
 }
 
 
                                                    rcu);
 
        tcf_exts_destroy(&head->exts);
-       tcf_em_tree_destroy(head->tp, &head->ematches);
+       tcf_em_tree_destroy(&head->ematches);
        kfree(head);
 }
 
 
        if (head) {
                tcf_exts_destroy(&head->exts);
-               tcf_em_tree_destroy(tp, &head->ematches);
+               tcf_em_tree_destroy(&head->ematches);
                RCU_INIT_POINTER(tp->root, NULL);
                kfree_rcu(head, rcu);
        }
 
 
        del_timer_sync(&f->perturb_timer);
        tcf_exts_destroy(&f->exts);
-       tcf_em_tree_destroy(f->tp, &f->ematches);
+       tcf_em_tree_destroy(&f->ematches);
        kfree(f);
 }
 
        return 0;
 
 err2:
-       tcf_em_tree_destroy(tp, &t);
+       tcf_em_tree_destroy(&t);
        kfree(fnew);
 err1:
        tcf_exts_destroy(&e);
 
        return match;
 }
 
-static int em_canid_change(struct tcf_proto *tp, void *data, int len,
+static int em_canid_change(struct net *net, void *data, int len,
                          struct tcf_ematch *m)
 {
        struct can_filter *conf = data; /* Array with rules */
        return 0;
 }
 
-static void em_canid_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_canid_destroy(struct tcf_ematch *m)
 {
        struct canid_match *cm = em_canid_priv(m);
 
 
 #include <net/ip.h>
 #include <net/pkt_cls.h>
 
-static int em_ipset_change(struct tcf_proto *tp, void *data, int data_len,
+static int em_ipset_change(struct net *net, void *data, int data_len,
                           struct tcf_ematch *em)
 {
        struct xt_set_info *set = data;
        ip_set_id_t index;
-       struct net *net = dev_net(qdisc_dev(tp->q));
 
        if (data_len != sizeof(*set))
                return -EINVAL;
        return -ENOMEM;
 }
 
-static void em_ipset_destroy(struct tcf_proto *p, struct tcf_ematch *em)
+static void em_ipset_destroy(struct tcf_ematch *em)
 {
        const struct xt_set_info *set = (const void *) em->data;
        if (set) {
-               ip_set_nfnl_put(dev_net(qdisc_dev(p->q)), set->index);
+               ip_set_nfnl_put(em->net, set->index);
                kfree((void *) em->data);
        }
 }
 
        [TCA_EM_META_HDR]       = { .len = sizeof(struct tcf_meta_hdr) },
 };
 
-static int em_meta_change(struct tcf_proto *tp, void *data, int len,
+static int em_meta_change(struct net *net, void *data, int len,
                          struct tcf_ematch *m)
 {
        int err;
        return err;
 }
 
-static void em_meta_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_meta_destroy(struct tcf_ematch *m)
 {
        if (m)
                meta_delete((struct meta_match *) m->data);
 
        char                    pattern[0];
 };
 
-static int em_nbyte_change(struct tcf_proto *tp, void *data, int data_len,
+static int em_nbyte_change(struct net *net, void *data, int data_len,
                           struct tcf_ematch *em)
 {
        struct tcf_em_nbyte *nbyte = data;
 
        return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX;
 }
 
-static int em_text_change(struct tcf_proto *tp, void *data, int len,
+static int em_text_change(struct net *net, void *data, int len,
                          struct tcf_ematch *m)
 {
        struct text_match *tm;
        return 0;
 }
 
-static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+static void em_text_destroy(struct tcf_ematch *m)
 {
        if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config)
                textsearch_destroy(EM_TEXT_PRIV(m)->config);
 
        struct tcf_ematch_hdr *em_hdr = nla_data(nla);
        int data_len = nla_len(nla) - sizeof(*em_hdr);
        void *data = (void *) em_hdr + sizeof(*em_hdr);
+       struct net *net = dev_net(qdisc_dev(tp->q));
 
        if (!TCF_EM_REL_VALID(em_hdr->flags))
                goto errout;
                        goto errout;
 
                if (em->ops->change) {
-                       err = em->ops->change(tp, data, data_len, em);
+                       err = em->ops->change(net, data, data_len, em);
                        if (err < 0)
                                goto errout;
                } else if (data_len > 0) {
        em->matchid = em_hdr->matchid;
        em->flags = em_hdr->flags;
        em->datalen = data_len;
+       em->net = net;
 
        err = 0;
 errout:
        return err;
 
 errout_abort:
-       tcf_em_tree_destroy(tp, tree);
+       tcf_em_tree_destroy(tree);
        return err;
 }
 EXPORT_SYMBOL(tcf_em_tree_validate);
  * tcf_em_tree_validate()/tcf_em_tree_change(). You must ensure that
  * the ematch tree is not in use before calling this function.
  */
-void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
+void tcf_em_tree_destroy(struct tcf_ematch_tree *tree)
 {
        int i;
 
 
                if (em->ops) {
                        if (em->ops->destroy)
-                               em->ops->destroy(tp, em);
+                               em->ops->destroy(em);
                        else if (!tcf_em_is_simple(em))
                                kfree((void *) em->data);
                        module_put(em->ops->owner);