/* Exported by fib_frontend.c */
 extern const struct nla_policy rtm_ipv4_policy[];
 extern void            ip_fib_init(void);
-extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
-                              struct net_device *dev, __be32 *spec_dst,
-                              u32 *itag, u32 mark);
+extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
+                              u8 tos, int oif, struct net_device *dev,
+                              __be32 *spec_dst, u32 *itag);
 extern void fib_select_default(struct fib_result *res);
 
 /* Exported by fib_semantics.c */
 
  * - check, that packet arrived from expected physical interface.
  * called with rcu_read_lock()
  */
-int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
-                       struct net_device *dev, __be32 *spec_dst,
-                       u32 *itag, u32 mark)
+int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
+                       int oif, struct net_device *dev, __be32 *spec_dst,
+                       u32 *itag)
 {
        struct in_device *in_dev;
        struct flowi4 fl4;
 
        fl4.flowi4_oif = 0;
        fl4.flowi4_iif = oif;
-       fl4.flowi4_mark = mark;
        fl4.daddr = src;
        fl4.saddr = dst;
        fl4.flowi4_tos = tos;
                no_addr = in_dev->ifa_list == NULL;
                rpf = IN_DEV_RPFILTER(in_dev);
                accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
-               if (mark && !IN_DEV_SRC_VMARK(in_dev))
-                       fl4.flowi4_mark = 0;
+               fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
        }
 
        if (in_dev == NULL)
 
                        goto e_inval;
                spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
        } else {
-               err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
-                                         &itag, 0);
+               err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst,
+                                         &itag);
                if (err < 0)
                        goto e_err;
        }
        }
 
 
-       err = fib_validate_source(saddr, daddr, tos, FIB_RES_OIF(*res),
-                                 in_dev->dev, &spec_dst, &itag, skb->mark);
+       err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
+                                 in_dev->dev, &spec_dst, &itag);
        if (err < 0) {
                ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
                                         saddr);
                goto brd_input;
 
        if (res.type == RTN_LOCAL) {
-               err = fib_validate_source(saddr, daddr, tos,
+               err = fib_validate_source(skb, saddr, daddr, tos,
                                          net->loopback_dev->ifindex,
-                                         dev, &spec_dst, &itag, skb->mark);
+                                         dev, &spec_dst, &itag);
                if (err < 0)
                        goto martian_source_keep_err;
                if (err)
        if (ipv4_is_zeronet(saddr))
                spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
        else {
-               err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
-                                         &itag, skb->mark);
+               err = fib_validate_source(skb, saddr, 0, tos, 0, dev, &spec_dst,
+                                         &itag);
                if (err < 0)
                        goto martian_source_keep_err;
                if (err)