patch-2.1.22 linux/net/ipv4/fib.c
Next file: linux/net/ipv4/ip_forward.c
Previous file: linux/net/ipv4/devinet.c
Back to the patch index
Back to the overall index
- Lines: 252
- Date:
Sun Jan 19 15:47:28 1997
- Orig file:
v2.1.21/linux/net/ipv4/fib.c
- Orig date:
Wed Dec 18 15:59:14 1996
diff -u --recursive --new-file v2.1.21/linux/net/ipv4/fib.c linux/net/ipv4/fib.c
@@ -66,7 +66,7 @@
static int fib_stamp;
-int rtmsg_process(struct nlmsghdr *n, struct in_rtmsg *r);
+static int rtmsg_process(struct nlmsghdr *n, struct in_rtmsg *r);
#ifdef CONFIG_RTNETLINK
@@ -119,7 +119,7 @@
static struct wait_queue *fib_wait;
atomic_t fib_users;
-void fib_lock(void)
+static void fib_lock(void)
{
while (fib_users)
sleep_on(&fib_wait);
@@ -127,7 +127,7 @@
dev_lock_list();
}
-void fib_unlock(void)
+static void fib_unlock(void)
{
dev_unlock_list();
if (atomic_dec_and_test(&fib_users)) {
@@ -496,7 +496,7 @@
struct fib_zone * fz;
if (((src^cl->cl_src) & cl->cl_srcmask) ||
- ((dst^cl->cl_dst) & cl->cl_dstmask) ||
+ ((daddr^cl->cl_dst) & cl->cl_dstmask) ||
(cl->cl_tos && cl->cl_tos != tos) ||
(cl->cl_dev && cl->cl_dev != devin))
continue;
@@ -561,7 +561,7 @@
((struct sockaddr_in*)&r.arp_pa)->sin_family = AF_INET;
((struct sockaddr_in*)&r.arp_pa)->sin_addr.s_addr = addr;
((struct sockaddr_in*)&r.arp_netmask)->sin_family = AF_INET;
- ((struct sockaddr_in*)&r.arp_netmask)->sin_addr.s_addr = fib_netmask(logmask);
+ ((struct sockaddr_in*)&r.arp_netmask)->sin_addr.s_addr = fib_mask(logmask);
if (op)
return arp_req_set(&r, NULL);
@@ -570,7 +570,8 @@
for (f1 = fz_hash(f->fib_key, fz); f1; f1=f1->fib_next) {
if (f->fib_key != f1->fib_key || f1->fib_flag ||
- f->fib_info->fib_flags != f1->fib_info->fib_flags)
+ (!RT_LOCALADDR(f1->fib_info->fib_flags) &&
+ !(f1->fib_info->fib_flags&RTF_NAT)))
continue;
return 0;
}
@@ -1032,6 +1033,8 @@
cli();
*fp = f->fib_next;
sti();
+ if (class == &local_class)
+ fib_autopublish(0, f, logmask);
#ifdef CONFIG_RTNETLINK
if (rt_nl_flags&RTCTL_FLUSH)
rtmsg_fib(RTMSG_DELROUTE, f, logmask, class, 0);
@@ -1397,7 +1400,7 @@
#endif
-int rtmsg_process(struct nlmsghdr *n, struct in_rtmsg *r)
+static int rtmsg_process(struct nlmsghdr *n, struct in_rtmsg *r)
{
unsigned long cmd=n->nlmsg_type;
struct device * dev = NULL;
@@ -1414,7 +1417,7 @@
/* Reject/throw directives have no interface/gateway specification */
if (r->rtmsg_flags & (RTF_REJECT|RTF_THROW)) {
- r->rtmsg_device[0] = 0;
+ r->rtmsg_ifindex = 0;
r->rtmsg_gateway.s_addr = 0;
r->rtmsg_flags &= ~RTF_GATEWAY;
}
@@ -1430,8 +1433,8 @@
if (cmd == RTMSG_DELROUTE)
r->rtmsg_flags &= RTF_FIB;
- if (r->rtmsg_device[0]) {
- dev = dev_get(r->rtmsg_device);
+ if (r->rtmsg_ifindex) {
+ dev = dev_get_by_index(r->rtmsg_ifindex);
if (!dev) {
rtmsg_ack(n, ENODEV);
return -ENODEV;
@@ -1525,8 +1528,8 @@
(r->rtrmsg_tos & ~IPTOS_TOS_MASK))
return -EINVAL;
- if (r->rtrmsg_device[0]) {
- dev = dev_get(r->rtrmsg_device);
+ if (r->rtrmsg_ifindex) {
+ dev = dev_get_by_index(r->rtrmsg_ifindex);
if (!dev)
return -ENODEV;
if (dev->family != AF_INET)
@@ -1574,9 +1577,18 @@
err = copy_from_user(&r, arg, sizeof(struct rtentry));
if (err)
return -EFAULT;
- if (r.rt_dev)
- if (copy_from_user(&rtm->rtmsg_device, r.rt_dev, 15))
+ if (r.rt_dev) {
+ struct device *dev;
+ char devname[16];
+
+ if (copy_from_user(devname, r.rt_dev, 15))
return -EFAULT;
+ devname[15] = 0;
+ dev = dev_get(devname);
+ if (!dev)
+ return -ENODEV;
+ rtm->rtmsg_ifindex = dev->ifindex;
+ }
rtm->rtmsg_flags = r.rt_flags;
@@ -1740,9 +1752,7 @@
r->rtmsg_mtu = fi->fib_mtu;
r->rtmsg_window = fi->fib_window;
r->rtmsg_rtt = fi->fib_irtt;
- memset(r->rtmsg_device, 0, sizeof(r->rtmsg_device));
- if (fi->fib_dev)
- strcpy(r->rtmsg_device, fi->fib_dev->name);
+ r->rtmsg_ifindex = fi->fib_dev ? fi->fib_dev->ifindex : 0;
}
}
end_bh_atomic();
@@ -1777,7 +1787,8 @@
r->ifmsg_mtu = dev->mtu;
r->ifmsg_metric = dev->metric;
r->ifmsg_prefixlen = 32 - fib_logmask(dev->pa_mask);
- strcpy(r->ifmsg_device, dev->name);
+ r->ifmsg_index = dev->ifindex;
+ strcpy(r->ifmsg_name, dev->name);
}
end_bh_atomic();
}
@@ -1866,6 +1877,28 @@
(&r, dev, (flags&RTF_LOCAL) ? &local_class : &main_class, &n);
}
+static void ip_rt_del_broadcasts(struct device *dev)
+{
+ u32 net = dev->pa_addr&dev->pa_mask;
+
+ fib_magic(RTMSG_DELROUTE, RTF_IFBRD, dev->pa_brdaddr, ~0, dev);
+ fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net, ~0, dev);
+ fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net|~dev->pa_mask, ~0, dev);
+}
+
+static void ip_rt_add_broadcasts(struct device *dev, u32 brd, u32 mask)
+{
+ u32 net = dev->pa_addr&mask;
+
+ if (dev->flags&IFF_BROADCAST)
+ fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, brd, ~0, dev);
+
+ if (net && !(mask&htonl(1))) {
+ fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net, ~0, dev);
+ fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net|~mask, ~0, dev);
+ }
+}
+
void ip_rt_change_broadcast(struct device *dev, u32 new_brd)
{
fib_lock();
@@ -1875,7 +1908,7 @@
fib_magic(RTMSG_DELROUTE, RTF_IFBRD, dev->pa_brdaddr, ~0, dev);
rtmsg_dev(RTMSG_DELDEVICE, dev, NULL);
rtmsg_dev(RTMSG_NEWDEVICE, dev, NULL);
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, new_brd, ~0, dev);
+ ip_rt_add_broadcasts(dev, new_brd, dev->pa_mask);
}
fib_unlock();
}
@@ -1908,22 +1941,19 @@
}
net = dev->pa_addr&dev->pa_mask;
fib_magic(RTMSG_DELROUTE, RTF_IFPREFIX, net, dev->pa_mask, dev);
- fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net, ~0, dev);
- fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net|~dev->pa_mask, ~0, dev);
+ ip_rt_del_broadcasts(dev);
if (mask != 0xFFFFFFFF && dev->flags&IFF_POINTOPOINT)
fib_magic(RTMSG_DELROUTE, RTF_IFPREFIX, dev->pa_dstaddr, ~0, dev);
rtmsg_dev(RTMSG_DELDEVICE, dev, NULL);
- dev->flags &= ~IFF_POINTOPOINT;
+ if (mask != 0xFFFFFFFF)
+ dev->flags &= ~IFF_POINTOPOINT;
rtmsg_dev(RTMSG_NEWDEVICE, dev, NULL);
net = dev->pa_addr&mask;
if (net)
fib_magic(RTMSG_NEWROUTE, RTF_IFPREFIX, net, mask, dev);
- if (net && mask != 0xFFFFFFFF) {
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net, ~0, dev);
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net|~mask, ~0, dev);
- }
+ ip_rt_add_broadcasts(dev, dev->pa_addr, mask);
fib_unlock();
}
@@ -1947,8 +1977,7 @@
else {
u32 net = dev->pa_addr&dev->pa_mask;
fib_magic(RTMSG_DELROUTE, RTF_IFPREFIX, net, dev->pa_mask, dev);
- fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net, ~0, dev);
- fib_magic(RTMSG_DELROUTE, RTF_IFBRD, net|~dev->pa_mask, ~0, dev);
+ ip_rt_del_broadcasts(dev);
}
rtmsg_dev(RTMSG_DELDEVICE, dev, NULL);
}
@@ -1971,14 +2000,12 @@
if (dev->flags&IFF_POINTOPOINT) {
if (dev->pa_dstaddr && dev->type != ARPHRD_TUNNEL)
fib_magic(RTMSG_NEWROUTE, RTF_IFPREFIX, dev->pa_dstaddr, ~0, dev);
- } else if (dev->pa_addr&dev->pa_mask) {
+ } else {
u32 net = dev->pa_addr&dev->pa_mask;
- fib_magic(RTMSG_NEWROUTE, RTF_IFPREFIX, net, dev->pa_mask, dev);
- if (dev->pa_mask != 0xFFFFFFFF) {
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net, ~0, dev);
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, net|~dev->pa_mask, ~0, dev);
- }
+ if (net)
+ fib_magic(RTMSG_NEWROUTE, RTF_IFPREFIX, net, dev->pa_mask, dev);
+ ip_rt_add_broadcasts(dev, dev->pa_brdaddr, dev->pa_mask);
}
fib_magic(RTMSG_NEWROUTE, RTF_IFLOCAL, dev->pa_addr, ~0, dev);
if (dev == &loopback_dev) {
@@ -1992,9 +2019,9 @@
mask, dev);
}
}
- if (dev->flags&IFF_BROADCAST)
- fib_magic(RTMSG_NEWROUTE, RTF_IFBRD, dev->pa_brdaddr, ~0, dev);
}
+ if (event == NETDEV_CHANGEMTU || event == NETDEV_CHANGEADDR)
+ rtmsg_dev(RTMSG_NEWDEVICE, dev, NULL);
fib_unlock();
return NOTIFY_DONE;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov