patch-1.3.99 linux/net/ipv4/route.c
Next file: linux/net/ipv4/tcp.c
Previous file: linux/net/ipv4/raw.c
Back to the patch index
Back to the overall index
- Lines: 289
- Date:
Tue May 7 12:06:54 1996
- Orig file:
v1.3.98/linux/net/ipv4/route.c
- Orig date:
Fri Apr 12 15:52:12 1996
diff -u --recursive --new-file v1.3.98/linux/net/ipv4/route.c linux/net/ipv4/route.c
@@ -321,42 +321,6 @@
}
/*
- * Used by 'rt_add()' when we can't get the netmask any other way..
- *
- * If the lower byte or two are zero, we guess the mask based on the
- * number of zero 8-bit net numbers, otherwise we use the "default"
- * masks judging by the destination address and our device netmask.
- */
-
-static __u32 unsigned long default_mask(__u32 dst)
-{
- dst = ntohl(dst);
- if (IN_CLASSA(dst))
- return htonl(IN_CLASSA_NET);
- if (IN_CLASSB(dst))
- return htonl(IN_CLASSB_NET);
- return htonl(IN_CLASSC_NET);
-}
-
-
-/*
- * If no mask is specified then generate a default entry.
- */
-
-static __u32 guess_mask(__u32 dst, struct device * dev)
-{
- __u32 mask;
-
- if (!dst)
- return 0;
- mask = default_mask(dst);
- if ((dst ^ dev->pa_addr) & mask)
- return mask;
- return dev->pa_mask;
-}
-
-
-/*
* Check if a mask is acceptable.
*/
@@ -527,50 +491,6 @@
struct fib_info * fi;
int logmask;
- if (flags & RTF_HOST)
- mask = 0xffffffff;
- /*
- * If mask is not specified, try to guess it.
- */
- else if (!mask)
- {
- if (!((dst ^ dev->pa_addr) & dev->pa_mask))
- {
- mask = dev->pa_mask;
- flags &= ~RTF_GATEWAY;
- if (flags & RTF_DYNAMIC)
- {
- printk("Dynamic route to my own net rejected\n");
- return;
- }
- }
- else
- mask = guess_mask(dst, dev);
- dst &= mask;
- }
-
- /*
- * A gateway must be reachable and not a local address
- */
-
- if (gw == dev->pa_addr)
- flags &= ~RTF_GATEWAY;
-
- if (flags & RTF_GATEWAY)
- {
- /*
- * Don't try to add a gateway we can't reach..
- * Tunnel devices are exempt from this rule.
- */
-
- if ((dev != get_gw_dev(gw)) && dev->type!=ARPHRD_TUNNEL)
- return;
-
- flags |= RTF_GATEWAY;
- }
- else
- gw = 0;
-
/*
* Allocate an entry and fill it in.
*/
@@ -632,7 +552,7 @@
if (fz->fz_nent >= RTZ_HASHING_LIMIT && !fz->fz_hash_table && logmask<32)
{
struct fib_node ** ht;
-#if RT_CACHE_DEBUG
+#if RT_CACHE_DEBUG >= 2
printk("fib_add_1: hashing for zone %d started\n", logmask);
#endif
ht = kmalloc(RTZ_HASH_DIVISOR*sizeof(struct rtable*), GFP_KERNEL);
@@ -747,7 +667,12 @@
struct fib_node *f;
while ((f = *fp) != NULL) {
- if (f->fib_info->fib_dev != dev) {
+/*
+ * "Magic" device route is allowed to point to loopback,
+ * discard it too.
+ */
+ if (f->fib_info->fib_dev != dev &&
+ (dev != &loopback_dev || f->fib_dst != dev->pa_addr)) {
fp = &f->fib_next;
continue;
}
@@ -797,7 +722,7 @@
*
* We preserve the old format but pad the buffers out. This means that
* we can spin over the other entries as we read them. Remember the
- * gated BGP4 code could need to read 60,000+ routes on occasion (thats
+ * gated BGP4 code could need to read 60,000+ routes on occasion (that's
* about 7Mb of data). To do that ok we will need to also cache the
* last route we got to (reads will generally be following on from
* one another without gaps).
@@ -961,12 +886,9 @@
{
struct hh_cache * hh = rt->rt_hh;
rt->rt_hh = NULL;
- if (hh && !--hh->hh_refcnt)
- {
- restore_flags(flags);
- kfree_s(hh, sizeof(struct hh_cache));
- }
restore_flags(flags);
+ if (hh && atomic_dec_and_test(&hh->hh_refcnt))
+ kfree_s(hh, sizeof(struct hh_cache));
kfree_s(rt, sizeof(struct rt_table));
return;
}
@@ -1000,12 +922,9 @@
#endif
*rtp = rt->rt_next;
rt->rt_hh = NULL;
- if (hh && !--hh->hh_refcnt)
- {
- sti();
- kfree_s(hh, sizeof(struct hh_cache));
- }
sti();
+ if (hh && atomic_dec_and_test(&hh->hh_refcnt))
+ kfree_s(hh, sizeof(struct hh_cache));
kfree_s(rt, sizeof(struct rt_table));
#if RT_CACHE_DEBUG >= 2
printk("rt_kick_free_queue: %08x is free\n", daddr);
@@ -1017,7 +936,8 @@
}
}
-void ip_rt_run_bh() {
+void ip_rt_run_bh()
+{
unsigned long flags;
save_flags(flags);
cli();
@@ -1409,7 +1329,7 @@
else
{
if (rtg->rt_hh)
- ATOMIC_INCR(&rtg->rt_hh->hh_refcnt);
+ atomic_inc(&rtg->rt_hh->hh_refcnt);
rth->rt_hh = rtg->rt_hh;
ip_rt_put(rtg);
}
@@ -1570,7 +1490,7 @@
{
rt_free(rth);
#if RT_CACHE_DEBUG >= 1
- printk("rt_cache: route to %08x was born dead\n", daddr);
+ printk(KERN_DEBUG "rt_cache: route to %08x was born dead\n", daddr);
#endif
}
@@ -1581,7 +1501,7 @@
void ip_rt_put(struct rtable * rt)
{
if (rt)
- ATOMIC_DECR(&rt->rt_refcnt);
+ atomic_dec(&rt->rt_refcnt);
}
struct rtable * ip_rt_route(__u32 daddr, int local)
@@ -1595,8 +1515,8 @@
if (rth->rt_dst == daddr)
{
rth->rt_lastuse = jiffies;
- ATOMIC_INCR(&rth->rt_use);
- ATOMIC_INCR(&rth->rt_refcnt);
+ atomic_inc(&rth->rt_use);
+ atomic_inc(&rth->rt_refcnt);
ip_rt_unlock();
return rth;
}
@@ -1671,42 +1591,49 @@
}
}
- /*
- * Ignore faulty masks
- */
-
- if (bad_mask(mask, daddr))
- mask=0;
-
- /*
- * Set the mask to nothing for host routes.
- */
-
- if (flags & RTF_HOST)
+ if (flags & RTF_HOST)
mask = 0xffffffff;
else if (mask && r->rt_genmask.sa_family != AF_INET)
return -EAFNOSUPPORT;
- /*
- * You can only gateway IP via IP..
- */
-
if (flags & RTF_GATEWAY)
{
if (r->rt_gateway.sa_family != AF_INET)
return -EAFNOSUPPORT;
+
+ /*
+ * Don't try to add a gateway we can't reach..
+ * Tunnel devices are exempt from this rule.
+ */
+
if (!dev)
dev = get_gw_dev(gw);
+ else if (dev != get_gw_dev(gw) && dev->type != ARPHRD_TUNNEL)
+ return -EINVAL;
+ if (!dev)
+ return -ENETUNREACH;
}
- else if (!dev)
- dev = ip_dev_check(daddr);
+ else
+ {
+ gw = 0;
+ if (!dev)
+ dev = ip_dev_bynet(daddr, mask);
+ if (!dev)
+ return -ENETUNREACH;
+ if (!mask)
+ {
+ if (((daddr ^ dev->pa_addr) & dev->pa_mask) == 0)
+ mask = dev->pa_mask;
+ }
+ }
- /*
- * Unknown device.
- */
-
- if (dev == NULL)
- return -ENETUNREACH;
+#ifndef CONFIG_IP_CLASSLESS
+ if (!mask)
+ mask = ip_get_mask(daddr);
+#endif
+
+ if (bad_mask(mask, daddr))
+ return -EINVAL;
/*
* Add the route
@@ -1783,3 +1710,10 @@
return;
}
+void ip_rt_update(int event, struct device *dev)
+{
+ if (event == NETDEV_UP)
+ rt_add(RTF_HOST|RTF_UP, dev->pa_addr, ~0, 0, dev, 0, 0, 0, 0);
+ else if (event == NETDEV_DOWN)
+ rt_del(dev->pa_addr, ~0, dev, 0, RTF_HOST|RTF_UP, 0);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this