Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route/route_ctl.c
Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
#define _MP_FLAGS CTLFLAG_RD | #define _MP_FLAGS CTLFLAG_RD | ||||
#endif | #endif | ||||
VNET_DEFINE(u_int, rib_route_multipath) = 1; | VNET_DEFINE(u_int, rib_route_multipath) = 1; | ||||
SYSCTL_UINT(_net_route, OID_AUTO, multipath, _MP_FLAGS | CTLFLAG_VNET, | SYSCTL_UINT(_net_route, OID_AUTO, multipath, _MP_FLAGS | CTLFLAG_VNET, | ||||
&VNET_NAME(rib_route_multipath), 0, "Enable route multipath"); | &VNET_NAME(rib_route_multipath), 0, "Enable route multipath"); | ||||
#undef _MP_FLAGS | #undef _MP_FLAGS | ||||
#if defined(INET) && defined(INET6) | |||||
FEATURE(ipv4_rfc5549_support, "Route IPv4 packets via IPv6 nexthops"); | |||||
zlei: For the feature routing IPv6 packets via IPv4 next-hops, it does not require too much effort. | |||||
Done Inline Actionslet's remove V6 over V4 for now. melifaro: let's remove V6 over V4 for now. | |||||
#define V_rib_route_ipv6_nexthop VNET(rib_route_ipv6_nexthop) | |||||
VNET_DEFINE(u_int, rib_route_ipv6_nexthop) = 1; | |||||
SYSCTL_UINT(_net_route, OID_AUTO, ipv6_nexthop, CTLFLAG_RW | CTLFLAG_VNET, | |||||
&VNET_NAME(rib_route_ipv6_nexthop), 0, "Enable IPv4 route via IPv6 Next Hop address"); | |||||
#endif | |||||
/* Routing table UMA zone */ | /* Routing table UMA zone */ | ||||
VNET_DEFINE_STATIC(uma_zone_t, rtzone); | VNET_DEFINE_STATIC(uma_zone_t, rtzone); | ||||
#define V_rtzone VNET(rtzone) | #define V_rtzone VNET(rtzone) | ||||
void | void | ||||
vnet_rtzone_init() | vnet_rtzone_init() | ||||
Done Inline ActionsCould you also add feature(3) knob here so the userland can check if the support for the functionality exists? melifaro: Could you also add feature(3) knob here so the userland can check if the support for the… | |||||
Done Inline ActionsI'm new to this feature(3) knob. Can you guide me please ? zlei: I'm new to this feature(3) knob. Can you guide me please ? | |||||
Done Inline ActionsSomething like FEATURE(ipv4_rfc5549_support, "Route IPv4 packets via IPv6 nexthops"); melifaro: Something like `FEATURE(ipv4_rfc5549_support, "Route IPv4 packets via IPv6 nexthops");`
You can… | |||||
{ | { | ||||
V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), | V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), | ||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); | ||||
} | } | ||||
#ifdef VIMAGE | #ifdef VIMAGE | ||||
void | void | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | get_rnh(uint32_t fibnum, const struct rt_addrinfo *info) | ||||
KASSERT((fibnum < rt_numfibs), ("rib_add_route: bad fibnum")); | KASSERT((fibnum < rt_numfibs), ("rib_add_route: bad fibnum")); | ||||
dst = info->rti_info[RTAX_DST]; | dst = info->rti_info[RTAX_DST]; | ||||
rnh = rt_tables_get_rnh(fibnum, dst->sa_family); | rnh = rt_tables_get_rnh(fibnum, dst->sa_family); | ||||
return (rnh); | return (rnh); | ||||
} | } | ||||
#if defined(INET) && defined(INET6) | |||||
static bool | |||||
rib_can_ipv6_nexthop_address(struct rib_head *rh) | |||||
{ | |||||
int result; | |||||
CURVNET_SET(rh->rib_vnet); | |||||
result = !!V_rib_route_ipv6_nexthop; | |||||
CURVNET_RESTORE(); | |||||
return (result); | |||||
} | |||||
#endif | |||||
#ifdef ROUTE_MPATH | #ifdef ROUTE_MPATH | ||||
static bool | static bool | ||||
rib_can_multipath(struct rib_head *rh) | rib_can_multipath(struct rib_head *rh) | ||||
{ | { | ||||
int result; | int result; | ||||
CURVNET_SET(rh->rib_vnet); | CURVNET_SET(rh->rib_vnet); | ||||
result = !!V_rib_route_multipath; | result = !!V_rib_route_multipath; | ||||
▲ Show 20 Lines • Show All 360 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Checks if @dst and @gateway is valid combination. | * Checks if @dst and @gateway is valid combination. | ||||
* | * | ||||
* Returns true if is valid, false otherwise. | * Returns true if is valid, false otherwise. | ||||
*/ | */ | ||||
static bool | static bool | ||||
check_gateway(struct rib_head *rnh, struct sockaddr *dst, | check_gateway(struct rib_head *rnh, struct sockaddr *dst, | ||||
Done Inline ActionsMind renaming to something like check_gateway_family() to match verb_description pattern for other static functions? melifaro: Mind renaming to something like `check_gateway_family()` to match verb_description pattern for… | |||||
struct sockaddr *gateway) | struct sockaddr *gateway) | ||||
{ | { | ||||
if (dst->sa_family == gateway->sa_family) | if (dst->sa_family == gateway->sa_family) | ||||
return (true); | return (true); | ||||
else if (gateway->sa_family == AF_UNSPEC) | else if (gateway->sa_family == AF_UNSPEC) | ||||
return (true); | return (true); | ||||
else if (gateway->sa_family == AF_LINK) | else if (gateway->sa_family == AF_LINK) | ||||
return (true); | return (true); | ||||
#if defined(INET) && defined(INET6) | |||||
else if (dst->sa_family == AF_INET && gateway->sa_family == AF_INET6 && | |||||
rib_can_ipv6_nexthop_address(rnh)) | |||||
return (true); | |||||
#endif | |||||
else | |||||
return (false); | return (false); | ||||
} | } | ||||
/* | /* | ||||
* Creates rtentry and nexthop based on @info data. | * Creates rtentry and nexthop based on @info data. | ||||
* Return 0 and fills in rtentry into @prt on success, | * Return 0 and fills in rtentry into @prt on success, | ||||
* return errno otherwise. | * return errno otherwise. | ||||
*/ | */ | ||||
static int | static int | ||||
create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info, | create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info, | ||||
struct rtentry **prt) | struct rtentry **prt) | ||||
{ | { | ||||
struct sockaddr *dst, *ndst, *gateway, *netmask; | struct sockaddr *dst, *ndst, *gateway, *netmask; | ||||
struct rtentry *rt; | struct rtentry *rt; | ||||
struct nhop_object *nh; | struct nhop_object *nh; | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
int error, flags; | int error, flags; | ||||
dst = info->rti_info[RTAX_DST]; | dst = info->rti_info[RTAX_DST]; | ||||
gateway = info->rti_info[RTAX_GATEWAY]; | gateway = info->rti_info[RTAX_GATEWAY]; | ||||
netmask = info->rti_info[RTAX_NETMASK]; | netmask = info->rti_info[RTAX_NETMASK]; | ||||
flags = info->rti_flags; | flags = info->rti_flags; | ||||
if ((flags & RTF_GATEWAY) && !gateway) | if ((flags & RTF_GATEWAY) && !gateway) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (dst && gateway && !check_gateway(rnh, dst, gateway)) | if (dst && gateway && !check_gateway(rnh, dst, gateway)) | ||||
Done Inline ActionsProbably worth moving to a separate function to improve readability melifaro: Probably worth moving to a separate function to improve readability | |||||
return (EINVAL); | return (EINVAL); | ||||
if (dst->sa_len > sizeof(((struct rtentry *)NULL)->rt_dstb)) | if (dst->sa_len > sizeof(((struct rtentry *)NULL)->rt_dstb)) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (info->rti_ifa == NULL) { | if (info->rti_ifa == NULL) { | ||||
error = rt_getifa_fib(info, rnh->rib_fibnum); | error = rt_getifa_fib(info, rnh->rib_fibnum); | ||||
if (error) | if (error) | ||||
▲ Show 20 Lines • Show All 942 Lines • Show Last 20 Lines |
For the feature routing IPv6 packets via IPv4 next-hops, it does not require too much effort. If it is useful in some case, I think we can put it in a separate diff.
I'm not expert on this. I'll appreciate if someone would share the use-cases of routing IPv6 packets via IPv4 next-hops.