Changeset View
Changeset View
Standalone View
Standalone View
sys/net/rtsock.c
Show First 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | |||||
static int sysctl_iflist(int af, struct walkarg *w); | static int sysctl_iflist(int af, struct walkarg *w); | ||||
static int sysctl_ifmalist(int af, struct walkarg *w); | static int sysctl_ifmalist(int af, struct walkarg *w); | ||||
static int route_output(struct mbuf *m, struct socket *so, ...); | static int route_output(struct mbuf *m, struct socket *so, ...); | ||||
static void rt_getmetrics(const struct rtentry *rt, | static void rt_getmetrics(const struct rtentry *rt, | ||||
const struct nhop_object *nh, struct rt_metrics *out); | const struct nhop_object *nh, struct rt_metrics *out); | ||||
static void rt_dispatch(struct mbuf *, sa_family_t); | static void rt_dispatch(struct mbuf *, sa_family_t); | ||||
static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum, | static int handle_rtm_get(struct rt_addrinfo *info, u_int fibnum, | ||||
struct rt_msghdr *rtm, struct rib_cmd_info *rc); | struct rt_msghdr *rtm, struct rib_cmd_info *rc); | ||||
static int update_rtm_from_rte(struct rt_addrinfo *info, | static int update_rtm_from_rc(struct rt_addrinfo *info, | ||||
struct rt_msghdr **prtm, int alloc_len, | struct rt_msghdr **prtm, int alloc_len, | ||||
struct rtentry *rt, struct nhop_object *nh); | struct rib_cmd_info *rc, struct nhop_object *nh); | ||||
static void send_rtm_reply(struct socket *so, struct rt_msghdr *rtm, | static void send_rtm_reply(struct socket *so, struct rt_msghdr *rtm, | ||||
struct mbuf *m, sa_family_t saf, u_int fibnum, | struct mbuf *m, sa_family_t saf, u_int fibnum, | ||||
int rtm_errno); | int rtm_errno); | ||||
static int can_export_rte(struct ucred *td_ucred, const struct rtentry *rt); | static int can_export_rte(struct ucred *td_ucred, const struct rtentry *rt); | ||||
static struct netisr_handler rtsock_nh = { | static struct netisr_handler rtsock_nh = { | ||||
.nh_name = "rtsock", | .nh_name = "rtsock", | ||||
.nh_handler = rts_input, | .nh_handler = rts_input, | ||||
▲ Show 20 Lines • Show All 544 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
rc->rc_nh_new = rc->rc_rt->rt_nhop; | rc->rc_nh_new = rc->rc_rt->rt_nhop; | ||||
RIB_RUNLOCK(rnh); | RIB_RUNLOCK(rnh); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Update sockaddrs, flags, etc in @prtm based on @rt data. | * Update sockaddrs, flags, etc in @prtm based on @rc data. | ||||
* rtm can be reallocated. | * rtm can be reallocated. | ||||
* | * | ||||
* Returns 0 on success, along with pointer to (potentially reallocated) | * Returns 0 on success, along with pointer to (potentially reallocated) | ||||
* rtm. | * rtm. | ||||
* | * | ||||
*/ | */ | ||||
static int | static int | ||||
update_rtm_from_rte(struct rt_addrinfo *info, struct rt_msghdr **prtm, | update_rtm_from_rc(struct rt_addrinfo *info, struct rt_msghdr **prtm, | ||||
int alloc_len, struct rtentry *rt, struct nhop_object *nh) | int alloc_len, struct rib_cmd_info *rc, struct nhop_object *nh) | ||||
{ | { | ||||
struct sockaddr_storage netmask_ss; | struct sockaddr_storage netmask_ss; | ||||
struct walkarg w; | struct walkarg w; | ||||
union sockaddr_union saun; | union sockaddr_union saun; | ||||
struct rt_msghdr *rtm, *orig_rtm = NULL; | struct rt_msghdr *rtm, *orig_rtm = NULL; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int error, len; | int error, len; | ||||
rtm = *prtm; | rtm = *prtm; | ||||
info->rti_info[RTAX_DST] = rt_key(rt); | info->rti_info[RTAX_DST] = rt_key(rc->rc_rt); | ||||
info->rti_info[RTAX_GATEWAY] = &nh->gw_sa; | info->rti_info[RTAX_GATEWAY] = &nh->gw_sa; | ||||
info->rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rt), | info->rti_info[RTAX_NETMASK] = rtsock_fix_netmask(rt_key(rc->rc_rt), | ||||
rt_mask(rt), &netmask_ss); | rt_mask(rc->rc_rt), &netmask_ss); | ||||
info->rti_info[RTAX_GENMASK] = 0; | info->rti_info[RTAX_GENMASK] = 0; | ||||
ifp = nh->nh_ifp; | ifp = nh->nh_ifp; | ||||
if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { | if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) { | ||||
if (ifp) { | if (ifp) { | ||||
info->rti_info[RTAX_IFP] = | info->rti_info[RTAX_IFP] = | ||||
ifp->if_addr->ifa_addr; | ifp->if_addr->ifa_addr; | ||||
error = rtm_get_jailed(info, ifp, nh, | error = rtm_get_jailed(info, ifp, nh, | ||||
&saun, curthread->td_ucred); | &saun, curthread->td_ucred); | ||||
Show All 28 Lines | if (len > alloc_len) { | ||||
* data referencing it. | * data referencing it. | ||||
*/ | */ | ||||
} | } | ||||
w.w_tmem = (caddr_t)rtm; | w.w_tmem = (caddr_t)rtm; | ||||
w.w_tmemsize = alloc_len; | w.w_tmemsize = alloc_len; | ||||
rtsock_msg_buffer(rtm->rtm_type, info, &w, &len); | rtsock_msg_buffer(rtm->rtm_type, info, &w, &len); | ||||
if (rt->rte_flags & RTF_GWFLAG_COMPAT) | rtm->rtm_flags = rc->rc_rt->rte_flags | nhop_get_rtflags(nh); | ||||
if (rtm->rtm_flags & RTF_GWFLAG_COMPAT) | |||||
rtm->rtm_flags = RTF_GATEWAY | | rtm->rtm_flags = RTF_GATEWAY | | ||||
(rt->rte_flags & ~RTF_GWFLAG_COMPAT); | (rtm->rtm_flags & ~RTF_GWFLAG_COMPAT); | ||||
else | rt_getmetrics(rc->rc_rt, nh, &rtm->rtm_rmx); | ||||
rtm->rtm_flags = rt->rte_flags; | rtm->rtm_rmx.rmx_weight = rc->rc_nh_weight; | ||||
rt_getmetrics(rt, nh, &rtm->rtm_rmx); | |||||
rtm->rtm_addrs = info->rti_addrs; | rtm->rtm_addrs = info->rti_addrs; | ||||
if (orig_rtm != NULL) | if (orig_rtm != NULL) | ||||
free(orig_rtm, M_TEMP); | free(orig_rtm, M_TEMP); | ||||
*prtm = rtm; | *prtm = rtm; | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | if (rtm->rtm_type == RTM_ADD) { | ||||
if (info.rti_info[RTAX_GATEWAY] == NULL) | if (info.rti_info[RTAX_GATEWAY] == NULL) | ||||
senderr(EINVAL); | senderr(EINVAL); | ||||
} | } | ||||
error = rib_action(fibnum, rtm->rtm_type, &info, &rc); | error = rib_action(fibnum, rtm->rtm_type, &info, &rc); | ||||
if (error == 0) { | if (error == 0) { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
rti_need_deembed = 1; | rti_need_deembed = 1; | ||||
#endif | #endif | ||||
rtm->rtm_index = rc.rc_nh_new->nh_ifp->if_index; | |||||
nh = rc.rc_nh_new; | nh = rc.rc_nh_new; | ||||
rtm->rtm_index = nh->nh_ifp->if_index; | |||||
} | } | ||||
break; | break; | ||||
case RTM_DELETE: | case RTM_DELETE: | ||||
error = rib_action(fibnum, RTM_DELETE, &info, &rc); | error = rib_action(fibnum, RTM_DELETE, &info, &rc); | ||||
if (error == 0) { | if (error == 0) { | ||||
nh = rc.rc_nh_old; | nh = rc.rc_nh_old; | ||||
goto report; | goto report; | ||||
Show All 10 Lines | if (error != 0) | ||||
senderr(error); | senderr(error); | ||||
nh = rc.rc_nh_new; | nh = rc.rc_nh_new; | ||||
report: | report: | ||||
if (!can_export_rte(curthread->td_ucred, rc.rc_rt)) { | if (!can_export_rte(curthread->td_ucred, rc.rc_rt)) { | ||||
senderr(ESRCH); | senderr(ESRCH); | ||||
} | } | ||||
error = update_rtm_from_rte(&info, &rtm, alloc_len, rc.rc_rt, nh); | error = update_rtm_from_rc(&info, &rtm, alloc_len, &rc, nh); | ||||
/* | /* | ||||
* Note that some sockaddr pointers may have changed to | * Note that some sockaddr pointers may have changed to | ||||
* point to memory outsize @rtm. Some may be pointing | * point to memory outsize @rtm. Some may be pointing | ||||
* to the on-stack variables. | * to the on-stack variables. | ||||
* Given that, any pointer in @info CANNOT BE USED. | * Given that, any pointer in @info CANNOT BE USED. | ||||
*/ | */ | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 1,194 Lines • Show Last 20 Lines |