addrconf.c (6ecf4c37eb3e89b0832c9616089a5cdca3747da7) addrconf.c (203651b665f72ba765fc4721842a471f8e9e5739)
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 *

--- 4780 unchanged lines hidden (view full) ---

4789 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
4790 + nla_total_size(16) /* IFA_LOCAL */
4791 + nla_total_size(16) /* IFA_ADDRESS */
4792 + nla_total_size(sizeof(struct ifa_cacheinfo))
4793 + nla_total_size(4) /* IFA_FLAGS */
4794 + nla_total_size(4) /* IFA_RT_PRIORITY */;
4795}
4796
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 *

--- 4780 unchanged lines hidden (view full) ---

4789 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
4790 + nla_total_size(16) /* IFA_LOCAL */
4791 + nla_total_size(16) /* IFA_ADDRESS */
4792 + nla_total_size(sizeof(struct ifa_cacheinfo))
4793 + nla_total_size(4) /* IFA_FLAGS */
4794 + nla_total_size(4) /* IFA_RT_PRIORITY */;
4795}
4796
4797struct inet6_fill_args {
4798 u32 portid;
4799 u32 seq;
4800 int event;
4801 unsigned int flags;
4802 int netnsid;
4803};
4804
4797static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4805static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
4798 u32 portid, u32 seq, int event, unsigned int flags,
4799 int netnsid)
4806 struct inet6_fill_args *args)
4800{
4801 struct nlmsghdr *nlh;
4802 u32 preferred, valid;
4803
4807{
4808 struct nlmsghdr *nlh;
4809 u32 preferred, valid;
4810
4804 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4811 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4812 sizeof(struct ifaddrmsg), args->flags);
4805 if (!nlh)
4806 return -EMSGSIZE;
4807
4808 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
4809 ifa->idev->dev->ifindex);
4810
4813 if (!nlh)
4814 return -EMSGSIZE;
4815
4816 put_ifaddrmsg(nlh, ifa->prefix_len, ifa->flags, rt_scope(ifa->scope),
4817 ifa->idev->dev->ifindex);
4818
4811 if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid))
4819 if (args->netnsid >= 0 &&
4820 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4812 goto error;
4813
4814 if (!((ifa->flags&IFA_F_PERMANENT) &&
4815 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
4816 preferred = ifa->prefered_lft;
4817 valid = ifa->valid_lft;
4818 if (preferred != INFINITY_LIFE_TIME) {
4819 long tval = (jiffies - ifa->tstamp)/HZ;

--- 35 unchanged lines hidden (view full) ---

4855 return 0;
4856
4857error:
4858 nlmsg_cancel(skb, nlh);
4859 return -EMSGSIZE;
4860}
4861
4862static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4821 goto error;
4822
4823 if (!((ifa->flags&IFA_F_PERMANENT) &&
4824 (ifa->prefered_lft == INFINITY_LIFE_TIME))) {
4825 preferred = ifa->prefered_lft;
4826 valid = ifa->valid_lft;
4827 if (preferred != INFINITY_LIFE_TIME) {
4828 long tval = (jiffies - ifa->tstamp)/HZ;

--- 35 unchanged lines hidden (view full) ---

4864 return 0;
4865
4866error:
4867 nlmsg_cancel(skb, nlh);
4868 return -EMSGSIZE;
4869}
4870
4871static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
4863 u32 portid, u32 seq, int event, u16 flags,
4864 int netnsid)
4872 struct inet6_fill_args *args)
4865{
4866 struct nlmsghdr *nlh;
4867 u8 scope = RT_SCOPE_UNIVERSE;
4868 int ifindex = ifmca->idev->dev->ifindex;
4869
4870 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
4871 scope = RT_SCOPE_SITE;
4872
4873{
4874 struct nlmsghdr *nlh;
4875 u8 scope = RT_SCOPE_UNIVERSE;
4876 int ifindex = ifmca->idev->dev->ifindex;
4877
4878 if (ipv6_addr_scope(&ifmca->mca_addr) & IFA_SITE)
4879 scope = RT_SCOPE_SITE;
4880
4873 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4881 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4882 sizeof(struct ifaddrmsg), args->flags);
4874 if (!nlh)
4875 return -EMSGSIZE;
4876
4883 if (!nlh)
4884 return -EMSGSIZE;
4885
4877 if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid))
4886 if (args->netnsid >= 0 &&
4887 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4878 return -EMSGSIZE;
4879
4880 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4881 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
4882 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
4883 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4884 nlmsg_cancel(skb, nlh);
4885 return -EMSGSIZE;
4886 }
4887
4888 nlmsg_end(skb, nlh);
4889 return 0;
4890}
4891
4892static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4888 return -EMSGSIZE;
4889
4890 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4891 if (nla_put_in6_addr(skb, IFA_MULTICAST, &ifmca->mca_addr) < 0 ||
4892 put_cacheinfo(skb, ifmca->mca_cstamp, ifmca->mca_tstamp,
4893 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4894 nlmsg_cancel(skb, nlh);
4895 return -EMSGSIZE;
4896 }
4897
4898 nlmsg_end(skb, nlh);
4899 return 0;
4900}
4901
4902static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
4893 u32 portid, u32 seq, int event,
4894 unsigned int flags, int netnsid)
4903 struct inet6_fill_args *args)
4895{
4896 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
4897 int ifindex = dev ? dev->ifindex : 1;
4898 struct nlmsghdr *nlh;
4899 u8 scope = RT_SCOPE_UNIVERSE;
4900
4901 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
4902 scope = RT_SCOPE_SITE;
4903
4904{
4905 struct net_device *dev = fib6_info_nh_dev(ifaca->aca_rt);
4906 int ifindex = dev ? dev->ifindex : 1;
4907 struct nlmsghdr *nlh;
4908 u8 scope = RT_SCOPE_UNIVERSE;
4909
4910 if (ipv6_addr_scope(&ifaca->aca_addr) & IFA_SITE)
4911 scope = RT_SCOPE_SITE;
4912
4904 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct ifaddrmsg), flags);
4913 nlh = nlmsg_put(skb, args->portid, args->seq, args->event,
4914 sizeof(struct ifaddrmsg), args->flags);
4905 if (!nlh)
4906 return -EMSGSIZE;
4907
4915 if (!nlh)
4916 return -EMSGSIZE;
4917
4908 if (netnsid >= 0 && nla_put_s32(skb, IFA_TARGET_NETNSID, netnsid))
4918 if (args->netnsid >= 0 &&
4919 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
4909 return -EMSGSIZE;
4910
4911 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4912 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
4913 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
4914 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4915 nlmsg_cancel(skb, nlh);
4916 return -EMSGSIZE;

--- 9 unchanged lines hidden (view full) ---

4926 ANYCAST_ADDR,
4927};
4928
4929/* called with rcu_read_lock() */
4930static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4931 struct netlink_callback *cb, enum addr_type_t type,
4932 int s_ip_idx, int *p_ip_idx, int netnsid)
4933{
4920 return -EMSGSIZE;
4921
4922 put_ifaddrmsg(nlh, 128, IFA_F_PERMANENT, scope, ifindex);
4923 if (nla_put_in6_addr(skb, IFA_ANYCAST, &ifaca->aca_addr) < 0 ||
4924 put_cacheinfo(skb, ifaca->aca_cstamp, ifaca->aca_tstamp,
4925 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
4926 nlmsg_cancel(skb, nlh);
4927 return -EMSGSIZE;

--- 9 unchanged lines hidden (view full) ---

4937 ANYCAST_ADDR,
4938};
4939
4940/* called with rcu_read_lock() */
4941static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
4942 struct netlink_callback *cb, enum addr_type_t type,
4943 int s_ip_idx, int *p_ip_idx, int netnsid)
4944{
4945 struct inet6_fill_args fillargs = {
4946 .portid = NETLINK_CB(cb->skb).portid,
4947 .seq = cb->nlh->nlmsg_seq,
4948 .flags = NLM_F_MULTI,
4949 .netnsid = netnsid,
4950 };
4934 struct ifmcaddr6 *ifmca;
4935 struct ifacaddr6 *ifaca;
4936 int err = 1;
4937 int ip_idx = *p_ip_idx;
4938
4939 read_lock_bh(&idev->lock);
4940 switch (type) {
4941 case UNICAST_ADDR: {
4942 struct inet6_ifaddr *ifa;
4951 struct ifmcaddr6 *ifmca;
4952 struct ifacaddr6 *ifaca;
4953 int err = 1;
4954 int ip_idx = *p_ip_idx;
4955
4956 read_lock_bh(&idev->lock);
4957 switch (type) {
4958 case UNICAST_ADDR: {
4959 struct inet6_ifaddr *ifa;
4960 fillargs.event = RTM_NEWADDR;
4943
4944 /* unicast address incl. temp addr */
4945 list_for_each_entry(ifa, &idev->addr_list, if_list) {
4946 if (++ip_idx < s_ip_idx)
4947 continue;
4961
4962 /* unicast address incl. temp addr */
4963 list_for_each_entry(ifa, &idev->addr_list, if_list) {
4964 if (++ip_idx < s_ip_idx)
4965 continue;
4948 err = inet6_fill_ifaddr(skb, ifa,
4949 NETLINK_CB(cb->skb).portid,
4950 cb->nlh->nlmsg_seq,
4951 RTM_NEWADDR,
4952 NLM_F_MULTI, netnsid);
4966 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
4953 if (err < 0)
4954 break;
4955 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4956 }
4957 break;
4958 }
4959 case MULTICAST_ADDR:
4967 if (err < 0)
4968 break;
4969 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4970 }
4971 break;
4972 }
4973 case MULTICAST_ADDR:
4974 fillargs.event = RTM_GETMULTICAST;
4975
4960 /* multicast address */
4961 for (ifmca = idev->mc_list; ifmca;
4962 ifmca = ifmca->next, ip_idx++) {
4963 if (ip_idx < s_ip_idx)
4964 continue;
4976 /* multicast address */
4977 for (ifmca = idev->mc_list; ifmca;
4978 ifmca = ifmca->next, ip_idx++) {
4979 if (ip_idx < s_ip_idx)
4980 continue;
4965 err = inet6_fill_ifmcaddr(skb, ifmca,
4966 NETLINK_CB(cb->skb).portid,
4967 cb->nlh->nlmsg_seq,
4968 RTM_GETMULTICAST,
4969 NLM_F_MULTI, netnsid);
4981 err = inet6_fill_ifmcaddr(skb, ifmca, &fillargs);
4970 if (err < 0)
4971 break;
4972 }
4973 break;
4974 case ANYCAST_ADDR:
4982 if (err < 0)
4983 break;
4984 }
4985 break;
4986 case ANYCAST_ADDR:
4987 fillargs.event = RTM_GETANYCAST;
4975 /* anycast address */
4976 for (ifaca = idev->ac_list; ifaca;
4977 ifaca = ifaca->aca_next, ip_idx++) {
4978 if (ip_idx < s_ip_idx)
4979 continue;
4988 /* anycast address */
4989 for (ifaca = idev->ac_list; ifaca;
4990 ifaca = ifaca->aca_next, ip_idx++) {
4991 if (ip_idx < s_ip_idx)
4992 continue;
4980 err = inet6_fill_ifacaddr(skb, ifaca,
4981 NETLINK_CB(cb->skb).portid,
4982 cb->nlh->nlmsg_seq,
4983 RTM_GETANYCAST,
4984 NLM_F_MULTI, netnsid);
4993 err = inet6_fill_ifacaddr(skb, ifaca, &fillargs);
4985 if (err < 0)
4986 break;
4987 }
4988 break;
4989 default:
4990 break;
4991 }
4992 read_unlock_bh(&idev->lock);

--- 84 unchanged lines hidden (view full) ---

5077
5078 return inet6_dump_addr(skb, cb, type);
5079}
5080
5081static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
5082 struct netlink_ext_ack *extack)
5083{
5084 struct net *net = sock_net(in_skb->sk);
4994 if (err < 0)
4995 break;
4996 }
4997 break;
4998 default:
4999 break;
5000 }
5001 read_unlock_bh(&idev->lock);

--- 84 unchanged lines hidden (view full) ---

5086
5087 return inet6_dump_addr(skb, cb, type);
5088}
5089
5090static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
5091 struct netlink_ext_ack *extack)
5092{
5093 struct net *net = sock_net(in_skb->sk);
5094 struct inet6_fill_args fillargs = {
5095 .portid = NETLINK_CB(in_skb).portid,
5096 .seq = nlh->nlmsg_seq,
5097 .event = RTM_NEWADDR,
5098 .flags = 0,
5099 .netnsid = -1,
5100 };
5085 struct net *tgt_net = net;
5086 struct ifaddrmsg *ifm;
5087 struct nlattr *tb[IFA_MAX+1];
5088 struct in6_addr *addr = NULL, *peer;
5089 struct net_device *dev = NULL;
5090 struct inet6_ifaddr *ifa;
5091 struct sk_buff *skb;
5101 struct net *tgt_net = net;
5102 struct ifaddrmsg *ifm;
5103 struct nlattr *tb[IFA_MAX+1];
5104 struct in6_addr *addr = NULL, *peer;
5105 struct net_device *dev = NULL;
5106 struct inet6_ifaddr *ifa;
5107 struct sk_buff *skb;
5092 int netnsid = -1;
5093 int err;
5094
5095 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5096 extack);
5097 if (err < 0)
5098 return err;
5099
5100 if (tb[IFA_TARGET_NETNSID]) {
5108 int err;
5109
5110 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy,
5111 extack);
5112 if (err < 0)
5113 return err;
5114
5115 if (tb[IFA_TARGET_NETNSID]) {
5101 netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5116 fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
5102
5103 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
5117
5118 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(in_skb).sk,
5104 netnsid);
5119 fillargs.netnsid);
5105 if (IS_ERR(tgt_net))
5106 return PTR_ERR(tgt_net);
5107 }
5108
5109 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
5110 if (!addr)
5111 return -EINVAL;
5112

