devinet.c (aaccf3c97418f169afdbb5855e9cbcbda34e90fd) devinet.c (dac9c9790e542777079999900594fd069ba10489)
1/*
2 * NET3 IP device support routines.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

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

95static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
96 [IFA_LOCAL] = { .type = NLA_U32 },
97 [IFA_ADDRESS] = { .type = NLA_U32 },
98 [IFA_BROADCAST] = { .type = NLA_U32 },
99 [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
100 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
101 [IFA_FLAGS] = { .type = NLA_U32 },
102 [IFA_RT_PRIORITY] = { .type = NLA_U32 },
1/*
2 * NET3 IP device support routines.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

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

95static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
96 [IFA_LOCAL] = { .type = NLA_U32 },
97 [IFA_ADDRESS] = { .type = NLA_U32 },
98 [IFA_BROADCAST] = { .type = NLA_U32 },
99 [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
100 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
101 [IFA_FLAGS] = { .type = NLA_U32 },
102 [IFA_RT_PRIORITY] = { .type = NLA_U32 },
103 [IFA_TARGET_NETNSID] = { .type = NLA_S32 },
103};
104
104};
105
106struct inet_fill_args {
107 u32 portid;
108 u32 seq;
109 int event;
110 unsigned int flags;
111 int netnsid;
112};
113
105#define IN4_ADDR_HSIZE_SHIFT 8
106#define IN4_ADDR_HSIZE (1U << IN4_ADDR_HSIZE_SHIFT)
107
108static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE];
109
110static u32 inet_addr_hash(const struct net *net, __be32 addr)
111{
112 u32 val = (__force u32) addr ^ net_hash_mix(net);

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

768 ifa->ifa_preferred_lft = timeout;
769 }
770 ifa->ifa_tstamp = jiffies;
771 if (!ifa->ifa_cstamp)
772 ifa->ifa_cstamp = ifa->ifa_tstamp;
773}
774
775static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
114#define IN4_ADDR_HSIZE_SHIFT 8
115#define IN4_ADDR_HSIZE (1U << IN4_ADDR_HSIZE_SHIFT)
116
117static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE];
118
119static u32 inet_addr_hash(const struct net *net, __be32 addr)
120{
121 u32 val = (__force u32) addr ^ net_hash_mix(net);

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

777 ifa->ifa_preferred_lft = timeout;
778 }
779 ifa->ifa_tstamp = jiffies;
780 if (!ifa->ifa_cstamp)
781 ifa->ifa_cstamp = ifa->ifa_tstamp;
782}
783
784static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
776 __u32 *pvalid_lft, __u32 *pprefered_lft)
785 __u32 *pvalid_lft, __u32 *pprefered_lft,
786 struct netlink_ext_ack *extack)
777{
778 struct nlattr *tb[IFA_MAX+1];
779 struct in_ifaddr *ifa;
780 struct ifaddrmsg *ifm;
781 struct net_device *dev;
782 struct in_device *in_dev;
783 int err;
784
785 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
787{
788 struct nlattr *tb[IFA_MAX+1];
789 struct in_ifaddr *ifa;
790 struct ifaddrmsg *ifm;
791 struct net_device *dev;
792 struct in_device *in_dev;
793 int err;
794
795 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy,
786 NULL);
796 extack);
787 if (err < 0)
788 goto errout;
789
790 ifm = nlmsg_data(nlh);
791 err = -EINVAL;
792 if (ifm->ifa_prefixlen > 32 || !tb[IFA_LOCAL])
793 goto errout;
794

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

883 struct net *net = sock_net(skb->sk);
884 struct in_ifaddr *ifa;
885 struct in_ifaddr *ifa_existing;
886 __u32 valid_lft = INFINITY_LIFE_TIME;
887 __u32 prefered_lft = INFINITY_LIFE_TIME;
888
889 ASSERT_RTNL();
890
797 if (err < 0)
798 goto errout;
799
800 ifm = nlmsg_data(nlh);
801 err = -EINVAL;
802 if (ifm->ifa_prefixlen > 32 || !tb[IFA_LOCAL])
803 goto errout;
804

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

893 struct net *net = sock_net(skb->sk);
894 struct in_ifaddr *ifa;
895 struct in_ifaddr *ifa_existing;
896 __u32 valid_lft = INFINITY_LIFE_TIME;
897 __u32 prefered_lft = INFINITY_LIFE_TIME;
898
899 ASSERT_RTNL();
900
891 ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft);
901 ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft, extack);
892 if (IS_ERR(ifa))
893 return PTR_ERR(ifa);
894
895 ifa_existing = find_matching_ifa(ifa);
896 if (!ifa_existing) {
897 /* It would be best to check for !NLM_F_CREATE here but
898 * userspace already relies on not having to provide this.
899 */

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

