Commit 9a218f37 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

Add new sysctl, medium_id, to devinet.

It is used to differentiate the devices by the medium
they are attached to.  It is used to change proxy_arp behavior:
the proxy arp feature is enabled for packets forwarded between
two devices attached to different media.
parent 1372dfd7
...@@ -355,6 +355,17 @@ mc_forwarding - BOOLEAN ...@@ -355,6 +355,17 @@ mc_forwarding - BOOLEAN
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
and a multicast routing daemon is required. and a multicast routing daemon is required.
medium_id - INTEGER
Integer value used to differentiate the devices by the medium they
are attached to. Two devices can have different id values when
the broadcast packets are received only on one of them.
The default value 0 means that the device is the only interface
to its medium, value of -1 means that medium is not known.
Currently, it is used to change the proxy_arp behavior:
the proxy_arp feature is enabled for packets forwarded between
two devices attached to different media.
proxy_arp - BOOLEAN proxy_arp - BOOLEAN
Do proxy arp. Do proxy arp.
......
...@@ -18,6 +18,7 @@ struct ipv4_devconf ...@@ -18,6 +18,7 @@ struct ipv4_devconf
int mc_forwarding; int mc_forwarding;
int tag; int tag;
int arp_filter; int arp_filter;
int medium_id;
void *sysctl; void *sysctl;
}; };
...@@ -48,6 +49,7 @@ struct in_device ...@@ -48,6 +49,7 @@ struct in_device
#define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects) #define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects)
#define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects)
#define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag)
#define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id)
#define IN_DEV_RX_REDIRECTS(in_dev) \ #define IN_DEV_RX_REDIRECTS(in_dev) \
((IN_DEV_FORWARD(in_dev) && \ ((IN_DEV_FORWARD(in_dev) && \
......
...@@ -333,7 +333,8 @@ enum ...@@ -333,7 +333,8 @@ enum
NET_IPV4_CONF_BOOTP_RELAY=10, NET_IPV4_CONF_BOOTP_RELAY=10,
NET_IPV4_CONF_LOG_MARTIANS=11, NET_IPV4_CONF_LOG_MARTIANS=11,
NET_IPV4_CONF_TAG=12, NET_IPV4_CONF_TAG=12,
NET_IPV4_CONF_ARPFILTER=13 NET_IPV4_CONF_ARPFILTER=13,
NET_IPV4_CONF_MEDIUM_ID=14,
}; };
/* /proc/sys/net/ipv6 */ /* /proc/sys/net/ipv6 */
......
...@@ -449,6 +449,32 @@ int arp_bind_neighbour(struct dst_entry *dst) ...@@ -449,6 +449,32 @@ int arp_bind_neighbour(struct dst_entry *dst)
return 0; return 0;
} }
/*
* Check if we can use proxy ARP for this path
*/
static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt)
{
struct in_device *out_dev;
int imi, omi = -1;
if (!IN_DEV_PROXY_ARP(in_dev))
return 0;
if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0)
return 1;
if (imi == -1)
return 0;
/* place to check for proxy_arp for routes */
if ((out_dev = in_dev_get(rt->u.dst.dev)) != NULL) {
omi = IN_DEV_MEDIUM_ID(out_dev);
in_dev_put(out_dev);
}
return (omi != imi && omi != -1);
}
/* /*
* Interface to link layer: send routine and receive handler. * Interface to link layer: send routine and receive handler.
*/ */
...@@ -755,7 +781,7 @@ int arp_process(struct sk_buff *skb) ...@@ -755,7 +781,7 @@ int arp_process(struct sk_buff *skb)
} else if (IN_DEV_FORWARD(in_dev)) { } else if (IN_DEV_FORWARD(in_dev)) {
if ((rt->rt_flags&RTCF_DNAT) || if ((rt->rt_flags&RTCF_DNAT) ||
(addr_type == RTN_UNICAST && rt->u.dst.dev != dev && (addr_type == RTN_UNICAST && rt->u.dst.dev != dev &&
(IN_DEV_PROXY_ARP(in_dev) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) { (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
n = neigh_event_ns(&arp_tbl, sha, &sip, dev); n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
if (n) if (n)
neigh_release(n); neigh_release(n);
......
...@@ -1032,7 +1032,7 @@ int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp, ...@@ -1032,7 +1032,7 @@ int devinet_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
static struct devinet_sysctl_table static struct devinet_sysctl_table
{ {
struct ctl_table_header *sysctl_header; struct ctl_table_header *sysctl_header;
ctl_table devinet_vars[14]; ctl_table devinet_vars[15];
ctl_table devinet_dev[2]; ctl_table devinet_dev[2];
ctl_table devinet_conf_dir[2]; ctl_table devinet_conf_dir[2];
ctl_table devinet_proto_dir[2]; ctl_table devinet_proto_dir[2];
...@@ -1066,6 +1066,9 @@ static struct devinet_sysctl_table ...@@ -1066,6 +1066,9 @@ static struct devinet_sysctl_table
{NET_IPV4_CONF_PROXY_ARP, "proxy_arp", {NET_IPV4_CONF_PROXY_ARP, "proxy_arp",
&ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL, &ipv4_devconf.proxy_arp, sizeof(int), 0644, NULL,
&proc_dointvec}, &proc_dointvec},
{NET_IPV4_CONF_MEDIUM_ID, "medium_id",
&ipv4_devconf.medium_id, sizeof(int), 0644, NULL,
&proc_dointvec},
{NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay", {NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay",
&ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL, &ipv4_devconf.bootp_relay, sizeof(int), 0644, NULL,
&proc_dointvec}, &proc_dointvec},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment