Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78156
b: refs/heads/master
c: 97c53ca
h: refs/heads/master
v: v3
  • Loading branch information
Denis V. Lunev authored and David S. Miller committed Jan 28, 2008
1 parent 10c7a67 commit df6cf3f
Show file tree
Hide file tree
Showing 22 changed files with 103 additions and 55 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b854272b3c732316676e9128f7b9e6f1e1ff88b0
refs/heads/master: 97c53cacf00d1f5aa04adabfebcc806ca8b22b10
8 changes: 4 additions & 4 deletions trunk/include/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,11 @@ extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
__rtattr_parse_nested_compat(tb, max, rta, len); })

extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
struct nlmsghdr *nlh, gfp_t flags);
extern void rtnl_set_sk_err(u32 group, int error);
extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
u32 id, u32 ts, u32 tsage, long expires,
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/net/net_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

struct proc_dir_entry;
struct net_device;
struct sock;
struct net {
atomic_t count; /* To decided when the network
* namespace should be freed.
Expand All @@ -29,6 +30,8 @@ struct net {
struct list_head dev_base_head;
struct hlist_head *dev_name_head;
struct hlist_head *dev_index_head;

struct sock *rtnl; /* rtnetlink socket */
};

#ifdef CONFIG_NET
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_LINK, err);
rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
}

/*
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,10 +599,10 @@ static void notify_rule_change(int event, struct fib_rule *rule,
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
err = rtnl_notify(skb, &init_net, pid, ops->nlgroup, nlh, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(ops->nlgroup, err);
rtnl_set_sk_err(&init_net, ops->nlgroup, err);
}

static void attach_rules(struct list_head *rules, struct net_device *dev)
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/core/neighbour.c
Original file line number Diff line number Diff line change
Expand Up @@ -2467,10 +2467,10 @@ static void __neigh_notify(struct neighbour *n, int type, int flags)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_NEIGH, err);
rtnl_set_sk_err(&init_net, RTNLGRP_NEIGH, err);
}

#ifdef CONFIG_ARPD
Expand Down
63 changes: 52 additions & 11 deletions trunk/net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ struct rtnl_link
};

static DEFINE_MUTEX(rtnl_mutex);
static struct sock *rtnl;

void rtnl_lock(void)
{
Expand Down Expand Up @@ -458,8 +457,9 @@ size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
return ret;
}

int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo)
{
struct sock *rtnl = net->rtnl;
int err = 0;

NETLINK_CB(skb).dst_group = group;
Expand All @@ -471,14 +471,17 @@ int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
return err;
}

int rtnl_unicast(struct sk_buff *skb, u32 pid)
int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
{
struct sock *rtnl = net->rtnl;

return nlmsg_unicast(rtnl, skb, pid);
}

int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
struct nlmsghdr *nlh, gfp_t flags)
{
struct sock *rtnl = net->rtnl;
int report = 0;

if (nlh)
Expand All @@ -487,8 +490,10 @@ int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
return nlmsg_notify(rtnl, skb, pid, group, report, flags);
}

void rtnl_set_sk_err(u32 group, int error)
void rtnl_set_sk_err(struct net *net, u32 group, int error)
{
struct sock *rtnl = net->rtnl;

netlink_set_err(rtnl, 0, group, error);
}

Expand Down Expand Up @@ -1201,7 +1206,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
kfree_skb(nskb);
goto errout;
}
err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
errout:
dev_put(dev);

Expand Down Expand Up @@ -1252,10 +1257,10 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_LINK, err);
rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
}

/* Protected by RTNL sempahore. */
Expand All @@ -1266,6 +1271,7 @@ static int rtattr_max;

static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
struct net *net = skb->sk->sk_net;
rtnl_doit_func doit;
int sz_idx, kind;
int min_len;
Expand Down Expand Up @@ -1294,13 +1300,15 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EPERM;

if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
struct sock *rtnl;
rtnl_dumpit_func dumpit;

dumpit = rtnl_get_dumpit(family, type);
if (dumpit == NULL)
return -EOPNOTSUPP;

__rtnl_unlock();
rtnl = net->rtnl;
err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
rtnl_lock();
return err;
Expand Down Expand Up @@ -1373,6 +1381,40 @@ static struct notifier_block rtnetlink_dev_notifier = {
.notifier_call = rtnetlink_event,
};


