OSDN Git Service

ipmr, ip6mr: Make mfc_cache a common structure
authorYuval Mintz <yuvalm@mellanox.com>
Wed, 28 Feb 2018 21:29:34 +0000 (23:29 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 1 Mar 2018 18:13:23 +0000 (13:13 -0500)
mfc_cache and mfc6_cache are almost identical - the main difference is
in the origin/group addresses and comparison-key. Make a common
structure encapsulating most of the multicast routing logic  - mr_mfc
and convert both ipmr and ip6mr into using it.

For easy conversion [casting, in this case] mr_mfc has to be the first
field inside every multicast routing abstraction utilizing it.

Signed-off-by: Yuval Mintz <yuvalm@mellanox.com>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
include/linux/mroute.h
include/linux/mroute6.h
include/linux/mroute_base.h
net/ipv4/ipmr.c
net/ipv6/ip6mr.c

index d20b143..978a3c7 100644 (file)
@@ -126,8 +126,8 @@ mlxsw_sp_mr_route_ivif_in_evifs(const struct mlxsw_sp_mr_route *mr_route)
 
        switch (mr_route->mr_table->proto) {
        case MLXSW_SP_L3_PROTO_IPV4:
-               ivif = mr_route->mfc4->mfc_parent;
-               return mr_route->mfc4->mfc_un.res.ttls[ivif] != 255;
+               ivif = mr_route->mfc4->_c.mfc_parent;
+               return mr_route->mfc4->_c.mfc_un.res.ttls[ivif] != 255;
        case MLXSW_SP_L3_PROTO_IPV6:
                /* fall through */
        default:
@@ -364,7 +364,7 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
        mr_route->mfc4 = mfc;
        mr_route->mr_table = mr_table;
        for (i = 0; i < MAXVIFS; i++) {
-               if (mfc->mfc_un.res.ttls[i] != 255) {
+               if (mfc->_c.mfc_un.res.ttls[i] != 255) {
                        err = mlxsw_sp_mr_route_evif_link(mr_route,
                                                          &mr_table->vifs[i]);
                        if (err)
@@ -374,7 +374,8 @@ mlxsw_sp_mr_route4_create(struct mlxsw_sp_mr_table *mr_table,
                                mr_route->min_mtu = mr_table->vifs[i].dev->mtu;
                }
        }
-       mlxsw_sp_mr_route_ivif_link(mr_route, &mr_table->vifs[mfc->mfc_parent]);
+       mlxsw_sp_mr_route_ivif_link(mr_route,
+                                   &mr_table->vifs[mfc->_c.mfc_parent]);
 
        mr_route->route_action = mlxsw_sp_mr_route_action(mr_route);
        return mr_route;
@@ -418,9 +419,9 @@ static void mlxsw_sp_mr_mfc_offload_set(struct mlxsw_sp_mr_route *mr_route,
        switch (mr_route->mr_table->proto) {
        case MLXSW_SP_L3_PROTO_IPV4:
                if (offload)
-                       mr_route->mfc4->mfc_flags |= MFC_OFFLOAD;
+                       mr_route->mfc4->_c.mfc_flags |= MFC_OFFLOAD;
                else
-                       mr_route->mfc4->mfc_flags &= ~MFC_OFFLOAD;
+                       mr_route->mfc4->_c.mfc_flags &= ~MFC_OFFLOAD;
                break;
        case MLXSW_SP_L3_PROTO_IPV6:
                /* fall through */
@@ -943,10 +944,10 @@ static void mlxsw_sp_mr_route_stats_update(struct mlxsw_sp *mlxsw_sp,
 
        switch (mr_route->mr_table->proto) {
        case MLXSW_SP_L3_PROTO_IPV4:
-               if (mr_route->mfc4->mfc_un.res.pkt != packets)
-                       mr_route->mfc4->mfc_un.res.lastuse = jiffies;
-               mr_route->mfc4->mfc_un.res.pkt = packets;
-               mr_route->mfc4->mfc_un.res.bytes = bytes;
+               if (mr_route->mfc4->_c.mfc_un.res.pkt != packets)
+                       mr_route->mfc4->_c.mfc_un.res.lastuse = jiffies;
+               mr_route->mfc4->_c.mfc_un.res.pkt = packets;
+               mr_route->mfc4->_c.mfc_un.res.bytes = bytes;
                break;
        case MLXSW_SP_L3_PROTO_IPV6:
                /* fall through */
index 8688c5d..63b36e6 100644 (file)
@@ -81,28 +81,13 @@ struct mfc_cache_cmp_arg {
 
 /**
  * struct mfc_cache - multicast routing entries
- * @mnode: rhashtable list
+ * @_c: Common multicast routing information; has to be first [for casting]
  * @mfc_mcastgrp: destination multicast group address
  * @mfc_origin: source address
  * @cmparg: used for rhashtable comparisons
- * @mfc_parent: source interface (iif)
- * @mfc_flags: entry flags
- * @expires: unresolved entry expire time
- * @unresolved: unresolved cached skbs
- * @last_assert: time of last assert
- * @minvif: minimum VIF id
- * @maxvif: maximum VIF id
- * @bytes: bytes that have passed for this entry
- * @pkt: packets that have passed for this entry
- * @wrong_if: number of wrong source interface hits
- * @lastuse: time of last use of the group (traffic or update)
- * @ttls: OIF TTL threshold array
- * @refcount: reference count for this entry
- * @list: global entry list
- * @rcu: used for entry destruction
  */
 struct mfc_cache {
-       struct rhlist_head mnode;
+       struct mr_mfc _c;
        union {
                struct {
                        __be32 mfc_mcastgrp;
@@ -110,28 +95,6 @@ struct mfc_cache {
                };
                struct mfc_cache_cmp_arg cmparg;
        };
-       vifi_t mfc_parent;
-       int mfc_flags;
-
-       union {
-               struct {
-                       unsigned long expires;
-                       struct sk_buff_head unresolved;
-               } unres;
-               struct {
-                       unsigned long last_assert;
-                       int minvif;
-                       int maxvif;
-                       unsigned long bytes;
-                       unsigned long pkt;
-                       unsigned long wrong_if;
-                       unsigned long lastuse;
-                       unsigned char ttls[MAXVIFS];
-                       refcount_t refcount;
-               } res;
-       } mfc_un;
-       struct list_head list;
-       struct rcu_head rcu;
 };
 
 struct mfc_entry_notifier_info {
@@ -155,12 +118,12 @@ static inline void ipmr_cache_free(struct mfc_cache *mfc_cache)
 
 static inline void ipmr_cache_put(struct mfc_cache *c)
 {
-       if (refcount_dec_and_test(&c->mfc_un.res.refcount))
+       if (refcount_dec_and_test(&c->_c.mfc_un.res.refcount))
                ipmr_cache_free(c);
 }
 static inline void ipmr_cache_hold(struct mfc_cache *c)
 {
-       refcount_inc(&c->mfc_un.res.refcount);
+       refcount_inc(&c->_c.mfc_un.res.refcount);
 }
 
 #endif
index d5c8dc1..6acf576 100644 (file)
@@ -71,7 +71,7 @@ struct mfc6_cache_cmp_arg {
 };
 
 struct mfc6_cache {
-       struct rhlist_head mnode;
+       struct mr_mfc _c;
        union {
                struct {
                        struct in6_addr mf6c_mcastgrp;
@@ -79,27 +79,6 @@ struct mfc6_cache {
                };
                struct mfc6_cache_cmp_arg cmparg;
        };
-       mifi_t mf6c_parent;                     /* Source interface             */
-       int mfc_flags;                          /* Flags on line                */
-
-       union {
-               struct {
-                       unsigned long expires;
-                       struct sk_buff_head unresolved; /* Unresolved buffers           */
-               } unres;
-               struct {
-                       unsigned long last_assert;
-                       int minvif;
-                       int maxvif;
-                       unsigned long bytes;
-                       unsigned long pkt;
-                       unsigned long wrong_if;
-                       unsigned long lastuse;
-                       unsigned char ttls[MAXMIFS];    /* TTL thresholds               */
-               } res;
-       } mfc_un;
-       struct list_head list;
-       struct rcu_head rcu;
 };
 
 #define MFC_STATIC             1
index 8053057..2769e2f 100644 (file)
@@ -45,6 +45,51 @@ struct vif_device {
 #define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev))
 
 /**
+ * struct mr_mfc - common multicast routing entries
+ * @mnode: rhashtable list
+ * @mfc_parent: source interface (iif)
+ * @mfc_flags: entry flags
+ * @expires: unresolved entry expire time
+ * @unresolved: unresolved cached skbs
+ * @last_assert: time of last assert
+ * @minvif: minimum VIF id
+ * @maxvif: maximum VIF id
+ * @bytes: bytes that have passed for this entry
+ * @pkt: packets that have passed for this entry
+ * @wrong_if: number of wrong source interface hits
+ * @lastuse: time of last use of the group (traffic or update)
+ * @ttls: OIF TTL threshold array
+ * @refcount: reference count for this entry
+ * @list: global entry list
+ * @rcu: used for entry destruction
+ */
+struct mr_mfc {
+       struct rhlist_head mnode;
+       unsigned short mfc_parent;
+       int mfc_flags;
+
+       union {
+               struct {
+                       unsigned long expires;
+                       struct sk_buff_head unresolved;
+               } unres;
+               struct {
+                       unsigned long last_assert;
+                       int minvif;
+                       int maxvif;
+                       unsigned long bytes;
+                       unsigned long pkt;
+                       unsigned long wrong_if;
+                       unsigned long lastuse;
+                       unsigned char ttls[MAXVIFS];
+                       refcount_t refcount;
+               } res;
+       } mfc_un;
+       struct list_head list;
+       struct rcu_head rcu;
+};
+
+/**
  * struct mr_table - a multicast routing table
  * @list: entry within a list of multicast routing tables
  * @net: net where this table belongs
index f213933..3f75150 100644 (file)
@@ -106,7 +106,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
 static int ipmr_cache_report(struct mr_table *mrt,
                             struct sk_buff *pkt, vifi_t vifi, int assert);
 static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
-                             struct mfc_cache *c, struct rtmsg *rtm);
+                             struct mr_mfc *c, struct rtmsg *rtm);
 static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
                                 int cmd);
 static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt);
@@ -343,7 +343,7 @@ static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
 }
 
 static const struct rhashtable_params ipmr_rht_params = {
-       .head_offset = offsetof(struct mfc_cache, mnode),
+       .head_offset = offsetof(struct mr_mfc, mnode),
        .key_offset = offsetof(struct mfc_cache, cmparg),
        .key_len = sizeof(struct mfc_cache_cmp_arg),
        .nelem_hint = 3,
@@ -752,14 +752,14 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify,
 
 static void ipmr_cache_free_rcu(struct rcu_head *head)
 {
-       struct mfc_cache *c = container_of(head, struct mfc_cache, rcu);
+       struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
 
-       kmem_cache_free(mrt_cachep, c);
+       kmem_cache_free(mrt_cachep, (struct mfc_cache *)c);
 }
 
 void ipmr_cache_free(struct mfc_cache *c)
 {
-       call_rcu(&c->rcu, ipmr_cache_free_rcu);
+       call_rcu(&c->_c.rcu, ipmr_cache_free_rcu);
 }
 EXPORT_SYMBOL(ipmr_cache_free);
 
@@ -774,7 +774,7 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
 
        atomic_dec(&mrt->cache_resolve_queue_len);
 
-       while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) {
+       while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved))) {
                if (ip_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = skb_pull(skb,
                                                        sizeof(struct iphdr));
@@ -798,9 +798,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
 static void ipmr_expire_process(struct timer_list *t)
 {
        struct mr_table *mrt = from_timer(mrt, t, ipmr_expire_timer);
-       unsigned long now;
+       struct mr_mfc *c, *next;
        unsigned long expires;
-       struct mfc_cache *c, *next;
+       unsigned long now;
 
        if (!spin_trylock(&mfc_unres_lock)) {
                mod_timer(&mrt->ipmr_expire_timer, jiffies+HZ/10);
@@ -822,8 +822,8 @@ static void ipmr_expire_process(struct timer_list *t)
                }
 
                list_del(&c->list);
-               mroute_netlink_event(mrt, c, RTM_DELROUTE);
-               ipmr_destroy_unres(mrt, c);
+               mroute_netlink_event(mrt, (struct mfc_cache *)c, RTM_DELROUTE);
+               ipmr_destroy_unres(mrt, (struct mfc_cache *)c);
        }
 
        if (!list_empty(&mrt->mfc_unres_queue))
@@ -834,7 +834,7 @@ out:
 }
 
 /* Fill oifs list. It is called under write locked mrt_lock. */
-static void ipmr_update_thresholds(struct mr_table *mrt, struct mfc_cache *cache,
+static void ipmr_update_thresholds(struct mr_table *mrt, struct mr_mfc *cache,
                                   unsigned char *ttls)
 {
        int vifi;
@@ -974,11 +974,11 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt,
                        .mfc_origin = origin
        };
        struct rhlist_head *tmp, *list;
-       struct mfc_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
-               return c;
+               return (struct mfc_cache *)c;
 
        return NULL;
 }
@@ -992,12 +992,12 @@ static struct mfc_cache *ipmr_cache_find_any_parent(struct mr_table *mrt,
                        .mfc_origin = htonl(INADDR_ANY)
        };
        struct rhlist_head *tmp, *list;
-       struct mfc_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
                if (c->mfc_un.res.ttls[vifi] < 255)
-                       return c;
+                       return (struct mfc_cache *)c;
 
        return NULL;
 }
@@ -1011,20 +1011,22 @@ static struct mfc_cache *ipmr_cache_find_any(struct mr_table *mrt,
                        .mfc_origin = htonl(INADDR_ANY)
        };
        struct rhlist_head *tmp, *list;
-       struct mfc_cache *c, *proxy;
+       struct mr_mfc *c;
 
        if (mcastgrp == htonl(INADDR_ANY))
                goto skip;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode) {
+               struct mfc_cache *proxy;
+
                if (c->mfc_un.res.ttls[vifi] < 255)
-                       return c;
+                       return (struct mfc_cache *)c;
 
                /* It's ok if the vifi is part of the static tree */
                proxy = ipmr_cache_find_any_parent(mrt, c->mfc_parent);
-               if (proxy && proxy->mfc_un.res.ttls[vifi] < 255)
-                       return c;
+               if (proxy && proxy->_c.mfc_un.res.ttls[vifi] < 255)
+                       return (struct mfc_cache *)c;
        }
 
 skip:
@@ -1041,12 +1043,12 @@ static struct mfc_cache *ipmr_cache_find_parent(struct mr_table *mrt,
                        .mfc_origin = origin,
        };
        struct rhlist_head *tmp, *list;
-       struct mfc_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ipmr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
                if (parent == -1 || parent == c->mfc_parent)
-                       return c;
+                       return (struct mfc_cache *)c;
 
        return NULL;
 }
@@ -1057,9 +1059,9 @@ static struct mfc_cache *ipmr_cache_alloc(void)
        struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
 
        if (c) {
-               c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
-               c->mfc_un.res.minvif = MAXVIFS;
-               refcount_set(&c->mfc_un.res.refcount, 1);
+               c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
+               c->_c.mfc_un.res.minvif = MAXVIFS;
+               refcount_set(&c->_c.mfc_un.res.refcount, 1);
        }
        return c;
 }
@@ -1069,8 +1071,8 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void)
        struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
 
        if (c) {
-               skb_queue_head_init(&c->mfc_un.unres.unresolved);
-               c->mfc_un.unres.expires = jiffies + 10*HZ;
+               skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
+               c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
        }
        return c;
 }
@@ -1083,12 +1085,13 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
        struct nlmsgerr *e;
 
        /* Play the pending entries through our router */
-       while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
+       while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
                if (ip_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = skb_pull(skb,
                                                        sizeof(struct iphdr));
 
-                       if (__ipmr_fill_mroute(mrt, skb, c, nlmsg_data(nlh)) > 0) {
+                       if (__ipmr_fill_mroute(mrt, skb, &c->_c,
+                                              nlmsg_data(nlh)) > 0) {
                                nlh->nlmsg_len = skb_tail_pointer(skb) -
                                                 (u8 *)nlh;
                        } else {
@@ -1196,7 +1199,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
        int err;
 
        spin_lock_bh(&mfc_unres_lock);
-       list_for_each_entry(c, &mrt->mfc_unres_queue, list) {
+       list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
                if (c->mfc_mcastgrp == iph->daddr &&
                    c->mfc_origin == iph->saddr) {
                        found = true;
@@ -1215,12 +1218,13 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
                }
 
                /* Fill in the new cache entry */
-               c->mfc_parent   = -1;
+               c->_c.mfc_parent = -1;
                c->mfc_origin   = iph->saddr;
                c->mfc_mcastgrp = iph->daddr;
 
                /* Reflect first query at mrouted. */
                err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE);
+
                if (err < 0) {
                        /* If the report failed throw the cache entry
                           out - Brad Parker
@@ -1233,15 +1237,16 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
                }
 
                atomic_inc(&mrt->cache_resolve_queue_len);
-               list_add(&c->list, &mrt->mfc_unres_queue);
+               list_add(&c->_c.list, &mrt->mfc_unres_queue);
                mroute_netlink_event(mrt, c, RTM_NEWROUTE);
 
                if (atomic_read(&mrt->cache_resolve_queue_len) == 1)
-                       mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires);
+                       mod_timer(&mrt->ipmr_expire_timer,
+                                 c->_c.mfc_un.unres.expires);
        }
 
        /* See if we can append the packet */
-       if (c->mfc_un.unres.unresolved.qlen > 3) {
+       if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
                kfree_skb(skb);
                err = -ENOBUFS;
        } else {
@@ -1249,7 +1254,7 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
                        skb->dev = dev;
                        skb->skb_iif = dev->ifindex;
                }
-               skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
+               skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
                err = 0;
        }
 
@@ -1271,8 +1276,8 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc, int parent)
        rcu_read_unlock();
        if (!c)
                return -ENOENT;
-       rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
-       list_del_rcu(&c->list);
+       rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ipmr_rht_params);
+       list_del_rcu(&c->_c.list);
        call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c, mrt->id);
        mroute_netlink_event(mrt, c, RTM_DELROUTE);
        ipmr_cache_put(c);
@@ -1284,6 +1289,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
                        struct mfcctl *mfc, int mrtsock, int parent)
 {
        struct mfc_cache *uc, *c;
+       struct mr_mfc *_uc;
        bool found;
        int ret;
 
@@ -1297,10 +1303,10 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
        rcu_read_unlock();
        if (c) {
                write_lock_bh(&mrt_lock);
-               c->mfc_parent = mfc->mfcc_parent;
-               ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls);
+               c->_c.mfc_parent = mfc->mfcc_parent;
+               ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
                if (!mrtsock)
-                       c->mfc_flags |= MFC_STATIC;
+                       c->_c.mfc_flags |= MFC_STATIC;
                write_unlock_bh(&mrt_lock);
                call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, c,
                                              mrt->id);
@@ -1318,28 +1324,29 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
 
        c->mfc_origin = mfc->mfcc_origin.s_addr;
        c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
-       c->mfc_parent = mfc->mfcc_parent;
-       ipmr_update_thresholds(mrt, c, mfc->mfcc_ttls);
+       c->_c.mfc_parent = mfc->mfcc_parent;
+       ipmr_update_thresholds(mrt, &c->_c, mfc->mfcc_ttls);
        if (!mrtsock)
-               c->mfc_flags |= MFC_STATIC;
+               c->_c.mfc_flags |= MFC_STATIC;
 
-       ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->mnode,
+       ret = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
                                  ipmr_rht_params);
        if (ret) {
                pr_err("ipmr: rhtable insert error %d\n", ret);
                ipmr_cache_free(c);
                return ret;
        }
-       list_add_tail_rcu(&c->list, &mrt->mfc_cache_list);
+       list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
        /* Check to see if we resolved a queued list. If so we
         * need to send on the frames and tidy up.
         */
        found = false;
        spin_lock_bh(&mfc_unres_lock);
-       list_for_each_entry(uc, &mrt->mfc_unres_queue, list) {
+       list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
+               uc = (struct mfc_cache *)_uc;
                if (uc->mfc_origin == c->mfc_origin &&
                    uc->mfc_mcastgrp == c->mfc_mcastgrp) {
-                       list_del(&uc->list);
+                       list_del(&_uc->list);
                        atomic_dec(&mrt->cache_resolve_queue_len);
                        found = true;
                        break;
@@ -1362,7 +1369,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
 static void mroute_clean_tables(struct mr_table *mrt, bool all)
 {
        struct net *net = read_pnet(&mrt->net);
-       struct mfc_cache *c, *tmp;
+       struct mr_mfc *c, *tmp;
+       struct mfc_cache *cache;
        LIST_HEAD(list);
        int i;
 
@@ -1380,18 +1388,20 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
                        continue;
                rhltable_remove(&mrt->mfc_hash, &c->mnode, ipmr_rht_params);
                list_del_rcu(&c->list);
-               call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, c,
+               cache = (struct mfc_cache *)c;
+               call_ipmr_mfc_entry_notifiers(net, FIB_EVENT_ENTRY_DEL, cache,
                                              mrt->id);
-               mroute_netlink_event(mrt, c, RTM_DELROUTE);
-               ipmr_cache_put(c);
+               mroute_netlink_event(mrt, cache, RTM_DELROUTE);
+               ipmr_cache_put(cache);
        }
 
        if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
                spin_lock_bh(&mfc_unres_lock);
                list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
                        list_del(&c->list);
-                       mroute_netlink_event(mrt, c, RTM_DELROUTE);
-                       ipmr_destroy_unres(mrt, c);
+                       cache = (struct mfc_cache *)c;
+                       mroute_netlink_event(mrt, cache, RTM_DELROUTE);
+                       ipmr_destroy_unres(mrt, cache);
                }
                spin_unlock_bh(&mfc_unres_lock);
        }
@@ -1683,9 +1693,9 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
                rcu_read_lock();
                c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
                if (c) {
-                       sr.pktcnt = c->mfc_un.res.pkt;
-                       sr.bytecnt = c->mfc_un.res.bytes;
-                       sr.wrong_if = c->mfc_un.res.wrong_if;
+                       sr.pktcnt = c->_c.mfc_un.res.pkt;
+                       sr.bytecnt = c->_c.mfc_un.res.bytes;
+                       sr.wrong_if = c->_c.mfc_un.res.wrong_if;
                        rcu_read_unlock();
 
                        if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -1757,9 +1767,9 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
                rcu_read_lock();
                c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr);
                if (c) {
-                       sr.pktcnt = c->mfc_un.res.pkt;
-                       sr.bytecnt = c->mfc_un.res.bytes;
-                       sr.wrong_if = c->mfc_un.res.wrong_if;
+                       sr.pktcnt = c->_c.mfc_un.res.pkt;
+                       sr.bytecnt = c->_c.mfc_un.res.bytes;
+                       sr.wrong_if = c->_c.mfc_un.res.wrong_if;
                        rcu_read_unlock();
 
                        if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -1983,18 +1993,18 @@ static int ipmr_find_vif(struct mr_table *mrt, struct net_device *dev)
 /* "local" means that we should preserve one skb (for local delivery) */
 static void ip_mr_forward(struct net *net, struct mr_table *mrt,
                          struct net_device *dev, struct sk_buff *skb,
-                         struct mfc_cache *cache, int local)
+                         struct mfc_cache *c, int local)
 {
        int true_vifi = ipmr_find_vif(mrt, dev);
        int psend = -1;
        int vif, ct;
 
-       vif = cache->mfc_parent;
-       cache->mfc_un.res.pkt++;
-       cache->mfc_un.res.bytes += skb->len;
-       cache->mfc_un.res.lastuse = jiffies;
+       vif = c->_c.mfc_parent;
+       c->_c.mfc_un.res.pkt++;
+       c->_c.mfc_un.res.bytes += skb->len;
+       c->_c.mfc_un.res.lastuse = jiffies;
 
-       if (cache->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
+       if (c->mfc_origin == htonl(INADDR_ANY) && true_vifi >= 0) {
                struct mfc_cache *cache_proxy;
 
                /* For an (*,G) entry, we only check that the incomming
@@ -2002,7 +2012,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
                 */
                cache_proxy = ipmr_cache_find_any_parent(mrt, vif);
                if (cache_proxy &&
-                   cache_proxy->mfc_un.res.ttls[true_vifi] < 255)
+                   cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255)
                        goto forward;
        }
 
@@ -2023,7 +2033,7 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
                        goto dont_forward;
                }
 
-               cache->mfc_un.res.wrong_if++;
+               c->_c.mfc_un.res.wrong_if++;
 
                if (true_vifi >= 0 && mrt->mroute_do_assert &&
                    /* pimsm uses asserts, when switching from RPT to SPT,
@@ -2032,10 +2042,11 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
                     * large chunk of pimd to kernel. Ough... --ANK
                     */
                    (mrt->mroute_do_pim ||
-                    cache->mfc_un.res.ttls[true_vifi] < 255) &&
+                    c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
                    time_after(jiffies,
-                              cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
-                       cache->mfc_un.res.last_assert = jiffies;
+                              c->_c.mfc_un.res.last_assert +
+                              MFC_ASSERT_THRESH)) {
+                       c->_c.mfc_un.res.last_assert = jiffies;
                        ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF);
                }
                goto dont_forward;
@@ -2046,33 +2057,33 @@ forward:
        mrt->vif_table[vif].bytes_in += skb->len;
 
        /* Forward the frame */
-       if (cache->mfc_origin == htonl(INADDR_ANY) &&
-           cache->mfc_mcastgrp == htonl(INADDR_ANY)) {
+       if (c->mfc_origin == htonl(INADDR_ANY) &&
+           c->mfc_mcastgrp == htonl(INADDR_ANY)) {
                if (true_vifi >= 0 &&
-                   true_vifi != cache->mfc_parent &&
+                   true_vifi != c->_c.mfc_parent &&
                    ip_hdr(skb)->ttl >
-                               cache->mfc_un.res.ttls[cache->mfc_parent]) {
+                               c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
                        /* It's an (*,*) entry and the packet is not coming from
                         * the upstream: forward the packet to the upstream
                         * only.
                         */
-                       psend = cache->mfc_parent;
+                       psend = c->_c.mfc_parent;
                        goto last_forward;
                }
                goto dont_forward;
        }
-       for (ct = cache->mfc_un.res.maxvif - 1;
-            ct >= cache->mfc_un.res.minvif; ct--) {
+       for (ct = c->_c.mfc_un.res.maxvif - 1;
+            ct >= c->_c.mfc_un.res.minvif; ct--) {
                /* For (*,G) entry, don't forward to the incoming interface */
-               if ((cache->mfc_origin != htonl(INADDR_ANY) ||
+               if ((c->mfc_origin != htonl(INADDR_ANY) ||
                     ct != true_vifi) &&
-                   ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
+                   ip_hdr(skb)->ttl > c->_c.mfc_un.res.ttls[ct]) {
                        if (psend != -1) {
                                struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 
                                if (skb2)
                                        ipmr_queue_xmit(net, mrt, true_vifi,
-                                                       skb2, cache, psend);
+                                                       skb2, c, psend);
                        }
                        psend = ct;
                }
@@ -2084,9 +2095,9 @@ last_forward:
 
                        if (skb2)
                                ipmr_queue_xmit(net, mrt, true_vifi, skb2,
-                                               cache, psend);
+                                               c, psend);
                } else {
-                       ipmr_queue_xmit(net, mrt, true_vifi, skb, cache, psend);
+                       ipmr_queue_xmit(net, mrt, true_vifi, skb, c, psend);
                        return;
                }
        }
@@ -2285,7 +2296,7 @@ drop:
 #endif
 
 static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
-                             struct mfc_cache *c, struct rtmsg *rtm)
+                             struct mr_mfc *c, struct rtmsg *rtm)
 {
        struct rta_mfc_stats mfcs;
        struct nlattr *mp_attr;
@@ -2401,7 +2412,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
        }
 
        read_lock(&mrt_lock);
-       err = __ipmr_fill_mroute(mrt, skb, cache, rtm);
+       err = __ipmr_fill_mroute(mrt, skb, &cache->_c, rtm);
        read_unlock(&mrt_lock);
        rcu_read_unlock();
        return err;
@@ -2429,7 +2440,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
                goto nla_put_failure;
        rtm->rtm_type     = RTN_MULTICAST;
        rtm->rtm_scope    = RT_SCOPE_UNIVERSE;
-       if (c->mfc_flags & MFC_STATIC)
+       if (c->_c.mfc_flags & MFC_STATIC)
                rtm->rtm_protocol = RTPROT_STATIC;
        else
                rtm->rtm_protocol = RTPROT_MROUTED;
@@ -2438,7 +2449,7 @@ static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
        if (nla_put_in_addr(skb, RTA_SRC, c->mfc_origin) ||
            nla_put_in_addr(skb, RTA_DST, c->mfc_mcastgrp))
                goto nla_put_failure;
-       err = __ipmr_fill_mroute(mrt, skb, c, rtm);
+       err = __ipmr_fill_mroute(mrt, skb, &c->_c, rtm);
        /* do not break the dump if cache is unresolved */
        if (err < 0 && err != -ENOENT)
                goto nla_put_failure;
@@ -2479,7 +2490,8 @@ static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(mroute_msgsize(mfc->mfc_parent >= MAXVIFS, mrt->maxvif),
+       skb = nlmsg_new(mroute_msgsize(mfc->_c.mfc_parent >= MAXVIFS,
+                                      mrt->maxvif),
                        GFP_ATOMIC);
        if (!skb)
                goto errout;
@@ -2624,10 +2636,10 @@ errout_free:
 static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct net *net = sock_net(skb->sk);
-       struct mr_table *mrt;
-       struct mfc_cache *mfc;
        unsigned int t = 0, s_t;
        unsigned int e = 0, s_e;
+       struct mr_table *mrt;
+       struct mr_mfc *mfc;
 
        s_t = cb->args[0];
        s_e = cb->args[1];
@@ -2642,8 +2654,8 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
                        if (ipmr_fill_mroute(mrt, skb,
                                             NETLINK_CB(cb->skb).portid,
                                             cb->nlh->nlmsg_seq,
-                                            mfc, RTM_NEWROUTE,
-                                            NLM_F_MULTI) < 0)
+                                            (struct mfc_cache *)mfc,
+                                            RTM_NEWROUTE, NLM_F_MULTI) < 0)
                                goto done;
 next_entry:
                        e++;
@@ -2658,8 +2670,8 @@ next_entry:
                        if (ipmr_fill_mroute(mrt, skb,
                                             NETLINK_CB(cb->skb).portid,
                                             cb->nlh->nlmsg_seq,
-                                            mfc, RTM_NEWROUTE,
-                                            NLM_F_MULTI) < 0) {
+                                            (struct mfc_cache *)mfc,
+                                            RTM_NEWROUTE, NLM_F_MULTI) < 0) {
                                spin_unlock_bh(&mfc_unres_lock);
                                goto done;
                        }
@@ -3051,20 +3063,21 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
                                          struct ipmr_mfc_iter *it, loff_t pos)
 {
        struct mr_table *mrt = it->mrt;
-       struct mfc_cache *mfc;
+       struct mr_mfc *mfc;
 
        rcu_read_lock();
        it->cache = &mrt->mfc_cache_list;
        list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
                if (pos-- == 0)
-                       return mfc;
+                       return (struct mfc_cache *)mfc;
        rcu_read_unlock();
 
        spin_lock_bh(&mfc_unres_lock);
        it->cache = &mrt->mfc_unres_queue;
        list_for_each_entry(mfc, it->cache, list)
                if (pos-- == 0)
-                       return mfc;
+                       return (struct mfc_cache *)mfc;
+
        spin_unlock_bh(&mfc_unres_lock);
 
        it->cache = NULL;
@@ -3100,8 +3113,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        if (v == SEQ_START_TOKEN)
                return ipmr_mfc_seq_idx(net, seq->private, 0);
 
-       if (mfc->list.next != it->cache)
-               return list_entry(mfc->list.next, struct mfc_cache, list);
+       if (mfc->_c.list.next != it->cache)
+               return (struct mfc_cache *)(list_entry(mfc->_c.list.next,
+                                                      struct mr_mfc, list));
 
        if (it->cache == &mrt->mfc_unres_queue)
                goto end_of_list;
@@ -3112,7 +3126,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
        spin_lock_bh(&mfc_unres_lock);
        if (!list_empty(it->cache))
-               return list_first_entry(it->cache, struct mfc_cache, list);
+               return (struct mfc_cache *)(list_first_entry(it->cache,
+                                                            struct mr_mfc,
+                                                            list));
 
 end_of_list:
        spin_unlock_bh(&mfc_unres_lock);
@@ -3147,20 +3163,20 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
                seq_printf(seq, "%08X %08X %-3hd",
                           (__force u32) mfc->mfc_mcastgrp,
                           (__force u32) mfc->mfc_origin,
-                          mfc->mfc_parent);
+                          mfc->_c.mfc_parent);
 
                if (it->cache != &mrt->mfc_unres_queue) {
                        seq_printf(seq, " %8lu %8lu %8lu",
-                                  mfc->mfc_un.res.pkt,
-                                  mfc->mfc_un.res.bytes,
-                                  mfc->mfc_un.res.wrong_if);
-                       for (n = mfc->mfc_un.res.minvif;
-                            n < mfc->mfc_un.res.maxvif; n++) {
+                                  mfc->_c.mfc_un.res.pkt,
+                                  mfc->_c.mfc_un.res.bytes,
+                                  mfc->_c.mfc_un.res.wrong_if);
+                       for (n = mfc->_c.mfc_un.res.minvif;
+                            n < mfc->_c.mfc_un.res.maxvif; n++) {
                                if (VIF_EXISTS(mrt, n) &&
-                                   mfc->mfc_un.res.ttls[n] < 255)
+                                   mfc->_c.mfc_un.res.ttls[n] < 255)
                                        seq_printf(seq,
                                           " %2d:%-3d",
-                                          n, mfc->mfc_un.res.ttls[n]);
+                                          n, mfc->_c.mfc_un.res.ttls[n]);
                        }
                } else {
                        /* unresolved mfc_caches don't contain
@@ -3219,7 +3235,7 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
 
        ipmr_for_each_table(mrt, net) {
                struct vif_device *v = &mrt->vif_table[0];
-               struct mfc_cache *mfc;
+               struct mr_mfc *mfc;
                int vifi;
 
                /* Notifiy on table VIF entries */
@@ -3236,7 +3252,8 @@ static int ipmr_dump(struct net *net, struct notifier_block *nb)
                /* Notify on table MFC entries */
                list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
                        call_ipmr_mfc_entry_notifier(nb, net,
-                                                    FIB_EVENT_ENTRY_ADD, mfc,
+                                                    FIB_EVENT_ENTRY_ADD,
+                                                    (struct mfc_cache *)mfc,
                                                     mrt->id);
        }
 
