73#include "opt_ipstealth.h"
77#include <sys/kernel.h>
78#include <sys/malloc.h>
80#include <sys/protosw.h>
82#include <sys/socket.h>
83#include <sys/sysctl.h>
86#include <net/if_types.h>
87#include <net/if_var.h>
91#include <net/route/nhop.h>
104#include <machine/in_cksum.h>
106#define V_ipsendredirects VNET(ipsendredirects)
115 KASSERT(nh != NULL, (
"%s: m %p nh is NULL\n", __func__, m));
136 if ((nh->nh_flags & (NHF_DEFAULT | NHF_REDIRECT |
137 NHF_BLACKHOLE | NHF_REJECT)) != 0)
141 if ((nh->nh_flags & NHF_GATEWAY) == 0 || nh->gw_sa.sa_family != AF_INET)
143 newgw->
s_addr = nh->gw4_sa.sin_addr.s_addr;
170 mcopy = m_gethdr(M_NOWAIT, m->m_type);
174 if (m_dup_pkthdr(mcopy, m, M_NOWAIT) == 0) {
184 mcopy->m_len = min(
ip_len, M_TRAILINGSPACE(mcopy));
185 mcopy->m_pkthdr.len = mcopy->m_len;
186 m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
195 struct nhop_object *nh;
203 return (EHOSTUNREACH);
208 if ((nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) != 0) {
211 return (EHOSTUNREACH);
214 if (nh->nh_flags & NHF_REJECT) {
217 return (EHOSTUNREACH);
236 struct mbuf *m0 = NULL;
237 struct nhop_object *nh = NULL;
240 const struct sockaddr *gw;
241 struct in_addr dest, odest, rtdest, osrc;
244 struct m_tag *fwd_tag = NULL;
245 struct mbuf *mcopy = NULL;
258 if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0)
265 ip = mtod(m,
struct ip *);
267 if (
ip->
ip_hl != (
sizeof(
struct ip) >> 2)) {
288 if ((m->m_flags & (M_BCAST|M_MCAST)) ||
289 (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) ||
292 IN_MULTICAST(ntohl(
ip->ip_src.s_addr)) ||
294 IN_LINKLOCAL(ntohl(
ip->ip_src.s_addr)) ||
328 ip = mtod(m,
struct ip *);
345 if (m->m_flags & M_FASTFWD_OURS) {
385 if ((m->m_flags & M_IP_NEXTHOP) &&
386 ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) {
392 m_tag_delete(m, fwd_tag);
393 m->m_flags &= ~M_IP_NEXTHOP;
414 PFIL_OUT | PFIL_FWD, NULL) != PFIL_PASS)
420 ip = mtod(m,
struct ip *);
426 if (m->m_flags & M_IP_NEXTHOP)
427 fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
434 if (m->m_flags & M_FASTFWD_OURS ||
in_localip(dest)) {
439 m->m_flags |= M_FASTFWD_OURS;
448 m_tag_delete(m, fwd_tag);
449 m->m_flags &= ~M_IP_NEXTHOP;
463 bzero(&ro,
sizeof(ro));
468 if (nh->nh_flags & NHF_GATEWAY) {
470 ro.ro_flags |= RT_HAS_GW;
472 gw = (
const struct sockaddr *)dst;
477 nh->nh_ifp == m->m_pkthdr.rcvif)
483 if (ip_len <= nh->nh_mtu) {
492 error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m, gw, &ro);
506 m->m_pkthdr.csum_flags |= CSUM_IP;
508 nh->nh_ifp->if_hwassist) != 0)
510 KASSERT(m != NULL, (
"null mbuf and no error"));
524 mtod(m,
struct ip *), nh->nh_ifp,
525 mtod(m,
struct ip *), NULL);
526 error = (*nh->nh_ifp->if_output)(nh->nh_ifp, m,
530 }
while ((m = m0) != NULL);
533 for (m = m0; m; m = m0) {
bool in_localip(struct in_addr in)
struct nhop_object * fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid, uint32_t flags, uint32_t flowid)
#define IP_PROBE(probe, arg0, arg1, arg2, arg3, arg4, arg5)
struct mbuf * ip_tryforward(struct mbuf *m)
static struct mbuf * ip_redir_alloc(struct mbuf *m, struct nhop_object *nh, u_short ip_len, struct in_addr *osrc, struct in_addr *newgw)
static int ip_findroute(struct nhop_object **pnh, struct in_addr dest, struct mbuf *m)
#define V_ipsendredirects
#define ICMP_UNREACH_HOST
#define ICMP_UNREACH_NEEDFRAG
#define ICMP_REDIRECT_HOST
#define ICMP_TIMXCEED_INTRANS
void icmp_error(struct mbuf *, int, int, uint32_t, int)
#define ICMP_UNREACH_FILTER_PROHIB
int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu, u_long if_hwassist_flags)
struct in_addr ip_src ip_dst