Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/route.c
Show First 20 Lines • Show All 821 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* Returns 0 on success. | * Returns 0 on success. | ||||
*/ | */ | ||||
int | int | ||||
rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags) | rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags) | ||||
{ | { | ||||
struct rt_metrics *rmx; | struct rt_metrics *rmx; | ||||
struct sockaddr *src, *dst; | struct sockaddr *src, *dst; | ||||
struct nhop_object *nh; | |||||
int sa_len; | int sa_len; | ||||
if (flags & NHR_COPY) { | if (flags & NHR_COPY) { | ||||
/* Copy destination if dst is non-zero */ | /* Copy destination if dst is non-zero */ | ||||
src = rt_key(rt); | src = rt_key(rt); | ||||
dst = info->rti_info[RTAX_DST]; | dst = info->rti_info[RTAX_DST]; | ||||
sa_len = src->sa_len; | sa_len = src->sa_len; | ||||
if (dst != NULL) { | if (dst != NULL) { | ||||
Show All 15 Lines | if (src != NULL && dst != NULL) { | ||||
*/ | */ | ||||
if (sa_len > dst->sa_len) | if (sa_len > dst->sa_len) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
memcpy(dst, src, src->sa_len); | memcpy(dst, src, src->sa_len); | ||||
info->rti_addrs |= RTA_NETMASK; | info->rti_addrs |= RTA_NETMASK; | ||||
} | } | ||||
/* Copy gateway is set && dst is non-zero */ | /* Copy gateway is set && dst is non-zero */ | ||||
src = rt->rt_gateway; | src = &rt->rt_nhop->gw_sa; | ||||
dst = info->rti_info[RTAX_GATEWAY]; | dst = info->rti_info[RTAX_GATEWAY]; | ||||
if ((rt->rt_flags & RTF_GATEWAY) && src != NULL && dst != NULL){ | if ((rt->rt_flags & RTF_GATEWAY) && src != NULL && dst != NULL){ | ||||
if (src->sa_len > dst->sa_len) | if (src->sa_len > dst->sa_len) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
memcpy(dst, src, src->sa_len); | memcpy(dst, src, src->sa_len); | ||||
info->rti_addrs |= RTA_GATEWAY; | info->rti_addrs |= RTA_GATEWAY; | ||||
} | } | ||||
} else { | } else { | ||||
info->rti_info[RTAX_DST] = rt_key(rt); | info->rti_info[RTAX_DST] = rt_key(rt); | ||||
info->rti_addrs |= RTA_DST; | info->rti_addrs |= RTA_DST; | ||||
if (rt_mask(rt) != NULL) { | if (rt_mask(rt) != NULL) { | ||||
info->rti_info[RTAX_NETMASK] = rt_mask(rt); | info->rti_info[RTAX_NETMASK] = rt_mask(rt); | ||||
info->rti_addrs |= RTA_NETMASK; | info->rti_addrs |= RTA_NETMASK; | ||||
} | } | ||||
if (rt->rt_flags & RTF_GATEWAY) { | if (rt->rt_flags & RTF_GATEWAY) { | ||||
info->rti_info[RTAX_GATEWAY] = rt->rt_gateway; | info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; | ||||
info->rti_addrs |= RTA_GATEWAY; | info->rti_addrs |= RTA_GATEWAY; | ||||
} | } | ||||
} | } | ||||
nh = rt->rt_nhop; | |||||
rmx = info->rti_rmx; | rmx = info->rti_rmx; | ||||
if (rmx != NULL) { | if (rmx != NULL) { | ||||
info->rti_mflags |= RTV_MTU; | info->rti_mflags |= RTV_MTU; | ||||
rmx->rmx_mtu = rt->rt_mtu; | rmx->rmx_mtu = nh->nh_mtu; | ||||
} | } | ||||
info->rti_flags = rt->rt_flags; | info->rti_flags = rt->rt_flags | nhop_get_rtflags(nh); | ||||
info->rti_ifp = rt->rt_ifp; | info->rti_ifp = nh->nh_ifp; | ||||
info->rti_ifa = rt->rt_ifa; | info->rti_ifa = nh->nh_ifa; | ||||
if (flags & NHR_REF) { | if (flags & NHR_REF) { | ||||
if_ref(info->rti_ifp); | if_ref(info->rti_ifp); | ||||
ifa_ref(info->rti_ifa); | ifa_ref(info->rti_ifa); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | rt_checkdelroute(struct radix_node *rn, void *arg) | ||||
di = (struct rt_delinfo *)arg; | di = (struct rt_delinfo *)arg; | ||||
rt = (struct rtentry *)rn; | rt = (struct rtentry *)rn; | ||||
info = &di->info; | info = &di->info; | ||||
error = 0; | error = 0; | ||||
info->rti_info[RTAX_DST] = rt_key(rt); | info->rti_info[RTAX_DST] = rt_key(rt); | ||||
info->rti_info[RTAX_NETMASK] = rt_mask(rt); | info->rti_info[RTAX_NETMASK] = rt_mask(rt); | ||||
info->rti_info[RTAX_GATEWAY] = rt->rt_gateway; | info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; | ||||
rt = rt_unlinkrte(di->rnh, info, &error); | rt = rt_unlinkrte(di->rnh, info, &error); | ||||
if (rt == NULL) { | if (rt == NULL) { | ||||
/* Either not allowed or not matched. Skip entry */ | /* Either not allowed or not matched. Skip entry */ | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Entry was unlinked. Add to the list and return */ | /* Entry was unlinked. Add to the list and return */ | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | if (info->rti_filter(rt, rt->rt_nhop, info->rti_filterdata)==0){ | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* | /* | ||||
* Filter function requested rte deletion. | * Filter function requested rte deletion. | ||||
* Ease the caller work by filling in remaining info | * Ease the caller work by filling in remaining info | ||||
* from that particular entry. | * from that particular entry. | ||||
*/ | */ | ||||
info->rti_info[RTAX_GATEWAY] = rt->rt_gateway; | info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; | ||||
} | } | ||||
/* | /* | ||||
* Remove the item from the tree and return it. | * Remove the item from the tree and return it. | ||||
* Complain if it is not there and do no more processing. | * Complain if it is not there and do no more processing. | ||||
*/ | */ | ||||
*perror = ESRCH; | *perror = ESRCH; | ||||
#ifdef RADIX_MPATH | #ifdef RADIX_MPATH | ||||
▲ Show 20 Lines • Show All 238 Lines • ▼ Show 20 Lines | rt_print(char *buf, int buflen, struct rtentry *rt) | ||||
i = p_sockaddr(buf, buflen, addr); | i = p_sockaddr(buf, buflen, addr); | ||||
if (!(rt->rt_flags & RTF_HOST)) { | if (!(rt->rt_flags & RTF_HOST)) { | ||||
buf[i++] = '/'; | buf[i++] = '/'; | ||||
i += p_sockaddr(buf + i, buflen - i, mask); | i += p_sockaddr(buf + i, buflen - i, mask); | ||||
} | } | ||||
if (rt->rt_flags & RTF_GATEWAY) { | if (rt->rt_flags & RTF_GATEWAY) { | ||||
buf[i++] = '>'; | buf[i++] = '>'; | ||||
i += p_sockaddr(buf + i, buflen - i, rt->rt_gateway); | i += p_sockaddr(buf + i, buflen - i, &rt->rt_nhop->gw_sa); | ||||
} | } | ||||
return (i); | return (i); | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef RADIX_MPATH | #ifdef RADIX_MPATH | ||||
/* | /* | ||||
Show All 40 Lines | if (rn) { | ||||
* For gateway routes, we need to | * For gateway routes, we need to | ||||
* make sure that we we are deleting | * make sure that we we are deleting | ||||
* the correct gateway. | * the correct gateway. | ||||
* rt_mpath_matchgate() does not | * rt_mpath_matchgate() does not | ||||
* check the case when there is only | * check the case when there is only | ||||
* one route in the chain. | * one route in the chain. | ||||
*/ | */ | ||||
if (gw && | if (gw && | ||||
(rt->rt_gateway->sa_len != gw->sa_len || | (rt->rt_nhop->gw_sa.sa_len != gw->sa_len || | ||||
memcmp(rt->rt_gateway, gw, gw->sa_len))) { | memcmp(&rt->rt_nhop->gw_sa, gw, gw->sa_len))) { | ||||
*perror = ESRCH; | *perror = ESRCH; | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* use the normal delete code to remove | * use the normal delete code to remove | ||||
* the first entry | * the first entry | ||||
▲ Show 20 Lines • Show All 532 Lines • ▼ Show 20 Lines | rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) | ||||
struct sockaddr *netmask; | struct sockaddr *netmask; | ||||
struct rtentry *rt = NULL; | struct rtentry *rt = NULL; | ||||
struct rt_addrinfo info; | struct rt_addrinfo info; | ||||
int error = 0; | int error = 0; | ||||
int startfib, endfib; | int startfib, endfib; | ||||
char tempbuf[_SOCKADDR_TMPSIZE]; | char tempbuf[_SOCKADDR_TMPSIZE]; | ||||
int didwork = 0; | int didwork = 0; | ||||
int a_failure = 0; | int a_failure = 0; | ||||
struct sockaddr_dl *sdl = NULL; | struct sockaddr_dl_short *sdl = NULL; | ||||
struct rib_head *rnh; | struct rib_head *rnh; | ||||
if (flags & RTF_HOST) { | if (flags & RTF_HOST) { | ||||
dst = ifa->ifa_dstaddr; | dst = ifa->ifa_dstaddr; | ||||
netmask = NULL; | netmask = NULL; | ||||
} else { | } else { | ||||
dst = ifa->ifa_addr; | dst = ifa->ifa_addr; | ||||
netmask = ifa->ifa_netmask; | netmask = ifa->ifa_netmask; | ||||
Show All 35 Lines | if (cmd == RTM_DELETE) { | ||||
* (Assuming we have a mask) | * (Assuming we have a mask) | ||||
* XXX this is kinda inet specific.. | * XXX this is kinda inet specific.. | ||||
*/ | */ | ||||
if (netmask != NULL) { | if (netmask != NULL) { | ||||
rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask); | rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask); | ||||
dst = (struct sockaddr *)tempbuf; | dst = (struct sockaddr *)tempbuf; | ||||
} | } | ||||
} else if (cmd == RTM_ADD) { | } else if (cmd == RTM_ADD) { | ||||
sdl = (struct sockaddr_dl *)tempbuf; | sdl = (struct sockaddr_dl_short *)tempbuf; | ||||
bzero(sdl, sizeof(struct sockaddr_dl)); | bzero(sdl, sizeof(struct sockaddr_dl_short)); | ||||
sdl->sdl_family = AF_LINK; | sdl->sdl_family = AF_LINK; | ||||
sdl->sdl_len = sizeof(struct sockaddr_dl); | sdl->sdl_len = sizeof(struct sockaddr_dl_short); | ||||
sdl->sdl_type = ifa->ifa_ifp->if_type; | sdl->sdl_type = ifa->ifa_ifp->if_type; | ||||
sdl->sdl_index = ifa->ifa_ifp->if_index; | sdl->sdl_index = ifa->ifa_ifp->if_index; | ||||
} | } | ||||
/* | /* | ||||
* Now go through all the requested tables (fibs) and do the | * Now go through all the requested tables (fibs) and do the | ||||
* requested action. Realistically, this will either be fib 0 | * requested action. Realistically, this will either be fib 0 | ||||
* for protocols that don't do multiple tables or all the | * for protocols that don't do multiple tables or all the | ||||
* tables for those that do. | * tables for those that do. | ||||
Show All 15 Lines | #ifdef RADIX_MPATH | ||||
if (rt_mpath_capable(rnh)) { | if (rt_mpath_capable(rnh)) { | ||||
if (rn == NULL) | if (rn == NULL) | ||||
error = ESRCH; | error = ESRCH; | ||||
else { | else { | ||||
rt = RNTORT(rn); | rt = RNTORT(rn); | ||||
/* | /* | ||||
* for interface route the | * for interface route the | ||||
* rt->rt_gateway is sockaddr_intf | * rt->rt_gateway is sockaddr_dl, so | ||||
* for cloning ARP entries, so | |||||
* rt_mpath_matchgate must use the | * rt_mpath_matchgate must use the | ||||
* interface address | * interface address | ||||
*/ | */ | ||||
rt = rt_mpath_matchgate(rt, | rt = rt_mpath_matchgate(rt, | ||||
ifa->ifa_addr); | ifa->ifa_addr); | ||||
if (rt == NULL) | if (rt == NULL) | ||||
error = ESRCH; | error = ESRCH; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 209 Lines • Show Last 20 Lines |