index d508528..3fe254f 100644 (file)
@@ -285,7 +285,7 @@ static int ip6mr_hash_cmp(struct rhashtable_compare_arg *arg,
 }
 
 static const struct rhashtable_params ip6mr_rht_params = {
-       .head_offset = offsetof(struct mfc6_cache, mnode),
+       .head_offset = offsetof(struct mr_mfc, mnode),
        .key_offset = offsetof(struct mfc6_cache, cmparg),
        .key_len = sizeof(struct mfc6_cache_cmp_arg),
        .nelem_hint = 3,
@@ -335,20 +335,20 @@ static struct mfc6_cache *ipmr_mfc_seq_idx(struct net *net,
                                           struct ipmr_mfc_iter *it, loff_t pos)
 {
        struct mr_table *mrt = it->mrt;
-       struct mfc6_cache *mfc;
+       struct mr_mfc *mfc;
 
        rcu_read_lock();
        it->cache = &mrt->mfc_cache_list;
        list_for_each_entry_rcu(mfc, &mrt->mfc_cache_list, list)
                if (pos-- == 0)
-                       return mfc;
+                       return (struct mfc6_cache *)mfc;
        rcu_read_unlock();
 
        spin_lock_bh(&mfc_unres_lock);
        it->cache = &mrt->mfc_unres_queue;
        list_for_each_entry(mfc, it->cache, list)
                if (pos-- == 0)
-                       return mfc;
+                       return (struct mfc6_cache *)mfc;
        spin_unlock_bh(&mfc_unres_lock);
 
        it->cache = NULL;
@@ -492,8 +492,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        if (v == SEQ_START_TOKEN)
                return ipmr_mfc_seq_idx(net, seq->private, 0);
 
-       if (mfc->list.next != it->cache)
-               return list_entry(mfc->list.next, struct mfc6_cache, list);
+       if (mfc->_c.list.next != it->cache)
+               return (struct mfc6_cache *)(list_entry(mfc->_c.list.next,
+                                                       struct mr_mfc, list));
 
        if (it->cache == &mrt->mfc_unres_queue)
                goto end_of_list;
@@ -504,7 +505,9 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
        spin_lock_bh(&mfc_unres_lock);
        if (!list_empty(it->cache))
-               return list_first_entry(it->cache, struct mfc6_cache, list);
+               return (struct mfc6_cache *)(list_first_entry(it->cache,
+                                                             struct mr_mfc,
+                                                             list));
 
  end_of_list:
        spin_unlock_bh(&mfc_unres_lock);
@@ -540,20 +543,20 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
 
                seq_printf(seq, "%pI6 %pI6 %-3hd",
                           &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
-                          mfc->mf6c_parent);
+                          mfc->_c.mfc_parent);
 
                if (it->cache != &mrt->mfc_unres_queue) {
                        seq_printf(seq, " %8lu %8lu %8lu",
-                                  mfc->mfc_un.res.pkt,
-                                  mfc->mfc_un.res.bytes,
-                                  mfc->mfc_un.res.wrong_if);
-                       for (n = mfc->mfc_un.res.minvif;
-                            n < mfc->mfc_un.res.maxvif; n++) {
+                                  mfc->_c.mfc_un.res.pkt,
+                                  mfc->_c.mfc_un.res.bytes,
+                                  mfc->_c.mfc_un.res.wrong_if);
+                       for (n = mfc->_c.mfc_un.res.minvif;
+                            n < mfc->_c.mfc_un.res.maxvif; n++) {
                                if (VIF_EXISTS(mrt, n) &&
-                                   mfc->mfc_un.res.ttls[n] < 255)
+                                   mfc->_c.mfc_un.res.ttls[n] < 255)
                                        seq_printf(seq,
-                                                  " %2d:%-3d",
-                                                  n, mfc->mfc_un.res.ttls[n]);
+                                                  " %2d:%-3d", n,
+                                                  mfc->_c.mfc_un.res.ttls[n]);
                        }
                } else {
                        /* unresolved mfc_caches don't contain
@@ -800,14 +803,14 @@ static int mif6_delete(struct mr_table *mrt, int vifi, int notify,
 
 static inline void ip6mr_cache_free_rcu(struct rcu_head *head)
 {
-       struct mfc6_cache *c = container_of(head, struct mfc6_cache, rcu);
+       struct mr_mfc *c = container_of(head, struct mr_mfc, rcu);
 
-       kmem_cache_free(mrt_cachep, c);
+       kmem_cache_free(mrt_cachep, (struct mfc6_cache *)c);
 }
 
 static inline void ip6mr_cache_free(struct mfc6_cache *c)
 {
-       call_rcu(&c->rcu, ip6mr_cache_free_rcu);
+       call_rcu(&c->_c.rcu, ip6mr_cache_free_rcu);
 }
 
 /* Destroy an unresolved cache entry, killing queued skbs
@@ -821,7 +824,7 @@ static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
 
        atomic_dec(&mrt->cache_resolve_queue_len);
 
-       while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved)) != NULL) {
+       while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved)) != NULL) {
                if (ipv6_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = skb_pull(skb,
                                                        sizeof(struct ipv6hdr));
@@ -844,7 +847,7 @@ static void ipmr_do_expire_process(struct mr_table *mrt)
 {
        unsigned long now = jiffies;
        unsigned long expires = 10 * HZ;
-       struct mfc6_cache *c, *next;
+       struct mr_mfc *c, *next;
 
        list_for_each_entry_safe(c, next, &mrt->mfc_unres_queue, list) {
                if (time_after(c->mfc_un.unres.expires, now)) {
@@ -856,8 +859,8 @@ static void ipmr_do_expire_process(struct mr_table *mrt)
                }
 
                list_del(&c->list);
-               mr6_netlink_event(mrt, c, RTM_DELROUTE);
-               ip6mr_destroy_unres(mrt, c);
+               mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
+               ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
        }
 
        if (!list_empty(&mrt->mfc_unres_queue))
@@ -882,7 +885,7 @@ static void ipmr_expire_process(struct timer_list *t)
 /* Fill oifs list. It is called under write locked mrt_lock. */
 
 static void ip6mr_update_thresholds(struct mr_table *mrt,
-                                   struct mfc6_cache *cache,
+                                   struct mr_mfc *cache,
                                    unsigned char *ttls)
 {
        int vifi;
@@ -986,11 +989,11 @@ static struct mfc6_cache *ip6mr_cache_find(struct mr_table *mrt,
                .mf6c_mcastgrp = *mcastgrp,
        };
        struct rhlist_head *tmp, *list;
-       struct mfc6_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
-               return c;
+               return (struct mfc6_cache *)c;
 
        return NULL;
 }
@@ -1004,12 +1007,12 @@ static struct mfc6_cache *ip6mr_cache_find_any_parent(struct mr_table *mrt,
                .mf6c_mcastgrp = in6addr_any,
        };
        struct rhlist_head *tmp, *list;
-       struct mfc6_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
                if (c->mfc_un.res.ttls[mifi] < 255)
-                       return c;
+                       return (struct mfc6_cache *)c;
 
        return NULL;
 }
