@@ -2219,9 +2219,10 @@ static struct net_device *ip_rt_get_dev(struct net *net,
22192219 * called with rcu_read_lock()
22202220 */
22212221
2222- static int ip_route_input_slow (struct sk_buff * skb , __be32 daddr , __be32 saddr ,
2223- u8 tos , struct net_device * dev ,
2224- struct fib_result * res )
2222+ static enum skb_drop_reason
2223+ ip_route_input_slow (struct sk_buff * skb , __be32 daddr , __be32 saddr ,
2224+ u8 tos , struct net_device * dev ,
2225+ struct fib_result * res )
22252226{
22262227 enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED ;
22272228 struct in_device * in_dev = __in_dev_get_rcu (dev );
@@ -2251,8 +2252,10 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
22512252 fl4 .flowi4_tun_key .tun_id = 0 ;
22522253 skb_dst_drop (skb );
22532254
2254- if (ipv4_is_multicast (saddr ) || ipv4_is_lbcast (saddr ))
2255+ if (ipv4_is_multicast (saddr ) || ipv4_is_lbcast (saddr )) {
2256+ reason = SKB_DROP_REASON_IP_INVALID_SOURCE ;
22552257 goto martian_source ;
2258+ }
22562259
22572260 res -> fi = NULL ;
22582261 res -> table = NULL ;
@@ -2262,21 +2265,29 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
22622265 /* Accept zero addresses only to limited broadcast;
22632266 * I even do not know to fix it or not. Waiting for complains :-)
22642267 */
2265- if (ipv4_is_zeronet (saddr ))
2268+ if (ipv4_is_zeronet (saddr )) {
2269+ reason = SKB_DROP_REASON_IP_INVALID_SOURCE ;
22662270 goto martian_source ;
2271+ }
22672272
2268- if (ipv4_is_zeronet (daddr ))
2273+ if (ipv4_is_zeronet (daddr )) {
2274+ reason = SKB_DROP_REASON_IP_INVALID_DEST ;
22692275 goto martian_destination ;
2276+ }
22702277
22712278 /* Following code try to avoid calling IN_DEV_NET_ROUTE_LOCALNET(),
22722279 * and call it once if daddr or/and saddr are loopback addresses
22732280 */
22742281 if (ipv4_is_loopback (daddr )) {
2275- if (!IN_DEV_NET_ROUTE_LOCALNET (in_dev , net ))
2282+ if (!IN_DEV_NET_ROUTE_LOCALNET (in_dev , net )) {
2283+ reason = SKB_DROP_REASON_IP_LOCALNET ;
22762284 goto martian_destination ;
2285+ }
22772286 } else if (ipv4_is_loopback (saddr )) {
2278- if (!IN_DEV_NET_ROUTE_LOCALNET (in_dev , net ))
2287+ if (!IN_DEV_NET_ROUTE_LOCALNET (in_dev , net )) {
2288+ reason = SKB_DROP_REASON_IP_LOCALNET ;
22792289 goto martian_source ;
2290+ }
22802291 }
22812292
22822293 /*
@@ -2331,19 +2342,26 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
23312342 err = - EHOSTUNREACH ;
23322343 goto no_route ;
23332344 }
2334- if (res -> type != RTN_UNICAST )
2345+ if (res -> type != RTN_UNICAST ) {
2346+ reason = SKB_DROP_REASON_IP_INVALID_DEST ;
23352347 goto martian_destination ;
2348+ }
23362349
23372350make_route :
23382351 err = ip_mkroute_input (skb , res , in_dev , daddr , saddr , tos , flkeys );
2339- out : return err ;
2352+ if (!err )
2353+ reason = SKB_NOT_DROPPED_YET ;
2354+
2355+ out :
2356+ return reason ;
23402357
23412358brd_input :
2342- if (skb -> protocol != htons (ETH_P_IP ))
2343- goto e_inval ;
2359+ if (skb -> protocol != htons (ETH_P_IP )) {
2360+ reason = SKB_DROP_REASON_INVALID_PROTO ;
2361+ goto out ;
2362+ }
23442363
23452364 if (!ipv4_is_zeronet (saddr )) {
2346- err = - EINVAL ;
23472365 reason = fib_validate_source_reason (skb , saddr , 0 , tos , 0 ,
23482366 dev , in_dev , & itag );
23492367 if (reason )
@@ -2364,7 +2382,7 @@ out: return err;
23642382 rth = rcu_dereference (nhc -> nhc_rth_input );
23652383 if (rt_cache_valid (rth )) {
23662384 skb_dst_set_noref (skb , & rth -> dst );
2367- err = 0 ;
2385+ reason = SKB_NOT_DROPPED_YET ;
23682386 goto out ;
23692387 }
23702388 }
@@ -2401,7 +2419,7 @@ out: return err;
24012419 rt_add_uncached_list (rth );
24022420 }
24032421 skb_dst_set (skb , & rth -> dst );
2404- err = 0 ;
2422+ reason = SKB_NOT_DROPPED_YET ;
24052423 goto out ;
24062424
24072425no_route :
@@ -2422,12 +2440,8 @@ out: return err;
24222440 & daddr , & saddr , dev -> name );
24232441#endif
24242442
2425- e_inval :
2426- err = - EINVAL ;
2427- goto out ;
2428-
24292443e_nobufs :
2430- err = - ENOBUFS ;
2444+ reason = SKB_DROP_REASON_NOMEM ;
24312445 goto out ;
24322446
24332447martian_source :
@@ -2483,7 +2497,7 @@ static int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
24832497 return reason ? - EINVAL : 0 ;
24842498 }
24852499
2486- return ip_route_input_slow (skb , daddr , saddr , tos , dev , res );
2500+ return ip_route_input_slow (skb , daddr , saddr , tos , dev , res ) ? - EINVAL : 0 ;
24872501}
24882502
24892503int ip_route_input_noref (struct sk_buff * skb , __be32 daddr , __be32 saddr ,
0 commit comments