git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ipmr: missing dev_put() on error path in vif_add()
[safe/jmp/linux-2.6]
/
net
/
ipv4
/
ipmr.c
diff --git
a/net/ipv4/ipmr.c
b/net/ipv4/ipmr.c
index
ffd9861
..
99508d6
100644
(file)
--- a/
net/ipv4/ipmr.c
+++ b/
net/ipv4/ipmr.c
@@
-99,10
+99,6
@@
static int ipmr_cache_report(struct net *net,
struct sk_buff *pkt, vifi_t vifi, int assert);
static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm);
struct sk_buff *pkt, vifi_t vifi, int assert);
static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm);
-#ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol;
-#endif
-
static struct timer_list ipmr_expire_timer;
/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
static struct timer_list ipmr_expire_timer;
/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
@@
-201,7
+197,7
@@
failure:
#ifdef CONFIG_IP_PIMSM
#ifdef CONFIG_IP_PIMSM
-static
in
t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
+static
netdev_tx_
t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net *net = dev_net(dev);
{
struct net *net = dev_net(dev);
@@
-212,7
+208,7
@@
static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
IGMPMSG_WHOLEPKT);
read_unlock(&mrt_lock);
kfree_skb(skb);
IGMPMSG_WHOLEPKT);
read_unlock(&mrt_lock);
kfree_skb(skb);
- return
0
;
+ return
NETDEV_TX_OK
;
}
static const struct net_device_ops reg_vif_netdev_ops = {
}
static const struct net_device_ops reg_vif_netdev_ops = {
@@
-226,9
+222,10
@@
static void reg_vif_setup(struct net_device *dev)
dev->flags = IFF_NOARP;
dev->netdev_ops = ®_vif_netdev_ops,
dev->destructor = free_netdev;
dev->flags = IFF_NOARP;
dev->netdev_ops = ®_vif_netdev_ops,
dev->destructor = free_netdev;
+ dev->features |= NETIF_F_NETNS_LOCAL;
}
}
-static struct net_device *ipmr_reg_vif(
void
)
+static struct net_device *ipmr_reg_vif(
struct net *net
)
{
struct net_device *dev;
struct in_device *in_dev;
{
struct net_device *dev;
struct in_device *in_dev;
@@
-238,6
+235,8
@@
static struct net_device *ipmr_reg_vif(void)
if (dev == NULL)
return NULL;
if (dev == NULL)
return NULL;
+ dev_net_set(dev, net);
+
if (register_netdevice(dev)) {
free_netdev(dev);
return NULL;
if (register_netdevice(dev)) {
free_netdev(dev);
return NULL;
@@
-448,7
+447,7
@@
static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
*/
if (net->ipv4.mroute_reg_vif_num >= 0)
return -EADDRINUSE;
*/
if (net->ipv4.mroute_reg_vif_num >= 0)
return -EADDRINUSE;
- dev = ipmr_reg_vif();
+ dev = ipmr_reg_vif(
net
);
if (!dev)
return -ENOBUFS;
err = dev_set_allmulti(dev, 1);
if (!dev)
return -ENOBUFS;
err = dev_set_allmulti(dev, 1);
@@
-484,8
+483,10
@@
static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
return -EINVAL;
}
return -EINVAL;
}
- if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
+ dev_put(dev);
return -EADDRNOTAVAIL;
return -EADDRNOTAVAIL;
+ }
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev);
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev);
@@
-932,7
+933,7
@@
static void mrtsock_destruct(struct sock *sk)
* MOSPF/PIM router set up we can clean this up.
*/
* MOSPF/PIM router set up we can clean this up.
*/
-int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
+int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval,
unsigned
int optlen)
{
int ret;
struct vifctl vif;
{
int ret;
struct vifctl vif;
@@
-1031,16
+1032,6
@@
int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
if (v != net->ipv4.mroute_do_pim) {
net->ipv4.mroute_do_pim = v;
net->ipv4.mroute_do_assert = v;
if (v != net->ipv4.mroute_do_pim) {
net->ipv4.mroute_do_pim = v;
net->ipv4.mroute_do_assert = v;
-#ifdef CONFIG_IP_PIMSM_V2
- if (net->ipv4.mroute_do_pim)
- ret = inet_add_protocol(&pim_protocol,
- IPPROTO_PIM);
- else
- ret = inet_del_protocol(&pim_protocol,
- IPPROTO_PIM);
- if (ret < 0)
- ret = -EAGAIN;
-#endif
}
rtnl_unlock();
return ret;
}
rtnl_unlock();
return ret;
@@
-1952,8
+1943,9
@@
static const struct file_operations ipmr_mfc_fops = {
#endif
#ifdef CONFIG_IP_PIMSM_V2
#endif
#ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol = {
+static
const
struct net_protocol pim_protocol = {
.handler = pim_rcv,
.handler = pim_rcv,
+ .netns_ok = 1,
};
#endif
};
#endif
@@
-2040,8
+2032,19
@@
int __init ip_mr_init(void)
err = register_netdevice_notifier(&ip_mr_notifier);
if (err)
goto reg_notif_fail;
err = register_netdevice_notifier(&ip_mr_notifier);
if (err)
goto reg_notif_fail;
+#ifdef CONFIG_IP_PIMSM_V2
+ if (inet_add_protocol(&pim_protocol, IPPROTO_PIM) < 0) {
+ printk(KERN_ERR "ip_mr_init: can't add PIM protocol\n");
+ err = -EAGAIN;
+ goto add_proto_fail;
+ }
+#endif
return 0;
return 0;
+#ifdef CONFIG_IP_PIMSM_V2
+add_proto_fail:
+ unregister_netdevice_notifier(&ip_mr_notifier);
+#endif
reg_notif_fail:
del_timer(&ipmr_expire_timer);
unregister_pernet_subsys(&ipmr_net_ops);
reg_notif_fail:
del_timer(&ipmr_expire_timer);
unregister_pernet_subsys(&ipmr_net_ops);