@@ -1024,7 +1027,8 @@ static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
                .mf6c_mcastgrp = *mcastgrp,
        };
        struct rhlist_head *tmp, *list;
-       struct mfc6_cache *c, *proxy;
+       struct mr_mfc *c;
+       struct mfc6_cache *proxy;
 
        if (ipv6_addr_any(mcastgrp))
                goto skip;
@@ -1032,12 +1036,12 @@ static struct mfc6_cache *ip6mr_cache_find_any(struct mr_table *mrt,
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode) {
                if (c->mfc_un.res.ttls[mifi] < 255)
-                       return c;
+                       return (struct mfc6_cache *)c;
 
                /* It's ok if the mifi is part of the static tree */
-               proxy = ip6mr_cache_find_any_parent(mrt, c->mf6c_parent);
-               if (proxy && proxy->mfc_un.res.ttls[mifi] < 255)
-                       return c;
+               proxy = ip6mr_cache_find_any_parent(mrt, c->mfc_parent);
+               if (proxy && proxy->_c.mfc_un.res.ttls[mifi] < 255)
+                       return (struct mfc6_cache *)c;
        }
 
 skip:
@@ -1056,12 +1060,12 @@ ip6mr_cache_find_parent(struct mr_table *mrt,
                .mf6c_mcastgrp = *mcastgrp,
        };
        struct rhlist_head *tmp, *list;
