route.c (f084e01477de7124ac47457a846441fbe690879f) route.c (995add1a12e8e31b09aa96412896a4cd94dcae05)
1/*
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)route.c 8.2 (Berkeley) 11/15/93
1/*
2 * Copyright (c) 1980, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)route.c 8.2 (Berkeley) 11/15/93
34 * $Id: route.c,v 1.10 1994/11/02 04:41:25 wollman Exp $
34 * $Id: route.c,v 1.11 1994/11/03 01:04:30 wollman Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/proc.h>
41#include <sys/mbuf.h>
42#include <sys/socket.h>

--- 40 unchanged lines hidden (view full) ---

83 * Packet routing routines.
84 */
85void
86rtalloc(ro)
87 register struct route *ro;
88{
89 if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
90 return; /* XXX */
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/kernel.h>
40#include <sys/proc.h>
41#include <sys/mbuf.h>
42#include <sys/socket.h>

--- 40 unchanged lines hidden (view full) ---

83 * Packet routing routines.
84 */
85void
86rtalloc(ro)
87 register struct route *ro;
88{
89 if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
90 return; /* XXX */
91 ro->ro_rt = rtalloc1(&ro->ro_dst, 1);
91 ro->ro_rt = rtalloc1(&ro->ro_dst, 1, 0UL);
92}
93
94struct rtentry *
92}
93
94struct rtentry *
95rtalloc1(dst, report)
95rtalloc1(dst, report, ignflags)
96 register struct sockaddr *dst;
97 int report;
96 register struct sockaddr *dst;
97 int report;
98 u_long ignflags;
98{
99 register struct radix_node_head *rnh = rt_tables[dst->sa_family];
100 register struct rtentry *rt;
101 register struct radix_node *rn;
102 struct rtentry *newrt = 0;
103 struct rt_addrinfo info;
99{
100 register struct radix_node_head *rnh = rt_tables[dst->sa_family];
101 register struct rtentry *rt;
102 register struct radix_node *rn;
103 struct rtentry *newrt = 0;
104 struct rt_addrinfo info;
105 u_long nflags;
104 int s = splnet(), err = 0, msgtype = RTM_MISS;
105
106 if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
107 ((rn->rn_flags & RNF_ROOT) == 0)) {
108 newrt = rt = (struct rtentry *)rn;
106 int s = splnet(), err = 0, msgtype = RTM_MISS;
107
108 if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
109 ((rn->rn_flags & RNF_ROOT) == 0)) {
110 newrt = rt = (struct rtentry *)rn;
109 if (report && (rt->rt_flags & RTF_CLONING)) {
111 nflags = rt->rt_flags & ~ignflags;
112 if (report && (nflags & (RTF_CLONING | RTF_PRCLONING))) {
110 err = rtrequest(RTM_RESOLVE, dst, SA(0),
111 SA(0), 0, &newrt);
112 if (err) {
113 newrt = rt;
114 rt->rt_refcnt++;
115 goto miss;
116 }
117 if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {

--- 76 unchanged lines hidden (view full) ---

194 struct rt_addrinfo info;
195 struct ifaddr *ifa;
196
197 /* verify the gateway is directly reachable */
198 if ((ifa = ifa_ifwithnet(gateway)) == 0) {
199 error = ENETUNREACH;
200 goto out;
201 }
113 err = rtrequest(RTM_RESOLVE, dst, SA(0),
114 SA(0), 0, &newrt);
115 if (err) {
116 newrt = rt;
117 rt->rt_refcnt++;
118 goto miss;
119 }
120 if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {

--- 76 unchanged lines hidden (view full) ---

197 struct rt_addrinfo info;
198 struct ifaddr *ifa;
199
200 /* verify the gateway is directly reachable */
201 if ((ifa = ifa_ifwithnet(gateway)) == 0) {
202 error = ENETUNREACH;
203 goto out;
204 }
202 rt = rtalloc1(dst, 0);
205 rt = rtalloc1(dst, 0, 0UL);
203 /*
204 * If the redirect isn't from our current router for this dst,
205 * it's either old or wrong. If it redirects us to ourselves,
206 * we have a routing loop, perhaps as a result of an interface
207 * going down recently.
208 */
209#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
210 if (!(flags & RTF_DONE) && rt &&

--- 103 unchanged lines hidden (view full) ---

314 * or host, the gateway may still be on the
315 * other end of a pt to pt link.
316 */
317 ifa = ifa_ifwithdstaddr(gateway);
318 }
319 if (ifa == 0)
320 ifa = ifa_ifwithnet(gateway);
321 if (ifa == 0) {
206 /*
207 * If the redirect isn't from our current router for this dst,
208 * it's either old or wrong. If it redirects us to ourselves,
209 * we have a routing loop, perhaps as a result of an interface
210 * going down recently.
211 */
212#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
213 if (!(flags & RTF_DONE) && rt &&

--- 103 unchanged lines hidden (view full) ---

317 * or host, the gateway may still be on the
318 * other end of a pt to pt link.
319 */
320 ifa = ifa_ifwithdstaddr(gateway);
321 }
322 if (ifa == 0)
323 ifa = ifa_ifwithnet(gateway);
324 if (ifa == 0) {
322 struct rtentry *rt = rtalloc1(dst, 0);
325 struct rtentry *rt = rtalloc1(dst, 0, 0UL);
323 if (rt == 0)
324 return (0);
325 rt->rt_refcnt--;
326 if ((ifa = rt->rt_ifa) == 0)
327 return (0);
328 }
329 if (ifa->ifa_addr->sa_family != dst->sa_family) {
330 struct ifaddr *oifa = ifa;

--- 47 unchanged lines hidden (view full) ---

378 rtfree(rt);
379 }
380 break;
381
382 case RTM_RESOLVE:
383 if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
384 senderr(EINVAL);
385 ifa = rt->rt_ifa;
326 if (rt == 0)
327 return (0);
328 rt->rt_refcnt--;
329 if ((ifa = rt->rt_ifa) == 0)
330 return (0);
331 }
332 if (ifa->ifa_addr->sa_family != dst->sa_family) {
333 struct ifaddr *oifa = ifa;

--- 47 unchanged lines hidden (view full) ---

381 rtfree(rt);
382 }
383 break;
384
385 case RTM_RESOLVE:
386 if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
387 senderr(EINVAL);
388 ifa = rt->rt_ifa;
386 flags = rt->rt_flags & ~RTF_CLONING;
387 prflags = rt->rt_prflags | RTPRF_WASCLONED;
389 flags = rt->rt_flags & ~(RTF_CLONING | RTF_PRCLONING);
390 flags |= RTF_WASCLONED;
388 gateway = rt->rt_gateway;
389 if ((netmask = rt->rt_genmask) == 0)
390 flags |= RTF_HOST;
391 if (flags & RTF_STATIC) {
392 flags &= ~RTF_STATIC;
393 }
394
395 goto makeroute;

--- 6 unchanged lines hidden (view full) ---

402 senderr(ENETUNREACH);
403
404 makeroute:
405 R_Malloc(rt, struct rtentry *, sizeof(*rt));
406 if (rt == 0)
407 senderr(ENOBUFS);
408 Bzero(rt, sizeof(*rt));
409 rt->rt_flags = RTF_UP | flags;
391 gateway = rt->rt_gateway;
392 if ((netmask = rt->rt_genmask) == 0)
393 flags |= RTF_HOST;
394 if (flags & RTF_STATIC) {
395 flags &= ~RTF_STATIC;
396 }
397
398 goto makeroute;

--- 6 unchanged lines hidden (view full) ---

405 senderr(ENETUNREACH);
406
407 makeroute:
408 R_Malloc(rt, struct rtentry *, sizeof(*rt));
409 if (rt == 0)
410 senderr(ENOBUFS);
411 Bzero(rt, sizeof(*rt));
412 rt->rt_flags = RTF_UP | flags;
410 rt->rt_prflags = prflags;
411 if (rt_setgate(rt, dst, gateway)) {
412 Free(rt);
413 senderr(ENOBUFS);
414 }
415 ndst = rt_key(rt);
416 if (netmask) {
417 rt_maskedcopy(dst, ndst, netmask);
418 } else

--- 49 unchanged lines hidden (view full) ---

468 Bcopy(dst, new, dlen);
469 Free(old);
470 }
471 if (rt->rt_gwroute) {
472 rt = rt->rt_gwroute; RTFREE(rt);
473 rt = rt0; rt->rt_gwroute = 0;
474 }
475 if (rt->rt_flags & RTF_GATEWAY) {
413 if (rt_setgate(rt, dst, gateway)) {
414 Free(rt);
415 senderr(ENOBUFS);
416 }
417 ndst = rt_key(rt);
418 if (netmask) {
419 rt_maskedcopy(dst, ndst, netmask);
420 } else

--- 49 unchanged lines hidden (view full) ---

470 Bcopy(dst, new, dlen);
471 Free(old);
472 }
473 if (rt->rt_gwroute) {
474 rt = rt->rt_gwroute; RTFREE(rt);
475 rt = rt0; rt->rt_gwroute = 0;
476 }
477 if (rt->rt_flags & RTF_GATEWAY) {
476 rt->rt_gwroute = rtalloc1(gate, 1);
478 rt->rt_gwroute = rtalloc1(gate, 1, 0UL);
477 }
478 return 0;
479}
480
481void
482rt_maskedcopy(src, dst, netmask)
483 struct sockaddr *src, *dst, *netmask;
484{

--- 32 unchanged lines hidden (view full) ---

517 dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
518 if (cmd == RTM_DELETE) {
519 if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
520 m = m_get(M_WAIT, MT_SONAME);
521 deldst = mtod(m, struct sockaddr *);
522 rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
523 dst = deldst;
524 }
479 }
480 return 0;
481}
482
483void
484rt_maskedcopy(src, dst, netmask)
485 struct sockaddr *src, *dst, *netmask;
486{

--- 32 unchanged lines hidden (view full) ---

519 dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
520 if (cmd == RTM_DELETE) {
521 if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
522 m = m_get(M_WAIT, MT_SONAME);
523 deldst = mtod(m, struct sockaddr *);
524 rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
525 dst = deldst;
526 }
525 rt = rtalloc1(dst, 0);
527 rt = rtalloc1(dst, 0, 0UL);
526 if (rt) {
527 rt->rt_refcnt--;
528 if (rt->rt_ifa != ifa) {
529 if (m)
530 (void) m_free(m);
531 return (flags & RTF_HOST ? EHOSTUNREACH
532 : ENETUNREACH);
533 }

--- 31 unchanged lines hidden ---
528 if (rt) {
529 rt->rt_refcnt--;
530 if (rt->rt_ifa != ifa) {
531 if (m)
532 (void) m_free(m);
533 return (flags & RTF_HOST ? EHOSTUNREACH
534 : ENETUNREACH);
535 }

--- 31 unchanged lines hidden ---