Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet6/icmp6.c
Show First 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | |||||
#endif /* VIMAGE */ | #endif /* VIMAGE */ | ||||
VNET_DECLARE(struct inpcbinfo, ripcbinfo); | VNET_DECLARE(struct inpcbinfo, ripcbinfo); | ||||
VNET_DECLARE(struct inpcbhead, ripcb); | VNET_DECLARE(struct inpcbhead, ripcb); | ||||
VNET_DECLARE(int, icmp6errppslim); | VNET_DECLARE(int, icmp6errppslim); | ||||
VNET_DEFINE_STATIC(int, icmp6errpps_count) = 0; | VNET_DEFINE_STATIC(int, icmp6errpps_count) = 0; | ||||
VNET_DEFINE_STATIC(struct timeval, icmp6errppslim_last); | VNET_DEFINE_STATIC(struct timeval, icmp6errppslim_last); | ||||
VNET_DECLARE(int, icmp6_nodeinfo); | VNET_DECLARE(int, icmp6_nodeinfo); | ||||
VNET_DEFINE_STATIC(int, icmp6_replyif) = 0; | |||||
melifaro: Would it be possible to name in in a bit more descriptive way? | |||||
VNET_DEFINE_STATIC(char, reply_src6[IFNAMSIZ]); | |||||
#define V_ripcbinfo VNET(ripcbinfo) | #define V_ripcbinfo VNET(ripcbinfo) | ||||
#define V_ripcb VNET(ripcb) | #define V_ripcb VNET(ripcb) | ||||
#define V_icmp6errppslim VNET(icmp6errppslim) | #define V_icmp6errppslim VNET(icmp6errppslim) | ||||
#define V_icmp6errpps_count VNET(icmp6errpps_count) | #define V_icmp6errpps_count VNET(icmp6errpps_count) | ||||
#define V_icmp6errppslim_last VNET(icmp6errppslim_last) | #define V_icmp6errppslim_last VNET(icmp6errppslim_last) | ||||
#define V_icmp6_nodeinfo VNET(icmp6_nodeinfo) | #define V_icmp6_nodeinfo VNET(icmp6_nodeinfo) | ||||
#define V_icmp6_replyif VNET(icmp6_replyif) | |||||
#define V_reply_src6 VNET(reply_src6) | |||||
static void icmp6_errcount(int, int); | static void icmp6_errcount(int, int); | ||||
static int icmp6_rip6_input(struct mbuf **, int); | static int icmp6_rip6_input(struct mbuf **, int); | ||||
static void icmp6_reflect(struct mbuf *, size_t); | static void icmp6_reflect(struct mbuf *, size_t); | ||||
static int icmp6_ratelimit(const struct in6_addr *, const int, const int); | static int icmp6_ratelimit(const struct in6_addr *, const int, const int); | ||||
static const char *icmp6_redirect_diag(struct in6_addr *, | static const char *icmp6_redirect_diag(struct in6_addr *, | ||||
struct in6_addr *, struct in6_addr *); | struct in6_addr *, struct in6_addr *); | ||||
static struct mbuf *ni6_input(struct mbuf *, int, struct prison *); | static struct mbuf *ni6_input(struct mbuf *, int, struct prison *); | ||||
static struct mbuf *ni6_nametodns(const char *, int, int); | static struct mbuf *ni6_nametodns(const char *, int, int); | ||||
static int ni6_dnsmatch(const char *, int, const char *, int); | static int ni6_dnsmatch(const char *, int, const char *, int); | ||||
static int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *, | static int ni6_addrs(struct icmp6_nodeinfo *, struct mbuf *, | ||||
struct ifnet **, struct in6_addr *); | struct ifnet **, struct in6_addr *); | ||||
static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *, | static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *, | ||||
struct ifnet *, int); | struct ifnet *, int); | ||||
static int icmp6_notify_error(struct mbuf **, int, int, int); | static int icmp6_notify_error(struct mbuf **, int, int, int); | ||||
SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, reply_from_interface, CTLFLAG_VNET | CTLFLAG_RW, | |||||
&VNET_NAME(icmp6_replyif), 0, | |||||
"ICMP6 reply from incoming interface for non-local packets"); | |||||
SYSCTL_STRING(_net_inet6_icmp6, OID_AUTO, reply_src, CTLFLAG_VNET | CTLFLAG_RW, | |||||
&VNET_NAME(reply_src6), IFNAMSIZ, | |||||
"ICMP6 reply source for non-local packets"); | |||||
/* | /* | ||||
* Kernel module interface for updating icmp6stat. The argument is an index | * Kernel module interface for updating icmp6stat. The argument is an index | ||||
* into icmp6stat treated as an array of u_quad_t. While this encodes the | * into icmp6stat treated as an array of u_quad_t. While this encodes the | ||||
* general layout of icmp6stat into the caller, it doesn't encode its | * general layout of icmp6stat into the caller, it doesn't encode its | ||||
* location, so that future changes to add, for example, per-CPU stats | * location, so that future changes to add, for example, per-CPU stats | ||||
* support won't cause binary compatibility problems for kernel modules. | * support won't cause binary compatibility problems for kernel modules. | ||||
*/ | */ | ||||
void | void | ||||
▲ Show 20 Lines • Show All 1,957 Lines • ▼ Show 20 Lines | if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { | ||||
if (ia != NULL) | if (ia != NULL) | ||||
ifa_free(&ia->ia_ifa); | ifa_free(&ia->ia_ifa); | ||||
} | } | ||||
if (srcp == NULL) { | if (srcp == NULL) { | ||||
int error; | int error; | ||||
struct in6_addr dst6; | struct in6_addr dst6; | ||||
uint32_t scopeid; | uint32_t scopeid; | ||||
struct ifnet *ifp; | |||||
struct ifaddr *ifa; | |||||
struct in6_ifaddr *ifa6; | |||||
/* | /* | ||||
* This case matches to multicasts, our anycast, or unicasts | * This case matches to multicasts, our anycast, or unicasts | ||||
* that we do not own. Select a source address based on the | * that we do not own. Select a source address based on the | ||||
* source address of the erroneous packet. | * source address of the erroneous packet. | ||||
*/ | */ | ||||
ifp = m->m_pkthdr.rcvif; | |||||
in6_splitscope(&ip6->ip6_src, &dst6, &scopeid); | in6_splitscope(&ip6->ip6_src, &dst6, &scopeid); | ||||
if (V_icmp6_replyif && ifp != NULL) { | |||||
melifaroUnsubmitted Not Done Inline ActionsStill, I'm wondering if you can move everything under V_icmp6_replyif into a separate function. melifaro: Still, I'm wondering if you can move everything under V_icmp6_replyif into a separate function. | |||||
hlim = in6_selecthlim(NULL, ifp); | |||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | |||||
ifa6 = (struct in6_ifaddr *)ifa; | |||||
Done Inline ActionsStyle: there should be no space after the cast. Ditto below. markj: Style: there should be no space after the cast. Ditto below. | |||||
if (ifa->ifa_addr->sa_family != AF_INET6) | |||||
continue; | |||||
if (in6_getscope(&ifa6->ia_addr.sin6_addr) != scopeid) | |||||
continue; | |||||
ia = ifatoia6(ifa); | |||||
srcp = IA6_IN6(ia); | |||||
break; | |||||
} | |||||
Done Inline ActionsWhat if there is no match? Then srcp is left pointing to NULL and we will crash when dereferencing it below. markj: What if there is no match? Then srcp is left pointing to NULL and we will crash when… | |||||
} else if (V_reply_src6[0] != '\0' && (ifp = ifunit(V_reply_src6))) { | |||||
hlim = in6_selecthlim(NULL, ifp); | |||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { | |||||
ifa6 = (struct in6_ifaddr *)ifa; | |||||
if (ifa->ifa_addr->sa_family != AF_INET6) | |||||
continue; | |||||
if (in6_getscope(&ifa6->ia_addr.sin6_addr) != scopeid) | |||||
continue; | |||||
ia = ifatoia6(ifa); | |||||
srcp = IA6_IN6(ia); | |||||
break; | |||||
} | |||||
} else { | |||||
error = in6_selectsrc_addr(M_GETFIB(m), &dst6, | error = in6_selectsrc_addr(M_GETFIB(m), &dst6, | ||||
scopeid, NULL, &src6, &hlim); | scopeid, NULL, &src6, &hlim); | ||||
if (error) { | if (error) { | ||||
char ip6buf[INET6_ADDRSTRLEN]; | char ip6buf[INET6_ADDRSTRLEN]; | ||||
nd6log((LOG_DEBUG, | nd6log((LOG_DEBUG, | ||||
"icmp6_reflect: source can't be determined: " | "icmp6_reflect: source can't be determined: " | ||||
"dst=%s, error=%d\n", | "dst=%s, error=%d\n", | ||||
ip6_sprintf(ip6buf, &ip6->ip6_dst), error)); | ip6_sprintf(ip6buf, &ip6->ip6_dst), error)); | ||||
goto bad; | goto bad; | ||||
} | } | ||||
srcp = &src6; | srcp = &src6; | ||||
Not Done Inline ActionsAny chance this block can be moved to a separate function, to ease reading / testing? melifaro: Any chance this block can be moved to a separate function, to ease reading / testing? | |||||
} | } | ||||
} | |||||
/* | |||||
* If address selection above did not give a source address, fail. | |||||
*/ | |||||
if (srcp == NULL) { | |||||
char ip6buf[INET6_ADDRSTRLEN]; | |||||
nd6log((LOG_DEBUG, | |||||
"icmp6_reflect: source address is null: " | |||||
"dst=%s\n", | |||||
ip6_sprintf(ip6buf, &ip6->ip6_dst))); | |||||
goto bad; | |||||
} | |||||
/* | /* | ||||
* ip6_input() drops a packet if its src is multicast. | * ip6_input() drops a packet if its src is multicast. | ||||
* So, the src is never multicast. | * So, the src is never multicast. | ||||
*/ | */ | ||||
ip6->ip6_dst = ip6->ip6_src; | ip6->ip6_dst = ip6->ip6_src; | ||||
ip6->ip6_src = *srcp; | ip6->ip6_src = *srcp; | ||||
ip6->ip6_flow = 0; | ip6->ip6_flow = 0; | ||||
ip6->ip6_vfc &= ~IPV6_VERSION_MASK; | ip6->ip6_vfc &= ~IPV6_VERSION_MASK; | ||||
▲ Show 20 Lines • Show All 652 Lines • Show Last 20 Lines |
Would it be possible to name in in a bit more descriptive way?