1579 ci.tstamp = cstamp_delta(tstamp);
1580 ci.ifa_prefered = preferred;
1581 ci.ifa_valid = valid;
1582
1583 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
1584}
1585
1586static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
902 if (IS_ERR(ifa))
903 return PTR_ERR(ifa);
904
905 ifa_existing = find_matching_ifa(ifa);
906 if (!ifa_existing) {
907 /* It would be best to check for !NLM_F_CREATE here but
908 * userspace already relies on not having to provide this.
909 */

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

1589 ci.tstamp = cstamp_delta(tstamp);
1590 ci.ifa_prefered = preferred;
1591 ci.ifa_valid = valid;
1592
1593 return nla_put(skb, IFA_CACHEINFO, sizeof(ci), &ci);
1594}
1595
1596static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1587 u32 portid, u32 seq, int event, unsigned int flags)
1597 struct inet_fill_args *args)
1588{
1589 struct ifaddrmsg *ifm;
1590 struct nlmsghdr *nlh;
1591 u32 preferred, valid;
1592
1598{
1599 struct ifaddrmsg *ifm;
1600 struct nlmsghdr *nlh;
1601 u32 preferred, valid;
1602
1593 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*ifm), flags);
1603 nlh = nlmsg_put(skb, args->portid, args->seq, args->event, sizeof(*ifm),
1604 args->flags);
1594 if (!nlh)
1595 return -EMSGSIZE;
1596
1597 ifm = nlmsg_data(nlh);
1598 ifm->ifa_family = AF_INET;
1599 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1600 ifm->ifa_flags = ifa->ifa_flags;
1601 ifm->ifa_scope = ifa->ifa_scope;
1602 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1603
1605 if (!nlh)
1606 return -EMSGSIZE;
1607
1608 ifm = nlmsg_data(nlh);
1609 ifm->ifa_family = AF_INET;
1610 ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1611 ifm->ifa_flags = ifa->ifa_flags;
1612 ifm->ifa_scope = ifa->ifa_scope;
1613 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
1614
1615 if (args->netnsid >= 0 &&
1616 nla_put_s32(skb, IFA_TARGET_NETNSID, args->netnsid))
1617 goto nla_put_failure;
1618
1604 if (!(ifm->ifa_flags & IFA_F_PERMANENT)) {
1605 preferred = ifa->ifa_preferred_lft;
1606 valid = ifa->ifa_valid_lft;
1607 if (preferred != INFINITY_LIFE_TIME) {
1608 long tval = (jiffies - ifa->ifa_tstamp) / HZ;
1609
1610 if (preferred > tval)
1611 preferred -= tval;

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

1642
1643nla_put_failure:
1644 nlmsg_cancel(skb, nlh);
1645 return -EMSGSIZE;
1646}
1647
1648static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1649{
1619 if (!(ifm->ifa_flags & IFA_F_PERMANENT)) {
1620 preferred = ifa->ifa_preferred_lft;
1621 valid = ifa->ifa_valid_lft;
1622 if (preferred != INFINITY_LIFE_TIME) {
1623 long tval = (jiffies - ifa->ifa_tstamp) / HZ;
1624
1625 if (preferred > tval)
1626 preferred -= tval;

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

1657
1658nla_put_failure:
1659 nlmsg_cancel(skb, nlh);
1660 return -EMSGSIZE;
1661}
1662
1663static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
1664{
1665 struct inet_fill_args fillargs = {
1666 .portid = NETLINK_CB(cb->skb).portid,
1667 .seq = cb->nlh->nlmsg_seq,
1668 .event = RTM_NEWADDR,
1669 .flags = NLM_F_MULTI,
1670 .netnsid = -1,
1671 };
1650 struct net *net = sock_net(skb->sk);
1672 struct net *net = sock_net(skb->sk);
1673 struct nlattr *tb[IFA_MAX+1];
1674 struct net *tgt_net = net;
1651 int h, s_h;
1652 int idx, s_idx;
1653 int ip_idx, s_ip_idx;
1654 struct net_device *dev;
1655 struct in_device *in_dev;
1656 struct in_ifaddr *ifa;
1657 struct hlist_head *head;
1658
1659 s_h = cb->args[0];
1660 s_idx = idx = cb->args[1];
1661 s_ip_idx = ip_idx = cb->args[2];
1662
1675 int h, s_h;
1676 int idx, s_idx;
1677 int ip_idx, s_ip_idx;
1678 struct net_device *dev;
1679 struct in_device *in_dev;
1680 struct in_ifaddr *ifa;
1681 struct hlist_head *head;
1682
1683 s_h = cb->args[0];
1684 s_idx = idx = cb->args[1];
1685 s_ip_idx = ip_idx = cb->args[2];
1686
1687 if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,
1688 ifa_ipv4_policy, cb->extack) >= 0) {
1689 if (tb[IFA_TARGET_NETNSID]) {
1690 fillargs.netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
1691
1692 tgt_net = rtnl_get_net_ns_capable(skb->sk,
1693 fillargs.netnsid);
1694 if (IS_ERR(tgt_net))
1695 return PTR_ERR(tgt_net);
1696 }
1697 }
1698
1663 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1664 idx = 0;
1699 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
1700 idx = 0;
1665 head = &net->dev_index_head[h];
1701 head = &tgt_net->dev_index_head[h];
1666 rcu_read_lock();
1702 rcu_read_lock();
1667 cb->seq = atomic_read(&net->ipv4.dev_addr_genid) ^
1668 net->dev_base_seq;
1703 cb->seq = atomic_read(&tgt_net->ipv4.dev_addr_genid) ^
1704 tgt_net->dev_base_seq;
1669 hlist_for_each_entry_rcu(dev, head, index_hlist) {
1670 if (idx < s_idx)
1671 goto cont;
1672 if (h > s_h || idx > s_idx)
1673 s_ip_idx = 0;
1674 in_dev = __in_dev_get_rcu(dev);
1675 if (!in_dev)
1676 goto cont;
1677
1678 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1679 ifa = ifa->ifa_next, ip_idx++) {
1680 if (ip_idx < s_ip_idx)
1681 continue;
1705 hlist_for_each_entry_rcu(dev, head, index_hlist) {
1706 if (idx < s_idx)
1707 goto cont;
1708 if (h > s_h || idx > s_idx)
1709 s_ip_idx = 0;
1710 in_dev = __in_dev_get_rcu(dev);
1711 if (!in_dev)
1712 goto cont;
1713
1714 for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
1715 ifa = ifa->ifa_next, ip_idx++) {
1716 if (ip_idx < s_ip_idx)
1717 continue;
1682 if (inet_fill_ifaddr(skb, ifa,
1683 NETLINK_CB(cb->skb).portid,
1684 cb->nlh->nlmsg_seq,
1685 RTM_NEWADDR, NLM_F_MULTI) < 0) {
1718 if (inet_fill_ifaddr(skb, ifa, &fillargs) < 0) {
1686 rcu_read_unlock();
1687 goto done;
1688 }
1689 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1690 }
1691cont:
1692 idx++;
1693 }
1694 rcu_read_unlock();
1695 }
1696
1697done:
1698 cb->args[0] = h;
1699 cb->args[1] = idx;
1700 cb->args[2] = ip_idx;
1719 rcu_read_unlock();
1720 goto done;
1721 }
1722 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1723 }
1724cont:
1725 idx++;
1726 }
1727 rcu_read_unlock();
1728 }
1729
1730done:
1731 cb->args[0] = h;
1732 cb->args[1] = idx;
1733 cb->args[2] = ip_idx;
1734 if (fillargs.netnsid >= 0)
1735 put_net(tgt_net);
1701
1702 return skb->len;
1703}
1704
1705static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
1706 u32 portid)
1707{
1736
1737 return skb->len;
1738}
1739
1740static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
1741 u32 portid)
1742{
1743 struct inet_fill_args fillargs = {
1744 .portid = portid,
1745 .seq = nlh ? nlh->nlmsg_seq : 0,
1746 .event = event,
1747 .flags = 0,
1748 .netnsid = -1,
1749 };
1708 struct sk_buff *skb;
1750 struct sk_buff *skb;
1709 u32 seq = nlh ? nlh->nlmsg_seq : 0;
1710 int err = -ENOBUFS;
1711 struct net *net;
1712
1713 net = dev_net(ifa->ifa_dev->dev);
1714 skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
1715 if (!skb)
1716 goto errout;
1717
1751 int err = -ENOBUFS;
1752 struct net *net;
1753
1754 net = dev_net(ifa->ifa_dev->dev);
1755 skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
1756 if (!skb)
1757 goto errout;
1758
1718 err = inet_fill_ifaddr(skb, ifa, portid, seq, event, 0);
1759 err = inet_fill_ifaddr(skb, ifa, &fillargs);
1719 if (err < 0) {
1720 /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
1721 WARN_ON(err == -EMSGSIZE);
1722 kfree_skb(skb);
1723 goto errout;
1724 }
1725 rtnl_notify(skb, net, portid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1726 return;

--- 803 unchanged lines hidden ---
1760 if (err < 0) {
1761 /* -EMSGSIZE implies BUG in inet_nlmsg_size() */
1762 WARN_ON(err == -EMSGSIZE);
1763 kfree_skb(skb);
1764 goto errout;
1765 }
1766 rtnl_notify(skb, net, portid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1767 return;

--- 803 unchanged lines hidden ---