Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/route.c
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
* XXX also has the problems getting the FIB from curthread which will not | * XXX also has the problems getting the FIB from curthread which will not | ||||
* always work given the fib can be overridden and prefixes can be added | * always work given the fib can be overridden and prefixes can be added | ||||
* from the network stack context. | * from the network stack context. | ||||
*/ | */ | ||||
VNET_DEFINE(u_int, rt_add_addr_allfibs) = 1; | VNET_DEFINE(u_int, rt_add_addr_allfibs) = 1; | ||||
SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET, | SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET, | ||||
&VNET_NAME(rt_add_addr_allfibs), 0, ""); | &VNET_NAME(rt_add_addr_allfibs), 0, ""); | ||||
VNET_DEFINE(struct rtstat, rtstat); | VNET_PCPUSTAT_DEFINE_STATIC(struct rtstat, rtstat); | ||||
#define V_rtstat VNET(rtstat) | #define RTSTAT_ADD(name, val) \ | ||||
VNET_PCPUSTAT_ADD(struct rtstat, rtstat, name, (val)) | |||||
#define RTSTAT_INC(name) RTSTAT_ADD(name, 1) | |||||
VNET_PCPUSTAT_SYSINIT(rtstat); | |||||
#ifdef VIMAGE | |||||
VNET_PCPUSTAT_SYSUNINIT(rtstat); | |||||
#endif | |||||
VNET_DEFINE(struct rib_head *, rt_tables); | VNET_DEFINE(struct rib_head *, rt_tables); | ||||
#define V_rt_tables VNET(rt_tables) | #define V_rt_tables VNET(rt_tables) | ||||
VNET_DEFINE(int, rttrash); /* routes not in table but not freed */ | VNET_DEFINE(int, rttrash); /* routes not in table but not freed */ | ||||
#define V_rttrash VNET(rttrash) | #define V_rttrash VNET(rttrash) | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 349 Lines • ▼ Show 20 Lines | #endif | ||||
} else if ((ignflags & RTF_RNH_LOCKED) == 0) | } else if ((ignflags & RTF_RNH_LOCKED) == 0) | ||||
RIB_RUNLOCK(rh); | RIB_RUNLOCK(rh); | ||||
/* | /* | ||||
* Either we hit the root or could not find any match, | * Either we hit the root or could not find any match, | ||||
* which basically means: "cannot get there from here". | * which basically means: "cannot get there from here". | ||||
*/ | */ | ||||
miss: | miss: | ||||
V_rtstat.rts_unreach++; | RTSTAT_INC(rts_unreach); | ||||
if (report) { | if (report) { | ||||
/* | /* | ||||
* If required, report the failure to the supervising | * If required, report the failure to the supervising | ||||
* Authorities. | * Authorities. | ||||
* For a delete, this is not an error. (report == 0) | * For a delete, this is not an error. (report == 0) | ||||
*/ | */ | ||||
bzero(&info, sizeof(info)); | bzero(&info, sizeof(info)); | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | rtredirect_fib(struct sockaddr *dst, | ||||
struct sockaddr *gateway, | struct sockaddr *gateway, | ||||
struct sockaddr *netmask, | struct sockaddr *netmask, | ||||
int flags, | int flags, | ||||
struct sockaddr *src, | struct sockaddr *src, | ||||
u_int fibnum) | u_int fibnum) | ||||
{ | { | ||||
struct rtentry *rt; | struct rtentry *rt; | ||||
int error = 0; | int error = 0; | ||||
short *stat = NULL; | |||||
struct rt_addrinfo info; | struct rt_addrinfo info; | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
struct rib_head *rnh; | struct rib_head *rnh; | ||||
NET_EPOCH_ASSERT(); | NET_EPOCH_ASSERT(); | ||||
ifa = NULL; | ifa = NULL; | ||||
rnh = rt_tables_get_rnh(fibnum, dst->sa_family); | rnh = rt_tables_get_rnh(fibnum, dst->sa_family); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | create: | ||||
ifa_ref(ifa); | ifa_ref(ifa); | ||||
info.rti_ifa = ifa; | info.rti_ifa = ifa; | ||||
info.rti_flags = flags; | info.rti_flags = flags; | ||||
error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum); | error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum); | ||||
if (rt != NULL) { | if (rt != NULL) { | ||||
RT_LOCK(rt); | RT_LOCK(rt); | ||||
flags = rt->rt_flags; | flags = rt->rt_flags; | ||||
} | } | ||||
if (error == 0) | |||||
stat = &V_rtstat.rts_dynamic; | RTSTAT_INC(rts_dynamic); | ||||
} else { | } else { | ||||
/* | /* | ||||
* Smash the current notion of the gateway to | * Smash the current notion of the gateway to | ||||
* this destination. Should check about netmask!!! | * this destination. Should check about netmask!!! | ||||
*/ | */ | ||||
if ((flags & RTF_GATEWAY) == 0) | if ((flags & RTF_GATEWAY) == 0) | ||||
rt->rt_flags &= ~RTF_GATEWAY; | rt->rt_flags &= ~RTF_GATEWAY; | ||||
rt->rt_flags |= RTF_MODIFIED; | rt->rt_flags |= RTF_MODIFIED; | ||||
flags |= RTF_MODIFIED; | flags |= RTF_MODIFIED; | ||||
stat = &V_rtstat.rts_newgateway; | RTSTAT_INC(rts_newgateway); | ||||
/* | /* | ||||
* add the key and gateway (in one malloc'd chunk). | * add the key and gateway (in one malloc'd chunk). | ||||
*/ | */ | ||||
RT_UNLOCK(rt); | RT_UNLOCK(rt); | ||||
RIB_WLOCK(rnh); | RIB_WLOCK(rnh); | ||||
RT_LOCK(rt); | RT_LOCK(rt); | ||||
rt_setgate(rt, rt_key(rt), gateway); | rt_setgate(rt, rt_key(rt), gateway); | ||||
RIB_WUNLOCK(rnh); | RIB_WUNLOCK(rnh); | ||||
} | } | ||||
} else | } else | ||||
error = EHOSTUNREACH; | error = EHOSTUNREACH; | ||||
done: | done: | ||||
if (rt) | if (rt) | ||||
RTFREE_LOCKED(rt); | RTFREE_LOCKED(rt); | ||||
out: | out: | ||||
if (error) | if (error) | ||||
V_rtstat.rts_badredirect++; | RTSTAT_INC(rts_badredirect); | ||||
else if (stat != NULL) | |||||
(*stat)++; | |||||
bzero((caddr_t)&info, sizeof(info)); | bzero((caddr_t)&info, sizeof(info)); | ||||
info.rti_info[RTAX_DST] = dst; | info.rti_info[RTAX_DST] = dst; | ||||
info.rti_info[RTAX_GATEWAY] = gateway; | info.rti_info[RTAX_GATEWAY] = gateway; | ||||
info.rti_info[RTAX_NETMASK] = netmask; | info.rti_info[RTAX_NETMASK] = netmask; | ||||
info.rti_info[RTAX_AUTHOR] = src; | info.rti_info[RTAX_AUTHOR] = src; | ||||
rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum); | rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,584 Lines • Show Last 20 Lines |