diff --git a/include/net/dropreason.h b/include/net/dropreason.h index 3c6f8e0f7..22e9299e4 100644 --- a/include/net/dropreason.h +++ b/include/net/dropreason.h @@ -264,6 +264,8 @@ enum skb_drop_reason { * 'SYN' packet */ SKB_DROP_REASON_TIMEWAIT, + /** @SKB_DROP_REASON_LSM: dropped by LSM */ + SKB_DROP_REASON_LSM, /** * @SKB_DROP_REASON_MAX: the maximum of drop reason, which shouldn't be * used as a real 'reason' diff --git a/include/net/tcp.h b/include/net/tcp.h index a38a09fe0..03fb1e80c 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2035,7 +2035,8 @@ struct tcp_request_sock_ops { __u16 *mss); #endif struct dst_entry *(*route_req)(const struct sock *sk, struct flowi *fl, - const struct request_sock *req); + struct request_sock *req, + enum skb_drop_reason *reason); u32 (*init_seq)(const struct sk_buff *skb); u32 (*init_ts_off)(const struct net *net, const struct sk_buff *skb); int (*send_synack)(const struct sock *sk, struct dst_entry *dst, diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index f8f97a316..24738aa6a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -6746,7 +6746,7 @@ enum skb_drop_reason tcp_conn_request(struct request_sock_ops *rsk_ops, if (tmp_opt.tstamp_ok) tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb); - dst = af_ops->route_req(sk, &fl, req); + dst = af_ops->route_req(sk, &fl, req, &reason); if (!dst) goto drop_and_free; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b7d675314..73b319c9a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1370,9 +1370,15 @@ static void tcp_v4_init_req(struct request_sock *req, static struct dst_entry *tcp_v4_route_req(const struct sock *sk, struct flowi *fl, - const struct request_sock *req) + struct request_sock *req, + enum skb_drop_reason *reason) { - return inet_csk_route_req(sk, &fl->u.ip4, req); + struct dst_entry *dst; + + dst = inet_csk_route_req(sk, &fl->u.ip4, req); + if (!dst) + SKB_DR_SET(*reason, IP_OUTNOROUTES); + return dst; } struct request_sock_ops tcp_request_sock_ops __read_mostly = { diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 891d18265..d013c87e6 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -770,9 +770,15 @@ static void tcp_v6_init_req(struct request_sock *req, static struct dst_entry *tcp_v6_route_req(const struct sock *sk, struct flowi *fl, - const struct request_sock *req) + struct request_sock *req, + enum skb_drop_reason *reason) { - return inet6_csk_route_req(sk, &fl->u.ip6, req, IPPROTO_TCP); + struct dst_entry *dst; + + dst = inet6_csk_route_req(sk, &fl->u.ip6, req, IPPROTO_TCP); + if (!dst) + SKB_DR_SET(*reason, IP_OUTNOROUTES); + return dst; } struct request_sock_ops tcp6_request_sock_ops __read_mostly = {