⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 route.generic

📁 VRRP双机热备份协议源吗
💻 GENERIC
📖 第 1 页 / 共 3 页
字号:
+			return -EINVAL;+	}++	/* INTERFACE */+	/* Store the interface information to allow users to get it via+	 * [SOL_IP, IP_PKTINFO] conrol message for locally seen packets+	 * (including broadcast and multicast ones).  --SAW */+	rth->rt_iif	= key->oif ? : dev_out->ifindex;+	/* Set output device */+	rth->u.dst.dev	= dev_out;+	dev_hold(dev_out);++	/* Set GATEWAY */+	rth->rt_gateway = daddr;+	/* if res->fi != NULL set the real gateway */+	rt_set_nexthop(rth, res, 0);++	rth->rt_flags = flags;++	hash = rt_hash_code(key->dst, key->src^(key->oif<<5), key->tos);+	return rt_intern_hash(hash, rth, rp);+}+ /*  * Major route resolver routine.  */- int ip_route_output_slow(struct rtable **rp, u32 daddr, u32 saddr, u32 tos, int oif) { 	struct rt_key key; 	struct fib_result res;-	unsigned flags = 0;-	struct rtable *rth; 	struct net_device *dev_out = NULL;-	unsigned hash;-	int free_res = 0; 	int err; -	tos &= IPTOS_TOS_MASK|RTO_ONLINK; 	key.dst = daddr; 	key.src = saddr; 	key.tos = tos&IPTOS_TOS_MASK;@@ -1619,252 +1792,100 @@ 	res.r = NULL; #endif -	if (saddr) {-		if (MULTICAST(saddr) || BADCLASS(saddr) || ZERONET(saddr))-			return -EINVAL;--		/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */-		dev_out = ip_dev_find(saddr);-		if (dev_out == NULL)-			return -EINVAL;--		/* I removed check for oif == dev_out->oif here.-		   It was wrong by three reasons:-		   1. ip_dev_find(saddr) can return wrong iface, if saddr is-		      assigned to multiple interfaces.-		   2. Moreover, we are allowed to send packets with saddr-		      of another iface. --ANK-		 */--		if (oif == 0 &&-			(MULTICAST(daddr) || daddr == 0xFFFFFFFF)) {-			/* Special hack: user can direct multicasts-			   and limited broadcast via necessary interface-			   without fiddling with IP_MULTICAST_IF or IP_PKTINFO.-			   This hack is not just for fun, it allows-			   vic,vat and friends to work.-			   They bind socket to loopback, set ttl to zero-			   and expect that it will work.-			   From the viewpoint of routing cache they are broken,-			   because we are not allowed to build multicast path-			   with loopback source addr (look, routing cache-			   cannot know, that ttl is zero, so that packet-			   will not leave this host and route is valid).-			   Luckily, this hack is good workaround.-			 */--			key.oif = dev_out->ifindex;-			goto make_route;-		}-		if (dev_out)-			dev_put(dev_out);-		dev_out = NULL;-	}-	if (oif) {-		dev_out = dev_get_by_index(oif);-		if (dev_out == NULL)-			return -ENODEV;-		if (__in_dev_get(dev_out) == NULL) {-			dev_put(dev_out);-			return -ENODEV;	/* Wrong error code */-		}--		if (LOCAL_MCAST(daddr) || daddr == 0xFFFFFFFF) {-			if (!key.src)-				key.src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK);-			goto make_route;-		}-		if (!key.src) {-			if (MULTICAST(daddr))-				key.src = inet_select_addr(dev_out, 0, key.scope);-			else if (!daddr)-				key.src = inet_select_addr(dev_out, 0, RT_SCOPE_HOST);-		}-	}+	if (!daddr)+		goto dest_insanity; -	if (!key.dst) {-		key.dst = key.src;-		if (!key.dst)-			key.dst = key.src = htonl(INADDR_LOOPBACK);-		if (dev_out)-			dev_put(dev_out);-		dev_out = &loopback_dev;+	err = fib_lookup(&key, &res);+	if (!err) {+		dev_out = FIB_RES_DEV(res); 		dev_hold(dev_out);-		key.oif = loopback_dev.ifindex;-		res.type = RTN_LOCAL;-		flags |= RTCF_LOCAL;-		goto make_route;-	}--	if (fib_lookup(&key, &res)) {-		res.fi = NULL;-		if (oif) {-			/* Apparently, routing tables are wrong. Assume,-			   that the destination is on link.--			   WHY? DW.-			   Because we are allowed to send to iface-			   even if it has NO routes and NO assigned-			   addresses. When oif is specified, routing-			   tables are looked up with only one purpose:-			   to catch if destination is gatewayed, rather than-			   direct. Moreover, if MSG_DONTROUTE is set,-			   we send packet, ignoring both routing tables-			   and ifaddr state. --ANK---			   We could make it even if oif is unknown,-			   likely IPv6, but we do not.+		if (saddr) {+			/* Verify user supplied source address */+			err = outrt_check_src(saddr, daddr, tos, dev_out);+		} else {+			/* Obtain path source from routing table */+			saddr = FIB_RES_PREFSRC(res);+			/* We don't verify source address obtained from routing+			 * table.  It's a task of administrators to keep it+			 * sane. 			 */--			if (key.src == 0)-				key.src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK);-			res.type = RTN_UNICAST;-			goto make_route; 		}-		if (dev_out)-			dev_put(dev_out);-		return -ENETUNREACH;-	}-	free_res = 1;--	if (res.type == RTN_NAT)-		goto e_inval;--	if (res.type == RTN_LOCAL) {-		if (!key.src)-			key.src = key.dst;-		if (dev_out)-			dev_put(dev_out);-		dev_out = &loopback_dev;-		dev_hold(dev_out);-		key.oif = dev_out->ifindex;-		if (res.fi)-			fib_info_put(res.fi);-		res.fi = NULL;-		flags |= RTCF_LOCAL;-		goto make_route;-	}--#ifdef CONFIG_IP_ROUTE_MULTIPATH-	if (res.fi->fib_nhs > 1 && key.oif == 0)-		fib_select_multipath(&key, &res);-	else-#endif-	if (res.prefixlen==0 && res.type == RTN_UNICAST && key.oif == 0)-		fib_select_default(&key, &res);--	if (!key.src)-		key.src = FIB_RES_PREFSRC(res);--	if (dev_out)-		dev_put(dev_out);-	dev_out = FIB_RES_DEV(res);-	dev_hold(dev_out);-	key.oif = dev_out->ifindex;--make_route:-	if (LOOPBACK(key.src) && !(dev_out->flags&IFF_LOOPBACK))-		goto e_inval;--	if (key.dst == 0xFFFFFFFF)-		res.type = RTN_BROADCAST;-	else if (MULTICAST(key.dst))-		res.type = RTN_MULTICAST;-	else if (BADCLASS(key.dst) || ZERONET(key.dst))-		goto e_inval;+		if (!err)+			err = outrt_make_route(rp, &key, daddr, saddr,+					dev_out, &res);+		fib_res_put(&res);+		/* The usual code path ends here */ -	if (dev_out->flags&IFF_LOOPBACK)-		flags |= RTCF_LOCAL;+	} else if (err == -ENETUNREACH) { -	if (res.type == RTN_BROADCAST) {-		flags |= RTCF_BROADCAST|RTCF_LOCAL;-		if (res.fi) {-			fib_info_put(res.fi);-			res.fi = NULL;-		}-	} else if (res.type == RTN_MULTICAST) {-		flags |= RTCF_MULTICAST|RTCF_LOCAL;-		read_lock(&inetdev_lock);-		if (!__in_dev_get(dev_out) || !ip_check_mc(__in_dev_get(dev_out), daddr))-			flags &= ~RTCF_LOCAL;-		read_unlock(&inetdev_lock);-		/* If multicast route do not exist use-		   default one, but do not gateway in this case.-		   Yes, it is hack.+		/* Just return if the access is prohibited etc.+		   If the routing table doesn't have both an appropriate route+		   and a default assume that the destination is on link.  --SAW++		   WHY? DW.+		   Because we are allowed to send to iface+		   even if it has NO routes and NO assigned+		   addresses. When oif is specified, routing+		   tables are looked up with only one purpose:+		   to catch if destination is gatewayed, rather than+		   direct. Moreover, if MSG_DONTROUTE is set,+		   we send packet, ignoring both routing tables+		   and ifaddr state. --ANK++		   We could make it even if oif is unknown,+		   likely IPv6, but we do not.++		   The above statements aren't exactly correct.+		   Routing tables contain a lot of useful information (like+		   preferred source, for instance).  But the general idea is+		   right.  --SAW 		 */-		if (res.fi && res.prefixlen < 4) {-			fib_info_put(res.fi);-			res.fi = NULL;-		}-	}--	rth = dst_alloc(&ipv4_dst_ops);-	if (!rth)-		goto e_nobufs;--	atomic_set(&rth->u.dst.__refcnt, 1);-	rth->u.dst.flags= DST_HOST;-	rth->key.dst	= daddr;-	rth->key.tos	= tos;-	rth->key.src	= saddr;-	rth->key.iif	= 0;-	rth->key.oif	= oif;-	rth->rt_dst	= key.dst;-	rth->rt_src	= key.src;-#ifdef CONFIG_IP_ROUTE_NAT-	rth->rt_dst_map	= key.dst;-	rth->rt_src_map	= key.src;-#endif-	rth->rt_iif	= oif ? : dev_out->ifindex;-	rth->u.dst.dev	= dev_out;-	dev_hold(dev_out);-	rth->rt_gateway = key.dst;-	rth->rt_spec_dst= key.src;--	rth->u.dst.output=ip_output;--	if (flags&RTCF_LOCAL) {-		rth->u.dst.input = ip_local_deliver;-		rth->rt_spec_dst = key.dst;-	}-	if (flags&(RTCF_BROADCAST|RTCF_MULTICAST)) {-		rth->rt_spec_dst = key.src;-		if (flags&RTCF_LOCAL && !(dev_out->flags&IFF_LOOPBACK))-			rth->u.dst.output = ip_mc_output;-#ifdef CONFIG_IP_MROUTE-		if (res.type == RTN_MULTICAST) {-			struct in_device *in_dev = in_dev_get(dev_out);-			if (in_dev) {-				if (IN_DEV_MFORWARD(in_dev) && !LOCAL_MCAST(daddr)) {-					rth->u.dst.input = ip_mr_input;-					rth->u.dst.output = ip_mc_output;-				}-				in_dev_put(in_dev);+		if (oif) {+			err = -ENODEV;+			dev_out = dev_get_by_index(oif);+			if (dev_out == NULL)+				goto out;+			if (__in_dev_get(dev_out) == NULL)+				goto out;	/* Wrong error code */+			if (saddr) {+				/* Verify user supplied source address */+				err = outrt_check_src(saddr, daddr, tos, dev_out);+				if (err)+					goto out;+			} else {+				int scope;+				if (LOCAL_MCAST(daddr) || daddr == 0xFFFFFFFF)+					scope = RT_SCOPE_LINK;+				else if (MULTICAST(daddr))+					scope = key.scope;+				else+					scope = RT_SCOPE_HOST;+				saddr = inet_select_addr(dev_out, 0, scope); 			}-		}-#endif+			res.type = RTN_UNICAST;+			res.fi = NULL;+			err = outrt_make_route(rp, &key, daddr, saddr, dev_out,+					&res);+		} else+			err = -ENETUNREACH; 	}--	rt_set_nexthop(rth, &res, 0);--	rth->rt_flags = flags;--	hash = rt_hash_code(daddr, saddr^(oif<<5), tos);-	err = rt_intern_hash(hash, rth, rp);-done:-	if (free_res)-		fib_res_put(&res);+out: 	if (dev_out) 		dev_put(dev_out); 	return err; -e_inval:-	err = -EINVAL;-	goto done;-e_nobufs:-	err = -ENOBUFS;-	goto done;+	/* I don't know what reason this hack was for */+dest_insanity:+	daddr = saddr;+	if (!daddr)+		daddr = saddr = htonl(INADDR_LOOPBACK);+	dev_out = &loopback_dev;+	dev_hold(dev_out);+	key.oif = loopback_dev.ifindex;+	res.type = RTN_LOCAL;+	res.fi = NULL;+	err = outrt_make_route(rp, &key, daddr, saddr, dev_out, &res);+	goto out; }  int ip_route_output(struct rtable **rp, u32 daddr, u32 saddr, u32 tos, int oif)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -