@@ -3008,14 +3008,11 @@ static int ipv6_mc_config(struct sock *sk, bool join,
3008
3008
* Manual configuration of address on an interface
3009
3009
*/
3010
3010
static 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 ,
3012
3012
struct netlink_ext_ack * extack )
3013
3013
{
3014
3014
struct inet6_ifaddr * ifp ;
3015
3015
struct inet6_dev * idev ;
3016
- unsigned long timeout ;
3017
- clock_t expires ;
3018
- u32 flags ;
3019
3016
3020
3017
ASSERT_RTNL ();
3021
3018
@@ -3024,12 +3021,6 @@ static int inet6_addr_add(struct net *net, struct net_device *dev,
3024
3021
return - EINVAL ;
3025
3022
}
3026
3023
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
-
3033
3024
if (cfg -> ifa_flags & IFA_F_MANAGETEMPADDR && cfg -> plen != 64 ) {
3034
3025
NL_SET_ERR_MSG_MOD (extack , "address with \"mngtmpaddr\" flag must have a prefix length of 64" );
3035
3026
return - EINVAL ;
@@ -3053,24 +3044,6 @@ static int inet6_addr_add(struct net *net, struct net_device *dev,
3053
3044
3054
3045
cfg -> scope = ipv6_addr_scope (cfg -> pfx );
3055
3046
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
-
3074
3047
ifp = ipv6_add_addr (idev , cfg , true, extack );
3075
3048
if (!IS_ERR (ifp )) {
3076
3049
if (!(cfg -> ifa_flags & IFA_F_NOPREFIXROUTE )) {
@@ -3180,7 +3153,7 @@ int addrconf_add_ifaddr(struct net *net, void __user *arg)
3180
3153
rtnl_net_lock (net );
3181
3154
dev = __dev_get_by_index (net , ireq .ifr6_ifindex );
3182
3155
if (dev )
3183
- err = inet6_addr_add (net , dev , & cfg , NULL );
3156
+ err = inet6_addr_add (net , dev , & cfg , 0 , 0 , NULL );
3184
3157
else
3185
3158
err = - ENODEV ;
3186
3159
rtnl_net_unlock (net );
@@ -4869,45 +4842,22 @@ static int modify_prefix_route(struct net *net, struct inet6_ifaddr *ifp,
4869
4842
}
4870
4843
4871
4844
static 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 )
4873
4847
{
4874
- u32 flags ;
4875
- clock_t expires ;
4876
- unsigned long timeout ;
4877
4848
bool was_managetempaddr ;
4878
- bool had_prefixroute ;
4879
4849
bool new_peer = false;
4850
+ bool had_prefixroute ;
4880
4851
4881
4852
ASSERT_RTNL ();
4882
4853
4883
- if (!cfg -> valid_lft || cfg -> preferred_lft > cfg -> valid_lft )
4884
- return - EINVAL ;
4885
-
4886
4854
if (cfg -> ifa_flags & IFA_F_MANAGETEMPADDR &&
4887
4855
(ifp -> flags & IFA_F_TEMPORARY || ifp -> prefix_len != 64 ))
4888
4856
return - EINVAL ;
4889
4857
4890
4858
if (!(ifp -> flags & IFA_F_TENTATIVE ) || ifp -> flags & IFA_F_DADFAILED )
4891
4859
cfg -> ifa_flags &= ~IFA_F_OPTIMISTIC ;
4892
4860
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
-
4911
4861
if (cfg -> peer_pfx &&
4912
4862
memcmp (& ifp -> peer_addr , cfg -> peer_pfx , sizeof (struct in6_addr ))) {
4913
4863
if (!ipv6_addr_any (& ifp -> peer_addr ))
@@ -4992,13 +4942,16 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
4992
4942
struct netlink_ext_ack * extack )
4993
4943
{
4994
4944
struct net * net = sock_net (skb -> sk );
4995
- struct ifaddrmsg * ifm ;
4996
4945
struct nlattr * tb [IFA_MAX + 1 ];
4997
4946
struct in6_addr * peer_pfx ;
4998
4947
struct inet6_ifaddr * ifa ;
4999
4948
struct net_device * dev ;
5000
4949
struct inet6_dev * idev ;
5001
4950
struct ifa6_config cfg ;
4951
+ struct ifaddrmsg * ifm ;
4952
+ unsigned long timeout ;
4953
+ clock_t expires ;
4954
+ u32 flags ;
5002
4955
int err ;
5003
4956
5004
4957
err = nlmsg_parse_deprecated (nlh , sizeof (* ifm ), tb , IFA_MAX ,
@@ -5028,15 +4981,39 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
5028
4981
IFA_F_MANAGETEMPADDR | IFA_F_NOPREFIXROUTE |
5029
4982
IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC ;
5030
4983
4984
+ cfg .ifa_flags |= IFA_F_PERMANENT ;
5031
4985
cfg .valid_lft = INFINITY_LIFE_TIME ;
5032
4986
cfg .preferred_lft = INFINITY_LIFE_TIME ;
4987
+ expires = 0 ;
4988
+ flags = 0 ;
5033
4989
5034
4990
if (tb [IFA_CACHEINFO ]) {
5035
4991
struct ifa_cacheinfo * ci ;
5036
4992
5037
4993
ci = nla_data (tb [IFA_CACHEINFO ]);
5038
4994
cfg .valid_lft = ci -> ifa_valid ;
5039
4995
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
+ }
5040
5017
}
5041
5018
5042
5019
dev = __dev_get_by_index (net , ifm -> ifa_index );
@@ -5064,15 +5041,15 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
5064
5041
* It would be best to check for !NLM_F_CREATE here but
5065
5042
* userspace already relies on not having to provide this.
5066
5043
*/
5067
- return inet6_addr_add (net , dev , & cfg , extack );
5044
+ return inet6_addr_add (net , dev , & cfg , expires , flags , extack );
5068
5045
}
5069
5046
5070
5047
if (nlh -> nlmsg_flags & NLM_F_EXCL ||
5071
5048
!(nlh -> nlmsg_flags & NLM_F_REPLACE )) {
5072
5049
NL_SET_ERR_MSG_MOD (extack , "address already assigned" );
5073
5050
err = - EEXIST ;
5074
5051
} else {
5075
- err = inet6_addr_modify (net , ifa , & cfg );
5052
+ err = inet6_addr_modify (net , ifa , & cfg , expires , flags );
5076
5053
}
5077
5054
5078
5055
in6_ifa_put (ifa );
0 commit comments