-       struct mfc6_cache *c;
+       struct mr_mfc *c;
 
        list = rhltable_lookup(&mrt->mfc_hash, &arg, ip6mr_rht_params);
        rhl_for_each_entry_rcu(c, tmp, list, mnode)
-               if (parent == -1 || parent == c->mf6c_parent)
-                       return c;
+               if (parent == -1 || parent == c->mfc_parent)
+                       return (struct mfc6_cache *)c;
 
        return NULL;
 }
@@ -1074,8 +1078,8 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
        struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
        if (!c)
                return NULL;
-       c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
-       c->mfc_un.res.minvif = MAXMIFS;
+       c->_c.mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
+       c->_c.mfc_un.res.minvif = MAXMIFS;
        return c;
 }
 
@@ -1084,8 +1088,8 @@ static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
        struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
        if (!c)
                return NULL;
-       skb_queue_head_init(&c->mfc_un.unres.unresolved);
-       c->mfc_un.unres.expires = jiffies + 10 * HZ;
+       skb_queue_head_init(&c->_c.mfc_un.unres.unresolved);
+       c->_c.mfc_un.unres.expires = jiffies + 10 * HZ;
        return c;
 }
 
@@ -1102,7 +1106,7 @@ static void ip6mr_cache_resolve(struct net *net, struct mr_table *mrt,
         *      Play the pending entries through our router
         */
 
-       while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
+       while ((skb = __skb_dequeue(&uc->_c.mfc_un.unres.unresolved))) {
                if (ipv6_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = skb_pull(skb,
                                                        sizeof(struct ipv6hdr));
@@ -1221,19 +1225,16 @@ static int ip6mr_cache_report(struct mr_table *mrt, struct sk_buff *pkt,
        return ret;
 }
 
-/*
- *     Queue a packet for resolution. It gets locked cache entry!
- */
-
-static int
-ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi, struct sk_buff *skb)
+/* Queue a packet for resolution. It gets locked cache entry! */
+static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
+                                 struct sk_buff *skb)
 {
+       struct mfc6_cache *c;
        bool found = false;
        int err;
-       struct mfc6_cache *c;
 
        spin_lock_bh(&mfc_unres_lock);
-       list_for_each_entry(c, &mrt->mfc_unres_queue, list) {
+       list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) {
                if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) &&
                    ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) {
                        found = true;
@@ -1254,10 +1255,8 @@ ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi, struct sk_buff *skb)
                        return -ENOBUFS;
                }
 
