diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index ae8fdc5..e4d93b2 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -13,7 +13,7 @@ enum { - IPV4_DEVCONF_FORWARDING=1, + IPV4_DEVCONF_FORWARDING, IPV4_DEVCONF_MC_FORWARDING, IPV4_DEVCONF_PROXY_ARP, IPV4_DEVCONF_ACCEPT_REDIRECTS, @@ -38,10 +38,9 @@ enum IPV4_DEVCONF_ACCEPT_LOCAL, IPV4_DEVCONF_SRC_VMARK, IPV4_DEVCONF_PROXY_ARP_PVLAN, - __IPV4_DEVCONF_MAX + IPV4_DEVCONF_MAX }; -#define IPV4_DEVCONF_MAX (__IPV4_DEVCONF_MAX - 1) struct ipv4_devconf { void *sysctl; @@ -72,20 +71,18 @@ struct in_device { struct rcu_head rcu_head; }; -#define IPV4_DEVCONF(cnf, attr) ((cnf).data[IPV4_DEVCONF_ ## attr - 1]) +#define IPV4_DEVCONF(cnf, attr) ((cnf).data[IPV4_DEVCONF_ ## attr]) #define IPV4_DEVCONF_ALL(net, attr) \ IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr) static inline int ipv4_devconf_get(struct in_device *in_dev, int index) { - index--; return in_dev->cnf.data[index]; } static inline void ipv4_devconf_set(struct in_device *in_dev, int index, int val) { - index--; set_bit(index, in_dev->cnf.state); in_dev->cnf.data[index] = val; } diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 748cb5b..181d558 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -65,20 +65,20 @@ static struct ipv4_devconf ipv4_devconf = { .data = { - [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1, + [IPV4_DEVCONF_ACCEPT_REDIRECTS] = 1, + [IPV4_DEVCONF_SEND_REDIRECTS] = 1, + [IPV4_DEVCONF_SECURE_REDIRECTS] = 1, + [IPV4_DEVCONF_SHARED_MEDIA] = 1, }, }; static struct ipv4_devconf ipv4_devconf_dflt = { .data = { - [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1, - [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1, - [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1, + [IPV4_DEVCONF_ACCEPT_REDIRECTS] = 1, + [IPV4_DEVCONF_SEND_REDIRECTS] = 1, + [IPV4_DEVCONF_SECURE_REDIRECTS] = 1, + [IPV4_DEVCONF_SHARED_MEDIA] = 1, + [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE] = 1, }, }; @@ -1304,12 +1304,15 @@ static int inet_validate_link_af(const struct net_device *dev, if (tb[IFLA_INET_CONF]) { nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) { - int cfgid = nla_type(a); + /* Userspace indexes these ids starting from 1. + * This was the way the kernel indexed elements too, + * but now it counts from 0 */ + int cfgid = nla_type(a) - 1; if (nla_len(a) < 4) return -EINVAL; - if (cfgid <= 0 || cfgid > IPV4_DEVCONF_MAX) + if (cfgid < 0 || cfgid >= IPV4_DEVCONF_MAX) return -EINVAL; } } @@ -1330,8 +1333,13 @@ static int inet_set_link_af(struct net_device *dev, const struct nlattr *nla) BUG(); if (tb[IFLA_INET_CONF]) { - nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) - ipv4_devconf_set(in_dev, nla_type(a), nla_get_u32(a)); + nla_for_each_nested(a, tb[IFLA_INET_CONF], rem) { + /* Userspace indexes these ids starting from 1. + * This was the way the kernel indexed elements too, + * but now it counts from 0 */ + int cfgid = nla_type(a) - 1; + ipv4_devconf_set(in_dev, cfgid, nla_get_u32(a)); + } } return 0; @@ -1449,7 +1457,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write, { \ .procname = name, \ .data = ipv4_devconf.data + \ - IPV4_DEVCONF_ ## attr - 1, \ + IPV4_DEVCONF_ ## attr, \ .maxlen = sizeof(int), \ .mode = mval, \ .proc_handler = proc, \ @@ -1470,7 +1478,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write, static struct devinet_sysctl_table { struct ctl_table_header *sysctl_header; - struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX]; + struct ctl_table devinet_vars[IPV4_DEVCONF_MAX + 1]; char *dev_name; } devinet_sysctl = { .devinet_vars = { @@ -1505,6 +1513,7 @@ static struct devinet_sysctl_table { "force_igmp_version"), DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, "promote_secondaries"), + { } }, }; @@ -1590,8 +1599,7 @@ static void devinet_sysctl_unregister(struct in_device *idev) static struct ctl_table ctl_forward_entry[] = { { .procname = "ip_forward", - .data = &ipv4_devconf.data[ - IPV4_DEVCONF_FORWARDING - 1], + .data = &ipv4_devconf.data[IPV4_DEVCONF_FORWARDING], .maxlen = sizeof(int), .mode = 0644, .proc_handler = devinet_sysctl_forward, @@ -1635,7 +1643,7 @@ static __net_init int devinet_init_net(struct net *net) if (tbl == NULL) goto err_alloc_ctl; - tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1]; + tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING]; tbl[0].extra1 = all; tbl[0].extra2 = net; #endif