patch-2.4.26 linux-2.4.26/net/ipv4/devinet.c
Next file: linux-2.4.26/net/ipv4/icmp.c
Previous file: linux-2.4.26/net/ipv4/arp.c
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
2004-04-14 06:05:41.000000000 -0700
- Orig file:
linux-2.4.25/net/ipv4/devinet.c
- Orig date:
2004-02-18 05:36:32.000000000 -0800
diff -urN linux-2.4.25/net/ipv4/devinet.c linux-2.4.26/net/ipv4/devinet.c
@@ -151,7 +151,8 @@
#ifdef CONFIG_SYSCTL
devinet_sysctl_register(in_dev, &in_dev->cnf);
#endif
- if (dev->flags&IFF_UP)
+ ip_mc_init_dev(in_dev);
+ if (dev->flags & IFF_UP)
ip_mc_up(in_dev);
return in_dev;
}
@@ -772,6 +773,84 @@
return 0;
}
+static u32 confirm_addr_indev(struct in_device *in_dev, u32 dst,
+ u32 local, int scope)
+{
+ int same = 0;
+ u32 addr = 0;
+
+ for_ifa(in_dev) {
+ if (!addr &&
+ (local == ifa->ifa_local || !local) &&
+ ifa->ifa_scope <= scope) {
+ addr = ifa->ifa_local;
+ if (same)
+ break;
+ }
+ if (!same) {
+ same = (!local || inet_ifa_match(local, ifa)) &&
+ (!dst || inet_ifa_match(dst, ifa));
+ if (same && addr) {
+ if (local || !dst)
+ break;
+ /* Is the selected addr into dst subnet? */
+ if (inet_ifa_match(addr, ifa))
+ break;
+ /* No, then can we use new local src? */
+ if (ifa->ifa_scope <= scope) {
+ addr = ifa->ifa_local;
+ break;
+ }
+ /* search for large dst subnet for addr */
+ same = 0;
+ }
+ }
+ } endfor_ifa(in_dev);
+
+ return same? addr : 0;
+}
+
+/*
+ * Confirm that local IP address exists using wildcards:
+ * - dev: only on this interface, 0=any interface
+ * - dst: only in the same subnet as dst, 0=any dst
+ * - local: address, 0=autoselect the local address
+ * - scope: maximum allowed scope value for the local address
+ */
+u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scope)
+{
+ u32 addr = 0;
+ struct in_device *in_dev;
+
+ if (dev) {
+ read_lock(&inetdev_lock);
+ if ((in_dev = __in_dev_get(dev))) {
+ read_lock(&in_dev->lock);
+ addr = confirm_addr_indev(in_dev, dst, local, scope);
+ read_unlock(&in_dev->lock);
+ }
+ read_unlock(&inetdev_lock);
+
+ return addr;
+ }
+
+ read_lock(&dev_base_lock);
+ read_lock(&inetdev_lock);
+ for (dev = dev_base; dev; dev = dev->next) {
+ if ((in_dev = __in_dev_get(dev))) {
+ read_lock(&in_dev->lock);
+ addr = confirm_addr_indev(in_dev, dst, local, scope);
+ read_unlock(&in_dev->lock);
+ if (addr)
+ break;
+ }
+ }
+ read_unlock(&inetdev_lock);
+ read_unlock(&dev_base_lock);
+
+ return addr;
+}
+
/*
* Device notifier
*/
@@ -1012,10 +1091,9 @@
#ifdef CONFIG_SYSCTL
-void inet_forward_change()
+void inet_forward_change(int on)
{
struct net_device *dev;
- int on = ipv4_devconf.forwarding;
ipv4_devconf.accept_redirects = !on;
ipv4_devconf_dflt.forwarding = on;
@@ -1046,7 +1124,7 @@
if (write && *valp != val) {
if (valp == &ipv4_devconf.forwarding)
- inet_forward_change();
+ inet_forward_change(*valp);
else if (valp != &ipv4_devconf_dflt.forwarding)
rt_cache_flush(0);
}
@@ -1057,7 +1135,7 @@
static struct devinet_sysctl_table
{
struct ctl_table_header *sysctl_header;
- ctl_table devinet_vars[18];
+ ctl_table devinet_vars[20];
ctl_table devinet_dev[2];
ctl_table devinet_conf_dir[2];
ctl_table devinet_proto_dir[2];
@@ -1106,6 +1184,12 @@
{NET_IPV4_CONF_ARPFILTER, "arp_filter",
&ipv4_devconf.arp_filter, sizeof(int), 0644, NULL,
&proc_dointvec},
+ {NET_IPV4_CONF_ARP_ANNOUNCE, "arp_announce",
+ &ipv4_devconf.arp_announce, sizeof(int), 0644, NULL,
+ &proc_dointvec},
+ {NET_IPV4_CONF_ARP_IGNORE, "arp_ignore",
+ &ipv4_devconf.arp_ignore, sizeof(int), 0644, NULL,
+ &proc_dointvec},
{NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version",
&ipv4_devconf.force_igmp_version, sizeof(int), 0644, NULL,
&proc_dointvec},
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)