rtsock.c (243882) | rtsock.c (243903) |
---|---|
1/*- 2 * Copyright (c) 1988, 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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)rtsock.c 8.7 (Berkeley) 10/12/95 | 1/*- 2 * Copyright (c) 1988, 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 --- 13 unchanged lines hidden (view full) --- 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)rtsock.c 8.7 (Berkeley) 10/12/95 |
30 * $FreeBSD: head/sys/net/rtsock.c 243882 2012-12-05 08:04:20Z glebius $ | 30 * $FreeBSD: head/sys/net/rtsock.c 243903 2012-12-05 19:45:24Z hrs $ |
31 */ 32#include "opt_compat.h" 33#include "opt_sctp.h" 34#include "opt_mpath.h" 35#include "opt_inet.h" 36#include "opt_inet6.h" 37 38#include <sys/param.h> --- 21 unchanged lines hidden (view full) --- 60#include <net/raw_cb.h> 61#include <net/route.h> 62#include <net/vnet.h> 63 64#include <netinet/in.h> 65#include <netinet/if_ether.h> 66#include <netinet/ip_carp.h> 67#ifdef INET6 | 31 */ 32#include "opt_compat.h" 33#include "opt_sctp.h" 34#include "opt_mpath.h" 35#include "opt_inet.h" 36#include "opt_inet6.h" 37 38#include <sys/param.h> --- 21 unchanged lines hidden (view full) --- 60#include <net/raw_cb.h> 61#include <net/route.h> 62#include <net/vnet.h> 63 64#include <netinet/in.h> 65#include <netinet/if_ether.h> 66#include <netinet/ip_carp.h> 67#ifdef INET6 |
68#include <netinet6/ip6_var.h> |
|
68#include <netinet6/scope6_var.h> 69#endif 70 71#if defined(INET) || defined(INET6) 72#ifdef SCTP 73extern void sctp_addr_change(struct ifaddr *ifa, int cmd); 74#endif /* SCTP */ 75#endif --- 94 unchanged lines hidden (view full) --- 170struct mtx rtsock_mtx; 171MTX_SYSINIT(rtsock, &rtsock_mtx, "rtsock route_cb lock", MTX_DEF); 172 173#define RTSOCK_LOCK() mtx_lock(&rtsock_mtx) 174#define RTSOCK_UNLOCK() mtx_unlock(&rtsock_mtx) 175#define RTSOCK_LOCK_ASSERT() mtx_assert(&rtsock_mtx, MA_OWNED) 176 177static SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD, 0, ""); | 69#include <netinet6/scope6_var.h> 70#endif 71 72#if defined(INET) || defined(INET6) 73#ifdef SCTP 74extern void sctp_addr_change(struct ifaddr *ifa, int cmd); 75#endif /* SCTP */ 76#endif --- 94 unchanged lines hidden (view full) --- 171struct mtx rtsock_mtx; 172MTX_SYSINIT(rtsock, &rtsock_mtx, "rtsock route_cb lock", MTX_DEF); 173 174#define RTSOCK_LOCK() mtx_lock(&rtsock_mtx) 175#define RTSOCK_UNLOCK() mtx_unlock(&rtsock_mtx) 176#define RTSOCK_LOCK_ASSERT() mtx_assert(&rtsock_mtx, MA_OWNED) 177 178static SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD, 0, ""); |
178#ifdef INET6 179static VNET_DEFINE(int, deembed_scopeid) = 1; 180#define V_deembed_scopeid VNET(deembed_scopeid) 181SYSCTL_DECL(_net_inet6_ip6); 182SYSCTL_VNET_INT(_net_inet6_ip6, OID_AUTO, deembed_scopeid, CTLFLAG_RW, 183 &VNET_NAME(deembed_scopeid), 0, 184 "Extract embedded zone ID and set it to sin6_scope_id in sockaddr_in6."); 185#endif | |
186 187struct walkarg { 188 int w_tmemsize; 189 int w_op, w_arg; 190 caddr_t w_tmem; 191 struct sysctl_req *w_req; 192}; 193 --- 373 unchanged lines hidden (view full) --- 567route_output(struct mbuf *m, struct socket *so) 568{ 569#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) 570 struct rt_msghdr *rtm = NULL; 571 struct rtentry *rt = NULL; 572 struct radix_node_head *rnh; 573 struct rt_addrinfo info; 574#ifdef INET6 | 179 180struct walkarg { 181 int w_tmemsize; 182 int w_op, w_arg; 183 caddr_t w_tmem; 184 struct sysctl_req *w_req; 185}; 186 --- 373 unchanged lines hidden (view full) --- 560route_output(struct mbuf *m, struct socket *so) 561{ 562#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) 563 struct rt_msghdr *rtm = NULL; 564 struct rtentry *rt = NULL; 565 struct radix_node_head *rnh; 566 struct rt_addrinfo info; 567#ifdef INET6 |
575 struct sockaddr_storage ss_dst; 576 struct sockaddr_storage ss_gw; | 568 struct sockaddr_storage ss; |
577 struct sockaddr_in6 *sin6; | 569 struct sockaddr_in6 *sin6; |
570 int i, rti_need_deembed = 0; |
|
578#endif 579 int len, error = 0; 580 struct ifnet *ifp = NULL; 581 union sockaddr_union saun; 582 sa_family_t saf = AF_UNSPEC; 583 584#define senderr(e) { error = e; goto flush;} 585 if (m == NULL || ((m->m_len < sizeof(long)) && --- 15 unchanged lines hidden (view full) --- 601 m_copydata(m, 0, len, (caddr_t)rtm); 602 if (rtm->rtm_version != RTM_VERSION) { 603 info.rti_info[RTAX_DST] = NULL; 604 senderr(EPROTONOSUPPORT); 605 } 606 rtm->rtm_pid = curproc->p_pid; 607 bzero(&info, sizeof(info)); 608 info.rti_addrs = rtm->rtm_addrs; | 571#endif 572 int len, error = 0; 573 struct ifnet *ifp = NULL; 574 union sockaddr_union saun; 575 sa_family_t saf = AF_UNSPEC; 576 577#define senderr(e) { error = e; goto flush;} 578 if (m == NULL || ((m->m_len < sizeof(long)) && --- 15 unchanged lines hidden (view full) --- 594 m_copydata(m, 0, len, (caddr_t)rtm); 595 if (rtm->rtm_version != RTM_VERSION) { 596 info.rti_info[RTAX_DST] = NULL; 597 senderr(EPROTONOSUPPORT); 598 } 599 rtm->rtm_pid = curproc->p_pid; 600 bzero(&info, sizeof(info)); 601 info.rti_addrs = rtm->rtm_addrs; |
602 /* 603 * rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6 604 * link-local address because rtrequest requires addresses with 605 * embedded scope id. 606 */ |
|
609 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 610 info.rti_info[RTAX_DST] = NULL; 611 senderr(EINVAL); 612 } 613 info.rti_flags = rtm->rtm_flags; 614 if (info.rti_info[RTAX_DST] == NULL || 615 info.rti_info[RTAX_DST]->sa_family >= AF_MAX || 616 (info.rti_info[RTAX_GATEWAY] != NULL && --- 50 unchanged lines hidden (view full) --- 667 if (info.rti_info[RTAX_GATEWAY] == NULL) 668 senderr(EINVAL); 669 saved_nrt = NULL; 670 671 /* support for new ARP code */ 672 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && 673 (rtm->rtm_flags & RTF_LLDATA) != 0) { 674 error = lla_rt_output(rtm, &info); | 607 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { 608 info.rti_info[RTAX_DST] = NULL; 609 senderr(EINVAL); 610 } 611 info.rti_flags = rtm->rtm_flags; 612 if (info.rti_info[RTAX_DST] == NULL || 613 info.rti_info[RTAX_DST]->sa_family >= AF_MAX || 614 (info.rti_info[RTAX_GATEWAY] != NULL && --- 50 unchanged lines hidden (view full) --- 665 if (info.rti_info[RTAX_GATEWAY] == NULL) 666 senderr(EINVAL); 667 saved_nrt = NULL; 668 669 /* support for new ARP code */ 670 if (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK && 671 (rtm->rtm_flags & RTF_LLDATA) != 0) { 672 error = lla_rt_output(rtm, &info); |
673#ifdef INET6 674 if (error == 0) 675 rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; 676#endif |
|
675 break; 676 } 677 error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt, 678 so->so_fibnum); 679 if (error == 0 && saved_nrt) { | 677 break; 678 } 679 error = rtrequest1_fib(RTM_ADD, &info, &saved_nrt, 680 so->so_fibnum); 681 if (error == 0 && saved_nrt) { |
682#ifdef INET6 683 rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; 684#endif |
|
680 RT_LOCK(saved_nrt); 681 rt_setmetrics(rtm->rtm_inits, 682 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 683 rtm->rtm_index = saved_nrt->rt_ifp->if_index; 684 RT_REMREF(saved_nrt); 685 RT_UNLOCK(saved_nrt); 686 } 687 break; 688 689 case RTM_DELETE: 690 saved_nrt = NULL; 691 /* support for new ARP code */ 692 if (info.rti_info[RTAX_GATEWAY] && 693 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 694 (rtm->rtm_flags & RTF_LLDATA) != 0) { 695 error = lla_rt_output(rtm, &info); | 685 RT_LOCK(saved_nrt); 686 rt_setmetrics(rtm->rtm_inits, 687 &rtm->rtm_rmx, &saved_nrt->rt_rmx); 688 rtm->rtm_index = saved_nrt->rt_ifp->if_index; 689 RT_REMREF(saved_nrt); 690 RT_UNLOCK(saved_nrt); 691 } 692 break; 693 694 case RTM_DELETE: 695 saved_nrt = NULL; 696 /* support for new ARP code */ 697 if (info.rti_info[RTAX_GATEWAY] && 698 (info.rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) && 699 (rtm->rtm_flags & RTF_LLDATA) != 0) { 700 error = lla_rt_output(rtm, &info); |
701#ifdef INET6 702 if (error == 0) 703 rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; 704#endif |
|
696 break; 697 } 698 error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, 699 so->so_fibnum); 700 if (error == 0) { 701 RT_LOCK(saved_nrt); 702 rt = saved_nrt; 703 goto report; 704 } | 705 break; 706 } 707 error = rtrequest1_fib(RTM_DELETE, &info, &saved_nrt, 708 so->so_fibnum); 709 if (error == 0) { 710 RT_LOCK(saved_nrt); 711 rt = saved_nrt; 712 goto report; 713 } |
714#ifdef INET6 715 /* rt_msg2() will not be used when RTM_DELETE fails. */ 716 rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; 717#endif |
|
705 break; 706 707 case RTM_GET: 708 case RTM_CHANGE: 709 case RTM_LOCK: 710 rnh = rt_tables_get_rnh(so->so_fibnum, 711 info.rti_info[RTAX_DST]->sa_family); 712 if (rnh == NULL) --- 85 unchanged lines hidden (view full) --- 798 if ((rt->rt_flags & RTF_HOST) == 0 799 ? jailed_without_vnet(curthread->td_ucred) 800 : prison_if(curthread->td_ucred, 801 rt_key(rt)) != 0) { 802 RT_UNLOCK(rt); 803 senderr(ESRCH); 804 } 805 info.rti_info[RTAX_DST] = rt_key(rt); | 718 break; 719 720 case RTM_GET: 721 case RTM_CHANGE: 722 case RTM_LOCK: 723 rnh = rt_tables_get_rnh(so->so_fibnum, 724 info.rti_info[RTAX_DST]->sa_family); 725 if (rnh == NULL) --- 85 unchanged lines hidden (view full) --- 811 if ((rt->rt_flags & RTF_HOST) == 0 812 ? jailed_without_vnet(curthread->td_ucred) 813 : prison_if(curthread->td_ucred, 814 rt_key(rt)) != 0) { 815 RT_UNLOCK(rt); 816 senderr(ESRCH); 817 } 818 info.rti_info[RTAX_DST] = rt_key(rt); |
806#ifdef INET6 807 if (V_deembed_scopeid) { 808 switch (rt_key(rt)->sa_family) { 809 case AF_INET6: 810 sin6 = (struct sockaddr_in6 *)&ss_dst; 811 bcopy(rt_key(rt), sin6, sizeof(*sin6)); 812 if (sa6_recoverscope(sin6) == 0) 813 info.rti_info[RTAX_DST] = 814 (struct sockaddr *)sin6; 815 break; 816 } 817 } 818#endif | |
819 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; | 819 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; |
820#ifdef INET6 821 if (V_deembed_scopeid) { 822 switch (rt->rt_gateway->sa_family) { 823 case AF_INET6: 824 sin6 = (struct sockaddr_in6 *)&ss_gw; 825 bcopy(rt->rt_gateway, sin6, 826 sizeof(*sin6)); 827 if (sa6_recoverscope(sin6) == 0) 828 info.rti_info[RTAX_GATEWAY] = 829 (struct sockaddr *)sin6; 830 break; 831 } 832 } 833#endif | |
834 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 835 info.rti_info[RTAX_GENMASK] = 0; 836 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 837 ifp = rt->rt_ifp; 838 if (ifp) { 839 info.rti_info[RTAX_IFP] = 840 ifp->if_addr->ifa_addr; 841 error = rtm_get_jailed(&info, ifp, rt, --- 125 unchanged lines hidden (view full) --- 967 Free(rtm); 968 m_freem(m); 969 return (error); 970 } 971 /* There is another listener, so construct message */ 972 rp = sotorawcb(so); 973 } 974 if (rtm) { | 820 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 821 info.rti_info[RTAX_GENMASK] = 0; 822 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { 823 ifp = rt->rt_ifp; 824 if (ifp) { 825 info.rti_info[RTAX_IFP] = 826 ifp->if_addr->ifa_addr; 827 error = rtm_get_jailed(&info, ifp, rt, --- 125 unchanged lines hidden (view full) --- 953 Free(rtm); 954 m_freem(m); 955 return (error); 956 } 957 /* There is another listener, so construct message */ 958 rp = sotorawcb(so); 959 } 960 if (rtm) { |
961#ifdef INET6 962 if (rti_need_deembed) { 963 /* sin6_scope_id is recovered before sending rtm. */ 964 for (i = 0; i < RTAX_MAX; i++) { 965 sin6 = (struct sockaddr_in6 *)&ss; 966 if (info.rti_info[i] == NULL) 967 continue; 968 if (info.rti_info[i]->sa_family != AF_INET6) 969 continue; 970 bcopy(info.rti_info[i], sin6, sizeof(*sin6)); 971 if (sa6_recoverscope(sin6) == 0) 972 bcopy(sin6, info.rti_info[i], 973 sizeof(*sin6)); 974 } 975 } 976#endif |
|
975 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 976 if (m->m_pkthdr.len < rtm->rtm_msglen) { 977 m_freem(m); 978 m = NULL; 979 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 980 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 981 } 982 if (m) { --- 77 unchanged lines hidden (view full) --- 1060 * This causes kernel to core dump. 1061 * for compatibility, If we see this, point to a safe address. 1062 */ 1063 if (sa->sa_len == 0) { 1064 rtinfo->rti_info[i] = &sa_zero; 1065 return (0); /* should be EINVAL but for compat */ 1066 } 1067 /* accept it */ | 977 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm); 978 if (m->m_pkthdr.len < rtm->rtm_msglen) { 979 m_freem(m); 980 m = NULL; 981 } else if (m->m_pkthdr.len > rtm->rtm_msglen) 982 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); 983 } 984 if (m) { --- 77 unchanged lines hidden (view full) --- 1062 * This causes kernel to core dump. 1063 * for compatibility, If we see this, point to a safe address. 1064 */ 1065 if (sa->sa_len == 0) { 1066 rtinfo->rti_info[i] = &sa_zero; 1067 return (0); /* should be EINVAL but for compat */ 1068 } 1069 /* accept it */ |
1070#ifdef INET6 1071 if (sa->sa_family == AF_INET6) 1072 sa6_embedscope((struct sockaddr_in6 *)sa, 1073 V_ip6_use_defzone); 1074#endif |
|
1068 rtinfo->rti_info[i] = sa; 1069 cp += SA_SIZE(sa); 1070 } 1071 return (0); 1072} 1073 1074/* 1075 * Used by the routing socket. --- 136 unchanged lines hidden (view full) --- 1212 cp += len; 1213 for (i = 0; i < RTAX_MAX; i++) { 1214 struct sockaddr *sa; 1215 1216 if ((sa = rtinfo->rti_info[i]) == NULL) 1217 continue; 1218 rtinfo->rti_addrs |= (1 << i); 1219 dlen = SA_SIZE(sa); | 1075 rtinfo->rti_info[i] = sa; 1076 cp += SA_SIZE(sa); 1077 } 1078 return (0); 1079} 1080 1081/* 1082 * Used by the routing socket. --- 136 unchanged lines hidden (view full) --- 1219 cp += len; 1220 for (i = 0; i < RTAX_MAX; i++) { 1221 struct sockaddr *sa; 1222 1223 if ((sa = rtinfo->rti_info[i]) == NULL) 1224 continue; 1225 rtinfo->rti_addrs |= (1 << i); 1226 dlen = SA_SIZE(sa); |
1227 if (cp) { |
|
1220#ifdef INET6 | 1228#ifdef INET6 |
1221 if (V_deembed_scopeid && sa->sa_family == AF_INET6) { 1222 sin6 = (struct sockaddr_in6 *)&ss; 1223 bcopy(sa, sin6, sizeof(*sin6)); 1224 if (sa6_recoverscope(sin6) == 0) 1225 sa = (struct sockaddr *)sin6; 1226 } | 1229 if (V_deembed_scopeid && sa->sa_family == AF_INET6) { 1230 sin6 = (struct sockaddr_in6 *)&ss; 1231 bcopy(sa, sin6, sizeof(*sin6)); 1232 if (sa6_recoverscope(sin6) == 0) 1233 sa = (struct sockaddr *)sin6; 1234 } |
1227#endif | 1235#endif |
1228 if (cp) { | |
1229 bcopy((caddr_t)sa, cp, (unsigned)dlen); 1230 cp += dlen; 1231 } 1232 len += dlen; 1233 } 1234 len = ALIGN(len); 1235 if (cp == NULL && w != NULL && !second_time) { 1236 struct walkarg *rw = w; --- 323 unchanged lines hidden (view full) --- 1560 */ 1561static int 1562sysctl_dumpentry(struct radix_node *rn, void *vw) 1563{ 1564 struct walkarg *w = vw; 1565 struct rtentry *rt = (struct rtentry *)rn; 1566 int error = 0, size; 1567 struct rt_addrinfo info; | 1236 bcopy((caddr_t)sa, cp, (unsigned)dlen); 1237 cp += dlen; 1238 } 1239 len += dlen; 1240 } 1241 len = ALIGN(len); 1242 if (cp == NULL && w != NULL && !second_time) { 1243 struct walkarg *rw = w; --- 323 unchanged lines hidden (view full) --- 1567 */ 1568static int 1569sysctl_dumpentry(struct radix_node *rn, void *vw) 1570{ 1571 struct walkarg *w = vw; 1572 struct rtentry *rt = (struct rtentry *)rn; 1573 int error = 0, size; 1574 struct rt_addrinfo info; |
1568#ifdef INET6 1569 struct sockaddr_storage ss[RTAX_MAX]; 1570 struct sockaddr_in6 *sin6; 1571 int i; 1572#endif | |
1573 1574 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1575 return 0; 1576 if ((rt->rt_flags & RTF_HOST) == 0 1577 ? jailed_without_vnet(w->w_req->td->td_ucred) 1578 : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0) 1579 return (0); 1580 bzero((caddr_t)&info, sizeof(info)); 1581 info.rti_info[RTAX_DST] = rt_key(rt); 1582 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1583 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1584 info.rti_info[RTAX_GENMASK] = 0; 1585 if (rt->rt_ifp) { 1586 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_addr->ifa_addr; 1587 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1588 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1589 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 1590 } | 1575 1576 if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg)) 1577 return 0; 1578 if ((rt->rt_flags & RTF_HOST) == 0 1579 ? jailed_without_vnet(w->w_req->td->td_ucred) 1580 : prison_if(w->w_req->td->td_ucred, rt_key(rt)) != 0) 1581 return (0); 1582 bzero((caddr_t)&info, sizeof(info)); 1583 info.rti_info[RTAX_DST] = rt_key(rt); 1584 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1585 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1586 info.rti_info[RTAX_GENMASK] = 0; 1587 if (rt->rt_ifp) { 1588 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_addr->ifa_addr; 1589 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr; 1590 if (rt->rt_ifp->if_flags & IFF_POINTOPOINT) 1591 info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr; 1592 } |
1591#ifdef INET6 1592 if (V_deembed_scopeid) { 1593 for (i = 0; i < RTAX_MAX; i++) { 1594 if (info.rti_info[i] == NULL) 1595 continue; 1596 if (info.rti_info[i]->sa_family != AF_INET6) 1597 continue; 1598 sin6 = (struct sockaddr_in6 *)&ss[i]; 1599 bcopy(info.rti_info[i], sin6, sizeof(*sin6)); 1600 if (sa6_recoverscope(sin6) == 0) 1601 info.rti_info[i] = (struct sockaddr *)sin6; 1602 } 1603 } 1604#endif | |
1605 size = rt_msg2(RTM_GET, &info, NULL, w); 1606 if (w->w_req && w->w_tmem) { 1607 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 1608 1609 rtm->rtm_flags = rt->rt_flags; 1610 /* 1611 * let's be honest about this being a retarded hack 1612 */ --- 398 unchanged lines hidden --- | 1593 size = rt_msg2(RTM_GET, &info, NULL, w); 1594 if (w->w_req && w->w_tmem) { 1595 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 1596 1597 rtm->rtm_flags = rt->rt_flags; 1598 /* 1599 * let's be honest about this being a retarded hack 1600 */ --- 398 unchanged lines hidden --- |