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: Christian Brauner <christian@brauner.io> Cc: Kirill Tkhai <ktkhai@virtuozzo.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
978a46fa6c
commit
203651b665
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue