?? route.generic
字號:
fib_disable_ip(ifa->ifa_dev->dev, 1); } else {+ printk("fib_inetaddr_event: dev down, fib_del_ifaddr\n"); fib_del_ifaddr(ifa); rt_cache_flush(-1); }@@ -606,11 +665,10 @@ struct net_device *dev = ptr; struct in_device *in_dev = __in_dev_get(dev); - if (!in_dev)- return NOTIFY_DONE;- switch (event) { case NETDEV_UP:+ if (!in_dev)+ break; for_ifa(in_dev) { fib_add_ifaddr(ifa); } endfor_ifa(in_dev);@@ -620,9 +678,18 @@ rt_cache_flush(-1); break; case NETDEV_DOWN:+ printk("fib_netdev_event: dev down, fib_disable_ip(0)\n"); fib_disable_ip(dev, 0); break; case NETDEV_UNREGISTER:+ /* Routes pointing to dev may still exists even when IP has+ * been shut down. It may happen because routes of local type+ * has special nexthop (see fib_create_info() and+ * fib_sync_dev_down()). I don't know if this state is valid.+ * Now I call fib_disable_ip() independently from if the device+ * has IP because otherwise stale device references are left.+ * 1999/11/28 SAW */+ printk("fib_netdev_event: dev unregister, fib_disable_ip(1)\n"); fib_disable_ip(dev, 1); break; case NETDEV_CHANGEMTU:diff -ru -x*~ linux-lt-2.3.99-pre3.prev/net/ipv4/fib_semantics.c linux-lt-2.3.99-pre3/net/ipv4/fib_semantics.c--- linux-lt-2.3.99-pre3.prev/net/ipv4/fib_semantics.c Tue Aug 24 01:01:02 1999+++ linux-lt-2.3.99-pre3/net/ipv4/fib_semantics.c Tue Mar 28 19:39:50 2000@@ -345,14 +345,15 @@ { int err; + if (nh->nh_flags&RTNH_F_PERVASIVE) {+ fi->fib_flags |= RTCF_PERVASIVE;+ return 0;+ }+ if (nh->nh_gw) { struct rt_key key; struct fib_result res; -#ifdef CONFIG_IP_ROUTE_PERVASIVE- if (nh->nh_flags&RTNH_F_PERVASIVE)- return 0;-#endif if (nh->nh_flags&RTNH_F_ONLINK) { struct net_device *dev; @@ -389,7 +390,7 @@ } else { struct in_device *in_dev; - if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))+ if (nh->nh_flags&RTNH_F_ONLINK) return -EINVAL; in_dev = inetdev_by_index(nh->nh_oif);@@ -528,7 +529,7 @@ } endfor_nexthops(fi) } - if (fi->fib_prefsrc) {+ if (fi->fib_prefsrc && !(fi->fib_flags&RTCF_PERVASIVE)) { if (r->rtm_type != RTN_LOCAL || rta->rta_dst == NULL || memcmp(&fi->fib_prefsrc, rta->rta_dst, 4)) if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)@@ -857,19 +858,34 @@ - device went down -> we must shutdown all nexthops going via it. */ -int fib_sync_down(u32 local, struct net_device *dev, int force)+int fib_sync_addr_down(u32 local)+{+ int ret = 0;++ if (!local)+ goto out;++ for_fib_info() {+ if (fi->fib_prefsrc == local &&+ !(fi->fib_flags&RTCF_PERVASIVE)) {+ fi->fib_flags |= RTCF_DEAD;+ ret++;+ }+ } endfor_fib_info();+out:+ return ret;+}++int fib_sync_dev_down(struct net_device *dev, int force) { int ret = 0; int scope = RT_SCOPE_NOWHERE;- + if (force) scope = -1; for_fib_info() {- if (local && fi->fib_prefsrc == local) {- fi->fib_flags |= RTNH_F_DEAD;- ret++;- } else if (dev && fi->fib_nhs) {+ if (fi->fib_nhs) { int dead = 0; change_nexthops(fi) {@@ -886,7 +902,7 @@ } } endfor_nexthops(fi) if (dead == fi->fib_nhs) {- fi->fib_flags |= RTNH_F_DEAD;+ fi->fib_flags |= RTCF_DEAD; ret++; } }@@ -947,6 +963,10 @@ int power = 0; change_nexthops(fi) { if (!(nh->nh_flags&RTNH_F_DEAD)) {+ if (nh->nh_flags&RTNH_F_USEFIRST) {+ res->nh_sel = nhsel;+ return;+ } power += nh->nh_weight; nh->nh_power = nh->nh_weight; }diff -ru -x*~ linux-lt-2.3.99-pre3.prev/net/ipv4/route.c linux-lt-2.3.99-pre3/net/ipv4/route.c--- linux-lt-2.3.99-pre3.prev/net/ipv4/route.c Mon Mar 27 18:25:56 2000+++ linux-lt-2.3.99-pre3/net/ipv4/route.c Tue Mar 28 19:57:19 2000@@ -711,22 +711,28 @@ struct rtable *rth, **rthp; u32 skeys[2] = { saddr, 0 }; int ikeys[2] = { dev->ifindex, 0 };+ char *reason; tos &= IPTOS_TOS_MASK; if (!in_dev) return; + reason = "bad gateway"; if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) || MULTICAST(new_gw) || BADCLASS(new_gw) || ZERONET(new_gw)) goto reject_redirect; if (!IN_DEV_SHARED_MEDIA(in_dev)) {- if (!inet_addr_onlink(in_dev, new_gw, old_gw))+ reason = "gateway not onlink";+ if (!inet_addr_onlink(dev, new_gw, saddr, tos)) goto reject_redirect;- if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))+ reason = "insecure gateway";+ if (IN_DEV_SEC_REDIRECTS(in_dev) &&+ ip_fib_check_default(new_gw, dev)) goto reject_redirect; } else {+ reason = "unacceptable gateway"; if (inet_addr_type(new_gw) != RTN_UNICAST) goto reject_redirect; }@@ -816,9 +822,9 @@ reject_redirect: #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())- printk(KERN_INFO "Redirect from %X/%s to %X ignored."+ printk(KERN_INFO "Redirect from %X/%s to %X ignored (%s). " "Path = %X -> %X, tos %02x\n",- ntohl(old_gw), dev->name, ntohl(new_gw),+ ntohl(old_gw), dev->name, ntohl(new_gw), reason, ntohl(saddr), ntohl(daddr), tos); #endif in_dev_put(in_dev);@@ -836,7 +842,7 @@ if ((rt->rt_flags&RTCF_REDIRECTED) || rt->u.dst.expires) { unsigned hash = rt_hash_code(rt->key.dst, rt->key.src^(rt->key.oif<<5), rt->key.tos); #if RT_CACHE_DEBUG >= 1- printk(KERN_DEBUG "ip_rt_advice: redirect to %d.%d.%d.%d/%02x dropped\n", NIPQUAD(rt->rt_dst), rt->key.tos);+ printk(KERN_DEBUG "ip_rt_advice: cache entry to %d.%d.%d.%d/%02x dropped\n", NIPQUAD(rt->rt_dst), rt->key.tos); #endif rt_del(hash, rt); return NULL;@@ -1106,6 +1112,10 @@ } #endif +/*********************************************************************+ Input/output routing+ *********************************************************************/+ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) { struct fib_info *fi = res->fi;@@ -1145,6 +1155,10 @@ rt->rt_type = res->type; } +/*********************************************************************+ Input+ *********************************************************************/+ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr, u8 tos, struct net_device *dev, int our)@@ -1362,9 +1376,7 @@ if (err) flags |= RTCF_DIRECTSRC; - if (out_dev == in_dev && err && !(flags&(RTCF_NAT|RTCF_MASQ)) &&- (IN_DEV_SHARED_MEDIA(out_dev)- || inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res))))+ if (out_dev == in_dev && err && !(flags&(RTCF_NAT|RTCF_MASQ))) flags |= RTCF_DOREDIRECT; if (skb->protocol != __constant_htons(ETH_P_IP)) {@@ -1592,22 +1604,183 @@ return ip_route_input_slow(skb, daddr, saddr, tos, dev); } +/*********************************************************************+ Output+ *********************************************************************/++/* TODO:+ - Check if CONFIG_IP_MROUTE ifdef makes any sense.+ */++/* User supplied source address verification for output packets.+ Such a verification can't be considered as a security measure.+ It's rather an additional Internet protection against bugs in applications+ (like using an uninitialized garbage as a source for UDP packets).+ */+static int outrt_check_src(u32 saddr, u32 daddr, u32 tos, struct net_device *dev_out)+{+ struct in_device *in_dev;+ int src_check;++ if (MULTICAST(saddr) || BADCLASS(saddr) || ZERONET(saddr))+ return -EINVAL;+ if (saddr == htonl(INADDR_BROADCAST))+ return -EINVAL;++ in_dev = in_dev_get(dev_out);+ src_check = IN_DEV_SRC_CHECK(in_dev);+ in_dev_put(in_dev);+ if (!src_check)+ return 0;++ if (LOOPBACK(saddr) && !(dev_out->flags&IFF_LOOPBACK))+ return -EINVAL;++ return fib_local_source(saddr, daddr, tos, dev_out);+}++static int outrt_make_route(struct rtable **rp,+ /* route lookup key */+ struct rt_key *key,+ /* path */+ u32 daddr, u32 saddr, struct net_device *dev_out,+ /* FIB lookup results (type, fi, nh.gw, nh.scope) */+ struct fib_result *res+ )+{+ struct rtable *rth;+ unsigned hash;+ unsigned flags;++ rth = dst_alloc(&ipv4_dst_ops);+ if (!rth)+ return -ENOBUFS;++ atomic_set(&rth->u.dst.__refcnt, 1);+ rth->u.dst.flags= DST_HOST;+ rth->key = *key;+ rth->key.iif = 0; /* output route */+ rth->rt_dst = daddr;+ rth->rt_src = saddr;+#ifdef CONFIG_IP_ROUTE_NAT+ rth->rt_dst_map = daddr;+ rth->rt_src_map = saddr;+#endif++ /* Set input, output ROUTINES and rt_spec_dst */+ switch (res->type) {+ case RTN_LOCAL:+ /* Use loopback interface for unicast local traffic */+ fib_res_put(res);+ res->fi = NULL;+#ifdef CONFIG_IP_MULTIPLE_TABLES+ res->r = NULL;+#endif+ dev_out = &loopback_dev;+ flags = RTCF_LOCAL;+ rth->u.dst.input = ip_local_deliver;+ rth->u.dst.output = ip_output;+ rth->rt_spec_dst = daddr; /* local side of the path */+ break;+ case RTN_UNICAST:+ flags = 0;+ rth->u.dst.output = ip_output;+ rth->rt_spec_dst = saddr;+#ifdef CONFIG_IP_ROUTE_MULTIPATH+ if (res->fi->fib_nhs > 1 && key->oif == 0)+ /* Set the proper res->nh_sel. */+ fib_select_multipath(key, res);+ else+#endif+ if (res->prefixlen == 0 && res->type == RTN_UNICAST &&+ key->oif == 0)+ fib_select_default(key, res);+ break;+ case RTN_BROADCAST:+ flags = RTCF_BROADCAST|RTCF_LOCAL;+ rth->u.dst.input = ip_local_deliver;+ if (!(dev_out->flags&IFF_LOOPBACK))+ rth->u.dst.output = ip_mc_output;+ else+ rth->u.dst.output = ip_output;+ rth->rt_spec_dst = saddr;+ break;+ case RTN_MULTICAST:+ {+ /* Please note that all ancient band-aids were removed.+ I don't try to catch route table deficient for+ multicast or 255.255.255.255 routes and "smartly"+ replace a gatewayed default by the corresponding+ route. 1999/11/06 SAW+ */+ struct in_device *in_dev = in_dev_get(dev_out);+ rth->u.dst.input = ip_local_deliver;+ rth->u.dst.output = ip_output;+ flags = RTCF_MULTICAST;+ if (in_dev && ip_check_mc(in_dev, daddr)) {+ /* Note: I preserve the original behaviour+ here. It means that users after joining and+ leaving a multicast group have to flush+ the route cache. I hope they know about it+ :-) 1999/11/06 SAW+ */+ flags = RTCF_MULTICAST|RTCF_LOCAL;+ if (!(dev_out->flags&IFF_LOOPBACK))+ rth->u.dst.output = ip_mc_output;+ }+#ifdef CONFIG_IP_MROUTE+ if (in_dev && !(dev_out->flags&IFF_LOOPBACK)) {+ if (IN_DEV_MFORWARD(in_dev) &&+ !LOCAL_MCAST(daddr))+ {+ rth->u.dst.input = ip_mr_input;+ rth->u.dst.output = ip_mc_output;+ }+ }+#endif+ if (in_dev)+ in_dev_put(in_dev);+ rth->rt_spec_dst = saddr;+ }+ break;+ case RTN_NAT:+ dst_free(&rth->u.dst);+ return -EINVAL;+ default:+ printk(KERN_CRIT "bad lookup result type in route output\n");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -