/* route.c 4.3 82/03/29 */
#include "../h/protosw.h"
#include "../net/in_systm.h"
#include "../net/route.h"
* Packet routing routines.
* With much ado about nothing...
* route the cars that climb halfway to the stars...
register struct route
*ro
;
register struct rtentry
*rt
, *rtmin
;
struct sockaddr
*dst
= &ro
->ro_dst
;
int af
= dst
->sa_family
, doinghost
;
if (ro
->ro_rt
&& ro
->ro_rt
->rt_ifp
) /* can't happen */
(*afswitch
[af
].af_hash
)(dst
, &h
);
m
= routehash
[h
.afh_hosthash
% RTHASHSIZ
];
rtmin
= 0, doinghost
= 1;
for (; m
; m
= m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof(struct sockaddr)) == 0)
if (!equal(&rt
->rt_dst
, dst
))
if (rt
->rt_dst
.sa_family
!= af
)
if ((*afswitch
[af
].af_netmatch
)(&rt
->rt_dst
, dst
) == 0)
if (rtmin
== 0 || rt
->rt_use
< rtmin
->rt_use
)
return (rt
->rt_flags
& RTF_DIRECT
);
m
= routehash
[h
.afh_nethash
% RTHASHSIZ
];
register struct rtentry
*rt
;
/* on refcnt == 0 reclaim? notify someone? */
register struct sockaddr
*sa
;
register struct rtentry
*rt
;
(*afswitch
[sa
->sa_family
].af_hash
)(sa
, &h
);
m
= routehash
[h
.afh_hosthash
];
for (; m
; m
= m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if (equal(&rt
->rt_gateway
, sa
))
* 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
;
struct sockaddr
*sa
= &new->rt_dst
;
int af
= sa
->sa_family
, doinghost
, s
, error
= 0;
(*afswitch
[af
].af_hash
)(sa
, &h
);
mprev
= &routehash
[h
.afh_hosthash
% RTHASHSIZ
];
for (; m
= *mprev
; mprev
= &m
->m_next
) {
rt
= mtod(m
, struct rtentry
*);
if (!equal(&rt
->rt_dst
, &new->rt_dst
))
if (rt
->rt_dst
.sa_family
!= af
)
if ((*afswitch
[af
].af_netmatch
)(&rt
->rt_dst
, sa
) == 0)
/* require full match on deletions */
!equal(&rt
->rt_gateway
, &new->rt_gateway
))
/* don't keep multiple identical entries */
equal(&rt
->rt_gateway
, &new->rt_gateway
)) {
if (m
== 0 && doinghost
) {
mprev
= &routehash
[h
.afh_nethash
% RTHASHSIZ
];
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
, &new->rt_gateway
))
m
= m_getclr(M_DONTWAIT
);
rt
= mtod(m
, struct rtentry
*);
rt
->rt_key
= h
.afh_nethash
| h
.afh_hosthash
;
rt
->rt_ifp
= if_ifonnetof(&new->rt_gateway
);