static int rtnetlink_net_init(struct net *net)
{
struct sock *sk;
sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
if (!sk)
return -ENOMEM;

/* Don't hold an extra reference on the namespace */
put_net(sk->sk_net);
net->rtnl = sk;
return 0;
}

static void rtnetlink_net_exit(struct net *net)
{
struct sock *sk = net->rtnl;
if (sk) {
/* At the last minute lie and say this is a socket for the
* initial network namespace. So the socket will be safe to
* free.
*/
sk->sk_net = get_net(&init_net);
sock_put(sk);
net->rtnl = NULL;
}
}

static struct pernet_operations rtnetlink_net_ops = {
.init = rtnetlink_net_init,
.exit = rtnetlink_net_exit,
};

void __init rtnetlink_init(void)
{
int i;
Expand All @@ -1385,10 +1427,9 @@ void __init rtnetlink_init(void)
if (!rta_buf)
panic("rtnetlink_init: cannot allocate rta_buf\n");

rtnl = netlink_kernel_create(&init_net, NETLINK_ROUTE, RTNLGRP_MAX,
rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
if (rtnl == NULL)
if (register_pernet_subsys(&rtnetlink_net_ops))
panic("rtnetlink_init: cannot initialize rtnetlink\n");

netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
register_netdevice_notifier(&rtnetlink_dev_notifier);

Expand Down
4 changes: 2 additions & 2 deletions trunk/net/decnet/dn_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -793,10 +793,10 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err);
rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
}

static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/decnet/dn_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1587,7 +1587,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
goto out_free;
}

return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);

out_free:
kfree_skb(skb);
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/decnet/dn_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,10 +375,10 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
err = rtnl_notify(skb, &init_net, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err);
rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_ROUTE, err);
}

static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/devinet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1240,10 +1240,10 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_IPV4_IFADDR, err);
rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
}

#ifdef CONFIG_SYSCTL
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,11 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
err = rtnl_notify(skb, &init_net, info->pid, RTNLGRP_IPV4_ROUTE,
info->nlh, GFP_KERNEL);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_IPV4_ROUTE, err);
rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_ROUTE, err);
}

/* Return the first fib alias matching TOS with
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
e->error = -ETIMEDOUT;
memset(&e->msg, 0, sizeof(e->msg));

rtnl_unicast(skb, NETLINK_CB(skb).pid);
rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
} else
kfree_skb(skb);
}
Expand Down Expand Up @@ -533,7 +533,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
memset(&e->msg, 0, sizeof(e->msg));
}

rtnl_unicast(skb, NETLINK_CB(skb).pid);
rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
} else
ip_mr_forward(skb, c, 0);
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2610,7 +2610,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
if (err <= 0)
goto errout_free;

err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
errout:
return err;

Expand Down
14 changes: 7 additions & 7 deletions trunk/net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3397,7 +3397,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
kfree_skb(skb);
goto errout_ifa;
}
err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
errout_ifa:
in6_ifa_put(ifa);
errout:
Expand All @@ -3420,10 +3420,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
}

static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
Expand Down Expand Up @@ -3628,10 +3628,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
}

static inline size_t inet6_prefix_nlmsg_size(void)
Expand Down Expand Up @@ -3697,10 +3697,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
kfree_skb(skb);
goto errout;
}
err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
errout:
if (err < 0)
rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
}

static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/addrlabel.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
goto out;
}

err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
out:
return err;
}
Expand Down
5 changes: 3 additions & 2 deletions trunk/net/ipv6/ndisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,8 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
&ipv6_hdr(ra)->saddr);
nlmsg_end(skb, nlh);

err = rtnl_notify(skb, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_ND_USEROPT, NULL,
GFP_ATOMIC);
if (err < 0)
goto errout;

Expand All @@ -1059,7 +1060,7 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
nlmsg_free(skb);
err = -EMSGSIZE;
errout:
rtnl_set_sk_err(RTNLGRP_ND_USEROPT, err);
rtnl_set_sk_err(&init_net, RTNLGRP_ND_USEROPT, err);
}

static void ndisc_router_discovery(struct sk_buff *skb)
Expand Down
Loading

0 comments on commit df6cf3f

Please sign in to comment.