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 ---