aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipmr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r--net/ipv4/ipmr.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 8eec8f4a0536..6168c4dc58b1 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -124,6 +124,8 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
124static struct kmem_cache *mrt_cachep __read_mostly; 124static struct kmem_cache *mrt_cachep __read_mostly;
125 125
126static struct mr_table *ipmr_new_table(struct net *net, u32 id); 126static struct mr_table *ipmr_new_table(struct net *net, u32 id);
127static void ipmr_free_table(struct mr_table *mrt);
128
127static int ip_mr_forward(struct net *net, struct mr_table *mrt, 129static int ip_mr_forward(struct net *net, struct mr_table *mrt,
128 struct sk_buff *skb, struct mfc_cache *cache, 130 struct sk_buff *skb, struct mfc_cache *cache,
129 int local); 131 int local);
@@ -131,6 +133,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
131 struct sk_buff *pkt, vifi_t vifi, int assert); 133 struct sk_buff *pkt, vifi_t vifi, int assert);
132static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 134static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
133 struct mfc_cache *c, struct rtmsg *rtm); 135 struct mfc_cache *c, struct rtmsg *rtm);
136static void mroute_clean_tables(struct mr_table *mrt);
134static void ipmr_expire_process(unsigned long arg); 137static void ipmr_expire_process(unsigned long arg);
135 138
136#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES 139#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -218,7 +221,7 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
218 return 0; 221 return 0;
219} 222}
220 223
221static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { 224static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = {
222 .family = RTNL_FAMILY_IPMR, 225 .family = RTNL_FAMILY_IPMR,
223 .rule_size = sizeof(struct ipmr_rule), 226 .rule_size = sizeof(struct ipmr_rule),
224 .addr_size = sizeof(u32), 227 .addr_size = sizeof(u32),
@@ -271,7 +274,7 @@ static void __net_exit ipmr_rules_exit(struct net *net)
271 274
272 list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { 275 list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {
273 list_del(&mrt->list); 276 list_del(&mrt->list);
274 kfree(mrt); 277 ipmr_free_table(mrt);
275 } 278 }
276 fib_rules_unregister(net->ipv4.mr_rules_ops); 279 fib_rules_unregister(net->ipv4.mr_rules_ops);
277} 280}
@@ -299,7 +302,7 @@ static int __net_init ipmr_rules_init(struct net *net)
299 302
300static void __net_exit ipmr_rules_exit(struct net *net) 303static void __net_exit ipmr_rules_exit(struct net *net)
301{ 304{
302 kfree(net->ipv4.mrt); 305 ipmr_free_table(net->ipv4.mrt);
303} 306}
304#endif 307#endif
305 308
@@ -336,6 +339,13 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
336 return mrt; 339 return mrt;
337} 340}
338 341
342static void ipmr_free_table(struct mr_table *mrt)
343{
344 del_timer_sync(&mrt->ipmr_expire_timer);
345 mroute_clean_tables(mrt);
346 kfree(mrt);
347}
348
339/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ 349/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
340 350
341static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) 351static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v)
@@ -616,7 +626,7 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
616 e->error = -ETIMEDOUT; 626 e->error = -ETIMEDOUT;
617 memset(&e->msg, 0, sizeof(e->msg)); 627 memset(&e->msg, 0, sizeof(e->msg));
618 628
619 rtnl_unicast(skb, net, NETLINK_CB(skb).pid); 629 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
620 } else { 630 } else {
621 kfree_skb(skb); 631 kfree_skb(skb);
622 } 632 }
@@ -860,7 +870,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
860 memset(&e->msg, 0, sizeof(e->msg)); 870 memset(&e->msg, 0, sizeof(e->msg));
861 } 871 }
862 872
863 rtnl_unicast(skb, net, NETLINK_CB(skb).pid); 873 rtnl_unicast(skb, net, NETLINK_CB(skb).portid);
864 } else { 874 } else {
865 ip_mr_forward(net, mrt, skb, c, 0); 875 ip_mr_forward(net, mrt, skb, c, 0);
866 } 876 }
@@ -1798,7 +1808,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb)
1798 .flowi4_oif = (rt_is_output_route(rt) ? 1808 .flowi4_oif = (rt_is_output_route(rt) ?
1799 skb->dev->ifindex : 0), 1809 skb->dev->ifindex : 0),
1800 .flowi4_iif = (rt_is_output_route(rt) ? 1810 .flowi4_iif = (rt_is_output_route(rt) ?
1801 net->loopback_dev->ifindex : 1811 LOOPBACK_IFINDEX :
1802 skb->dev->ifindex), 1812 skb->dev->ifindex),
1803 .flowi4_mark = skb->mark, 1813 .flowi4_mark = skb->mark,
1804 }; 1814 };
@@ -2107,12 +2117,12 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb,
2107} 2117}
2108 2118
2109static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 2119static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
2110 u32 pid, u32 seq, struct mfc_cache *c) 2120 u32 portid, u32 seq, struct mfc_cache *c)
2111{ 2121{
2112 struct nlmsghdr *nlh; 2122 struct nlmsghdr *nlh;
2113 struct rtmsg *rtm; 2123 struct rtmsg *rtm;
2114 2124
2115 nlh = nlmsg_put(skb, pid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI); 2125 nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*rtm), NLM_F_MULTI);
2116 if (nlh == NULL) 2126 if (nlh == NULL)
2117 return -EMSGSIZE; 2127 return -EMSGSIZE;
2118 2128
@@ -2166,7 +2176,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
2166 if (e < s_e) 2176 if (e < s_e)
2167 goto next_entry; 2177 goto next_entry;
2168 if (ipmr_fill_mroute(mrt, skb, 2178 if (ipmr_fill_mroute(mrt, skb,
2169 NETLINK_CB(cb->skb).pid, 2179 NETLINK_CB(cb->skb).portid,
2170 cb->nlh->nlmsg_seq, 2180 cb->nlh->nlmsg_seq,
2171 mfc) < 0) 2181 mfc) < 0)
2172 goto done; 2182 goto done;