aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorstephen hemminger <stephen@networkplumber.org>2013-12-12 16:06:50 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-14 00:58:22 -0500
commitf085ff1c131c08fb6b34802f63c22921c4d8c506 (patch)
tree45f3f1819353cbcd4f89a2656b4384b0b9fea151 /net/ipv4/devinet.c
parent68536053600425c24aba031c45f053d447eedd9c (diff)
netconf: add proxy-arp support
Add support to netconf to show changes to proxy-arp status on a per interface basis via netlink in a manner similar to forwarding and reverse path state. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 84956f5f0135..de03fe7002d0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1696,6 +1696,8 @@ static int inet_netconf_msgsize_devconf(int type)
1696 size += nla_total_size(4); 1696 size += nla_total_size(4);
1697 if (type == -1 || type == NETCONFA_MC_FORWARDING) 1697 if (type == -1 || type == NETCONFA_MC_FORWARDING)
1698 size += nla_total_size(4); 1698 size += nla_total_size(4);
1699 if (type == -1 || type == NETCONFA_PROXY_ARP)
1700 size += nla_total_size(4);
1699 1701
1700 return size; 1702 return size;
1701} 1703}
@@ -1732,6 +1734,10 @@ static int inet_netconf_fill_devconf(struct sk_buff *skb, int ifindex,
1732 nla_put_s32(skb, NETCONFA_MC_FORWARDING, 1734 nla_put_s32(skb, NETCONFA_MC_FORWARDING,
1733 IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0) 1735 IPV4_DEVCONF(*devconf, MC_FORWARDING)) < 0)
1734 goto nla_put_failure; 1736 goto nla_put_failure;
1737 if ((type == -1 || type == NETCONFA_PROXY_ARP) &&
1738 nla_put_s32(skb, NETCONFA_PROXY_ARP,
1739 IPV4_DEVCONF(*devconf, PROXY_ARP)) < 0)
1740 goto nla_put_failure;
1735 1741
1736 return nlmsg_end(skb, nlh); 1742 return nlmsg_end(skb, nlh);
1737 1743
@@ -1769,6 +1775,7 @@ static const struct nla_policy devconf_ipv4_policy[NETCONFA_MAX+1] = {
1769 [NETCONFA_IFINDEX] = { .len = sizeof(int) }, 1775 [NETCONFA_IFINDEX] = { .len = sizeof(int) },
1770 [NETCONFA_FORWARDING] = { .len = sizeof(int) }, 1776 [NETCONFA_FORWARDING] = { .len = sizeof(int) },
1771 [NETCONFA_RP_FILTER] = { .len = sizeof(int) }, 1777 [NETCONFA_RP_FILTER] = { .len = sizeof(int) },
1778 [NETCONFA_PROXY_ARP] = { .len = sizeof(int) },
1772}; 1779};
1773 1780
1774static int inet_netconf_get_devconf(struct sk_buff *in_skb, 1781static int inet_netconf_get_devconf(struct sk_buff *in_skb,
@@ -1950,6 +1957,19 @@ static void inet_forward_change(struct net *net)
1950 } 1957 }
1951} 1958}
1952 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
1953static int devinet_conf_proc(struct ctl_table *ctl, int write, 1973static int devinet_conf_proc(struct ctl_table *ctl, int write,
1954 void __user *buffer, 1974 void __user *buffer,
1955 size_t *lenp, loff_t *ppos) 1975 size_t *lenp, loff_t *ppos)
@@ -1962,6 +1982,7 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
1962 struct ipv4_devconf *cnf = ctl->extra1; 1982 struct ipv4_devconf *cnf = ctl->extra1;
1963 struct net *net = ctl->extra2; 1983 struct net *net = ctl->extra2;
1964 int i = (int *)ctl->data - cnf->data; 1984 int i = (int *)ctl->data - cnf->data;
1985 int ifindex;
1965 1986
1966 set_bit(i, cnf->state); 1987 set_bit(i, cnf->state);
1967 1988
@@ -1971,23 +1992,19 @@ static int devinet_conf_proc(struct ctl_table *ctl, int write,
1971 i == IPV4_DEVCONF_ROUTE_LOCALNET - 1) 1992 i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
1972 if ((new_value == 0) && (old_value != 0)) 1993 if ((new_value == 0) && (old_value != 0))
1973 rt_cache_flush(net); 1994 rt_cache_flush(net);
1995
1974 if (i == IPV4_DEVCONF_RP_FILTER - 1 && 1996 if (i == IPV4_DEVCONF_RP_FILTER - 1 &&
1975 new_value != old_value) { 1997 new_value != old_value) {
1976 int ifindex; 1998 ifindex = devinet_conf_ifindex(net, cnf);
1977
1978 if (cnf == net->ipv4.devconf_dflt)
1979 ifindex = NETCONFA_IFINDEX_DEFAULT;
1980 else if (cnf == net->ipv4.devconf_all)
1981 ifindex = NETCONFA_IFINDEX_ALL;
1982 else {
1983 struct in_device *idev =
1984 container_of(cnf, struct in_device,
1985 cnf);
1986 ifindex = idev->dev->ifindex;
1987 }
1988 inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER, 1999 inet_netconf_notify_devconf(net, NETCONFA_RP_FILTER,
1989 ifindex, cnf); 2000 ifindex, cnf);
1990 } 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_ARP,
2006 ifindex, cnf);
2007 }
1991 } 2008 }
1992 2009
1993 return ret; 2010 return ret;