diff -wur kernel-source-2.6.9/include/linux/pfkeyv2.h kernel-source-2.6.9b/include/linux/pfkeyv2.h --- kernel-source-2.6.9/include/linux/pfkeyv2.h 2004-10-18 23:54:55.000000000 +0200 +++ kernel-source-2.6.9b/include/linux/pfkeyv2.h 2005-02-16 08:18:37.000000000 +0100 @@ -216,6 +216,14 @@ } __attribute__((packed)); /* sizeof(struct sadb_x_nat_t_port) == 8 */ +/* Pass a Fwmark match */ +struct sadb_x_mark { + uint16_t sadb_x_mark_len; + uint16_t sadb_x_mark_exttype; + uint32_t sadb_x_mark_match; +} __attribute__((packed)); +/* sizeof(struct sadb_x_mark) == 8 */ + /* Message types */ #define SADB_RESERVED 0 #define SADB_GETSPI 1 @@ -324,7 +332,9 @@ #define SADB_X_EXT_NAT_T_SPORT 21 #define SADB_X_EXT_NAT_T_DPORT 22 #define SADB_X_EXT_NAT_T_OA 23 -#define SADB_EXT_MAX 23 +/* The following entry is for matching SPD to fwmark */ +#define SADB_X_EXT_MARK 24 +#define SADB_EXT_MAX 24 /* Identity Extension values */ #define SADB_IDENTTYPE_RESERVED 0 diff -wur kernel-source-2.6.9/include/linux/xfrm.h kernel-source-2.6.9b/include/linux/xfrm.h --- kernel-source-2.6.9/include/linux/xfrm.h 2004-10-18 23:53:43.000000000 +0200 +++ kernel-source-2.6.9b/include/linux/xfrm.h 2005-01-20 21:08:27.000000000 +0100 @@ -43,6 +43,7 @@ __u8 proto; int ifindex; uid_t user; + __u32 fwmark; }; #define XFRM_INF (~(__u64)0) diff -wur kernel-source-2.6.9/include/net/xfrm.h kernel-source-2.6.9b/include/net/xfrm.h --- kernel-source-2.6.9/include/net/xfrm.h 2004-11-17 11:47:11.000000000 +0100 +++ kernel-source-2.6.9b/include/net/xfrm.h 2005-01-20 21:15:19.000000000 +0100 @@ -469,7 +469,8 @@ !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && (fl->proto == sel->proto || !sel->proto) && - (fl->oif == sel->ifindex || !sel->ifindex); + (fl->oif == sel->ifindex || !sel->ifindex) && + (fl->fl4_fwmark == sel->fwmark || !sel->fwmark); } static inline int diff -wur kernel-source-2.6.9/net/key/af_key.c kernel-source-2.6.9b/net/key/af_key.c --- kernel-source-2.6.9/net/key/af_key.c 2004-10-18 23:55:36.000000000 +0200 +++ kernel-source-2.6.9b/net/key/af_key.c 2005-01-20 21:25:24.000000000 +0100 @@ -336,6 +336,7 @@ [SADB_X_EXT_NAT_T_SPORT] = (u8) sizeof(struct sadb_x_nat_t_port), [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), + [SADB_X_EXT_MARK] = (u8) sizeof(struct sadb_x_mark), }; /* Verify sadb_address_{len,prefixlen} against sa_family. */ @@ -892,6 +893,7 @@ n_port->sadb_x_nat_t_port_reserved = 0; } + return skb; } @@ -1647,7 +1649,8 @@ (sockaddr_size * 2) + sizeof(struct sadb_x_policy) + (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + - (socklen * 2))); + (socklen * 2))) + + sizeof(struct sadb_x_mark); } static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp) @@ -1671,6 +1674,7 @@ struct sadb_lifetime *lifetime; struct sadb_x_policy *pol; struct sockaddr_in *sin; + struct sadb_x_mark *match; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct sockaddr_in6 *sin6; #endif @@ -1855,6 +1859,11 @@ } } } + match = (struct sadb_x_mark*) skb_put(skb, sizeof (struct sadb_x_mark)); + match->sadb_x_mark_len = sizeof(*match)/sizeof(uint64_t); + match->sadb_x_mark_exttype = SADB_X_EXT_MARK; + match->sadb_x_mark_match = xp->selector.fwmark; + hdr->sadb_msg_len = size / sizeof(uint64_t); hdr->sadb_msg_reserved = atomic_read(&xp->refcnt); } @@ -1868,6 +1877,7 @@ struct xfrm_policy *xp; struct sk_buff *out_skb; struct sadb_msg *out_hdr; + struct sadb_x_mark *mark; if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || @@ -1930,6 +1940,9 @@ xp->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime; xp->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime; } + if ((mark = ext_hdrs[SADB_X_EXT_MARK-1]) != NULL) { + xp->selector.fwmark = mark->sadb_x_mark_match; + } xp->xfrm_nr = 0; if (pol->sadb_x_policy_type == IPSEC_POLICY_IPSEC && (err = parse_ipsecrequests(xp, pol)) < 0)