net: ip: make ip_mkroute_input/__mkroute_input return drop reasons
authorMenglong Dong <menglong8.dong@gmail.com>
Thu, 7 Nov 2024 12:56:00 +0000 (20:56 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 12 Nov 2024 10:24:51 +0000 (11:24 +0100)
In this commit, we make ip_mkroute_input() and __mkroute_input() return
drop reasons.

The drop reason "SKB_DROP_REASON_ARP_PVLAN_DISABLE" is introduced for
the case: the packet which is not IP is forwarded to the in_dev, and
the proxy_arp_pvlan is not enabled.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/dropreason-core.h
net/ipv4/route.c

index 74624d3..6c5a1ea 100644 (file)
        FN(IP_TUNNEL_ECN)               \
        FN(TUNNEL_TXINFO)               \
        FN(LOCAL_MAC)                   \
+       FN(ARP_PVLAN_DISABLE)           \
        FNe(MAX)
 
 /**
@@ -477,6 +478,12 @@ enum skb_drop_reason {
         * the MAC address of the local netdev.
         */
        SKB_DROP_REASON_LOCAL_MAC,
+       /**
+        * @SKB_DROP_REASON_ARP_PVLAN_DISABLE: packet which is not IP is
+        * forwarded to the in_dev, and the proxy_arp_pvlan is not
+        * enabled.
+        */
+       SKB_DROP_REASON_ARP_PVLAN_DISABLE,
        /**
         * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
         * shouldn't be used as a real 'reason' - only for tracing code gen
index 5a7edb6..2697a6c 100644 (file)
@@ -1782,10 +1782,12 @@ static void ip_handle_martian_source(struct net_device *dev,
 }
 
 /* called in rcu_read_lock() section */
-static int __mkroute_input(struct sk_buff *skb, const struct fib_result *res,
-                          struct in_device *in_dev, __be32 daddr,
-                          __be32 saddr, dscp_t dscp)
+static enum skb_drop_reason
+__mkroute_input(struct sk_buff *skb, const struct fib_result *res,
+               struct in_device *in_dev, __be32 daddr,
+               __be32 saddr, dscp_t dscp)
 {
+       enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
        struct fib_nh_common *nhc = FIB_RES_NHC(*res);
        struct net_device *dev = nhc->nhc_dev;
        struct fib_nh_exception *fnhe;
@@ -1799,13 +1801,13 @@ static int __mkroute_input(struct sk_buff *skb, const struct fib_result *res,
        out_dev = __in_dev_get_rcu(dev);
        if (!out_dev) {
                net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n");
-               return -EINVAL;
+               return reason;
        }
 
        err = fib_validate_source(skb, saddr, daddr, dscp, FIB_RES_OIF(*res),
                                  in_dev->dev, in_dev, &itag);
        if (err < 0) {
-               err = -EINVAL;
+               reason = -err;
                ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
                                         saddr);
 
@@ -1833,7 +1835,7 @@ static int __mkroute_input(struct sk_buff *skb, const struct fib_result *res,
                 */
                if (out_dev == in_dev &&
                    IN_DEV_PROXY_ARP_PVLAN(in_dev) == 0) {
-                       err = -EINVAL;
+                       reason = SKB_DROP_REASON_ARP_PVLAN_DISABLE;
                        goto cleanup;
                }
        }
@@ -1856,7 +1858,7 @@ static int __mkroute_input(struct sk_buff *skb, const struct fib_result *res,
        rth = rt_dst_alloc(out_dev->dev, 0, res->type,
                           IN_DEV_ORCONF(out_dev, NOXFRM));
        if (!rth) {
-               err = -ENOBUFS;
+               reason = SKB_DROP_REASON_NOMEM;
                goto cleanup;
        }
 
@@ -1870,9 +1872,9 @@ static int __mkroute_input(struct sk_buff *skb, const struct fib_result *res,
        lwtunnel_set_redirect(&rth->dst);
        skb_dst_set(skb, &rth->dst);
 out:
-       err = 0;
- cleanup:
-       return err;
+       reason = SKB_NOT_DROPPED_YET;
+cleanup:
+       return reason;
 }
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -2130,9 +2132,10 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
 }
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
 
-static int ip_mkroute_input(struct sk_buff *skb, struct fib_result *res,
-                           struct in_device *in_dev, __be32 daddr,
-                           __be32 saddr, dscp_t dscp, struct flow_keys *hkeys)
+static enum skb_drop_reason
+ip_mkroute_input(struct sk_buff *skb, struct fib_result *res,
+                struct in_device *in_dev, __be32 daddr,
+                __be32 saddr, dscp_t dscp, struct flow_keys *hkeys)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
        if (res->fi && fib_info_num_path(res->fi) > 1) {
@@ -2346,9 +2349,8 @@ ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        }
 
 make_route:
-       err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, dscp, flkeys);
-       if (!err)
-               reason = SKB_NOT_DROPPED_YET;
+       reason = ip_mkroute_input(skb, res, in_dev, daddr, saddr, dscp,
+                                 flkeys);
 
 out:
        return reason;