@@ -4793,12 +4793,19 @@ static inline int inet6_ifaddr_msgsize(void)
47934793 + nla_total_size (4 ) /* IFA_RT_PRIORITY */ ;
47944794}
47954795
4796+ enum addr_type_t {
4797+ UNICAST_ADDR ,
4798+ MULTICAST_ADDR ,
4799+ ANYCAST_ADDR ,
4800+ };
4801+
47964802struct inet6_fill_args {
47974803 u32 portid ;
47984804 u32 seq ;
47994805 int event ;
48004806 unsigned int flags ;
48014807 int netnsid ;
4808+ enum addr_type_t type ;
48024809};
48034810
48044811static int inet6_fill_ifaddr (struct sk_buff * skb , struct inet6_ifaddr * ifa ,
@@ -4930,66 +4937,55 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
49304937 return 0 ;
49314938}
49324939
4933- enum addr_type_t {
4934- UNICAST_ADDR ,
4935- MULTICAST_ADDR ,
4936- ANYCAST_ADDR ,
4937- };
4938-
49394940/* called with rcu_read_lock() */
49404941static int in6_dump_addrs (struct inet6_dev * idev , struct sk_buff * skb ,
4941- struct netlink_callback * cb , enum addr_type_t type ,
4942- int s_ip_idx , int * p_ip_idx , int netnsid )
4942+ struct netlink_callback * cb ,
4943+ int s_ip_idx , int * p_ip_idx ,
4944+ struct inet6_fill_args * fillargs )
49434945{
4944- struct inet6_fill_args fillargs = {
4945- .portid = NETLINK_CB (cb -> skb ).portid ,
4946- .seq = cb -> nlh -> nlmsg_seq ,
4947- .flags = NLM_F_MULTI ,
4948- .netnsid = netnsid ,
4949- };
49504946 struct ifmcaddr6 * ifmca ;
49514947 struct ifacaddr6 * ifaca ;
49524948 int err = 1 ;
49534949 int ip_idx = * p_ip_idx ;
49544950
49554951 read_lock_bh (& idev -> lock );
4956- switch (type ) {
4952+ switch (fillargs -> type ) {
49574953 case UNICAST_ADDR : {
49584954 struct inet6_ifaddr * ifa ;
4959- fillargs . event = RTM_NEWADDR ;
4955+ fillargs -> event = RTM_NEWADDR ;
49604956
49614957 /* unicast address incl. temp addr */
49624958 list_for_each_entry (ifa , & idev -> addr_list , if_list ) {
49634959 if (++ ip_idx < s_ip_idx )
49644960 continue ;
4965- err = inet6_fill_ifaddr (skb , ifa , & fillargs );
4961+ err = inet6_fill_ifaddr (skb , ifa , fillargs );
49664962 if (err < 0 )
49674963 break ;
49684964 nl_dump_check_consistent (cb , nlmsg_hdr (skb ));
49694965 }
49704966 break ;
49714967 }
49724968 case MULTICAST_ADDR :
4973- fillargs . event = RTM_GETMULTICAST ;
4969+ fillargs -> event = RTM_GETMULTICAST ;
49744970
49754971 /* multicast address */
49764972 for (ifmca = idev -> mc_list ; ifmca ;
49774973 ifmca = ifmca -> next , ip_idx ++ ) {
49784974 if (ip_idx < s_ip_idx )
49794975 continue ;
4980- err = inet6_fill_ifmcaddr (skb , ifmca , & fillargs );
4976+ err = inet6_fill_ifmcaddr (skb , ifmca , fillargs );
49814977 if (err < 0 )
49824978 break ;
49834979 }
49844980 break ;
49854981 case ANYCAST_ADDR :
4986- fillargs . event = RTM_GETANYCAST ;
4982+ fillargs -> event = RTM_GETANYCAST ;
49874983 /* anycast address */
49884984 for (ifaca = idev -> ac_list ; ifaca ;
49894985 ifaca = ifaca -> aca_next , ip_idx ++ ) {
49904986 if (ip_idx < s_ip_idx )
49914987 continue ;
4992- err = inet6_fill_ifacaddr (skb , ifaca , & fillargs );
4988+ err = inet6_fill_ifacaddr (skb , ifaca , fillargs );
49934989 if (err < 0 )
49944990 break ;
49954991 }
@@ -5005,10 +5001,16 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
50055001static int inet6_dump_addr (struct sk_buff * skb , struct netlink_callback * cb ,
50065002 enum addr_type_t type )
50075003{
5004+ struct inet6_fill_args fillargs = {
5005+ .portid = NETLINK_CB (cb -> skb ).portid ,
5006+ .seq = cb -> nlh -> nlmsg_seq ,
5007+ .flags = NLM_F_MULTI ,
5008+ .netnsid = -1 ,
5009+ .type = type ,
5010+ };
50085011 struct net * net = sock_net (skb -> sk );
50095012 struct nlattr * tb [IFA_MAX + 1 ];
50105013 struct net * tgt_net = net ;
5011- int netnsid = -1 ;
50125014 int h , s_h ;
50135015 int idx , ip_idx ;
50145016 int s_idx , s_ip_idx ;
@@ -5023,9 +5025,10 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50235025 if (nlmsg_parse (cb -> nlh , sizeof (struct ifaddrmsg ), tb , IFA_MAX ,
50245026 ifa_ipv6_policy , cb -> extack ) >= 0 ) {
50255027 if (tb [IFA_TARGET_NETNSID ]) {
5026- netnsid = nla_get_s32 (tb [IFA_TARGET_NETNSID ]);
5028+ fillargs . netnsid = nla_get_s32 (tb [IFA_TARGET_NETNSID ]);
50275029
5028- tgt_net = rtnl_get_net_ns_capable (skb -> sk , netnsid );
5030+ tgt_net = rtnl_get_net_ns_capable (skb -> sk ,
5031+ fillargs .netnsid );
50295032 if (IS_ERR (tgt_net ))
50305033 return PTR_ERR (tgt_net );
50315034 }
@@ -5046,8 +5049,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50465049 if (!idev )
50475050 goto cont ;
50485051
5049- if (in6_dump_addrs (idev , skb , cb , type ,
5050- s_ip_idx , & ip_idx , netnsid ) < 0 )
5052+ if (in6_dump_addrs (idev , skb , cb , s_ip_idx , & ip_idx ,
5053+ & fillargs ) < 0 )
50515054 goto done ;
50525055cont :
50535056 idx ++ ;
@@ -5058,7 +5061,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
50585061 cb -> args [0 ] = h ;
50595062 cb -> args [1 ] = idx ;
50605063 cb -> args [2 ] = ip_idx ;
5061- if (netnsid >= 0 )
5064+ if (fillargs . netnsid >= 0 )
50625065 put_net (tgt_net );
50635066
50645067 return skb -> len ;
0 commit comments