diff options
author | stephen hemminger <stephen@networkplumber.org> | 2013-12-12 16:06:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-14 00:58:22 -0500 |
commit | f085ff1c131c08fb6b34802f63c22921c4d8c506 (patch) | |
tree | 45f3f1819353cbcd4f89a2656b4384b0b9fea151 /net/ipv4/devinet.c | |
parent | 68536053600425c24aba031c45f053d447eedd9c (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.c | 41 |
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 | ||
1774 | static int inet_netconf_get_devconf(struct sk_buff *in_skb, | 1781 | static 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 | ||
1960 | static 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 | |||
1953 | static int devinet_conf_proc(struct ctl_table *ctl, int write, | 1973 | static 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; |