/* route.c 4.6 82/03/31 */
#include "../h/protosw.h"
#include "../net/in_systm.h"
#include "../net/route.h"
* 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 (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_dst
.sa_family
!= af
|| !(*match
)(&rt
->rt_dst
, dst
))
if (rtmin
== 0 || rt
->rt_use
< rtmin
->rt_use
)
register struct rtentry
*rt
;
/* on refcnt == 0 reclaim? notify someone? */
(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 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
*new;
register struct rtentry
*rt
;
register struct mbuf
*m
, **mprev
;
register int hash
, (*match
)();
register struct sockaddr
*sa
= &new->rt_dst
;
register struct sockaddr
*gate
= &new->rt_gateway
;
int af
= sa
->sa_family
, doinghost
, s
, error
= 0;
(*afswitch
[af
].af_hash
)(sa
, &h
);
mprev
= &rthost
[hash
% RTHASHSIZ
];
for (; m
= *mprev
; mprev
= &m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if (!equal(&rt
->rt_dst
, sa
))
if (rt
->rt_dst
.sa_family
!= sa
->sa_family
||
(*match
)(&rt
->rt_dst
, sa
) == 0)
/* require full match on deletions */
if (req
== SIOCDELRT
&& !equal(&rt
->rt_gateway
, gate
))
/* don't keep multiple identical entries */
if (req
== SIOCADDRT
&& equal(&rt
->rt_gateway
, gate
)) {
if (m
== 0 && doinghost
) {
mprev
= &rtnet
[hash
% RTHASHSIZ
];
match
= afswitch
[af
].af_netmatch
;
if (m
== 0 && req
!= SIOCADDRT
) {
if (rt
->rt_refcnt
> 0) /* should we notify protocols? */
rt
->rt_flags
= new->rt_flags
;
else if (!equal(&rt
->rt_gateway
, gate
))
m
->m_len
= sizeof (struct rtentry
);
rt
= mtod(m
, struct rtentry
*);
if (new->rt_flags
& RTF_HOST
) {
rt
->rt_hash
= h
.afh_hosthash
;
rt
->rt_hash
= h
.afh_nethash
;
rt
->rt_ifp
= if_ifwithnet(gate
);
* Set up a routing table entry, normally
rtinit(dst
, gateway
, flags
)
struct sockaddr
*dst
, *gateway
;
route
.rt_gateway
= *gateway
;
(void) rtrequest(SIOCADDRT
, &route
);