Commit 203651b6 authored by Christian Brauner's avatar Christian Brauner Committed by David S. Miller

ipv6: add inet6_fill_args

inet6_fill_if{addr,mcaddr, acaddr}() already took 6 arguments which
meant the 7th argument would need to be pushed onto the stack on x86.
Add a new struct inet6_fill_args which holds common information passed
to inet6_fill_if{addr,mcaddr, acaddr}() and shortens the functions to
three pointer arguments.
Signed-off-by: default avatarChristian Brauner <christian@brauner.io>
Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 978a46fa
...@@ -4794,21 +4794,30 @@ static inline int inet6_ifaddr_msgsize(void) ...@@ -4794,21 +4794,30 @@ static inline int inet6_ifaddr_msgsize(void)
+ nla_total_size(4) /* IFA_RT_PRIORITY */; + nla_total_size(4) /* IFA_RT_PRIORITY */;
} }
struct inet6_fill_args {
u32 portid;
u32 seq;
int event;
unsigned int flags;
int netnsid;
};
static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
u32 portid, u32 seq, int event, unsigned int flags, struct inet6_fill_args *args)
int netnsid)
{ {
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
u32 preferred, valid; u32 preferred, valid;
nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags); nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
sizeof(struct ifaddrmsg), args->flags);
if (!nlh) if (!nlh)
return -EMSGSIZE; return -EMSGSIZE;
put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope), put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
ifa->idev->dev->ifindex); ifa->idev->dev->ifindex);
if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid)) if (args->netnsid >= 0 &&
nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
goto error; goto error;
if (!((ifa->flags&IFA_F_PERMANENT) && if (!((ifa->flags&IFA_F_PERMANENT) &&
...@@ -4860,8 +4869,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, ...@@ -4860,8 +4869,7 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
} }
static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
u32 portid, u32 seq, int event, u16 flags, struct inet6_fill_args *args)
int netnsid)
{ {
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
u8 scope = RT_SCOPE_UNIVERSE; u8 scope = RT_SCOPE_UNIVERSE;
...@@ -4870,11 +4878,13 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, ...@@ -4870,11 +4878,13 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE) if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
scope = RT_SCOPE_SITE; scope = RT_SCOPE_SITE;
nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags); nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
sizeof(struct ifaddrmsg), args->flags);
if (!nlh) if (!nlh)
return -EMSGSIZE; return -EMSGSIZE;
if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid)) if (args->netnsid >= 0 &&
nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
return -EMSGSIZE; return -EMSGSIZE;
put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
...@@ -4890,8 +4900,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, ...@@ -4890,8 +4900,7 @@ static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
} }
static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
u32 portid, u32 seq, int event, struct inet6_fill_args *args)
unsigned int flags, int netnsid)
{ {
struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt); struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
int ifindex = dev ? dev->ifindex : 1; int ifindex = dev ? dev->ifindex : 1;
...@@ -4901,11 +4910,13 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, ...@@ -4901,11 +4910,13 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE) if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
scope = RT_SCOPE_SITE; scope = RT_SCOPE_SITE;
nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags); nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
sizeof(struct ifaddrmsg), args->flags);
if (!nlh) if (!nlh)
return -EMSGSIZE; return -EMSGSIZE;
if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid)) if (args->netnsid >= 0 &&
nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
return -EMSGSIZE; return -EMSGSIZE;
put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex); put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
...@@ -4931,6 +4942,12 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, ...@@ -4931,6 +4942,12 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
struct netlink_callback *cb, enum addr_type_t type, struct netlink_callback *cb, enum addr_type_t type,
int s_ip_idx, int *p_ip_idx, int netnsid) int s_ip_idx, int *p_ip_idx, int netnsid)
{ {
struct inet6_fill_args fillargs = {
.portid = NETLINK_CB(cb->skb).portid,
.seq = cb->nlh->nlmsg_seq,
.flags = NLM_F_MULTI,
.netnsid = netnsid,
};
struct ifmcaddr6 *ifmca; struct ifmcaddr6 *ifmca;
struct ifacaddr6 *ifaca; struct ifacaddr6 *ifaca;
int err = 1; int err = 1;
...@@ -4940,16 +4957,13 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, ...@@ -4940,16 +4957,13 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
switch (type) { switch (type) {
case UNICAST_ADDR: { case UNICAST_ADDR: {
struct inet6_ifaddr *ifa; struct inet6_ifaddr *ifa;
fillargs.event = RTM_NEWADDR;
/* unicast address incl. temp addr */ /* unicast address incl. temp addr */
list_for_each_entry(ifa, &idev->addr_list, if_list) { list_for_each_entry(ifa, &idev->addr_list, if_list) {
if (++ip_idx < s_ip_idx) if (++ip_idx < s_ip_idx)
continue; continue;
err = inet6_fill_ifaddr(skb, ifa, err = inet6_fill_ifaddr(skb, ifa, &fillargs);
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_NEWADDR,
NLM_F_MULTI, netnsid);
if (err < 0) if (err < 0)
break; break;
nl_dump_check_consistent(cb, nlmsg_hdr(skb)); nl_dump_check_consistent(cb, nlmsg_hdr(skb));
...@@ -4957,31 +4971,26 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, ...@@ -4957,31 +4971,26 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
break; break;
} }
case MULTICAST_ADDR: case MULTICAST_ADDR:
fillargs.event = RTM_GETMULTICAST;
/* multicast address */ /* multicast address */
for (ifmca = idev->mc_list; ifmca; for (ifmca = idev->mc_list; ifmca;
ifmca = ifmca->next, ip_idx++) { ifmca = ifmca->next, ip_idx++) {
if (ip_idx < s_ip_idx) if (ip_idx < s_ip_idx)
continue; continue;
err = inet6_fill_ifmcaddr(skb, ifmca, err = inet6_fill_ifmcaddr(skb, ifmca, &fillargs);
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_GETMULTICAST,
NLM_F_MULTI, netnsid);
if (err < 0) if (err < 0)
break; break;
} }
break; break;
case ANYCAST_ADDR: case ANYCAST_ADDR:
fillargs.event = RTM_GETANYCAST;
/* anycast address */ /* anycast address */
for (ifaca = idev->ac_list; ifaca; for (ifaca = idev->ac_list; ifaca;
ifaca = ifaca->aca_next, ip_idx++) { ifaca = ifaca->aca_next, ip_idx++) {
if (ip_idx < s_ip_idx) if (ip_idx < s_ip_idx)
continue; continue;
err = inet6_fill_ifacaddr(skb, ifaca, err = inet6_fill_ifacaddr(skb, ifaca, &fillargs);
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_GETANYCAST,
NLM_F_MULTI, netnsid);
if (err < 0) if (err < 0)
break; break;
} }
...@@ -5082,6 +5091,13 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -5082,6 +5091,13 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct net *net = sock_net(in_skb->sk); struct net *net = sock_net(in_skb->sk);
struct inet6_fill_args fillargs = {
.portid = NETLINK_CB(in_skb).portid,
.seq = nlh->nlmsg_seq,
.event = RTM_NEWADDR,
.flags = 0,
.netnsid = -1,
};
struct net *tgt_net = net; struct net *tgt_net = net;
struct ifaddrmsg *ifm; struct ifaddrmsg *ifm;
struct nlattr *tb[IFA_MAX+1]; struct nlattr *tb[IFA_MAX+1];
...@@ -5089,7 +5105,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -5089,7 +5105,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct inet6_ifaddr *ifa; struct inet6_ifaddr *ifa;
struct sk_buff *skb; struct sk_buff *skb;
int netnsid = -1;
int err; int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy, err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
...@@ -5098,10 +5113,10 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -5098,10 +5113,10 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
return err; return err;
if (tb[IFA_TARGET_NETNSID]) { if (tb[IFA_TARGET_NETNSID]) {
netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk, tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
netnsid); fillargs.netnsid);
if (IS_ERR(tgt_net)) if (IS_ERR(tgt_net))
return PTR_ERR(tgt_net); return PTR_ERR(tgt_net);
} }
...@@ -5126,8 +5141,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -5126,8 +5141,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
goto errout_ifa; goto errout_ifa;
} }
err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid, err = inet6_fill_ifaddr(skb, ifa, &fillargs);
nlh->nlmsg_seq, RTM_NEWADDR, 0, netnsid);
if (err < 0) { if (err < 0) {
/* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
WARN_ON(err == -EMSGSIZE); WARN_ON(err == -EMSGSIZE);
...@@ -5140,7 +5154,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -5140,7 +5154,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
errout: errout:
if (dev) if (dev)
dev_put(dev); dev_put(dev);
if (netnsid >= 0) if (fillargs.netnsid >= 0)
put_net(tgt_net); put_net(tgt_net);
return err; return err;
...@@ -5150,13 +5164,20 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) ...@@ -5150,13 +5164,20 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct net *net = dev_net(ifa->idev->dev); struct net *net = dev_net(ifa->idev->dev);
struct inet6_fill_args fillargs = {
.portid = 0,
.seq = 0,
.event = event,
.flags = 0,
.netnsid = -1,
};
int err = -ENOBUFS; int err = -ENOBUFS;
skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC); skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
if (!skb) if (!skb)
goto errout; goto errout;
err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0, -1); err = inet6_fill_ifaddr(skb, ifa, &fillargs);
if (err < 0) { if (err < 0) {
/* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */ /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
WARN_ON(err == -EMSGSIZE); WARN_ON(err == -EMSGSIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment