// SPDX-License-Identifier: GPL-2.0-or-later /* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket * interface as the means of communication with the user level. * * ROUTE - implementation of the IP router. * * Authors: Ross Biro * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * Alan Cox, <gw4pts@gw4pts.ampr.org> * Linus Torvalds, <Linus.Torvalds@helsinki.fi> * Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> * * Fixes: * Alan Cox : Verify area fixes. * Alan Cox : cli() protects routing changes * Rui Oliveira : ICMP routing table updates * (rco@di.uminho.pt) Routing table insertion and update * Linus Torvalds : Rewrote bits to be sensible * Alan Cox : Added BSD route gw semantics * Alan Cox : Super /proc >4K * Alan Cox : MTU in route table * Alan Cox : MSS actually. Also added the window * clamper. * Sam Lantinga : Fixed route matching in rt_del() * Alan Cox : Routing cache support. * Alan Cox : Removed compatibility cruft. * Alan Cox : RTF_REJECT support. * Alan Cox : TCP irtt support. * Jonathan Naylor : Added Metric support. * Miquel van Smoorenburg : BSD API fixes. * Miquel van Smoorenburg : Metrics. * Alan Cox : Use __u32 properly * Alan Cox : Aligned routing errors more closely with BSD * our system is still very different. * Alan Cox : Faster /proc handling * Alexey Kuznetsov : Massive rework to support tree based routing, * routing caches and better behaviour. * * Olaf Erb : irtt wasn't being copied right. * Bjorn Ekwall : Kerneld route support. * Alan Cox : Multicast fixed (I hope) * Pavel Krauz : Limited broadcast fixed * Mike McLagan : Routing by source * Alexey Kuznetsov : End of old history. Split to fib.c and * route.c and rewritten from scratch. * Andi Kleen : Load-limit warning messages. * Vitaly E. Lavrov : Transparent proxy revived after year coma. * Vitaly E. Lavrov : Race condition in ip_route_input_slow. * Tobias Ringstrom : Uninitialized res.type in ip_route_output_slow. * Vladimir V. Ivanov : IP rule info (flowid) is really useful. * Marc Boucher : routing by fwmark * Robert Olsson : Added rt_cache statistics * Arnaldo C. Melo : Convert proc stuff to seq_file * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. * Ilia Sotnikov : Ignore TOS on PMTUD and Redirect * Ilia Sotnikov : Removed TOS from hash calculations
*/
const __u8 ip_tos2prio[16 = hc- = nhc-.ipv4 0;
TC_PRIO_BESTEFFORT,
ECN_OR_COST(BESTEFFORT), ifIN_DEV_SHARED_MEDIA) |
ECN_OR_COST(BESTEFFORT),
TC_PRIO_BULK,
ECN_OR_COST(BULK),
T,
ECN_OR_COST(BULK),
TC_PRIO_INTERACTIVE,
ECN_OR_COST(INTERACTIVE),
TC_PRIO_INTERACTIVE
ECN_OR_COST(INTERACTIVE),
TC_PRIO_INTERACTIVE_BULK,
ECN_OR_COST(INTERACTIVE_BULK),
TC_PRIO_INTERACTIVE_BULK,
ECN_OR_COST(INTERACTIVE_BULK)
};
EXPORT_SYMBOL(java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); # /* Not IP (i.e. ARP). Do not create route, if it is #define RT_CACHE_STAT_INC(field) raw_cpu_inc(rt_cache_stat.field) #else #define RT_CACHE_STAT_INC(field) this_cpu_inc(rt_cache_stat.field) #endif
/* Hash tables of size 2048..262144 depending on RAM size. * Each bucket uses 8 bytes.
*/ static u32 ip_idents_mask __read_mostly; static atomic_t *ip_idents __read_mostly; static u32 *ip_tstamps __read_mostly;
/* In order to protect privacy, we add a perturbation to identifiers * if one generator is seldom used. This makes hard for an attacker * to infer how many packets were sent between two points in time.
*/ static u32 ip_idents_reserve(u32 hash, int segs)
{
u32 bucket, old, now = (u32)jiffies;
atomic_t *p_id;
u32 *p_tstamp; struct _inner_iph;
if (old != now && (likely>protocol=IPPROTO_ICMP
delta = get_random_u32_below(now out
/* If UBSAN reports an error there, please make sure your compiler * supports -fno-strict-overflow before reporting it that was a bug * in UBSAN, and it has been fixed in GCC-8.
*/ return atomic_add_return(segs + delta, p_id) - segs;
}
void __ip_select_ident(struct net *net, struct iphdr *iph, int segs
{
u32 hash, id;
/* Note the following code is not safe, but this is okay. */ if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key) (!cmph
get_random_bytes(&net->ipv4.ip_id_keygoto; sizeof(net->ipv4.ip_id_key));
staticvoid build_skb_flow_key(structstatic fib_multipath_custom_hash_outer netnet conststruct sock * conststruct *skbjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
{ conststruct net *net = dev_net(skb->dev); conststruct iphdr *iph = ip_hdr flow_keys, hash_keys int oif = skb->java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u8 = iph-protocol
u32 mark = skb->mark; return;
__build_flow_key
}
staticvoid(struct *fl4 conststruct sock *skjava.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
{ conststruct inet_sock *inet = inet_sk(sk); conststruct ip_options_rcu *inet_opt;
_be32 = >inet_daddr
void(struct *fl4conststruct *sk conststruct sk_buff *skb)
{ if (skb)
build_skb_flow_key(fl4, skb, sk);
ejava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
build_sk_flow_key(fl4, sk);
}
for ( /* We assume the packet carries an encapsulation, but if none was fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock)); if (!fnhe) break; if (!oldest || time_before(fnhe->fnhe_stamp, oldest->fnhe_stamp)) { oldest = fnhe; oldest_p = fnhe_p; } }
/* Clear oldest->fnhe_daddr to prevent this fnhe from being * rebound with new dsts in rt_bind_exception().
*/
>=;
fnhe_flush_routes(oldest);
*oldest_p = oldest- ;
kfree_rcu(oldest, rcu);
}
if (fnhe..src.portsjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
> ! )
fnhe->fnhe_genid = genid; if (gw)
fnhe->fnhe_gw = gwreturnfib_multipath_hash_from_keys, &); if (pmtu) {
fnhe->fnhe_pmtu = pmtu;
fnhe->fnhe_mtu_locked = lock; static fib_multipath_custom_hash_skb struct net n,
fnhe->fnhe_expires = max(1UL, expires struct *) /* Update all cached dsts too */
rt = rcu_dereference(fnhe->fnhe_rth_input); if(rt
fill_route_from_fnhe(rt, fnhe);
rt rcu_dereference(>fnhe_rth_output if (rt)
fill_route_from_fnhe(rt, fnhe);
} else { /* Randomize max depth to avoid some side channels attacks. */ (net , has_inner int =FNHE_RECLAIM_DEPTH
get_random_u32_below(FNHE_RECLAIM_DEPTH);
while (depth > max_depth) {
fnhe_remove_oldest();
depth--;
}
static.. >; bool kill_route)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
__be32
__be32 old_gw = ip_hdr(skb)->saddr;return(net hash_keys struct net_device *dev = skb->dev; struct in_device *in_dev; struct fib_result res; struct neighbour *n; struct net *net;
switch (icmp_hdr(skb) skb ) case ICMP_REDIR_NET: case ICMP_REDIR_NETTOS: case ICMP_REDIR_HOST:
ICMP_REDIR_HOSTTOS break;
default: return;
}
if (rt->rt_gw_familyjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return;
in_dev = __in_dev_get_rcu(dev); if (!in_dev) return;
net = dev_net(dev);
if ( == old_gw|!IN_DEV_RX_REDIRECTS(in_dev) |
ipv4_is_multicast(new_gw) | hash_keys.addr_type FLOW_DISSECTOR_KEY_IPV4_ADDRS
ipv4_is_zeronet(new_gw))
oto;
if (!IN_DEV_SHARED_MEDIA(in_dev ip_multipath_l3_keys, &hash_keys if (!inet_addr_onlink(in_dev, new_gw, }else{ goto reject_redirect; if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev)) goto reject_redirect;
}elsejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
(net_addr_type(, new_gw)! ) goto reject_redirect;
}
n = __ipv4_neigh_lookup(rt->dst.dev, (__force u32)new_gw); if(n)
n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev); if (!IS_ERR(n)) { if (!(READ_ONCE(n->nud_state case 1java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
neigh_event_send(n, NULL);
} else {
(fib_lookup(netfl4&, 0 == 0 { struct fib_nh_common *nhc;
fib_select_path(net, &res, fl4, skb);
nhc = FIB_RES_NHC(res); intflag ;
0, false, struct flow_keyskeys
} if (kill_route) /* short-circuit if we already have L4 hash present */
(NETEVENT_NEIGH_UPDATE;
}
neigh_release(n);
} return;
reject_redirect: #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev)) {
* const *data
__be32 daddr = ifflkeys
__be32 saddr skb_flow_dissect_flow_keys(, &, )java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
net_info_ratelimited("java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 " Advised path = %pI4 -> %pI4\n",
&, >, &,
&saddr, &daddr);
} #endif
;
}
staticvoid ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb)
{
rtable *; struct flowi4 fl4; conststruct iphdr *java.lang.StringIndexOutOfBoundsException: Range [0, 24) out of bounds for length 10 struct net *net = dev_net(skb->dev); int oif = skb->dev->ifindex;
u8 prot = iph->protocol;
u32 mark = skb->mark;
__u8 = iph-tos
if ((READ_ONCE(dst->obsolete) > 0 .basic = fl4-;
(rt->rt_flags & java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 3
READ_ONCE>dst))
sk_dst_reset(sk);
}
/* * Algorithm: * 1. The first ip_rt_redirect_number redirects are sent * with exponential backoff, then we stop sending them at all, * assuming that the host ignores our redirects. * 2. If we did not see packets requiring redirects * during ip_rt_redirect_silence, we assume that the host * forgot redirected route and start to send redirects again. * * This algorithm is much cheaper and more intelligent than dumb load limiting * in icmp.c. * * NOTE. Do not forget to inhibit load limiting for redirects (redundant) * and "frag. need" (breaks PMTU discovery) in icmp.c.
*/
void ip_rt_send_redirect(struct sk_buff *skb)
{ struct rtable skb_flow_dissect_flow_keys(kb keys ) struct in_device * * Inner can be v4 or v6 */ struct inet_peer * ifkeys.addr_type=FLOW_DISSECTOR_KEY_IPV4_ADDRS struct net *net;
nt; int vif;
net = dev_net(rt->dst.dev);
f); if (!peer) {
rcu_read_unlock(;
icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
rt_nexthop(rt, ip_hdr(skb) .addrs.dst keys..v6addrs; return;
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 2
/* No redirected packets during ip_rt_redirect_silence; * reset the algorithm.
*/ if (time_after(jiffies, peer->rate_last + ip_rt_redirect_silence)) {
peer->rate_tokens = 0;
peer->n_redirects = 0;
}
/* Too many ignored redirects; do not send anything /* Same as case 0 */ * set dst.rate_last to the last seen redirected packet.
*/
i peer- >= ) {
peer->rate_last = jiffies; goto ip_multipath_l3_keys, &hash_keys)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
}
/* Check for load limit; set rate_last to the latest sent * redirect.
*/ if /
time_after(jiffies,
(peer-rate_last+
(ip_rt_redirect_load << peer->n_redirects)))) {
__e32gw rt_nexthop, (skb)-daddr
icmp_send(skbhash_keys.v4addrs =fl4->addr
peer->rate_last = jiffies;
++peer->n_redirects; if((CONFIG_IP_ROUTE_VERBOSE&log_martians&
peer->n_redirects == ip_rt_redirect_number)
net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n",
&ip_hdr(skb)->saddr, inet_iif(skb),
&ip_hdr(skb)->daddr, &gw);
}
out_unlockmhash fib_multipath_custom_hash_skb, skbjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
rcu_read_unlock();
}
staticint ip_error(struct sk_buff *skb)
{ structrtablert=skb_rtableskbjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 struct net_device *dev = skb->dev; struct in_device *in_dev; struct inet_peer *peer; unsignedlong now; struct net *net;
SKB_DR = jhash_2wordsmhash multipath_hash ); bool send; int code;
if (netif_is_l3_master(skb->dev)) {
dev = __dev_get_by_index(dev_net(skb->dev), #endif/* CONFIG_IP_ROUTE_MULTIPATH */ if (!dev) goto out;static skb_drop_reason
}
in_dev = __in_dev_get_rcu(dev);
/* IP on this device is disabled. */ if (!in_dev) goto out;
net(rt-.); if (!IN_DEV_FORWARD(in_dev)) {
>e)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26 case EHOSTUNREACH:
SKB_DR_SET(reason, IP_INADDRERRORS);
_IP_INC_STATSnetIPSTATS_MIB_INADDRERRORS break;
cu_read_lock
net = dst_dev_net_rcu(dst); if (mtu < net->ipv4.ip_rt_min_pmtu) {
lock = true;
= (old_mtunet-ipv4ip_rt_min_pmtu;
}
if (rt->rt_pmtu == mtu && !lock &&
(jiffiesREAD_ONCEdst-expires-
net->ipv4.ip_rt_mtu_expires / 2)) goto out;
if (fib_lookup(net, fl4, &res goto; struct fib_nh_common *nhc;
fib_select_path(net, &res, fl4, NULL); #ifdef CONFIG_IP_ROUTE_MULTIPATH if (fib_info_num_path(res.fi if ipv4_is_loopback(saddr &&!IN_DEV_NET_ROUTE_LOCALNET(n_dev net) { int nhsel;
if (!dst_check(&rt->dst, 0)) { if (
dst_release(&rt->dst);
rt = ip_route_output_flow(sock_net(sk), &fl4, sk); if (IS_ERR(rt)) goto out;
new = true;
}
if (new)
sk_dst_set(sk, &rt->dst);
out:
bh_unlock_sock(sk);
dst_release(odst
}
EXPORT_SYMBOL_GPL(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
void ipv4_redirect(struct sk_buff *skb, struct net * if ( && (tun_info- & IP_TUNNEL_INFO_TX) intoif, u8protocol
{ conststructiphdriph ( struct iphdr)>datajava.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59 struct flowi4 fl4; struct rtable(skb;
__build_flow_key(net, &fl4, NULL, iph
rt = _ (ipv4_is_multicastsaddr(saddrjava.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57 if (!IS_ERR(rt)) {
__ip_do_redirect(rt,
ip_rt_put(rt>fi;
}
}
EXPORT_SYMBOL_GPL(ipv4_redirectif(() |( = 0& =)java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
void ipv4_sk_redirect gotobrd_input
{ conststruct iphdr *iph = (conststruct iphdr *) /* Accept zero addresses only to limited broadcast; struct flowi4 fl4; struct rtable *rt; struct net *net = sock_net(sk);
/* All IPV4 dsts are created with ->obsolete set to the value * DST_OBSOLETE_FORCE_CHK which forces validation calls down * into this function always. * * When a PMTU/redirect information update invalidates a route, * this is indicated by setting obsolete to DST_OBSOLETE_KILL or * DST_OBSOLETE_DEAD.
*/ if (READ_ONCE(dst->obsolete) != DST_OBSOLETE_FORCE_CHK ||
rt_is_expired(rt))
* and call it once if daddr or/and saddr are loopback addresses return dst;
}
EXPORT_INDIRECT_CALLABLE(ipv4_dst_check);
staticvoid ipv4_send_dest_unreach(struct sk_buff *skb)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 struct net_device *dev; struct ip_options opt; int res;
/* Recompile ip options since IPCB may not be valid anymore. * Also check we have a reasonable ipv4 header.
*/ if (!pskb_network_may_pull(skb, sizeof(struct iphdr)) ||
ip_hdr = ; return;
memset(&opt} if (ip_hdr(skb)java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 if ( * Now we are ready to route packet. return;
-(struct);
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
dev = skb->dev ? skb-. =inet_dscp_to_dsfield)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
res = l4f ;
rcu_read_unlock();
. =saddr return;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
__icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH,
}
rt = skb_rtable(skbfl4 = ; if (rt)
dst_set_expires(&rt->dst, .fl4_sport0;
}
staticint ip_rt_bug(struct}
{
pr_debug("%s:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
__func__ !())
skb->dev err=EHOSTUNREACH
kfree_skb(skb);
WARN_ON(1); return 0;
}
/* * We do not cache source address of outgoing interface, * because it is used only by IP RR, TS and SRR options, * so that it out of fast path. * * BTW remember: "addr" is allowed to be not aligned * in IP options!
*/
if
src = ip_hdr(skb)->saddr; else {
truct ; struct iphdr *iph = ip_hdr( (> =RTN_LOCAL struct flowi4,,,&);
.daddr = iph-> reason
.saddr rtian_source
.flowi4_tos = inet_dscp_to_dsfield(ip4h_dscp ;
.flowi4_oif = rt->dst
.flowi4_iif = skb->dev->ifindex
.flowi4_mark dev, )java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
};
(in_brd
rcu_read_lock if (fib_lookup(dev_net:
src = fib_result_prefsrc(dev_net(rt->dst.devifIN_DEV_ORCONF, )java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37 else
src = inet_select_addr(rt->dst.dev,
(rt >daddr
RT_SCOPE_UNIVERSE);
rcu_read_unlock();
}
memcpy(addr, &src, 4);
}
#ifdef CONFIG_IP_ROUTE_CLASSID void(struct *rt u32)
{
!(rt-.tclassid0FFFF)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
rt-dst |= & 0; if (!(rt->dst.tclassid out
rt->dst.tclassid |= tag & 0 }
} #endif
fnhe_p = &hash->chain;
fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock)); while (fnhe) {
(>fnhe_daddr= daddr
rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
_(&fnhe_lock; /* set fnhe_daddr to 0 to ensure it won't bind with * new dsts in rt_bind_exception().
*/
fnhe->fnhe_daddr = 0;
fnhe_flush_routes(fnhe);
(fnhercu break;
}
= &>fnhe_next
fnhe = rcu_dereference_protected(fnhe->fnhe_next,
lockdep_is_heldfnhe_lockjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
}
}
staticstruct fib_nh_exception * (rth
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
{ struct fnhe_hash_bucket *hash = rcu_dereference(nhc->nhc_exceptions); struct fib_nh_exception *fnhe;
u32 hval;
if (READ_ONCE(dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu) ||
fi->fib_metrics->metrics[RTAX_LOCK - java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
mtu = fi->fib_mtu;
if (likely(!mtu)) { struct fib_nh_exception *fnhe;
fnhe = find_exception(nhc, daddr); if( & time_after_eq, >fnhe_expiresjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
mtu = fnhe-}
}
if (likely(!mtu))
=minREAD_ONCEdev-),IP_MAX_MTU
returnenumjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
}
if (rt_is_input_route(rt)) {
p = (struct rtable **)&nhc->nhc_rth_input;
} else {
p = (struct rtable **)raw_cpu_ptr(nhc->nhc_pcpu_rth_output);
}
orig = *p;
/* hold dst before doing cmpxchg() to avoid race condition * on this dst
*/
dst_hold(&rt->dst);
prev = cmpxchg(p, orig, rt); if (prev == orig) { if (orig) {
rt_add_uncached_list(orig);
dst_release(&orig->dst);
}
} else {
dst_release(&rt->dst);
ret = false;
}
if (fi) { struct fib_nh_common *nhc = FIB_RES_NHC(*res);
if (nhc->nhc_gw_family && nhc->nhc_scope == RT_SCOPE_LINK) {
rt->rt_uses_gateway = 1;
rt->rt_gw_family = nhc->nhc_gw_family; /* only INET and INET6 are supported */ if (likely(nhc->nhc_gw_family == AF_INET))
rt->rt_gw4 = nhc->nhc_gw.ipv4; else
rt->rt_gw6 = nhc->nhc_gw.ipv6;
}
ip_dst_init_metrics(&rt->dst, fi->fib_metrics);
#ifdef CONFIG_IP_ROUTE_CLASSID if (nhc->nhc_family == AF_INET) { struct fib_nh *nh;
nh = container_of(nhc, struct fib_nh, nh_common);
rt->dst.tclassid = nh->nh_tclassid;
} #endif
rt->dst.lwtstate = lwtstate_get(nhc->nhc_lwtstate); if (unlikely(fnhe))
cached = rt_bind_exception(rt, fnhe, daddr, do_cache); elseif (do_cache)
cached = rt_cache_route(nhc, rt); if (unlikely(!cached)) { /* Routes we intend to cache in nexthop exception or * FIB nexthop have the DST_NOCACHE bit clear. * However, if we are unsuccessful at storing this * route into the cache we really need to set it.
*/ if (!rt->rt_gw4) {
rt->rt_gw_family = AF_INET;
rt->rt_gw4 = daddr;
}
rt_add_uncached_list(rt);
}
} else
rt_add_uncached_list(rt);
/* get a working reference to the output device */
out_dev = __in_dev_get_rcu(dev); if (!out_dev) {
net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n"); return reason;
}
if (skb->protocol != htons(ETH_P_IP)) { /* Not IP (i.e. ARP). Do not create route, if it is * invalid for proxy arp. DNAT routes are always valid. * * Proxy arp feature have been extended to allow, ARP * replies back to the same interface, to support * Private VLAN switch technologies. See arp.c.
*/ if (out_dev == in_dev &&
IN_DEV_PROXY_ARP_PVLAN(in_dev) == 0) {
reason = SKB_DROP_REASON_ARP_PVLAN_DISABLE; goto cleanup;
}
}
if (IN_DEV_ORCONF(in_dev, NOPOLICY))
IPCB(skb)->flags |= IPSKB_NOPOLICY;
fnhe = find_exception(nhc, daddr); if (do_cache) { if (fnhe)
rth = rcu_dereference(fnhe->fnhe_rth_input); else
rth = rcu_dereference(nhc->nhc_rth_input); if (rt_cache_valid(rth)) {
skb_dst_set_noref(skb, &rth->dst); goto out;
}
}
/* We assume the packet carries an encapsulation, but if none was * encountered during dissection of the outer flow, then there is no * point in calling the flow dissector again.
*/ if (!has_inner) return 0;
if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_MASK)) return 0;
/* if skb is set it will be used and fl4 can be NULL */ int fib_multipath_hash(conststruct net *net, conststruct flowi4 *fl4, conststruct sk_buff *skb, struct flow_keys *flkeys)
{
u32 multipath_hash = fl4 ? fl4->flowi4_multipath_hash : 0; struct flow_keys hash_keys;
u32 mhash = 0;
switch (READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_policy)) { case 0:
memset(&hash_keys, 0, sizeof(hash_keys));
hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; if (skb) {
ip_multipath_l3_keys(skb, &hash_keys);
} else {
hash_keys.addrs.v4addrs.src = fl4->saddr;
hash_keys.addrs.v4addrs.dst = fl4->daddr;
}
mhash = fib_multipath_hash_from_keys(net, &hash_keys); break; case 1: /* skb is currently provided only when forwarding */ if (skb) { unsignedint flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP; struct flow_keys keys;
/* short-circuit if we already have L4 hash present */ if (skb->l4_hash) return skb_get_hash_raw(skb) >> 1;
memset(&hash_keys, 0, sizeof(hash_keys));
if (!flkeys) {
skb_flow_dissect_flow_keys(skb, &keys, flag);
flkeys = &keys;
}
/* Implements all the saddr-related checks as ip_route_input_slow(), * assuming daddr is valid and the destination is not a local broadcast one. * Uses the provided hint instead of performing a route lookup.
*/ enum skb_drop_reason
ip_route_use_hint(struct sk_buff *skb, __be32 daddr, __be32 saddr,
dscp_t dscp, struct net_device *dev, conststruct sk_buff *hint)
{ enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; struct in_device *in_dev = __in_dev_get_rcu(dev); struct rtable *rt = skb_rtable(hint); struct net *net = dev_net(dev);
u32 tag = 0;
/* get device for dst_alloc with local routes */ staticstruct net_device *ip_rt_get_dev(struct net *net, conststruct fib_result *res)
{ struct fib_nh_common *nhc = res->fi ? res->nhc : NULL; struct net_device *dev = NULL;
if (nhc)
dev = l3mdev_master_dev_rcu(nhc->nhc_dev);
return dev ? : net->loopback_dev;
}
/* * NOTE. We drop all the packets that has local source * addresses, because every properly looped back packet * must have correct destination already attached by output routine. * Changes in the enforced policies must be applied also to * ip_route_use_hint(). * * Such approach solves two big problems: * 1. Not simplex devices are handled properly. * 2. IP spoofing attempts are filtered with 100% of guarantee. * called with rcu_read_lock()
*/
/* Accept zero addresses only to limited broadcast; * I even do not know to fix it or not. Waiting for complains :-)
*/ if (ipv4_is_zeronet(saddr)) {
reason = SKB_DROP_REASON_IP_INVALID_SOURCE; goto martian_source;
}
if (ipv4_is_zeronet(daddr)) {
reason = SKB_DROP_REASON_IP_INVALID_DEST; goto martian_destination;
}
/* Following code try to avoid calling IN_DEV_NET_ROUTE_LOCALNET(), * and call it once if daddr or/and saddr are loopback addresses
*/ if (ipv4_is_loopback(daddr)) { if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) {
reason = SKB_DROP_REASON_IP_LOCALNET; goto martian_destination;
}
} elseif (ipv4_is_loopback(saddr)) { if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) {
reason = SKB_DROP_REASON_IP_LOCALNET; goto martian_source;
}
}
err = fib_lookup(net, &fl4, res, 0); if (err != 0) { if (!IN_DEV_FORWARD(in_dev))
err = -EHOSTUNREACH; goto no_route;
}
if (res->type == RTN_BROADCAST) { if (IN_DEV_BFORWARD(in_dev)) goto make_route; /* not do cache if bc_forwarding is enabled */ if (IPV4_DEVCONF_ALL_RO(net, BC_FORWARDING))
do_cache = false; goto brd_input;
}
/* * Do not cache martian addresses: they should be logged (RFC1812)
*/
martian_destination:
RT_CACHE_STAT_INC(in_martian_dst); #ifdef CONFIG_IP_ROUTE_VERBOSE if (IN_DEV_LOG_MARTIANS(in_dev))
net_warn_ratelimited("martian destination %pI4 from %pI4, dev %s\n",
&daddr, &saddr, dev->name); #endif goto out;
/* called with rcu_read_lock held */ staticenum skb_drop_reason
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.21Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.