Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in.c
Show First 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
#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/route/nhop.h> | ||||
#include <net/route/route_ctl.h> | #include <net/route/route_ctl.h> | ||||
#include <net/vnet.h> | #include <net/vnet.h> | ||||
#include <netinet/if_ether.h> | #include <netinet/if_ether.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/in_fib.h> | |||||
#include <netinet/in_var.h> | #include <netinet/in_var.h> | ||||
#include <netinet/in_pcb.h> | #include <netinet/in_pcb.h> | ||||
#include <netinet/ip_var.h> | #include <netinet/ip_var.h> | ||||
#include <netinet/ip_carp.h> | #include <netinet/ip_carp.h> | ||||
#include <netinet/igmp_var.h> | #include <netinet/igmp_var.h> | ||||
#include <netinet/udp.h> | #include <netinet/udp.h> | ||||
#include <netinet/udp_var.h> | #include <netinet/udp_var.h> | ||||
▲ Show 20 Lines • Show All 1,278 Lines • ▼ Show 20 Lines | in_lltable_free_entry(struct lltable *llt, struct llentry *lle) | ||||
/* Drop hold queue */ | /* Drop hold queue */ | ||||
pkts_dropped = llentry_free(lle); | pkts_dropped = llentry_free(lle); | ||||
ARPSTAT_ADD(dropped, pkts_dropped); | ARPSTAT_ADD(dropped, pkts_dropped); | ||||
} | } | ||||
static int | static int | ||||
in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr) | in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr) | ||||
{ | { | ||||
struct rt_addrinfo info; | struct nhop_object *nh; | ||||
struct sockaddr_in rt_key, rt_mask; | struct in_addr addr; | ||||
struct sockaddr rt_gateway; | |||||
int rt_flags; | |||||
KASSERT(l3addr->sa_family == AF_INET, | KASSERT(l3addr->sa_family == AF_INET, | ||||
("sin_family %d", l3addr->sa_family)); | ("sin_family %d", l3addr->sa_family)); | ||||
bzero(&rt_key, sizeof(rt_key)); | addr = ((const struct sockaddr_in *)l3addr)->sin_addr; | ||||
rt_key.sin_len = sizeof(rt_key); | |||||
bzero(&rt_mask, sizeof(rt_mask)); | |||||
rt_mask.sin_len = sizeof(rt_mask); | |||||
bzero(&rt_gateway, sizeof(rt_gateway)); | |||||
rt_gateway.sa_len = sizeof(rt_gateway); | |||||
bzero(&info, sizeof(info)); | nh = fib4_lookup(ifp->if_fib, addr, 0, NHR_NONE, 0); | ||||
info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key; | if (nh == NULL) | ||||
info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&rt_mask; | |||||
info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway; | |||||
if (rib_lookup_info(ifp->if_fib, l3addr, NHR_REF, 0, &info) != 0) | |||||
return (EINVAL); | return (EINVAL); | ||||
rt_flags = info.rti_flags; | |||||
/* | /* | ||||
* If the gateway for an existing host route matches the target L3 | * If the gateway for an existing host route matches the target L3 | ||||
* address, which is a special route inserted by some implementation | * address, which is a special route inserted by some implementation | ||||
* such as MANET, and the interface is of the correct type, then | * such as MANET, and the interface is of the correct type, then | ||||
* allow for ARP to proceed. | * allow for ARP to proceed. | ||||
*/ | */ | ||||
if (rt_flags & RTF_GATEWAY) { | if (nh->nh_flags & NHF_GATEWAY) { | ||||
if (!(rt_flags & RTF_HOST) || !info.rti_ifp || | if (!(nh->nh_flags & NHF_HOST) || nh->nh_ifp->if_type != IFT_ETHER || | ||||
ae: This will look better if you move second condition to the next line. | |||||
info.rti_ifp->if_type != IFT_ETHER || | (nh->nh_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 || | ||||
(info.rti_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 || | memcmp(nh->gw_sa.sa_data, l3addr->sa_data, | ||||
memcmp(rt_gateway.sa_data, l3addr->sa_data, | |||||
sizeof(in_addr_t)) != 0) { | sizeof(in_addr_t)) != 0) { | ||||
rib_free_info(&info); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
} | } | ||||
rib_free_info(&info); | |||||
/* | /* | ||||
* Make sure that at least the destination address is covered | * Make sure that at least the destination address is covered | ||||
* by the route. This is for handling the case where 2 or more | * by the route. This is for handling the case where 2 or more | ||||
* interfaces have the same prefix. An incoming packet arrives | * interfaces have the same prefix. An incoming packet arrives | ||||
* on one interface and the corresponding outgoing packet leaves | * on one interface and the corresponding outgoing packet leaves | ||||
* another interface. | * another interface. | ||||
*/ | */ | ||||
if (!(rt_flags & RTF_HOST) && info.rti_ifp != ifp) { | if ((nh->nh_ifp != ifp) && (nh->nh_flags & NHF_HOST) == 0) { | ||||
const char *sa, *mask, *addr, *lim; | struct in_ifaddr *ia = (struct in_ifaddr *)ifaof_ifpforaddr(l3addr, ifp); | ||||
Not Done Inline ActionsIf you move these declarations to the top of function, the expression will not exceed the line length :) ae: If you move these declarations to the top of function, the expression will not exceed the line… | |||||
const struct sockaddr_in *l3sin; | struct in_addr dst_addr, mask_addr; | ||||
mask = (const char *)&rt_mask; | if (ia == NULL) | ||||
return (EINVAL); | |||||
/* | /* | ||||
* Just being extra cautious to avoid some custom | * ifaof_ifpforaddr() returns _best matching_ IFA. | ||||
* code getting into trouble. | * It is possible that ifa prefix does not cover our address. | ||||
* Explicitly verify and fail if that's the case. | |||||
*/ | */ | ||||
if ((info.rti_addrs & RTA_NETMASK) == 0) | dst_addr = IA_SIN(ia)->sin_addr; | ||||
return (EINVAL); | mask_addr.s_addr = htonl(ia->ia_subnetmask); | ||||
sa = (const char *)&rt_key; | if (!IN_ARE_MASKED_ADDR_EQUAL(dst_addr, addr, mask_addr)) | ||||
addr = (const char *)l3addr; | |||||
l3sin = (const struct sockaddr_in *)l3addr; | |||||
lim = addr + l3sin->sin_len; | |||||
for ( ; addr < lim; sa++, mask++, addr++) { | |||||
if ((*sa ^ *addr) & *mask) { | |||||
#ifdef DIAGNOSTIC | |||||
char addrbuf[INET_ADDRSTRLEN]; | |||||
log(LOG_INFO, "IPv4 address: \"%s\" " | |||||
"is not on the network\n", | |||||
inet_ntoa_r(l3sin->sin_addr, addrbuf)); | |||||
#endif | |||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
} | |||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static inline uint32_t | static inline uint32_t | ||||
in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize) | in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 251 Lines • Show Last 20 Lines |
This will look better if you move second condition to the next line.