Loading include/net/dst.h +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ struct dst_entry { #define DST_OBSOLETE_NONE 0 #define DST_OBSOLETE_DEAD 2 #define DST_OBSOLETE_FORCE_CHK -1 #define DST_OBSOLETE_KILL -2 unsigned short header_len; /* more space at head required */ unsigned short trailer_len; /* space to reserve at tail */ #ifdef CONFIG_IP_ROUTE_CLASSID Loading net/ipv4/route.c +29 −12 Original line number Diff line number Diff line Loading @@ -673,7 +673,8 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, return; } static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flowi4 *fl4) static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flowi4 *fl4, bool kill_route) { __be32 new_gw = icmp_hdr(skb)->un.gateway; __be32 old_gw = ip_hdr(skb)->saddr; Loading Loading @@ -728,8 +729,8 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow update_or_create_fnhe(nh, fl4->daddr, new_gw, 0, 0); } rt->rt_gateway = new_gw; rt->rt_flags |= RTCF_REDIRECTED; if (kill_route) rt->dst.obsolete = DST_OBSOLETE_KILL; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } neigh_release(n); Loading Loading @@ -760,7 +761,7 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf rt = (struct rtable *) dst; ip_rt_build_flow_key(&fl4, sk, skb); __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, true); } static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) Loading Loading @@ -919,7 +920,7 @@ out: kfree_skb(skb); return 0; } static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) { struct fib_result res; Loading @@ -932,8 +933,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) update_or_create_fnhe(nh, fl4->daddr, 0, mtu, jiffies + ip_rt_mtu_expires); } rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); return mtu; } static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, Loading @@ -943,7 +943,14 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct flowi4 fl4; ip_rt_build_flow_key(&fl4, sk, skb); __ip_rt_update_pmtu(rt, &fl4, mtu); mtu = __ip_rt_update_pmtu(rt, &fl4, mtu); if (!rt->rt_pmtu) { dst->obsolete = DST_OBSOLETE_KILL; } else { rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); } } void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, Loading Loading @@ -989,7 +996,7 @@ void ipv4_redirect(struct sk_buff *skb, struct net *net, RT_TOS(iph->tos), protocol, mark, flow_flags); rt = __ip_route_output_key(net, &fl4); if (!IS_ERR(rt)) { __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, false); ip_rt_put(rt); } } Loading @@ -1004,7 +1011,7 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk) __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); rt = __ip_route_output_key(sock_net(sk), &fl4); if (!IS_ERR(rt)) { __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, false); ip_rt_put(rt); } } Loading @@ -1014,7 +1021,15 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { struct rtable *rt = (struct rtable *) dst; if (rt_is_expired(rt)) /* 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. */ if (dst->obsolete == DST_OBSOLETE_KILL || rt_is_expired(rt)) return NULL; return dst; } Loading Loading @@ -1186,8 +1201,10 @@ static void rt_bind_exception(struct rtable *rt, struct fib_nh *nh, __be32 daddr dst_set_expires(&rt->dst, diff); } } if (gw) if (gw) { rt->rt_flags |= RTCF_REDIRECTED; rt->rt_gateway = gw; } fnhe->fnhe_stamp = jiffies; break; } Loading Loading
include/net/dst.h +1 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ struct dst_entry { #define DST_OBSOLETE_NONE 0 #define DST_OBSOLETE_DEAD 2 #define DST_OBSOLETE_FORCE_CHK -1 #define DST_OBSOLETE_KILL -2 unsigned short header_len; /* more space at head required */ unsigned short trailer_len; /* space to reserve at tail */ #ifdef CONFIG_IP_ROUTE_CLASSID Loading
net/ipv4/route.c +29 −12 Original line number Diff line number Diff line Loading @@ -673,7 +673,8 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw, return; } static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flowi4 *fl4) static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flowi4 *fl4, bool kill_route) { __be32 new_gw = icmp_hdr(skb)->un.gateway; __be32 old_gw = ip_hdr(skb)->saddr; Loading Loading @@ -728,8 +729,8 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow update_or_create_fnhe(nh, fl4->daddr, new_gw, 0, 0); } rt->rt_gateway = new_gw; rt->rt_flags |= RTCF_REDIRECTED; if (kill_route) rt->dst.obsolete = DST_OBSOLETE_KILL; call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, n); } neigh_release(n); Loading Loading @@ -760,7 +761,7 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf rt = (struct rtable *) dst; ip_rt_build_flow_key(&fl4, sk, skb); __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, true); } static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) Loading Loading @@ -919,7 +920,7 @@ out: kfree_skb(skb); return 0; } static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) { struct fib_result res; Loading @@ -932,8 +933,7 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) update_or_create_fnhe(nh, fl4->daddr, 0, mtu, jiffies + ip_rt_mtu_expires); } rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); return mtu; } static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, Loading @@ -943,7 +943,14 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct flowi4 fl4; ip_rt_build_flow_key(&fl4, sk, skb); __ip_rt_update_pmtu(rt, &fl4, mtu); mtu = __ip_rt_update_pmtu(rt, &fl4, mtu); if (!rt->rt_pmtu) { dst->obsolete = DST_OBSOLETE_KILL; } else { rt->rt_pmtu = mtu; dst_set_expires(&rt->dst, ip_rt_mtu_expires); } } void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, Loading Loading @@ -989,7 +996,7 @@ void ipv4_redirect(struct sk_buff *skb, struct net *net, RT_TOS(iph->tos), protocol, mark, flow_flags); rt = __ip_route_output_key(net, &fl4); if (!IS_ERR(rt)) { __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, false); ip_rt_put(rt); } } Loading @@ -1004,7 +1011,7 @@ void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk) __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); rt = __ip_route_output_key(sock_net(sk), &fl4); if (!IS_ERR(rt)) { __ip_do_redirect(rt, skb, &fl4); __ip_do_redirect(rt, skb, &fl4, false); ip_rt_put(rt); } } Loading @@ -1014,7 +1021,15 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) { struct rtable *rt = (struct rtable *) dst; if (rt_is_expired(rt)) /* 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. */ if (dst->obsolete == DST_OBSOLETE_KILL || rt_is_expired(rt)) return NULL; return dst; } Loading Loading @@ -1186,8 +1201,10 @@ static void rt_bind_exception(struct rtable *rt, struct fib_nh *nh, __be32 daddr dst_set_expires(&rt->dst, diff); } } if (gw) if (gw) { rt->rt_flags |= RTCF_REDIRECTED; rt->rt_gateway = gw; } fnhe->fnhe_stamp = jiffies; break; } Loading