FRA_UNUSED3,
        FRA_UNUSED4,
        FRA_UNUSED5,
-       FRA_FWMARK,     /* netfilter mark (IPv4) */
+       FRA_FWMARK,     /* netfilter mark (IPv4/IPv6) */
        FRA_FLOW,       /* flow/class id */
        FRA_UNUSED6,
        FRA_UNUSED7,
 
                struct {
                        struct in6_addr         daddr;
                        struct in6_addr         saddr;
+                       __u32                   fwmark;
                        __u32                   flowlabel;
                } ip6_u;
 
 #define fld_scope      nl_u.dn_u.scope
 #define fl6_dst                nl_u.ip6_u.daddr
 #define fl6_src                nl_u.ip6_u.saddr
+#define fl6_fwmark     nl_u.ip6_u.fwmark
 #define fl6_flowlabel  nl_u.ip6_u.flowlabel
 #define fl4_dst                nl_u.ip4_u.daddr
 #define fl4_src                nl_u.ip4_u.saddr
 
        ---help---
          Support multiple routing tables.
 
+config IPV6_ROUTE_FWMARK
+       bool "IPv6: use netfilter MARK value as routing key"
+       depends on IPV6_MULTIPLE_TABLES && NETFILTER
+       ---help---
+         If you say Y here, you will be able to specify different routes for
+         packets with different mark values (see iptables(8), MARK target).
+
 
        struct fib_rule         common;
        struct rt6key           src;
        struct rt6key           dst;
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+       u8                      fwmark;
+#endif
        u8                      tclass;
 };
 
        if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
                return 0;
 
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+       if (r->fwmark && (r->fwmark != fl->fl6_fwmark))
+               return 0;
+#endif
+
        return 1;
 }
 
                nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
                           sizeof(struct in6_addr));
 
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+       if (tb[FRA_FWMARK])
+               rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
+#endif
+
        rule6->src.plen = frh->src_len;
        rule6->dst.plen = frh->dst_len;
        rule6->tclass = frh->tos;
            nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
                return 0;
 
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+       if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
+               return 0;
+#endif
+
        return 1;
 }
 
                NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
                        &rule6->src.addr);
 
+#ifdef CONFIG_IPV6_ROUTE_FWMARK
+       if (rule6->fwmark)
+               NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
+#endif
+
        return 0;
 
 nla_put_failure: