diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r-- | net/ipv4/ipmr.c | 28 |
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); | |||
124 | static struct kmem_cache *mrt_cachep __read_mostly; | 124 | static struct kmem_cache *mrt_cachep __read_mostly; |
125 | 125 | ||
126 | static struct mr_table *ipmr_new_table(struct net *net, u32 id); | 126 | static struct mr_table *ipmr_new_table(struct net *net, u32 id); |
127 | static void ipmr_free_table(struct mr_table *mrt); | ||
128 | |||
127 | static int ip_mr_forward(struct net *net, struct mr_table *mrt, | 129 | static 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); |
132 | static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 134 | static 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); |
136 | static void mroute_clean_tables(struct mr_table *mrt); | ||
134 | static void ipmr_expire_process(unsigned long arg); | 137 | static 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 | ||
221 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { | 224 | static 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 | ||
300 | static void __net_exit ipmr_rules_exit(struct net *net) | 303 | static 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 | ||
342 | static 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 | ||
341 | static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v) | 351 | static 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 | ||
2109 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 2119 | static 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; |