#define SO_SECURITY_ENCRYPTION_TRANSPORT       20
 #define SO_SECURITY_ENCRYPTION_NETWORK         21
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __ASM_AVR32_SOCKET_H */
 
 #define SO_PASSSEC             34
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
+
+#define SO_MARK                        36
+
 #endif                         /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_IA64_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_M32R_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #ifdef __KERNEL__
 
 /** sock_type - Socket types
 
 #define SO_PEERSEC             0x401d
 #define SO_PASSSEC             0x401e
 
+#define SO_MARK                        0x401f
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_POWERPC_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __ASM_SH_SOCKET_H */
 
 #define SO_TIMESTAMPNS         0x0021
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        0x0022
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
 
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
 #define SO_SECURITY_ENCRYPTION_NETWORK         0x5004
 
+#define SO_MARK                        0x0022
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* __V850_SOCKET_H__ */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _ASM_SOCKET_H */
 
 #define SO_TIMESTAMPNS         35
 #define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
 
+#define SO_MARK                        36
+
 #endif /* _XTENSA_SOCKET_H */
 
 #include <net/dst.h>
 #include <net/inetpeer.h>
 #include <net/flow.h>
+#include <net/sock.h>
 #include <linux/in_route.h>
 #include <linux/rtnetlink.h>
 #include <linux/route.h>
                                   int flags)
 {
        struct flowi fl = { .oif = oif,
+                           .mark = sk->sk_mark,
                            .nl_u = { .ip4_u = { .daddr = dst,
                                                 .saddr = src,
                                                 .tos   = tos } },
 
        __u32                   sk_sndmsg_off;
        int                     sk_write_pending;
        void                    *sk_security;
+       __u32                   sk_mark;
+       /* XXX 4 bytes hole on 64 bit */
        void                    (*sk_state_change)(struct sock *sk);
        void                    (*sk_data_ready)(struct sock *sk, int bytes);
        void                    (*sk_write_space)(struct sock *sk);
 
                else
                        clear_bit(SOCK_PASSSEC, &sock->flags);
                break;
+       case SO_MARK:
+               if (!capable(CAP_NET_ADMIN))
+                       ret = -EPERM;
+               else {
+                       sk->sk_mark = val;
+               }
+               break;
 
                /* We implement the SO_SNDLOWAT etc to
                   not be settable (1003.1g 5.3) */
        case SO_PEERSEC:
                return security_socket_getpeersec_stream(sock, optval, optlen, len);
 
+       case SO_MARK:
+               v.val = sk->sk_mark;
+               break;
+
        default:
                return -ENOPROTOOPT;
        }
 
        }
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        /* Send it out. */
        return ip_local_out(skb);
                             (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        return ip_local_out(skb);
 
        iph->daddr = rt->rt_dst;
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        if (iph->protocol == IPPROTO_ICMP)
 
        skb_reserve(skb, hh_len);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        skb_reset_network_header(skb);
 
        {
                struct flowi fl = { .oif = ipc.oif,
+                                   .mark = sk->sk_mark,
                                    .nl_u = { .ip4_u =
                                              { .daddr = daddr,
                                                .saddr = saddr,
 
        ipv6_addr_copy(&hdr->daddr, first_hop);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        mtu = dst_mtu(dst);
        if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
        ipv6_addr_copy(&hdr->daddr, final_dst);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
 
        skb->dst = dst_clone(&rt->u.dst);
        IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
 
        skb_reserve(skb, hh_len);
 
        skb->priority = sk->sk_priority;
+       skb->mark = sk->sk_mark;
        skb->dst = dst_clone(&rt->u.dst);
 
        skb_put(skb, length);
         */
        memset(&fl, 0, sizeof(fl));
 
+       fl.mark = sk->sk_mark;
+
        if (sin6) {
                if (addr_len < SIN6_LEN_RFC2133)
                        return -EINVAL;