/* route.c 4.14 82/12/14 */
#include "../h/protosw.h"
#include "../net/route.h"
int rttrash
; /* routes not in table but not freed */
* Packet routing routines.
register struct route
*ro
;
register struct rtentry
*rt
, *rtmin
;
register int hash
, (*match
)();
struct sockaddr
*dst
= &ro
->ro_dst
;
if (ro
->ro_rt
&& ro
->ro_rt
->rt_ifp
) /* XXX */
(*afswitch
[af
].af_hash
)(dst
, &h
);
rtmin
= 0, hash
= h
.afh_hosthash
;
for (m
= rthost
[hash
% RTHASHSIZ
]; m
; m
= m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if ((rt
->rt_flags
& RTF_UP
) == 0 ||
(rt
->rt_ifp
->if_flags
& IFF_UP
) == 0)
if (bcmp((caddr_t
)&rt
->rt_dst
, (caddr_t
)dst
, sizeof (*dst
)))
if (rtmin
== 0 || rt
->rt_use
< rtmin
->rt_use
)
match
= afswitch
[af
].af_netmatch
;
for (m
= rtnet
[hash
% RTHASHSIZ
]; m
; m
= m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if ((rt
->rt_flags
& RTF_UP
) == 0 ||
(rt
->rt_ifp
->if_flags
& IFF_UP
) == 0)
if (rt
->rt_dst
.sa_family
!= af
|| !(*match
)(&rt
->rt_dst
, dst
))
if (rtmin
== 0 || rt
->rt_use
< rtmin
->rt_use
)
register struct rtentry
*rt
;
if (rt
->rt_refcnt
== 0 && (rt
->rt_flags
&RTF_UP
) == 0) {
* Carry out a request to change the routing table. Called by
* interfaces at boot time to make their ``local routes'' known
register struct rtentry
*entry
;
register struct mbuf
*m
, **mprev
;
register struct rtentry
*rt
;
int af
, s
, error
= 0, hash
, (*match
)();
af
= entry
->rt_dst
.sa_family
;
(*afswitch
[af
].af_hash
)(&entry
->rt_dst
, &h
);
if (entry
->rt_flags
& RTF_HOST
) {
mprev
= &rthost
[hash
% RTHASHSIZ
];
mprev
= &rtnet
[hash
% RTHASHSIZ
];
match
= afswitch
[af
].af_netmatch
;
for (; m
= *mprev
; mprev
= &m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if (entry
->rt_flags
& RTF_HOST
) {
(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 0)
if (!equal(&rt
->rt_dst
, &entry
->rt_dst
))
if (rt
->rt_dst
.sa_family
!= entry
->rt_dst
.sa_family
||
(*match
)(&rt
->rt_dst
, &entry
->rt_dst
) == 0)
if (equal(&rt
->rt_gateway
, &entry
->rt_gateway
))
ifp
= if_ifwithaddr(&entry
->rt_gateway
);
ifp
= if_ifwithnet(&entry
->rt_gateway
);
m
= m_get(M_DONTWAIT
, MT_RTABLE
);
m
->m_len
= sizeof (struct rtentry
);
rt
= mtod(m
, struct rtentry
*);
rt
->rt_dst
= entry
->rt_dst
;
rt
->rt_gateway
= entry
->rt_gateway
;
RTF_UP
| (entry
->rt_flags
& (RTF_HOST
|RTF_GATEWAY
));
* Set up a routing table entry, normally
rtinit(dst
, gateway
, flags
)
struct sockaddr
*dst
, *gateway
;
bzero((caddr_t
)&route
, sizeof (route
));
route
.rt_gateway
= *gateway
;
(void) rtrequest((int)SIOCADDRT
, &route
);