addrconf.c (8814c4b533817df825485ff32ce6ac406c3a54d1) | addrconf.c (55ebaef1d5db9c1c76ba01a87fd986db5dee550d) |
---|---|
1/* 2 * IPv6 Address [auto]configuration 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * --- 1859 unchanged lines hidden (view full) --- 1868 rtnl_unlock(); 1869 return err; 1870} 1871 1872/* 1873 * Manual configuration of address on an interface 1874 */ 1875static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | 1/* 2 * IPv6 Address [auto]configuration 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 8 * --- 1859 unchanged lines hidden (view full) --- 1868 rtnl_unlock(); 1869 return err; 1870} 1871 1872/* 1873 * Manual configuration of address on an interface 1874 */ 1875static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, |
1876 __u32 prefered_lft, __u32 valid_lft) | 1876 __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft) |
1877{ 1878 struct inet6_ifaddr *ifp; 1879 struct inet6_dev *idev; 1880 struct net_device *dev; | 1877{ 1878 struct inet6_ifaddr *ifp; 1879 struct inet6_dev *idev; 1880 struct net_device *dev; |
1881 __u8 ifa_flags = 0; | |
1882 int scope; 1883 1884 ASSERT_RTNL(); 1885 1886 /* check the lifetime */ 1887 if (!valid_lft || prefered_lft > valid_lft) 1888 return -EINVAL; 1889 --- 76 unchanged lines hidden (view full) --- 1966 if (!capable(CAP_NET_ADMIN)) 1967 return -EPERM; 1968 1969 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) 1970 return -EFAULT; 1971 1972 rtnl_lock(); 1973 err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, | 1881 int scope; 1882 1883 ASSERT_RTNL(); 1884 1885 /* check the lifetime */ 1886 if (!valid_lft || prefered_lft > valid_lft) 1887 return -EINVAL; 1888 --- 76 unchanged lines hidden (view full) --- 1965 if (!capable(CAP_NET_ADMIN)) 1966 return -EPERM; 1967 1968 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) 1969 return -EFAULT; 1970 1971 rtnl_lock(); 1972 err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, |
1974 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); | 1973 IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); |
1975 rtnl_unlock(); 1976 return err; 1977} 1978 1979int addrconf_del_ifaddr(void __user *arg) 1980{ 1981 struct in6_ifreq ireq; 1982 int err; --- 526 unchanged lines hidden (view full) --- 2509 net_srandom(ifp->addr.s6_addr32[3]); 2510 2511 read_lock_bh(&idev->lock); 2512 if (ifp->dead) 2513 goto out; 2514 spin_lock_bh(&ifp->lock); 2515 2516 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || | 1974 rtnl_unlock(); 1975 return err; 1976} 1977 1978int addrconf_del_ifaddr(void __user *arg) 1979{ 1980 struct in6_ifreq ireq; 1981 int err; --- 526 unchanged lines hidden (view full) --- 2508 net_srandom(ifp->addr.s6_addr32[3]); 2509 2510 read_lock_bh(&idev->lock); 2511 if (ifp->dead) 2512 goto out; 2513 spin_lock_bh(&ifp->lock); 2514 2515 if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || |
2517 !(ifp->flags&IFA_F_TENTATIVE)) { | 2516 !(ifp->flags&IFA_F_TENTATIVE) || 2517 ifp->flags & IFA_F_NODAD) { |
2518 ifp->flags &= ~IFA_F_TENTATIVE; 2519 spin_unlock_bh(&ifp->lock); 2520 read_unlock_bh(&idev->lock); 2521 2522 addrconf_dad_completed(ifp); 2523 return; 2524 } 2525 --- 381 unchanged lines hidden (view full) --- 2907 ifm = nlmsg_data(nlh); 2908 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); 2909 if (pfx == NULL) 2910 return -EINVAL; 2911 2912 return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); 2913} 2914 | 2518 ifp->flags &= ~IFA_F_TENTATIVE; 2519 spin_unlock_bh(&ifp->lock); 2520 read_unlock_bh(&idev->lock); 2521 2522 addrconf_dad_completed(ifp); 2523 return; 2524 } 2525 --- 381 unchanged lines hidden (view full) --- 2907 ifm = nlmsg_data(nlh); 2908 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); 2909 if (pfx == NULL) 2910 return -EINVAL; 2911 2912 return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); 2913} 2914 |
2915static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 prefered_lft, 2916 u32 valid_lft) | 2915static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, 2916 u32 prefered_lft, u32 valid_lft) |
2917{ | 2917{ |
2918 int ifa_flags = 0; 2919 | |
2920 if (!valid_lft || (prefered_lft > valid_lft)) 2921 return -EINVAL; 2922 2923 if (valid_lft == INFINITY_LIFE_TIME) | 2918 if (!valid_lft || (prefered_lft > valid_lft)) 2919 return -EINVAL; 2920 2921 if (valid_lft == INFINITY_LIFE_TIME) |
2924 ifa_flags = IFA_F_PERMANENT; | 2922 ifa_flags |= IFA_F_PERMANENT; |
2925 else if (valid_lft >= 0x7FFFFFFF/HZ) 2926 valid_lft = 0x7FFFFFFF/HZ; 2927 2928 if (prefered_lft == 0) | 2923 else if (valid_lft >= 0x7FFFFFFF/HZ) 2924 valid_lft = 0x7FFFFFFF/HZ; 2925 2926 if (prefered_lft == 0) |
2929 ifa_flags = IFA_F_DEPRECATED; | 2927 ifa_flags |= IFA_F_DEPRECATED; |
2930 else if ((prefered_lft >= 0x7FFFFFFF/HZ) && 2931 (prefered_lft != INFINITY_LIFE_TIME)) 2932 prefered_lft = 0x7FFFFFFF/HZ; 2933 2934 spin_lock_bh(&ifp->lock); | 2928 else if ((prefered_lft >= 0x7FFFFFFF/HZ) && 2929 (prefered_lft != INFINITY_LIFE_TIME)) 2930 prefered_lft = 0x7FFFFFFF/HZ; 2931 2932 spin_lock_bh(&ifp->lock); |
2935 ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED|IFA_F_PERMANENT)) | ifa_flags; 2936 | 2933 ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED | IFA_F_PERMANENT | IFA_F_NODAD)) | ifa_flags; |
2937 ifp->tstamp = jiffies; 2938 ifp->valid_lft = valid_lft; 2939 ifp->prefered_lft = prefered_lft; 2940 2941 spin_unlock_bh(&ifp->lock); 2942 if (!(ifp->flags&IFA_F_TENTATIVE)) 2943 ipv6_ifa_notify(0, ifp); 2944 --- 5 unchanged lines hidden (view full) --- 2950static int 2951inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 2952{ 2953 struct ifaddrmsg *ifm; 2954 struct nlattr *tb[IFA_MAX+1]; 2955 struct in6_addr *pfx; 2956 struct inet6_ifaddr *ifa; 2957 struct net_device *dev; | 2934 ifp->tstamp = jiffies; 2935 ifp->valid_lft = valid_lft; 2936 ifp->prefered_lft = prefered_lft; 2937 2938 spin_unlock_bh(&ifp->lock); 2939 if (!(ifp->flags&IFA_F_TENTATIVE)) 2940 ipv6_ifa_notify(0, ifp); 2941 --- 5 unchanged lines hidden (view full) --- 2947static int 2948inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 2949{ 2950 struct ifaddrmsg *ifm; 2951 struct nlattr *tb[IFA_MAX+1]; 2952 struct in6_addr *pfx; 2953 struct inet6_ifaddr *ifa; 2954 struct net_device *dev; |
2958 u32 valid_lft, preferred_lft; | 2955 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; 2956 u8 ifa_flags; |
2959 int err; 2960 2961 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 2962 if (err < 0) 2963 return err; 2964 2965 ifm = nlmsg_data(nlh); 2966 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); --- 10 unchanged lines hidden (view full) --- 2977 preferred_lft = INFINITY_LIFE_TIME; 2978 valid_lft = INFINITY_LIFE_TIME; 2979 } 2980 2981 dev = __dev_get_by_index(ifm->ifa_index); 2982 if (dev == NULL) 2983 return -ENODEV; 2984 | 2957 int err; 2958 2959 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 2960 if (err < 0) 2961 return err; 2962 2963 ifm = nlmsg_data(nlh); 2964 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); --- 10 unchanged lines hidden (view full) --- 2975 preferred_lft = INFINITY_LIFE_TIME; 2976 valid_lft = INFINITY_LIFE_TIME; 2977 } 2978 2979 dev = __dev_get_by_index(ifm->ifa_index); 2980 if (dev == NULL) 2981 return -ENODEV; 2982 |
2983 /* We ignore other flags so far. */ 2984 ifa_flags = ifm->ifa_flags & IFA_F_NODAD; 2985 |
|
2985 ifa = ipv6_get_ifaddr(pfx, dev, 1); 2986 if (ifa == NULL) { 2987 /* 2988 * It would be best to check for !NLM_F_CREATE here but 2989 * userspace alreay relies on not having to provide this. 2990 */ 2991 return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, | 2986 ifa = ipv6_get_ifaddr(pfx, dev, 1); 2987 if (ifa == NULL) { 2988 /* 2989 * It would be best to check for !NLM_F_CREATE here but 2990 * userspace alreay relies on not having to provide this. 2991 */ 2992 return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, |
2992 preferred_lft, valid_lft); | 2993 ifa_flags, preferred_lft, valid_lft); |
2993 } 2994 2995 if (nlh->nlmsg_flags & NLM_F_EXCL || 2996 !(nlh->nlmsg_flags & NLM_F_REPLACE)) 2997 err = -EEXIST; 2998 else | 2994 } 2995 2996 if (nlh->nlmsg_flags & NLM_F_EXCL || 2997 !(nlh->nlmsg_flags & NLM_F_REPLACE)) 2998 err = -EEXIST; 2999 else |
2999 err = inet6_addr_modify(ifa, preferred_lft, valid_lft); | 3000 err = inet6_addr_modify(ifa, ifa_flags, preferred_lft, valid_lft); |
3000 3001 in6_ifa_put(ifa); 3002 3003 return err; 3004} 3005 3006static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags, 3007 u8 scope, int ifindex) --- 1108 unchanged lines hidden --- | 3001 3002 in6_ifa_put(ifa); 3003 3004 return err; 3005} 3006 3007static void put_ifaddrmsg(struct nlmsghdr *nlh, u8 prefixlen, u8 flags, 3008 u8 scope, int ifindex) --- 1108 unchanged lines hidden --- |