-               /*
-                *      Fill in the new cache entry
-                */
-               c->mf6c_parent = -1;
+               /* Fill in the new cache entry */
+               c->_c.mfc_parent = -1;
                c->mf6c_origin = ipv6_hdr(skb)->saddr;
                c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr;
 
@@ -1277,20 +1276,18 @@ ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi, struct sk_buff *skb)
                }
 
                atomic_inc(&mrt->cache_resolve_queue_len);
-               list_add(&c->list, &mrt->mfc_unres_queue);
+               list_add(&c->_c.list, &mrt->mfc_unres_queue);
                mr6_netlink_event(mrt, c, RTM_NEWROUTE);
 
                ipmr_do_expire_process(mrt);
        }
 
-       /*
-        *      See if we can append the packet
-        */
-       if (c->mfc_un.unres.unresolved.qlen > 3) {
+       /* See if we can append the packet */
+       if (c->_c.mfc_un.unres.unresolved.qlen > 3) {
                kfree_skb(skb);
                err = -ENOBUFS;
        } else {
-               skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
+               skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb);
                err = 0;
        }
 
@@ -1314,8 +1311,8 @@ static int ip6mr_mfc_delete(struct mr_table *mrt, struct mf6cctl *mfc,
        rcu_read_unlock();
        if (!c)
                return -ENOENT;
-       rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
-       list_del_rcu(&c->list);
+       rhltable_remove(&mrt->mfc_hash, &c->_c.mnode, ip6mr_rht_params);
+       list_del_rcu(&c->_c.list);
 
        mr6_netlink_event(mrt, c, RTM_DELROUTE);
        ip6mr_cache_free(c);
@@ -1454,6 +1451,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
 {
        unsigned char ttls[MAXMIFS];
        struct mfc6_cache *uc, *c;
+       struct mr_mfc *_uc;
        bool found;
        int i, err;
 
@@ -1473,10 +1471,10 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
        rcu_read_unlock();
        if (c) {
                write_lock_bh(&mrt_lock);
-               c->mf6c_parent = mfc->mf6cc_parent;
-               ip6mr_update_thresholds(mrt, c, ttls);
+               c->_c.mfc_parent = mfc->mf6cc_parent;
+               ip6mr_update_thresholds(mrt, &c->_c, ttls);
                if (!mrtsock)
-                       c->mfc_flags |= MFC_STATIC;
+                       c->_c.mfc_flags |= MFC_STATIC;
                write_unlock_bh(&mrt_lock);
                mr6_netlink_event(mrt, c, RTM_NEWROUTE);
                return 0;
@@ -1492,29 +1490,30 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
 
        c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
        c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
-       c->mf6c_parent = mfc->mf6cc_parent;
-       ip6mr_update_thresholds(mrt, c, ttls);
+       c->_c.mfc_parent = mfc->mf6cc_parent;
+       ip6mr_update_thresholds(mrt, &c->_c, ttls);
        if (!mrtsock)
-               c->mfc_flags |= MFC_STATIC;
+               c->_c.mfc_flags |= MFC_STATIC;
 
-       err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->mnode,
+       err = rhltable_insert_key(&mrt->mfc_hash, &c->cmparg, &c->_c.mnode,
                                  ip6mr_rht_params);
        if (err) {
                pr_err("ip6mr: rhtable insert error %d\n", err);
                ip6mr_cache_free(c);
                return err;
        }
-       list_add_tail_rcu(&c->list, &mrt->mfc_cache_list);
+       list_add_tail_rcu(&c->_c.list, &mrt->mfc_cache_list);
 
        /* Check to see if we resolved a queued list. If so we
         * need to send on the frames and tidy up.
         */
        found = false;
        spin_lock_bh(&mfc_unres_lock);
-       list_for_each_entry(uc, &mrt->mfc_unres_queue, list) {
+       list_for_each_entry(_uc, &mrt->mfc_unres_queue, list) {
+               uc = (struct mfc6_cache *)_uc;
                if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
                    ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
-                       list_del(&uc->list);
+                       list_del(&_uc->list);
                        atomic_dec(&mrt->cache_resolve_queue_len);
                        found = true;
                        break;
@@ -1538,7 +1537,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
 
 static void mroute_clean_tables(struct mr_table *mrt, bool all)
 {
-       struct mfc6_cache *c, *tmp;
+       struct mr_mfc *c, *tmp;
        LIST_HEAD(list);
        int i;
 
@@ -1556,16 +1555,17 @@ static void mroute_clean_tables(struct mr_table *mrt, bool all)
                        continue;
                rhltable_remove(&mrt->mfc_hash, &c->mnode, ip6mr_rht_params);
                list_del_rcu(&c->list);
-               mr6_netlink_event(mrt, c, RTM_DELROUTE);
-               ip6mr_cache_free(c);
+               mr6_netlink_event(mrt, (struct mfc6_cache *)c, RTM_DELROUTE);
+               ip6mr_cache_free((struct mfc6_cache *)c);
        }
 
        if (atomic_read(&mrt->cache_resolve_queue_len) != 0) {
                spin_lock_bh(&mfc_unres_lock);
                list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
                        list_del(&c->list);
-                       mr6_netlink_event(mrt, c, RTM_DELROUTE);
-                       ip6mr_destroy_unres(mrt, c);
+                       mr6_netlink_event(mrt, (struct mfc6_cache *)c,
+                                         RTM_DELROUTE);
+                       ip6mr_destroy_unres(mrt, (struct mfc6_cache *)c);
                }
                spin_unlock_bh(&mfc_unres_lock);
        }
@@ -1899,9 +1899,9 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
                rcu_read_lock();
                c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
                if (c) {
-                       sr.pktcnt = c->mfc_un.res.pkt;
-                       sr.bytecnt = c->mfc_un.res.bytes;
-                       sr.wrong_if = c->mfc_un.res.wrong_if;
+                       sr.pktcnt = c->_c.mfc_un.res.pkt;
+                       sr.bytecnt = c->_c.mfc_un.res.bytes;
+                       sr.wrong_if = c->_c.mfc_un.res.wrong_if;
                        rcu_read_unlock();
 
                        if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -1973,9 +1973,9 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
                rcu_read_lock();
                c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr);
                if (c) {
-                       sr.pktcnt = c->mfc_un.res.pkt;
-                       sr.bytecnt = c->mfc_un.res.bytes;
-                       sr.wrong_if = c->mfc_un.res.wrong_if;
+                       sr.pktcnt = c->_c.mfc_un.res.pkt;
+                       sr.bytecnt = c->_c.mfc_un.res.bytes;
+                       sr.wrong_if = c->_c.mfc_un.res.wrong_if;
                        rcu_read_unlock();
 
                        if (copy_to_user(arg, &sr, sizeof(sr)))
@@ -2089,18 +2089,18 @@ static int ip6mr_find_vif(struct mr_table *mrt, struct net_device *dev)
 }
 
 static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
-                          struct sk_buff *skb, struct mfc6_cache *cache)
+                          struct sk_buff *skb, struct mfc6_cache *c)
 {
        int psend = -1;
        int vif, ct;
        int true_vifi = ip6mr_find_vif(mrt, skb->dev);
 
-       vif = cache->mf6c_parent;
-       cache->mfc_un.res.pkt++;
-       cache->mfc_un.res.bytes += skb->len;
-       cache->mfc_un.res.lastuse = jiffies;
+       vif = c->_c.mfc_parent;
+       c->_c.mfc_un.res.pkt++;
+       c->_c.mfc_un.res.bytes += skb->len;
+       c->_c.mfc_un.res.lastuse = jiffies;
 
-       if (ipv6_addr_any(&cache->mf6c_origin) && true_vifi >= 0) {
+       if (ipv6_addr_any(&c->mf6c_origin) && true_vifi >= 0) {
                struct mfc6_cache *cache_proxy;
 
                /* For an (*,G) entry, we only check that the incoming
@@ -2109,7 +2109,7 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
                rcu_read_lock();
                cache_proxy = ip6mr_cache_find_any_parent(mrt, vif);
                if (cache_proxy &&
-                   cache_proxy->mfc_un.res.ttls[true_vifi] < 255) {
+                   cache_proxy->_c.mfc_un.res.ttls[true_vifi] < 255) {
                        rcu_read_unlock();
                        goto forward;
                }
@@ -2120,7 +2120,7 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
         * Wrong interface: drop packet and (maybe) send PIM assert.
         */
        if (mrt->vif_table[vif].dev != skb->dev) {
-               cache->mfc_un.res.wrong_if++;
+               c->_c.mfc_un.res.wrong_if++;
 
                if (true_vifi >= 0 && mrt->mroute_do_assert &&
                    /* pimsm uses asserts, when switching from RPT to SPT,
@@ -2129,10 +2129,11 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
                       large chunk of pimd to kernel. Ough... --ANK
                     */
                    (mrt->mroute_do_pim ||
-                    cache->mfc_un.res.ttls[true_vifi] < 255) &&
+                    c->_c.mfc_un.res.ttls[true_vifi] < 255) &&
                    time_after(jiffies,
-                              cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) {
-                       cache->mfc_un.res.last_assert = jiffies;
+                              c->_c.mfc_un.res.last_assert +
+                              MFC_ASSERT_THRESH)) {
+                       c->_c.mfc_un.res.last_assert = jiffies;
                        ip6mr_cache_report(mrt, skb, true_vifi, MRT6MSG_WRONGMIF);
                }
                goto dont_forward;
@@ -2145,36 +2146,38 @@ forward:
        /*
         *      Forward the frame
         */
-       if (ipv6_addr_any(&cache->mf6c_origin) &&
-           ipv6_addr_any(&cache->mf6c_mcastgrp)) {
+       if (ipv6_addr_any(&c->mf6c_origin) &&
+           ipv6_addr_any(&c->mf6c_mcastgrp)) {
                if (true_vifi >= 0 &&
-                   true_vifi != cache->mf6c_parent &&
+                   true_vifi != c->_c.mfc_parent &&
                    ipv6_hdr(skb)->hop_limit >
-                               cache->mfc_un.res.ttls[cache->mf6c_parent]) {
+                               c->_c.mfc_un.res.ttls[c->_c.mfc_parent]) {
                        /* It's an (*,*) entry and the packet is not coming from
                         * the upstream: forward the packet to the upstream
                         * only.
                         */
-                       psend = cache->mf6c_parent;
+                       psend = c->_c.mfc_parent;
                        goto last_forward;
                }
                goto dont_forward;
        }
-       for (ct = cache->mfc_un.res.maxvif - 1; ct >= cache->mfc_un.res.minvif; ct--) {
+       for (ct = c->_c.mfc_un.res.maxvif - 1;
+            ct >= c->_c.mfc_un.res.minvif; ct--) {
                /* For (*,G) entry, don't forward to the incoming interface */
-               if ((!ipv6_addr_any(&cache->mf6c_origin) || ct != true_vifi) &&
-                   ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) {
+               if ((!ipv6_addr_any(&c->mf6c_origin) || ct != true_vifi) &&
+                   ipv6_hdr(skb)->hop_limit > c->_c.mfc_un.res.ttls[ct]) {
                        if (psend != -1) {
                                struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (skb2)
-                                       ip6mr_forward2(net, mrt, skb2, cache, psend);
+                                       ip6mr_forward2(net, mrt, skb2,
+                                                      c, psend);
                        }
                        psend = ct;
                }
        }
 last_forward:
        if (psend != -1) {
-               ip6mr_forward2(net, mrt, skb, cache, psend);
+               ip6mr_forward2(net, mrt, skb, c, psend);
                return;
        }
 
@@ -2252,21 +2255,22 @@ static int __ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
        int ct;
 
        /* If cache is unresolved, don't try to parse IIF and OIF */
-       if (c->mf6c_parent >= MAXMIFS) {
+       if (c->_c.mfc_parent >= MAXMIFS) {
                rtm->rtm_flags |= RTNH_F_UNRESOLVED;
                return -ENOENT;
        }
 
-       if (VIF_EXISTS(mrt, c->mf6c_parent) &&
+       if (VIF_EXISTS(mrt, c->_c.mfc_parent) &&
            nla_put_u32(skb, RTA_IIF,
-                       mrt->vif_table[c->mf6c_parent].dev->ifindex) < 0)
+                       mrt->vif_table[c->_c.mfc_parent].dev->ifindex) < 0)
                return -EMSGSIZE;
        mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
        if (!mp_attr)
                return -EMSGSIZE;
 
-       for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
-               if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
+       for (ct = c->_c.mfc_un.res.minvif;
+            ct < c->_c.mfc_un.res.maxvif; ct++) {
+               if (VIF_EXISTS(mrt, ct) && c->_c.mfc_un.res.ttls[ct] < 255) {
                        nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
                        if (!nhp) {
                                nla_nest_cancel(skb, mp_attr);
@@ -2274,7 +2278,7 @@ static int __ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
                        }
 
                        nhp->rtnh_flags = 0;
-                       nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
+                       nhp->rtnh_hops = c->_c.mfc_un.res.ttls[ct];
                        nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex;
                        nhp->rtnh_len = sizeof(*nhp);
                }
@@ -2282,12 +2286,12 @@ static int __ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
 
        nla_nest_end(skb, mp_attr);
 
-       lastuse = READ_ONCE(c->mfc_un.res.lastuse);
+       lastuse = READ_ONCE(c->_c.mfc_un.res.lastuse);
        lastuse = time_after_eq(jiffies, lastuse) ? jiffies - lastuse : 0;
 
-       mfcs.mfcs_packets = c->mfc_un.res.pkt;
-       mfcs.mfcs_bytes = c->mfc_un.res.bytes;
-       mfcs.mfcs_wrong_if = c->mfc_un.res.wrong_if;
+       mfcs.mfcs_packets = c->_c.mfc_un.res.pkt;
+       mfcs.mfcs_bytes = c->_c.mfc_un.res.bytes;
+       mfcs.mfcs_wrong_if = c->_c.mfc_un.res.wrong_if;
        if (nla_put_64bit(skb, RTA_MFC_STATS, sizeof(mfcs), &mfcs, RTA_PAD) ||
            nla_put_u64_64bit(skb, RTA_EXPIRES, jiffies_to_clock_t(lastuse),
                              RTA_PAD))
@@ -2363,7 +2367,7 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,
        }
 
        if (rtm->rtm_flags & RTM_F_NOTIFY)
-               cache->mfc_flags |= MFC_NOTIFY;
+               cache->_c.mfc_flags |= MFC_NOTIFY;
 
        err = __ip6mr_fill_mroute(mrt, skb, cache, rtm);
        read_unlock(&mrt_lock);
@@ -2392,7 +2396,7 @@ static int ip6mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
                goto nla_put_failure;
        rtm->rtm_type = RTN_MULTICAST;
        rtm->rtm_scope    = RT_SCOPE_UNIVERSE;
-       if (c->mfc_flags & MFC_STATIC)
+       if (c->_c.mfc_flags & MFC_STATIC)
                rtm->rtm_protocol = RTPROT_STATIC;
        else
                rtm->rtm_protocol = RTPROT_MROUTED;
@@ -2442,7 +2446,7 @@ static void mr6_netlink_event(struct mr_table *mrt, struct mfc6_cache *mfc,
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(mr6_msgsize(mfc->mf6c_parent >= MAXMIFS, mrt->maxvif),
+       skb = nlmsg_new(mr6_msgsize(mfc->_c.mfc_parent >= MAXMIFS, mrt->maxvif),
                        GFP_ATOMIC);
        if (!skb)
                goto errout;
@@ -2528,10 +2532,10 @@ errout:
 static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct net *net = sock_net(skb->sk);
-       struct mr_table *mrt;
-       struct mfc6_cache *mfc;
        unsigned int t = 0, s_t;
        unsigned int e = 0, s_e;
+       struct mr_table *mrt;
+       struct mr_mfc *mfc;
 
        s_t = cb->args[0];
        s_e = cb->args[1];
@@ -2546,8 +2550,8 @@ static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
                        if (ip6mr_fill_mroute(mrt, skb,
                                              NETLINK_CB(cb->skb).portid,
                                              cb->nlh->nlmsg_seq,
-                                             mfc, RTM_NEWROUTE,
-                                             NLM_F_MULTI) < 0)
+                                             (struct mfc6_cache *)mfc,
+                                             RTM_NEWROUTE, NLM_F_MULTI) < 0)
                                goto done;
 next_entry:
                        e++;
@@ -2562,8 +2566,8 @@ next_entry:
                        if (ip6mr_fill_mroute(mrt, skb,
                                              NETLINK_CB(cb->skb).portid,
                                              cb->nlh->nlmsg_seq,
-                                             mfc, RTM_NEWROUTE,
-                                             NLM_F_MULTI) < 0) {
+                                            (struct mfc6_cache *)mfc,
+                                             RTM_NEWROUTE, NLM_F_MULTI) < 0) {
                                spin_unlock_bh(&mfc_unres_lock);
                                goto done;
                        }