@@ -3008,14 +3008,11 @@ static int ipv6_mc_config(struct sock *sk, bool join,
30083008 * Manual configuration of address on an interface
30093009 */
30103010static int inet6_addr_add (struct net * net , struct net_device * dev ,
3011- struct ifa6_config * cfg ,
3011+ struct ifa6_config * cfg , clock_t expires , u32 flags ,
30123012 struct netlink_ext_ack * extack )
30133013{
30143014 struct inet6_ifaddr * ifp ;
30153015 struct inet6_dev * idev ;
3016- unsigned long timeout ;
3017- clock_t expires ;
3018- u32 flags ;
30193016
30203017 ASSERT_RTNL ();
30213018
@@ -3024,12 +3021,6 @@ static int inet6_addr_add(struct net *net, struct net_device *dev,
30243021 return - EINVAL ;
30253022 }
30263023
3027- /* check the lifetime */
3028- if (!cfg -> valid_lft || cfg -> preferred_lft > cfg -> valid_lft ) {
3029- NL_SET_ERR_MSG_MOD (extack , "address lifetime invalid" );
3030- return - EINVAL ;
3031- }
3032-
30333024 if (cfg -> ifa_flags & IFA_F_MANAGETEMPADDR && cfg -> plen != 64 ) {
30343025 NL_SET_ERR_MSG_MOD (extack , "address with \"mngtmpaddr\" flag must have a prefix length of 64" );
30353026 return - EINVAL ;
@@ -3053,24 +3044,6 @@ static int inet6_addr_add(struct net *net, struct net_device *dev,
30533044
30543045 cfg -> scope = ipv6_addr_scope (cfg -> pfx );
30553046
3056- timeout = addrconf_timeout_fixup (cfg -> valid_lft , HZ );
3057- if (addrconf_finite_timeout (timeout )) {
3058- expires = jiffies_to_clock_t (timeout * HZ );
3059- cfg -> valid_lft = timeout ;
3060- flags = RTF_EXPIRES ;
3061- } else {
3062- expires = 0 ;
3063- flags = 0 ;
3064- cfg -> ifa_flags |= IFA_F_PERMANENT ;
3065- }
3066-
3067- timeout = addrconf_timeout_fixup (cfg -> preferred_lft , HZ );
3068- if (addrconf_finite_timeout (timeout )) {
3069- if (timeout == 0 )
3070- cfg -> ifa_flags |= IFA_F_DEPRECATED ;
3071- cfg -> preferred_lft = timeout ;
3072- }
3073-
30743047 ifp = ipv6_add_addr (idev , cfg , true, extack );
30753048 if (!IS_ERR (ifp )) {
30763049 if (!(cfg -> ifa_flags & IFA_F_NOPREFIXROUTE )) {
@@ -3180,7 +3153,7 @@ int addrconf_add_ifaddr(struct net *net, void __user *arg)
31803153 rtnl_net_lock (net );
31813154 dev = __dev_get_by_index (net , ireq .ifr6_ifindex );
31823155 if (dev )
3183- err = inet6_addr_add (net , dev , & cfg , NULL );
3156+ err = inet6_addr_add (net , dev , & cfg , 0 , 0 , NULL );
31843157 else
31853158 err = - ENODEV ;
31863159 rtnl_net_unlock (net );
@@ -4869,45 +4842,22 @@ static int modify_prefix_route(struct net *net, struct inet6_ifaddr *ifp,
48694842}
48704843
48714844static int inet6_addr_modify (struct net * net , struct inet6_ifaddr * ifp ,
4872- struct ifa6_config * cfg )
4845+ struct ifa6_config * cfg , clock_t expires ,
4846+ u32 flags )
48734847{
4874- u32 flags ;
4875- clock_t expires ;
4876- unsigned long timeout ;
48774848 bool was_managetempaddr ;
4878- bool had_prefixroute ;
48794849 bool new_peer = false;
4850+ bool had_prefixroute ;
48804851
48814852 ASSERT_RTNL ();
48824853
4883- if (!cfg -> valid_lft || cfg -> preferred_lft > cfg -> valid_lft )
4884- return - EINVAL ;
4885-
48864854 if (cfg -> ifa_flags & IFA_F_MANAGETEMPADDR &&
48874855 (ifp -> flags & IFA_F_TEMPORARY || ifp -> prefix_len != 64 ))
48884856 return - EINVAL ;
48894857
48904858 if (!(ifp -> flags & IFA_F_TENTATIVE ) || ifp -> flags & IFA_F_DADFAILED )
48914859 cfg -> ifa_flags &= ~IFA_F_OPTIMISTIC ;
48924860
4893- timeout = addrconf_timeout_fixup (cfg -> valid_lft , HZ );
4894- if (addrconf_finite_timeout (timeout )) {
4895- expires = jiffies_to_clock_t (timeout * HZ );
4896- cfg -> valid_lft = timeout ;
4897- flags = RTF_EXPIRES ;
4898- } else {
4899- expires = 0 ;
4900- flags = 0 ;
4901- cfg -> ifa_flags |= IFA_F_PERMANENT ;
4902- }
4903-
4904- timeout = addrconf_timeout_fixup (cfg -> preferred_lft , HZ );
4905- if (addrconf_finite_timeout (timeout )) {
4906- if (timeout == 0 )
4907- cfg -> ifa_flags |= IFA_F_DEPRECATED ;
4908- cfg -> preferred_lft = timeout ;
4909- }
4910-
49114861 if (cfg -> peer_pfx &&
49124862 memcmp (& ifp -> peer_addr , cfg -> peer_pfx , sizeof (struct in6_addr ))) {
49134863 if (!ipv6_addr_any (& ifp -> peer_addr ))
@@ -4992,13 +4942,16 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
49924942 struct netlink_ext_ack * extack )
49934943{
49944944 struct net * net = sock_net (skb -> sk );
4995- struct ifaddrmsg * ifm ;
49964945 struct nlattr * tb [IFA_MAX + 1 ];
49974946 struct in6_addr * peer_pfx ;
49984947 struct inet6_ifaddr * ifa ;
49994948 struct net_device * dev ;
50004949 struct inet6_dev * idev ;
50014950 struct ifa6_config cfg ;
4951+ struct ifaddrmsg * ifm ;
4952+ unsigned long timeout ;
4953+ clock_t expires ;
4954+ u32 flags ;
50024955 int err ;
50034956
50044957 err = nlmsg_parse_deprecated (nlh , sizeof (* ifm ), tb , IFA_MAX ,
@@ -5028,15 +4981,39 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
50284981 IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE |
50294982 IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC ;
50304983
4984+ cfg .ifa_flags |= IFA_F_PERMANENT ;
50314985 cfg .valid_lft = INFINITY_LIFE_TIME ;
50324986 cfg .preferred_lft = INFINITY_LIFE_TIME ;
4987+ expires = 0 ;
4988+ flags = 0 ;
50334989
50344990 if (tb [IFA_CACHEINFO ]) {
50354991 struct ifa_cacheinfo * ci ;
50364992
50374993 ci = nla_data (tb [IFA_CACHEINFO ]);
50384994 cfg .valid_lft = ci -> ifa_valid ;
50394995 cfg .preferred_lft = ci -> ifa_prefered ;
4996+
4997+ if (!cfg .valid_lft || cfg .preferred_lft > cfg .valid_lft ) {
4998+ NL_SET_ERR_MSG_MOD (extack , "address lifetime invalid" );
4999+ return - EINVAL ;
5000+ }
5001+
5002+ timeout = addrconf_timeout_fixup (cfg .valid_lft , HZ );
5003+ if (addrconf_finite_timeout (timeout )) {
5004+ cfg .ifa_flags &= ~IFA_F_PERMANENT ;
5005+ cfg .valid_lft = timeout ;
5006+ expires = jiffies_to_clock_t (timeout * HZ );
5007+ flags = RTF_EXPIRES ;
5008+ }
5009+
5010+ timeout = addrconf_timeout_fixup (cfg .preferred_lft , HZ );
5011+ if (addrconf_finite_timeout (timeout )) {
5012+ if (timeout == 0 )
5013+ cfg .ifa_flags |= IFA_F_DEPRECATED ;
5014+
5015+ cfg .preferred_lft = timeout ;
5016+ }
50405017 }
50415018
50425019 dev = __dev_get_by_index (net , ifm -> ifa_index );
@@ -5064,15 +5041,15 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
50645041 * It would be best to check for !NLM_F_CREATE here but
50655042 * userspace already relies on not having to provide this.
50665043 */
5067- return inet6_addr_add (net , dev , & cfg , extack );
5044+ return inet6_addr_add (net , dev , & cfg , expires , flags , extack );
50685045 }
50695046
50705047 if (nlh -> nlmsg_flags & NLM_F_EXCL ||
50715048 !(nlh -> nlmsg_flags & NLM_F_REPLACE )) {
50725049 NL_SET_ERR_MSG_MOD (extack , "address already assigned" );
50735050 err = - EEXIST ;
50745051 } else {
5075- err = inet6_addr_modify (net , ifa , & cfg );
5052+ err = inet6_addr_modify (net , ifa , & cfg , expires , flags );
50765053 }
50775054
50785055 in6_ifa_put (ifa );
0 commit comments