1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Add three new route flags to help determine what sort of address

the destination represents.  For IP:

- Iff it is a host route, RTF_LOCAL and RTF_BROADCAST indicate local
  (belongs to this host) and broadcast addresses, respectively.

- For all routes, RTF_MULTICAST is set if the destination is multicast.

The RTF_BROADCAST flag is used by ip_output() to eliminate a call to
in_broadcast() in a common case; this gives about 1% in our packet-generation
experiments.  All three flags might be used (although they aren't now)
to determine whether a packet can be forwarded; a given host route can
represent a forwardable address if:

	(rt->rt_flags & (RTF_HOST | RTF_LOCAL | RTF_BROADCAST | RTF_MULTICAST))
	== RTF_HOST

Obviously, one still has to do all the work if a host route is not present,
but this code allows one to cache the results of such a lookup if rtalloc1()
is called without masking RTF_PRCLONING.
This commit is contained in:
Garrett Wollman 1996-05-06 17:42:13 +00:00
parent b74a76ee15
commit 9f9b3dc4ae
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15652
3 changed files with 48 additions and 11 deletions

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)route.h 8.3 (Berkeley) 4/19/94
* $Id: route.h,v 1.19 1995/12/14 09:53:28 phk Exp $
* $Id: route.h,v 1.20 1996/01/30 22:58:00 mpp Exp $
*/
#ifndef _NET_ROUTE_H_
@ -154,7 +154,10 @@ struct ortentry {
#define RTF_PROTO3 0x40000 /* protocol specific routing flag */
#define RTF_CHAINDELETE 0x80000 /* chain is being deleted (internal) */
#define RTF_PINNED 0x100000 /* future use */
/* 0x200000 and up unassigned */
#define RTF_LOCAL 0x200000 /* route represents a local address */
#define RTF_BROADCAST 0x400000 /* route represents a bcast address */
#define RTF_MULTICAST 0x800000 /* route represents a mcast address */
/* 0x1000000 and up unassigned */
/*
* Routing statistics.

View File

@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: in_rmx.c,v 1.23 1996/01/23 05:15:30 fenner Exp $
* $Id: in_rmx.c,v 1.24 1996/04/26 18:31:41 wollman Exp $
*/
/*
@ -84,9 +84,38 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
/*
* For IP, all unicast non-host routes are automatically cloning.
*/
if(!(rt->rt_flags & (RTF_HOST | RTF_CLONING))) {
if(!IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
rt->rt_flags |= RTF_PRCLONING;
if(IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
rt->rt_flags |= RTF_MULTICAST;
if(!(rt->rt_flags & (RTF_HOST | RTF_CLONING | RTF_MULTICAST))) {
rt->rt_flags |= RTF_PRCLONING;
}
/*
* A little bit of help for both IP output and input:
* For host routes, we make sure that RTF_BROADCAST
* is set for anything that looks like a broadcast address.
* This way, we can avoid an expensive call to in_broadcast()
* in ip_output() most of the time (because the route passed
* to ip_output() is almost always a host route).
*
* We also do the same for local addresses, with the thought
* that this might one day be used to speed up ip_input().
*
* We also mark routes to multicast addresses as such, because
* it's easy to do and might be useful (but this is much more
* dubious since it's so easy to inspect the address). (This
* is done above.)
*/
if (rt->rt_flags & RTF_HOST) {
if (in_broadcast(sin->sin_addr, rt->rt_ifp)) {
rt->rt_flags |= RTF_BROADCAST;
} else {
#define satosin(sa) ((struct sockaddr_in *)sa)
if (satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr
== sin->sin_addr.s_addr)
rt->rt_flags |= RTF_LOCAL;
#undef satosin
}
}

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
* $Id: ip_output.c,v 1.35 1996/04/18 15:49:06 wollman Exp $
* $Id: ip_output.c,v 1.36 1996/04/21 13:47:43 bde Exp $
*/
#define _IP_VHL
@ -94,6 +94,7 @@ ip_output(m0, opt, ro, flags, imo)
int len, off, error = 0;
struct sockaddr_in *dst;
struct in_ifaddr *ia;
int isbroadcast;
#ifdef DIAGNOSTIC
if ((m->m_flags & M_PKTHDR) == 0)
@ -150,6 +151,7 @@ ip_output(m0, opt, ro, flags, imo)
}
ifp = ia->ia_ifp;
ip->ip_ttl = 1;
isbroadcast = in_broadcast(dst->sin_addr, ifp);
} else {
/*
* If this is the case, we probably don't want to allocate
@ -172,6 +174,10 @@ ip_output(m0, opt, ro, flags, imo)
ro->ro_rt->rt_use++;
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
if (ro->ro_rt->rt_flags & RTF_HOST)
isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
else
isbroadcast = in_broadcast(dst->sin_addr, ifp);
}
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
struct in_multi *inm;
@ -296,7 +302,7 @@ ip_output(m0, opt, ro, flags, imo)
* and verify user is allowed to send
* such a packet.
*/
if (in_broadcast(dst->sin_addr, ifp)) {
if (isbroadcast) {
if ((ifp->if_flags & IFF_BROADCAST) == 0) {
error = EADDRNOTAVAIL;
goto bad;
@ -311,8 +317,9 @@ ip_output(m0, opt, ro, flags, imo)
goto bad;
}
m->m_flags |= M_BCAST;
} else
} else {
m->m_flags &= ~M_BCAST;
}
sendit:
/*
@ -345,7 +352,6 @@ ip_output(m0, opt, ro, flags, imo)
*/
if (ip->ip_off & IP_DF) {
error = EMSGSIZE;
#if 1
/*
* This case can happen if the user changed the MTU
* of an interface after enabling IP on it. Because
@ -358,7 +364,6 @@ ip_output(m0, opt, ro, flags, imo)
&& (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
}
#endif
ipstat.ips_cantfrag++;
goto bad;
}