addrconf.c (ff299f1b1cb4e0c44a3f76d1f8ee4eb2f64f098f) | addrconf.c (fe2c6338fd2c6f383c4d4164262f35c8f3708e1f) |
---|---|
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 * --- 1112 unchanged lines hidden (view full) --- 1121 1122 addr_flags = IFA_F_TEMPORARY; 1123 /* set in addrconf_prefix_rcv() */ 1124 if (ifp->flags & IFA_F_OPTIMISTIC) 1125 addr_flags |= IFA_F_OPTIMISTIC; 1126 1127 ift = !max_addresses || 1128 ipv6_count_addresses(idev) < max_addresses ? | 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 * --- 1112 unchanged lines hidden (view full) --- 1121 1122 addr_flags = IFA_F_TEMPORARY; 1123 /* set in addrconf_prefix_rcv() */ 1124 if (ifp->flags & IFA_F_OPTIMISTIC) 1125 addr_flags |= IFA_F_OPTIMISTIC; 1126 1127 ift = !max_addresses || 1128 ipv6_count_addresses(idev) < max_addresses ? |
1129 ipv6_add_addr(idev, &addr, tmp_plen, 1130 ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, | 1129 ipv6_add_addr(idev, &addr, tmp_plen, ipv6_addr_scope(&addr), |
1131 addr_flags) : NULL; 1132 if (IS_ERR_OR_NULL(ift)) { 1133 in6_ifa_put(ifp); 1134 in6_dev_put(idev); 1135 pr_info("%s: retry temporary address regeneration\n", __func__); 1136 tmpaddr = &addr; 1137 write_lock(&idev->lock); 1138 goto retry; --- 1258 unchanged lines hidden (view full) --- 2397 rtnl_unlock(); 2398 return err; 2399} 2400 2401/* 2402 * Manual configuration of address on an interface 2403 */ 2404static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx, | 1130 addr_flags) : NULL; 1131 if (IS_ERR_OR_NULL(ift)) { 1132 in6_ifa_put(ifp); 1133 in6_dev_put(idev); 1134 pr_info("%s: retry temporary address regeneration\n", __func__); 1135 tmpaddr = &addr; 1136 write_lock(&idev->lock); 1137 goto retry; --- 1258 unchanged lines hidden (view full) --- 2396 rtnl_unlock(); 2397 return err; 2398} 2399 2400/* 2401 * Manual configuration of address on an interface 2402 */ 2403static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx, |
2404 const struct in6_addr *peer_pfx, |
|
2405 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, 2406 __u32 valid_lft) 2407{ 2408 struct inet6_ifaddr *ifp; 2409 struct inet6_dev *idev; 2410 struct net_device *dev; 2411 int scope; 2412 u32 flags; --- 39 unchanged lines hidden (view full) --- 2452 2453 ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); 2454 2455 if (!IS_ERR(ifp)) { 2456 spin_lock_bh(&ifp->lock); 2457 ifp->valid_lft = valid_lft; 2458 ifp->prefered_lft = prefered_lft; 2459 ifp->tstamp = jiffies; | 2405 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, 2406 __u32 valid_lft) 2407{ 2408 struct inet6_ifaddr *ifp; 2409 struct inet6_dev *idev; 2410 struct net_device *dev; 2411 int scope; 2412 u32 flags; --- 39 unchanged lines hidden (view full) --- 2452 2453 ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); 2454 2455 if (!IS_ERR(ifp)) { 2456 spin_lock_bh(&ifp->lock); 2457 ifp->valid_lft = valid_lft; 2458 ifp->prefered_lft = prefered_lft; 2459 ifp->tstamp = jiffies; |
2460 if (peer_pfx) 2461 ifp->peer_addr = *peer_pfx; |
|
2460 spin_unlock_bh(&ifp->lock); 2461 2462 addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 2463 expires, flags); 2464 /* 2465 * Note that section 3.1 of RFC 4429 indicates 2466 * that the Optimistic flag should not be set for 2467 * manually configured addresses --- 53 unchanged lines hidden (view full) --- 2521 2522 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 2523 return -EPERM; 2524 2525 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) 2526 return -EFAULT; 2527 2528 rtnl_lock(); | 2462 spin_unlock_bh(&ifp->lock); 2463 2464 addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 2465 expires, flags); 2466 /* 2467 * Note that section 3.1 of RFC 4429 indicates 2468 * that the Optimistic flag should not be set for 2469 * manually configured addresses --- 53 unchanged lines hidden (view full) --- 2523 2524 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 2525 return -EPERM; 2526 2527 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) 2528 return -EFAULT; 2529 2530 rtnl_lock(); |
2529 err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, | 2531 err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr, NULL, |
2530 ireq.ifr6_prefixlen, IFA_F_PERMANENT, 2531 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); 2532 rtnl_unlock(); 2533 return err; 2534} 2535 2536int addrconf_del_ifaddr(struct net *net, void __user *arg) 2537{ --- 283 unchanged lines hidden (view full) --- 2821 if (IS_ERR(idev)) { 2822 pr_debug("init ip6-ip6: add_dev failed\n"); 2823 return; 2824 } 2825 ip6_tnl_add_linklocal(idev); 2826} 2827 2828static int addrconf_notify(struct notifier_block *this, unsigned long event, | 2532 ireq.ifr6_prefixlen, IFA_F_PERMANENT, 2533 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); 2534 rtnl_unlock(); 2535 return err; 2536} 2537 2538int addrconf_del_ifaddr(struct net *net, void __user *arg) 2539{ --- 283 unchanged lines hidden (view full) --- 2823 if (IS_ERR(idev)) { 2824 pr_debug("init ip6-ip6: add_dev failed\n"); 2825 return; 2826 } 2827 ip6_tnl_add_linklocal(idev); 2828} 2829 2830static int addrconf_notify(struct notifier_block *this, unsigned long event, |
2829 void *data) | 2831 void *ptr) |
2830{ | 2832{ |
2831 struct net_device *dev = (struct net_device *) data; | 2833 struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
2832 struct inet6_dev *idev = __in6_dev_get(dev); 2833 int run_pending = 0; 2834 int err; 2835 2836 switch (event) { 2837 case NETDEV_REGISTER: 2838 if (!idev && dev->mtu >= IPV6_MIN_MTU) { 2839 idev = ipv6_add_dev(dev); --- 767 unchanged lines hidden (view full) --- 3607 now, next, next_sec, next_sched)); 3608 3609 addr_chk_timer.expires = next_sched; 3610 add_timer(&addr_chk_timer); 3611 spin_unlock(&addrconf_verify_lock); 3612 rcu_read_unlock_bh(); 3613} 3614 | 2834 struct inet6_dev *idev = __in6_dev_get(dev); 2835 int run_pending = 0; 2836 int err; 2837 2838 switch (event) { 2839 case NETDEV_REGISTER: 2840 if (!idev && dev->mtu >= IPV6_MIN_MTU) { 2841 idev = ipv6_add_dev(dev); --- 767 unchanged lines hidden (view full) --- 3609 now, next, next_sec, next_sched)); 3610 3611 addr_chk_timer.expires = next_sched; 3612 add_timer(&addr_chk_timer); 3613 spin_unlock(&addrconf_verify_lock); 3614 rcu_read_unlock_bh(); 3615} 3616 |
3615static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) | 3617static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local, 3618 struct in6_addr **peer_pfx) |
3616{ 3617 struct in6_addr *pfx = NULL; 3618 | 3619{ 3620 struct in6_addr *pfx = NULL; 3621 |
3622 *peer_pfx = NULL; 3623 |
|
3619 if (addr) 3620 pfx = nla_data(addr); 3621 3622 if (local) { 3623 if (pfx && nla_memcmp(local, pfx, sizeof(*pfx))) | 3624 if (addr) 3625 pfx = nla_data(addr); 3626 3627 if (local) { 3628 if (pfx && nla_memcmp(local, pfx, sizeof(*pfx))) |
3624 pfx = NULL; 3625 else 3626 pfx = nla_data(local); | 3629 *peer_pfx = pfx; 3630 pfx = nla_data(local); |
3627 } 3628 3629 return pfx; 3630} 3631 3632static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { 3633 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, 3634 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, 3635 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, 3636}; 3637 3638static int 3639inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) 3640{ 3641 struct net *net = sock_net(skb->sk); 3642 struct ifaddrmsg *ifm; 3643 struct nlattr *tb[IFA_MAX+1]; | 3631 } 3632 3633 return pfx; 3634} 3635 3636static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { 3637 [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, 3638 [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, 3639 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, 3640}; 3641 3642static int 3643inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) 3644{ 3645 struct net *net = sock_net(skb->sk); 3646 struct ifaddrmsg *ifm; 3647 struct nlattr *tb[IFA_MAX+1]; |
3644 struct in6_addr *pfx; | 3648 struct in6_addr *pfx, *peer_pfx; |
3645 int err; 3646 3647 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3648 if (err < 0) 3649 return err; 3650 3651 ifm = nlmsg_data(nlh); | 3649 int err; 3650 3651 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3652 if (err < 0) 3653 return err; 3654 3655 ifm = nlmsg_data(nlh); |
3652 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); | 3656 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer_pfx); |
3653 if (pfx == NULL) 3654 return -EINVAL; 3655 3656 return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); 3657} 3658 3659static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, 3660 u32 prefered_lft, u32 valid_lft) --- 41 unchanged lines hidden (view full) --- 3702} 3703 3704static int 3705inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) 3706{ 3707 struct net *net = sock_net(skb->sk); 3708 struct ifaddrmsg *ifm; 3709 struct nlattr *tb[IFA_MAX+1]; | 3657 if (pfx == NULL) 3658 return -EINVAL; 3659 3660 return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen); 3661} 3662 3663static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, 3664 u32 prefered_lft, u32 valid_lft) --- 41 unchanged lines hidden (view full) --- 3706} 3707 3708static int 3709inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) 3710{ 3711 struct net *net = sock_net(skb->sk); 3712 struct ifaddrmsg *ifm; 3713 struct nlattr *tb[IFA_MAX+1]; |
3710 struct in6_addr *pfx; | 3714 struct in6_addr *pfx, *peer_pfx; |
3711 struct inet6_ifaddr *ifa; 3712 struct net_device *dev; 3713 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; 3714 u8 ifa_flags; 3715 int err; 3716 3717 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3718 if (err < 0) 3719 return err; 3720 3721 ifm = nlmsg_data(nlh); | 3715 struct inet6_ifaddr *ifa; 3716 struct net_device *dev; 3717 u32 valid_lft = INFINITY_LIFE_TIME, preferred_lft = INFINITY_LIFE_TIME; 3718 u8 ifa_flags; 3719 int err; 3720 3721 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 3722 if (err < 0) 3723 return err; 3724 3725 ifm = nlmsg_data(nlh); |
3722 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); | 3726 pfx = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer_pfx); |
3723 if (pfx == NULL) 3724 return -EINVAL; 3725 3726 if (tb[IFA_CACHEINFO]) { 3727 struct ifa_cacheinfo *ci; 3728 3729 ci = nla_data(tb[IFA_CACHEINFO]); 3730 valid_lft = ci->ifa_valid; --- 11 unchanged lines hidden (view full) --- 3742 ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); 3743 3744 ifa = ipv6_get_ifaddr(net, pfx, dev, 1); 3745 if (ifa == NULL) { 3746 /* 3747 * It would be best to check for !NLM_F_CREATE here but 3748 * userspace alreay relies on not having to provide this. 3749 */ | 3727 if (pfx == NULL) 3728 return -EINVAL; 3729 3730 if (tb[IFA_CACHEINFO]) { 3731 struct ifa_cacheinfo *ci; 3732 3733 ci = nla_data(tb[IFA_CACHEINFO]); 3734 valid_lft = ci->ifa_valid; --- 11 unchanged lines hidden (view full) --- 3746 ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); 3747 3748 ifa = ipv6_get_ifaddr(net, pfx, dev, 1); 3749 if (ifa == NULL) { 3750 /* 3751 * It would be best to check for !NLM_F_CREATE here but 3752 * userspace alreay relies on not having to provide this. 3753 */ |
3750 return inet6_addr_add(net, ifm->ifa_index, pfx, | 3754 return inet6_addr_add(net, ifm->ifa_index, pfx, peer_pfx, |
3751 ifm->ifa_prefixlen, ifa_flags, 3752 preferred_lft, valid_lft); 3753 } 3754 3755 if (nlh->nlmsg_flags & NLM_F_EXCL || 3756 !(nlh->nlmsg_flags & NLM_F_REPLACE)) 3757 err = -EEXIST; 3758 else --- 40 unchanged lines hidden (view full) --- 3799 return RT_SCOPE_SITE; 3800 else 3801 return RT_SCOPE_UNIVERSE; 3802} 3803 3804static inline int inet6_ifaddr_msgsize(void) 3805{ 3806 return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | 3755 ifm->ifa_prefixlen, ifa_flags, 3756 preferred_lft, valid_lft); 3757 } 3758 3759 if (nlh->nlmsg_flags & NLM_F_EXCL || 3760 !(nlh->nlmsg_flags & NLM_F_REPLACE)) 3761 err = -EEXIST; 3762 else --- 40 unchanged lines hidden (view full) --- 3803 return RT_SCOPE_SITE; 3804 else 3805 return RT_SCOPE_UNIVERSE; 3806} 3807 3808static inline int inet6_ifaddr_msgsize(void) 3809{ 3810 return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
3811 + nla_total_size(16) /* IFA_LOCAL */ |
|
3807 + nla_total_size(16) /* IFA_ADDRESS */ 3808 + nla_total_size(sizeof(struct ifa_cacheinfo)); 3809} 3810 3811static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3812 u32 portid, u32 seq, int event, unsigned int flags) 3813{ 3814 struct nlmsghdr *nlh; --- 22 unchanged lines hidden (view full) --- 3837 valid = 0; 3838 } 3839 } 3840 } else { 3841 preferred = INFINITY_LIFE_TIME; 3842 valid = INFINITY_LIFE_TIME; 3843 } 3844 | 3812 + nla_total_size(16) /* IFA_ADDRESS */ 3813 + nla_total_size(sizeof(struct ifa_cacheinfo)); 3814} 3815 3816static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3817 u32 portid, u32 seq, int event, unsigned int flags) 3818{ 3819 struct nlmsghdr *nlh; --- 22 unchanged lines hidden (view full) --- 3842 valid = 0; 3843 } 3844 } 3845 } else { 3846 preferred = INFINITY_LIFE_TIME; 3847 valid = INFINITY_LIFE_TIME; 3848 } 3849 |
3845 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0 || 3846 put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) { 3847 nlmsg_cancel(skb, nlh); 3848 return -EMSGSIZE; 3849 } | 3850 if (!ipv6_addr_any(&ifa->peer_addr)) { 3851 if (nla_put(skb, IFA_LOCAL, 16, &ifa->addr) < 0 || 3852 nla_put(skb, IFA_ADDRESS, 16, &ifa->peer_addr) < 0) 3853 goto error; 3854 } else 3855 if (nla_put(skb, IFA_ADDRESS, 16, &ifa->addr) < 0) 3856 goto error; |
3850 | 3857 |
3858 if (put_cacheinfo(skb, ifa->cstamp, ifa->tstamp, preferred, valid) < 0) 3859 goto error; 3860 |
|
3851 return nlmsg_end(skb, nlh); | 3861 return nlmsg_end(skb, nlh); |
3862 3863error: 3864 nlmsg_cancel(skb, nlh); 3865 return -EMSGSIZE; |
|
3852} 3853 3854static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3855 u32 portid, u32 seq, int event, u16 flags) 3856{ 3857 struct nlmsghdr *nlh; 3858 u8 scope = RT_SCOPE_UNIVERSE; 3859 int ifindex = ifmca->idev->dev->ifindex; --- 183 unchanged lines hidden (view full) --- 4043 return inet6_dump_addr(skb, cb, type); 4044} 4045 4046static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh) 4047{ 4048 struct net *net = sock_net(in_skb->sk); 4049 struct ifaddrmsg *ifm; 4050 struct nlattr *tb[IFA_MAX+1]; | 3866} 3867 3868static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, 3869 u32 portid, u32 seq, int event, u16 flags) 3870{ 3871 struct nlmsghdr *nlh; 3872 u8 scope = RT_SCOPE_UNIVERSE; 3873 int ifindex = ifmca->idev->dev->ifindex; --- 183 unchanged lines hidden (view full) --- 4057 return inet6_dump_addr(skb, cb, type); 4058} 4059 4060static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh) 4061{ 4062 struct net *net = sock_net(in_skb->sk); 4063 struct ifaddrmsg *ifm; 4064 struct nlattr *tb[IFA_MAX+1]; |
4051 struct in6_addr *addr = NULL; | 4065 struct in6_addr *addr = NULL, *peer; |
4052 struct net_device *dev = NULL; 4053 struct inet6_ifaddr *ifa; 4054 struct sk_buff *skb; 4055 int err; 4056 4057 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 4058 if (err < 0) 4059 goto errout; 4060 | 4066 struct net_device *dev = NULL; 4067 struct inet6_ifaddr *ifa; 4068 struct sk_buff *skb; 4069 int err; 4070 4071 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy); 4072 if (err < 0) 4073 goto errout; 4074 |
4061 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL]); | 4075 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer); |
4062 if (addr == NULL) { 4063 err = -EINVAL; 4064 goto errout; 4065 } 4066 4067 ifm = nlmsg_data(nlh); 4068 if (ifm->ifa_index) 4069 dev = __dev_get_by_index(net, ifm->ifa_index); --- 491 unchanged lines hidden (view full) --- 4561 * we inserted the route at the start of 4562 * our DAD process, so we don't need 4563 * to do it again 4564 */ 4565 if (!(ifp->rt->rt6i_node)) 4566 ip6_ins_rt(ifp->rt); 4567 if (ifp->idev->cnf.forwarding) 4568 addrconf_join_anycast(ifp); | 4076 if (addr == NULL) { 4077 err = -EINVAL; 4078 goto errout; 4079 } 4080 4081 ifm = nlmsg_data(nlh); 4082 if (ifm->ifa_index) 4083 dev = __dev_get_by_index(net, ifm->ifa_index); --- 491 unchanged lines hidden (view full) --- 4575 * we inserted the route at the start of 4576 * our DAD process, so we don't need 4577 * to do it again 4578 */ 4579 if (!(ifp->rt->rt6i_node)) 4580 ip6_ins_rt(ifp->rt); 4581 if (ifp->idev->cnf.forwarding) 4582 addrconf_join_anycast(ifp); |
4583 if (!ipv6_addr_any(&ifp->peer_addr)) 4584 addrconf_prefix_route(&ifp->peer_addr, 128, 4585 ifp->idev->dev, 0, 0); |
|
4569 break; 4570 case RTM_DELADDR: 4571 if (ifp->idev->cnf.forwarding) 4572 addrconf_leave_anycast(ifp); 4573 addrconf_leave_solict(ifp->idev, &ifp->addr); | 4586 break; 4587 case RTM_DELADDR: 4588 if (ifp->idev->cnf.forwarding) 4589 addrconf_leave_anycast(ifp); 4590 addrconf_leave_solict(ifp->idev, &ifp->addr); |
4591 if (!ipv6_addr_any(&ifp->peer_addr)) { 4592 struct rt6_info *rt; 4593 struct net_device *dev = ifp->idev->dev; 4594 4595 rt = rt6_lookup(dev_net(dev), &ifp->peer_addr, NULL, 4596 dev->ifindex, 1); 4597 if (rt) { 4598 dst_hold(&rt->dst); 4599 if (ip6_del_rt(rt)) 4600 dst_free(&rt->dst); 4601 } 4602 } |
|
4574 dst_hold(&ifp->rt->dst); 4575 4576 if (ip6_del_rt(ifp->rt)) 4577 dst_free(&ifp->rt->dst); 4578 break; 4579 } 4580 atomic_inc(&net->ipv6.dev_addr_genid); 4581} --- 4 unchanged lines hidden (view full) --- 4586 if (likely(ifp->idev->dead == 0)) 4587 __ipv6_ifa_notify(event, ifp); 4588 rcu_read_unlock_bh(); 4589} 4590 4591#ifdef CONFIG_SYSCTL 4592 4593static | 4603 dst_hold(&ifp->rt->dst); 4604 4605 if (ip6_del_rt(ifp->rt)) 4606 dst_free(&ifp->rt->dst); 4607 break; 4608 } 4609 atomic_inc(&net->ipv6.dev_addr_genid); 4610} --- 4 unchanged lines hidden (view full) --- 4615 if (likely(ifp->idev->dead == 0)) 4616 __ipv6_ifa_notify(event, ifp); 4617 rcu_read_unlock_bh(); 4618} 4619 4620#ifdef CONFIG_SYSCTL 4621 4622static |
4594int addrconf_sysctl_forward(ctl_table *ctl, int write, | 4623int addrconf_sysctl_forward(struct ctl_table *ctl, int write, |
4595 void __user *buffer, size_t *lenp, loff_t *ppos) 4596{ 4597 int *valp = ctl->data; 4598 int val = *valp; 4599 loff_t pos = *ppos; | 4624 void __user *buffer, size_t *lenp, loff_t *ppos) 4625{ 4626 int *valp = ctl->data; 4627 int val = *valp; 4628 loff_t pos = *ppos; |
4600 ctl_table lctl; | 4629 struct ctl_table lctl; |
4601 int ret; 4602 4603 /* 4604 * ctl->data points to idev->cnf.forwarding, we should 4605 * not modify it until we get the rtnl lock. 4606 */ 4607 lctl = *ctl; 4608 lctl.data = &val; --- 4 unchanged lines hidden (view full) --- 4613 ret = addrconf_fixup_forwarding(ctl, valp, val); 4614 if (ret) 4615 *ppos = pos; 4616 return ret; 4617} 4618 4619static void dev_disable_change(struct inet6_dev *idev) 4620{ | 4630 int ret; 4631 4632 /* 4633 * ctl->data points to idev->cnf.forwarding, we should 4634 * not modify it until we get the rtnl lock. 4635 */ 4636 lctl = *ctl; 4637 lctl.data = &val; --- 4 unchanged lines hidden (view full) --- 4642 ret = addrconf_fixup_forwarding(ctl, valp, val); 4643 if (ret) 4644 *ppos = pos; 4645 return ret; 4646} 4647 4648static void dev_disable_change(struct inet6_dev *idev) 4649{ |
4650 struct netdev_notifier_info info; 4651 |
|
4621 if (!idev || !idev->dev) 4622 return; 4623 | 4652 if (!idev || !idev->dev) 4653 return; 4654 |
4655 netdev_notifier_info_init(&info, idev->dev); |
|
4624 if (idev->cnf.disable_ipv6) | 4656 if (idev->cnf.disable_ipv6) |
4625 addrconf_notify(NULL, NETDEV_DOWN, idev->dev); | 4657 addrconf_notify(NULL, NETDEV_DOWN, &info); |
4626 else | 4658 else |
4627 addrconf_notify(NULL, NETDEV_UP, idev->dev); | 4659 addrconf_notify(NULL, NETDEV_UP, &info); |
4628} 4629 4630static void addrconf_disable_change(struct net *net, __s32 newf) 4631{ 4632 struct net_device *dev; 4633 struct inet6_dev *idev; 4634 4635 rcu_read_lock(); --- 32 unchanged lines hidden (view full) --- 4668 } else if ((!newf) ^ (!old)) 4669 dev_disable_change((struct inet6_dev *)table->extra1); 4670 4671 rtnl_unlock(); 4672 return 0; 4673} 4674 4675static | 4660} 4661 4662static void addrconf_disable_change(struct net *net, __s32 newf) 4663{ 4664 struct net_device *dev; 4665 struct inet6_dev *idev; 4666 4667 rcu_read_lock(); --- 32 unchanged lines hidden (view full) --- 4700 } else if ((!newf) ^ (!old)) 4701 dev_disable_change((struct inet6_dev *)table->extra1); 4702 4703 rtnl_unlock(); 4704 return 0; 4705} 4706 4707static |
4676int addrconf_sysctl_disable(ctl_table *ctl, int write, | 4708int addrconf_sysctl_disable(struct ctl_table *ctl, int write, |
4677 void __user *buffer, size_t *lenp, loff_t *ppos) 4678{ 4679 int *valp = ctl->data; 4680 int val = *valp; 4681 loff_t pos = *ppos; | 4709 void __user *buffer, size_t *lenp, loff_t *ppos) 4710{ 4711 int *valp = ctl->data; 4712 int val = *valp; 4713 loff_t pos = *ppos; |
4682 ctl_table lctl; | 4714 struct ctl_table lctl; |
4683 int ret; 4684 4685 /* 4686 * ctl->data points to idev->cnf.disable_ipv6, we should 4687 * not modify it until we get the rtnl lock. 4688 */ 4689 lctl = *ctl; 4690 lctl.data = &val; --- 5 unchanged lines hidden (view full) --- 4696 if (ret) 4697 *ppos = pos; 4698 return ret; 4699} 4700 4701static struct addrconf_sysctl_table 4702{ 4703 struct ctl_table_header *sysctl_header; | 4715 int ret; 4716 4717 /* 4718 * ctl->data points to idev->cnf.disable_ipv6, we should 4719 * not modify it until we get the rtnl lock. 4720 */ 4721 lctl = *ctl; 4722 lctl.data = &val; --- 5 unchanged lines hidden (view full) --- 4728 if (ret) 4729 *ppos = pos; 4730 return ret; 4731} 4732 4733static struct addrconf_sysctl_table 4734{ 4735 struct ctl_table_header *sysctl_header; |
4704 ctl_table addrconf_vars[DEVCONF_MAX+1]; | 4736 struct ctl_table addrconf_vars[DEVCONF_MAX+1]; |
4705} addrconf_sysctl __read_mostly = { 4706 .sysctl_header = NULL, 4707 .addrconf_vars = { 4708 { 4709 .procname = "forwarding", 4710 .data = &ipv6_devconf.forwarding, 4711 .maxlen = sizeof(int), 4712 .mode = 0644, --- 470 unchanged lines hidden --- | 4737} addrconf_sysctl __read_mostly = { 4738 .sysctl_header = NULL, 4739 .addrconf_vars = { 4740 { 4741 .procname = "forwarding", 4742 .data = &ipv6_devconf.forwarding, 4743 .maxlen = sizeof(int), 4744 .mode = 0644, --- 470 unchanged lines hidden --- |