aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c62
1 files changed, 42 insertions, 20 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a1b5bcbd04ae..0feebd5de295 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -99,6 +99,7 @@ static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
99 [IFA_BROADCAST] = { .type = NLA_U32 }, 99 [IFA_BROADCAST] = { .type = NLA_U32 },
100 [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 100 [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 },
101 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, 101 [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
102 [IFA_FLAGS] = { .type = NLA_U32 },
102}; 103};
103 104
104#define IN4_ADDR_HSIZE_SHIFT 8 105#define IN4_ADDR_HSIZE_SHIFT 8
@@ -500,6 +501,7 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
500 return -ENOBUFS; 501 return -ENOBUFS;
501 } 502 }
502 ipv4_devconf_setall(in_dev); 503 ipv4_devconf_setall(in_dev);
504 neigh_parms_data_state_setall(in_dev->arp_parms);
503 if (ifa->ifa_dev != in_dev) { 505 if (ifa->ifa_dev != in_dev) {
504 WARN_ON(ifa->ifa_dev); 506 WARN_ON(ifa->ifa_dev);
505 in_dev_hold(in_dev); 507 in_dev_hold(in_dev);
@@ -747,6 +749,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
747 goto errout; 749 goto errout;
748 750
749 ipv4_devconf_setall(in_dev); 751 ipv4_devconf_setall(in_dev);
752 neigh_parms_data_state_setall(in_dev->arp_parms);
750 in_dev_hold(in_dev); 753 in_dev_hold(in_dev);
751 754
752 if (tb[IFA_ADDRESS] == NULL) 755 if (tb[IFA_ADDRESS] == NULL)
@@ -755,7 +758,8 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
755 INIT_HLIST_NODE(&ifa->hash); 758 INIT_HLIST_NODE(&ifa->hash);
756 ifa->ifa_prefixlen = ifm->ifa_prefixlen; 759 ifa->ifa_prefixlen = ifm->ifa_prefixlen;
757 ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen); 760 ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
758 ifa->ifa_flags = ifm->ifa_flags; 761 ifa->ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) :
762 ifm->ifa_flags;
759 ifa->ifa_scope = ifm->ifa_scope; 763 ifa->ifa_scope = ifm->ifa_scope;
760 ifa->ifa_dev = in_dev; 764 ifa->ifa_dev = in_dev;
761 765
@@ -1236,22 +1240,21 @@ static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
1236 1240
1237/* 1241/*
1238 * Confirm that local IP address exists using wildcards: 1242 * Confirm that local IP address exists using wildcards:
1239 * - in_dev: only on this interface, 0=any interface 1243 * - net: netns to check, cannot be NULL
1244 * - in_dev: only on this interface, NULL=any interface
1240 * - dst: only in the same subnet as dst, 0=any dst 1245 * - dst: only in the same subnet as dst, 0=any dst
1241 * - local: address, 0=autoselect the local address 1246 * - local: address, 0=autoselect the local address
1242 * - scope: maximum allowed scope value for the local address 1247 * - scope: maximum allowed scope value for the local address
1243 */ 1248 */
1244__be32 inet_confirm_addr(struct in_device *in_dev, 1249__be32 inet_confirm_addr(struct net *net, struct in_device *in_dev,
1245 __be32 dst, __be32 local, int scope) 1250 __be32 dst, __be32 local, int scope)
1246{ 1251{
1247 __be32 addr = 0; 1252 __be32 addr = 0;
1248 struct net_device *dev; 1253 struct net_device *dev;
1249 struct net *net;
1250 1254
1251 if (scope != RT_SCOPE_LINK) 1255 if (in_dev != NULL)
1252 return confirm_addr_indev(in_dev, dst, local, scope); 1256 return confirm_addr_indev(in_dev, dst, local, scope);
1253 1257
1254 net = dev_net(in_dev->dev);
1255 rcu_read_lock(); 1258 rcu_read_lock();
1256 for_each_netdev_rcu(net, dev) { 1259 for_each_netdev_rcu(net, dev) {
1257 in_dev = __in_dev_get_rcu(dev); 1260 in_dev = __in_dev_get_rcu(dev);
@@ -1435,7 +1438,8 @@ static size_t inet_nlmsg_size(void)
1435 + nla_total_size(4) /* IFA_ADDRESS */ 1438 + nla_total_size(4) /* IFA_ADDRESS */
1436 + nla_total_size(4) /* IFA_LOCAL */ 1439 + nla_total_size(4) /* IFA_LOCAL */
1437 + nla_total_size(4) /* IFA_BROADCAST */ 1440 + nla_total_size(4) /* IFA_BROADCAST */
1438 + nla_total_size(IFNAMSIZ); /* IFA_LABEL */ 1441 + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
1442 + nla_total_size(4); /* IFA_FLAGS */
1439} 1443}
1440 1444
1441static inline u32 cstamp_delta(unsigned long cstamp) 1445static inline u32 cstamp_delta(unsigned long cstamp)
@@ -1503,6 +1507,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1503 nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) || 1507 nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) ||
1504 (ifa->ifa_label[0] && 1508 (ifa->ifa_label[0] &&
1505 nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) || 1509 nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
1510 nla_put_u32(skb, IFA_FLAGS, ifa->ifa_flags) ||
1506 put_cacheinfo(skb, ifa->ifa_cstamp, ifa->ifa_tstamp, 1511 put_cacheinfo(skb, ifa->ifa_cstamp, ifa->ifa_tstamp,
1507 preferred, valid)) 1512 preferred, valid))
1508 goto nla_put_failure; 1513 goto nla_put_failure;
@@ -1691,6 +1696,8 @@ static int inet_netconf_msgsize_devconf(int type)
1691 size += nla_total_size(4); 1696 size += nla_total_size(4);
1692 if (type == -1 || type == NETCONFA_MC_FORWARDING) 1697 if (type == -1 || type == NETCONFA_MC_FORWARDING)
1693 size += nla_total_size(4); 1698 size += nla_total_size(4);
1699 if (type == -1 || type == NETCONFA_PROXY_NEIGH)
1700 size += nla_total_size(4);
1694 1701
1695 return size; 1702 return size;
1696} 1703}
@@ -1727,6 +1734,10 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
1727 nla_put_s32(skb, NETCONFA_MC_FORWARDING, 1734 nla_put_s32(skb, NETCONFA_MC_FORWARDING,
1728 IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0) 1735 IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0)
1729 goto nla_put_failure; 1736 goto nla_put_failure;
1737 if ((type == -1 || type == NETCONFA_PROXY_NEIGH) &&
1738 nla_put_s32(skb, NETCONFA_PROXY_NEIGH,
1739 IPV4_DEVCONF(*devconf, PROXY_ARP)) < 0)
1740 goto nla_put_failure;
1730 1741
1731 return nlmsg_end(skb, nlh); 1742 return nlmsg_end(skb, nlh);
1732 1743
@@ -1764,6 +1775,7 @@ static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = {
1764 [NETCONFA_IFINDEX] = { .len = sizeof(int) }, 1775 [NETCONFA_IFINDEX] = { .len = sizeof(int) },
1765 [NETCONFA_FORWARDING] = { .len = sizeof(int) }, 1776 [NETCONFA_FORWARDING] = { .len = sizeof(int) },
1766 [NETCONFA_RP_FILTER] = { .len = sizeof(int) }, 1777 [NETCONFA_RP_FILTER] = { .len = sizeof(int) },
1778 [NETCONFA_PROXY_NEIGH] = { .len = sizeof(int) },
1767}; 1779};
1768 1780
1769static int inet_netconf_get_devconf(struct sk_buff *in_skb, 1781static int inet_netconf_get_devconf(struct sk_buff *in_skb,
@@ -1945,6 +1957,19 @@ static void inet_forward_change(struct net *net)
1945 } 1957 }
1946} 1958}
1947 1959
1960static int devinet_conf_ifindex(struct net *net, struct ipv4_devconf *cnf)
1961{
1962 if (cnf == net->ipv4.devconf_dflt)
1963 return NETCONFA_IFINDEX_DEFAULT;
1964 else if (cnf == net->ipv4.devconf_all)
1965 return NETCONFA_IFINDEX_ALL;
1966 else {
1967 struct in_device *idev
1968 = container_of(cnf, struct in_device, cnf);
1969 return idev->dev->ifindex;
1970 }
1971}
1972
1948static int devinet_conf_proc(struct ctl_table *ctl, int write, 1973static int devinet_conf_proc(struct ctl_table *ctl, int write,
1949 void __user *buffer, 1974 void __user *buffer,
1950 size_t *lenp, loff_t *ppos) 1975 size_t *lenp, loff_t *ppos)
@@ -1957,6 +1982,7 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
1957 struct ipv4_devconf *cnf = ctl->extra1; 1982 struct ipv4_devconf *cnf = ctl->extra1;
1958 struct net *net = ctl->extra2; 1983 struct net *net = ctl->extra2;
1959 int i = (int *)ctl->data - cnf->data; 1984 int i = (int *)ctl->data - cnf->data;
1985 int ifindex;
1960 1986
1961 set_bit(i, cnf->state); 1987 set_bit(i, cnf->state);
1962 1988
@@ -1966,23 +1992,19 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
1966 i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) 1992 i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
1967 if ((new_value == 0) && (old_value != 0)) 1993 if ((new_value == 0) && (old_value != 0))
1968 rt_cache_flush(net); 1994 rt_cache_flush(net);
1995
1969 if (i == IPV4_DEVCONF_RP_FILTER - 1 && 1996 if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
1970 new_value != old_value) { 1997 new_value != old_value) {
1971 int ifindex; 1998 ifindex = devinet_conf_ifindex(net, cnf);
1972
1973 if (cnf == net->ipv4.devconf_dflt)
1974 ifindex = NETCONFA_IFINDEX_DEFAULT;
1975 else if (cnf == net->ipv4.devconf_all)
1976 ifindex = NETCONFA_IFINDEX_ALL;
1977 else {
1978 struct in_device *idev =
1979 container_of(cnf, struct in_device,
1980 cnf);
1981 ifindex = idev->dev->ifindex;
1982 }
1983 inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER, 1999 inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER,
1984 ifindex, cnf); 2000 ifindex, cnf);
1985 } 2001 }
2002 if (i == IPV4_DEVCONF_PROXY_ARP - 1 &&
2003 new_value != old_value) {
2004 ifindex = devinet_conf_ifindex(net, cnf);
2005 inet_netconf_notify_devconf(net, NETCONFA_PROXY_NEIGH,
2006 ifindex, cnf);
2007 }
1986 } 2008 }
1987 2009
1988 return ret; 2010 return ret;
@@ -2160,7 +2182,7 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
2160 2182
2161static void devinet_sysctl_register(struct in_device *idev) 2183static void devinet_sysctl_register(struct in_device *idev)
2162{ 2184{
2163 neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL); 2185 neigh_sysctl_register(idev->dev, idev->arp_parms, NULL);
2164 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, 2186 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
2165 &idev->cnf); 2187 &idev->cnf);
2166} 2188}