Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_icmp.c
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#include <sys/rmlock.h> | #include <sys/rmlock.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/syslog.h> | #include <sys/syslog.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <net/if_types.h> | #include <net/if_types.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <net/route/nhop.h> | |||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_fib.h> | #include <netinet/in_fib.h> | ||||
#include <netinet/in_pcb.h> | #include <netinet/in_pcb.h> | ||||
#include <netinet/in_systm.h> | #include <netinet/in_systm.h> | ||||
#include <netinet/in_var.h> | #include <netinet/in_var.h> | ||||
#include <netinet/ip.h> | #include <netinet/ip.h> | ||||
▲ Show 20 Lines • Show All 877 Lines • ▼ Show 20 Lines | |||||
* @gateway: new proposed gateway | * @gateway: new proposed gateway | ||||
* | * | ||||
* Returns 0 on success. | * Returns 0 on success. | ||||
*/ | */ | ||||
static int | static int | ||||
icmp_verify_redirect_gateway(struct sockaddr_in *src, struct sockaddr_in *dst, | icmp_verify_redirect_gateway(struct sockaddr_in *src, struct sockaddr_in *dst, | ||||
struct sockaddr_in *gateway, u_int fibnum) | struct sockaddr_in *gateway, u_int fibnum) | ||||
{ | { | ||||
struct rtentry *rt; | struct nhop_object *nh; | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
NET_EPOCH_ASSERT(); | NET_EPOCH_ASSERT(); | ||||
/* Verify the gateway is directly reachable. */ | /* Verify the gateway is directly reachable. */ | ||||
if ((ifa = ifa_ifwithnet((struct sockaddr *)gateway, 0, fibnum))==NULL) | if ((ifa = ifa_ifwithnet((struct sockaddr *)gateway, 0, fibnum))==NULL) | ||||
return (ENETUNREACH); | return (ENETUNREACH); | ||||
/* TODO: fib-aware. */ | /* TODO: fib-aware. */ | ||||
if (ifa_ifwithaddr_check((struct sockaddr *)gateway)) | if (ifa_ifwithaddr_check((struct sockaddr *)gateway)) | ||||
return (EHOSTUNREACH); | return (EHOSTUNREACH); | ||||
rt = rtalloc1_fib((struct sockaddr *)dst, 0, 0UL, fibnum); /* NB: rt is locked */ | nh = fib4_lookup(fibnum, dst->sin_addr, 0, NHR_NONE, 0); | ||||
if (rt == NULL) | if (nh == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* | /* | ||||
* If the redirect isn't from our current router for this dst, | * If the redirect isn't from our current router for this dst, | ||||
* it's either old or wrong. If it redirects us to ourselves, | * it's either old or wrong. If it redirects us to ourselves, | ||||
* we have a routing loop, perhaps as a result of an interface | * we have a routing loop, perhaps as a result of an interface | ||||
* going down recently. | * going down recently. | ||||
*/ | */ | ||||
if (!sa_equal((struct sockaddr *)src, rt->rt_gateway)) { | if (!sa_equal((struct sockaddr *)src, &nh->gw_sa)) | ||||
ae: In another review you told that proper sin_family initialization is not required. Will sa_equal… | |||||
melifaroAuthorUnsubmitted Done Inline Actionssin_family initialisation is not required for the lookup. Gateway sockaddr in the nexthop is aways filled in properly. As here src should also be proper sockaddr, I guess it should continue working as is. melifaro: sin_family initialisation is not required for the //lookup//. Gateway sockaddr in the nexthop… | |||||
RTFREE_LOCKED(rt); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | if (nh->nh_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK) | ||||
if (rt->rt_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK) { | |||||
RTFREE_LOCKED(rt); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
/* If host route already exists, ignore redirect. */ | /* If host route already exists, ignore redirect. */ | ||||
if (rt->rt_flags & RTF_HOST) { | if (nh->nh_flags & NHF_HOST) | ||||
RTFREE_LOCKED(rt); | |||||
return (EEXIST); | return (EEXIST); | ||||
} | |||||
/* If the prefix is directly reachable, ignore redirect. */ | /* If the prefix is directly reachable, ignore redirect. */ | ||||
if (!(rt->rt_flags & RTF_GATEWAY)) { | if (!(nh->nh_flags & NHF_GATEWAY)) | ||||
RTFREE_LOCKED(rt); | |||||
return (EEXIST); | return (EEXIST); | ||||
} | |||||
RTFREE_LOCKED(rt); | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Send an icmp packet back to the ip level, | * Send an icmp packet back to the ip level, | ||||
* after supplying a checksum. | * after supplying a checksum. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 148 Lines • Show Last 20 Lines |
In another review you told that proper sin_family initialization is not required. Will sa_equal work correctly in this case? Is this structure properly initialized? :)