--- 8 unchanged lines hidden (view full) ---

5121 }
5122
5123 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
5124 if (!skb) {
5125 err = -ENOBUFS;
5126 goto errout_ifa;
5127 }
5128
5120 if (IS_ERR(tgt_net))
5121 return PTR_ERR(tgt_net);
5122 }
5123
5124 addr = extract_addr(tb[IFA_ADDRESS], tb[IFA_LOCAL], &peer);
5125 if (!addr)
5126 return -EINVAL;
5127

--- 8 unchanged lines hidden (view full) ---

5136 }
5137
5138 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
5139 if (!skb) {
5140 err = -ENOBUFS;
5141 goto errout_ifa;
5142 }
5143
5129 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).portid,
5130 nlh->nlmsg_seq, RTM_NEWADDR, 0, netnsid);
5144 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
5131 if (err < 0) {
5132 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5133 WARN_ON(err == -EMSGSIZE);
5134 kfree_skb(skb);
5135 goto errout_ifa;
5136 }
5137 err = rtnl_unicast(skb, tgt_net, NETLINK_CB(in_skb).portid);
5138errout_ifa:
5139 in6_ifa_put(ifa);
5140errout:
5141 if (dev)
5142 dev_put(dev);
5145 if (err < 0) {
5146 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5147 WARN_ON(err == -EMSGSIZE);
5148 kfree_skb(skb);
5149 goto errout_ifa;
5150 }
5151 err = rtnl_unicast(skb, tgt_net, NETLINK_CB(in_skb).portid);
5152errout_ifa:
5153 in6_ifa_put(ifa);
5154errout:
5155 if (dev)
5156 dev_put(dev);
5143 if (netnsid >= 0)
5157 if (fillargs.netnsid >= 0)
5144 put_net(tgt_net);
5145
5146 return err;
5147}
5148
5149static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
5150{
5151 struct sk_buff *skb;
5152 struct net *net = dev_net(ifa->idev->dev);
5158 put_net(tgt_net);
5159
5160 return err;
5161}
5162
5163static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
5164{
5165 struct sk_buff *skb;
5166 struct net *net = dev_net(ifa->idev->dev);
5167 struct inet6_fill_args fillargs = {
5168 .portid = 0,
5169 .seq = 0,
5170 .event = event,
5171 .flags = 0,
5172 .netnsid = -1,
5173 };
5153 int err = -ENOBUFS;
5154
5155 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
5156 if (!skb)
5157 goto errout;
5158
5174 int err = -ENOBUFS;
5175
5176 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
5177 if (!skb)
5178 goto errout;
5179
5159 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0, -1);
5180 err = inet6_fill_ifaddr(skb, ifa, &fillargs);
5160 if (err < 0) {
5161 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5162 WARN_ON(err == -EMSGSIZE);
5163 kfree_skb(skb);
5164 goto errout;
5165 }
5166 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
5167 return;

--- 1714 unchanged lines hidden ---
5181 if (err < 0) {
5182 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */
5183 WARN_ON(err == -EMSGSIZE);
5184 kfree_skb(skb);
5185 goto errout;
5186 }
5187 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
5188 return;

--- 1714 unchanged lines hidden ---