| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rtsock.c,v 1.115.2.2 2009/01/09 02:58:58 snj Exp $ */ | | 1 | /* $NetBSD: rtsock.c,v 1.115.2.3 2009/03/15 20:00:30 snj Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | | 4 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -51,27 +51,27 @@ | | | @@ -51,27 +51,27 @@ |
51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
58 | * SUCH DAMAGE. | | 58 | * SUCH DAMAGE. |
59 | * | | 59 | * |
60 | * @(#)rtsock.c 8.7 (Berkeley) 10/12/95 | | 60 | * @(#)rtsock.c 8.7 (Berkeley) 10/12/95 |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.115.2.2 2009/01/09 02:58:58 snj Exp $"); | | 64 | __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.115.2.3 2009/03/15 20:00:30 snj Exp $"); |
65 | | | 65 | |
66 | #include "opt_inet.h" | | 66 | #include "opt_inet.h" |
67 | | | 67 | |
68 | #include <sys/param.h> | | 68 | #include <sys/param.h> |
69 | #include <sys/systm.h> | | 69 | #include <sys/systm.h> |
70 | #include <sys/proc.h> | | 70 | #include <sys/proc.h> |
71 | #include <sys/mbuf.h> | | 71 | #include <sys/mbuf.h> |
72 | #include <sys/socket.h> | | 72 | #include <sys/socket.h> |
73 | #include <sys/socketvar.h> | | 73 | #include <sys/socketvar.h> |
74 | #include <sys/domain.h> | | 74 | #include <sys/domain.h> |
75 | #include <sys/protosw.h> | | 75 | #include <sys/protosw.h> |
76 | #include <sys/sysctl.h> | | 76 | #include <sys/sysctl.h> |
77 | #include <sys/kauth.h> | | 77 | #include <sys/kauth.h> |
| @@ -203,29 +203,29 @@ intern_netmask(const struct sockaddr *ma | | | @@ -203,29 +203,29 @@ intern_netmask(const struct sockaddr *ma |
203 | return mask; | | 203 | return mask; |
204 | } | | 204 | } |
205 | | | 205 | |
206 | /*ARGSUSED*/ | | 206 | /*ARGSUSED*/ |
207 | int | | 207 | int |
208 | route_output(struct mbuf *m, ...) | | 208 | route_output(struct mbuf *m, ...) |
209 | { | | 209 | { |
210 | struct sockproto proto = { .sp_family = PF_ROUTE, }; | | 210 | struct sockproto proto = { .sp_family = PF_ROUTE, }; |
211 | struct rt_msghdr *rtm = NULL; | | 211 | struct rt_msghdr *rtm = NULL; |
212 | struct rt_msghdr *old_rtm = NULL; | | 212 | struct rt_msghdr *old_rtm = NULL; |
213 | struct rtentry *rt = NULL; | | 213 | struct rtentry *rt = NULL; |
214 | struct rtentry *saved_nrt = NULL; | | 214 | struct rtentry *saved_nrt = NULL; |
215 | struct rt_addrinfo info; | | 215 | struct rt_addrinfo info; |
216 | int len, error = 0, ifa_route = 0; | | 216 | int len, error = 0; |
217 | struct ifnet *ifp = NULL; | | 217 | struct ifnet *ifp = NULL; |
218 | struct ifaddr *ifa = NULL, *oifa; | | 218 | struct ifaddr *ifa = NULL; |
219 | struct socket *so; | | 219 | struct socket *so; |
220 | va_list ap; | | 220 | va_list ap; |
221 | sa_family_t family; | | 221 | sa_family_t family; |
222 | | | 222 | |
223 | va_start(ap, m); | | 223 | va_start(ap, m); |
224 | so = va_arg(ap, struct socket *); | | 224 | so = va_arg(ap, struct socket *); |
225 | va_end(ap); | | 225 | va_end(ap); |
226 | | | 226 | |
227 | #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0) | | 227 | #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0) |
228 | if (m == NULL || ((m->m_len < sizeof(int32_t)) && | | 228 | if (m == NULL || ((m->m_len < sizeof(int32_t)) && |
229 | (m = m_pullup(m, sizeof(int32_t))) == NULL)) | | 229 | (m = m_pullup(m, sizeof(int32_t))) == NULL)) |
230 | return ENOBUFS; | | 230 | return ENOBUFS; |
231 | if ((m->m_flags & M_PKTHDR) == 0) | | 231 | if ((m->m_flags & M_PKTHDR) == 0) |
| @@ -282,32 +282,26 @@ route_output(struct mbuf *m, ...) | | | @@ -282,32 +282,26 @@ route_output(struct mbuf *m, ...) |
282 | senderr(EINVAL); | | 282 | senderr(EINVAL); |
283 | error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); | | 283 | error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); |
284 | if (error == 0 && saved_nrt) { | | 284 | if (error == 0 && saved_nrt) { |
285 | rt_setmetrics(rtm->rtm_inits, | | 285 | rt_setmetrics(rtm->rtm_inits, |
286 | &rtm->rtm_rmx, &saved_nrt->rt_rmx); | | 286 | &rtm->rtm_rmx, &saved_nrt->rt_rmx); |
287 | saved_nrt->rt_refcnt--; | | 287 | saved_nrt->rt_refcnt--; |
288 | } | | 288 | } |
289 | break; | | 289 | break; |
290 | | | 290 | |
291 | case RTM_DELETE: | | 291 | case RTM_DELETE: |
292 | error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); | | 292 | error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); |
293 | if (error == 0) { | | 293 | if (error == 0) { |
294 | (rt = saved_nrt)->rt_refcnt++; | | 294 | (rt = saved_nrt)->rt_refcnt++; |
295 | ifa = rt_get_ifa(rt); | | | |
296 | /* | | | |
297 | * If deleting an automatic route, scrub the flag. | | | |
298 | */ | | | |
299 | if (ifa->ifa_flags & IFA_ROUTE) | | | |
300 | ifa->ifa_flags &= ~IFA_ROUTE; | | | |
301 | goto report; | | 295 | goto report; |
302 | } | | 296 | } |
303 | break; | | 297 | break; |
304 | | | 298 | |
305 | case RTM_GET: | | 299 | case RTM_GET: |
306 | case RTM_CHANGE: | | 300 | case RTM_CHANGE: |
307 | case RTM_LOCK: | | 301 | case RTM_LOCK: |
308 | /* XXX This will mask info.rti_info[RTAX_DST] with | | 302 | /* XXX This will mask info.rti_info[RTAX_DST] with |
309 | * info.rti_info[RTAX_NETMASK] before | | 303 | * info.rti_info[RTAX_NETMASK] before |
310 | * searching. It did not used to do that. --dyoung | | 304 | * searching. It did not used to do that. --dyoung |
311 | */ | | 305 | */ |
312 | error = rtrequest1(RTM_GET, &info, &rt); | | 306 | error = rtrequest1(RTM_GET, &info, &rt); |
313 | if (error != 0) | | 307 | if (error != 0) |
| @@ -405,48 +399,33 @@ route_output(struct mbuf *m, ...) | | | @@ -405,48 +399,33 @@ route_output(struct mbuf *m, ...) |
405 | (ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP])) && | | 399 | (ifa = ifa_ifwithnet(info.rti_info[RTAX_IFP])) && |
406 | (ifp = ifa->ifa_ifp) && (info.rti_info[RTAX_IFA] || | | 400 | (ifp = ifa->ifa_ifp) && (info.rti_info[RTAX_IFA] || |
407 | info.rti_info[RTAX_GATEWAY])) { | | 401 | info.rti_info[RTAX_GATEWAY])) { |
408 | ifa = ifaof_ifpforaddr(info.rti_info[RTAX_IFA] ? | | 402 | ifa = ifaof_ifpforaddr(info.rti_info[RTAX_IFA] ? |
409 | info.rti_info[RTAX_IFA] : | | 403 | info.rti_info[RTAX_IFA] : |
410 | info.rti_info[RTAX_GATEWAY], ifp); | | 404 | info.rti_info[RTAX_GATEWAY], ifp); |
411 | } else if ((info.rti_info[RTAX_IFA] && | | 405 | } else if ((info.rti_info[RTAX_IFA] && |
412 | (ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]))) || | | 406 | (ifa = ifa_ifwithaddr(info.rti_info[RTAX_IFA]))) || |
413 | (info.rti_info[RTAX_GATEWAY] && | | 407 | (info.rti_info[RTAX_GATEWAY] && |
414 | (ifa = ifa_ifwithroute(rt->rt_flags, | | 408 | (ifa = ifa_ifwithroute(rt->rt_flags, |
415 | rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) { | | 409 | rt_getkey(rt), info.rti_info[RTAX_GATEWAY])))) { |
416 | ifp = ifa->ifa_ifp; | | 410 | ifp = ifa->ifa_ifp; |
417 | } | | 411 | } |
418 | oifa = rt->rt_ifa; | | | |
419 | if (oifa && oifa->ifa_flags & IFA_ROUTE) { | | | |
420 | /* | | | |
421 | * If changing an automatically added route, | | | |
422 | * remove the flag and store the fact. | | | |
423 | */ | | | |
424 | oifa->ifa_flags &= ~IFA_ROUTE; | | | |
425 | ifa_route = 1; | | | |
426 | } | | | |
427 | if (ifa) { | | 412 | if (ifa) { |
| | | 413 | struct ifaddr *oifa = rt->rt_ifa; |
428 | if (oifa != ifa) { | | 414 | if (oifa != ifa) { |
429 | if (oifa && oifa->ifa_rtrequest) { | | 415 | if (oifa && oifa->ifa_rtrequest) { |
430 | oifa->ifa_rtrequest(RTM_DELETE, | | 416 | oifa->ifa_rtrequest(RTM_DELETE, |
431 | rt, &info); | | 417 | rt, &info); |
432 | } | | 418 | } |
433 | /* | | | |
434 | * If changing an automatically added | | | |
435 | * route, store this if not static. | | | |
436 | */ | | | |
437 | if (ifa_route && | | | |
438 | !(rt->rt_flags & RTF_STATIC)) | | | |
439 | ifa->ifa_flags |= IFA_ROUTE; | | | |
440 | rt_replace_ifa(rt, ifa); | | 419 | rt_replace_ifa(rt, ifa); |
441 | rt->rt_ifp = ifp; | | 420 | rt->rt_ifp = ifp; |
442 | } | | 421 | } |
443 | } | | 422 | } |
444 | rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, | | 423 | rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, |
445 | &rt->rt_rmx); | | 424 | &rt->rt_rmx); |
446 | if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) | | 425 | if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) |
447 | rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); | | 426 | rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); |
448 | /*FALLTHROUGH*/ | | 427 | /*FALLTHROUGH*/ |
449 | case RTM_LOCK: | | 428 | case RTM_LOCK: |
450 | rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); | | 429 | rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits); |
451 | rt->rt_rmx.rmx_locks |= | | 430 | rt->rt_rmx.rmx_locks |= |
452 | (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); | | 431 | (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks); |