* [PATCH] [IPSEC]: Add populate from packet (PFP) support
@ 2007-12-12 3:23 Tyler Hicks
2007-12-12 13:52 ` Herbert Xu
0 siblings, 1 reply; 2+ messages in thread
From: Tyler Hicks @ 2007-12-12 3:23 UTC (permalink / raw)
To: linux netdev, David Miller; +Cc: Herbert Xu, Joy Latten
RFC 4301 requires us to associate each SPD entry with a set of flags to
determine how to assign the selector values when creating a new SAD entry.
Each selector in the new xfrm_state can either be assigned using the
corresponding selector in the xfrm_policy or with the corresponding value
in the flowi. Prior to this patch, the fields in the flowi were always
used.
Signed-off-by: Tyler Hicks <tyhicks@ou.edu>
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index b58adc5..ce6b1b5 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -362,6 +362,11 @@ struct xfrm_userpolicy_info {
#define XFRM_POLICY_BLOCK 1
__u8 flags;
#define XFRM_POLICY_LOCALOK 1 /* Allow user to override global policy */
+#define XFRM_POLICY_PFP_SADDR 2
+#define XFRM_POLICY_PFP_DADDR 4
+#define XFRM_POLICY_PFP_PROTO 8
+#define XFRM_POLICY_PFP_SPORT 16
+#define XFRM_POLICY_PFP_DPORT 32
__u8 share;
};
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 58dfa82..5a039a2 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -261,9 +261,12 @@ struct xfrm_state_afinfo {
struct xfrm_type *type_map[IPPROTO_MAX];
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
int (*init_flags)(struct xfrm_state *x);
- void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
+ void (*init_tempsel)(struct xfrm_state *x,
+ struct flowi *fl,
struct xfrm_tmpl *tmpl,
- xfrm_address_t *daddr, xfrm_address_t *saddr);
+ struct xfrm_policy *pol,
+ xfrm_address_t *daddr,
+ xfrm_address_t *saddr);
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
int (*output)(struct sk_buff *skb);
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 13d54a1..0fb1092 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -23,18 +23,39 @@ static int xfrm4_init_flags(struct xfrm_state *x)
static void
__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
+ struct xfrm_tmpl *tmpl, struct xfrm_policy *pol,
xfrm_address_t *daddr, xfrm_address_t *saddr)
{
- x->sel.daddr.a4 = fl->fl4_dst;
- x->sel.saddr.a4 = fl->fl4_src;
- x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = htons(0xffff);
- x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = htons(0xffff);
- x->sel.prefixlen_d = 32;
- x->sel.prefixlen_s = 32;
- x->sel.proto = fl->proto;
+ if (pol->flags & XFRM_POLICY_PFP_DADDR) {
+ x->sel.daddr.a4 = fl->fl4_dst;
+ x->sel.prefixlen_d = 32;
+ } else {
+ x->sel.daddr.a4 = pol->selector.daddr.a4;
+ x->sel.prefixlen_d = pol->selector.prefixlen_d;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_SADDR) {
+ x->sel.saddr.a4 = fl->fl4_src;
+ x->sel.prefixlen_s = 32;
+ } else {
+ x->sel.saddr.a4 = pol->selector.saddr.a4;
+ x->sel.prefixlen_s = pol->selector.prefixlen_s;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_DPORT) {
+ x->sel.dport = xfrm_flowi_dport(fl);
+ x->sel.dport_mask = htons(0xffff);
+ } else {
+ x->sel.dport = pol->selector.dport;
+ x->sel.dport_mask = pol->selector.dport_mask;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_SPORT) {
+ x->sel.sport = xfrm_flowi_sport(fl);
+ x->sel.sport_mask = htons(0xffff);
+ } else {
+ x->sel.sport = pol->selector.sport;
+ x->sel.sport = pol->selector.sport_mask;
+ }
+ x->sel.proto = pol->flags & XFRM_POLICY_PFP_PROTO ?
+ fl->proto : pol->selector.proto;
x->sel.ifindex = fl->oif;
x->id = tmpl->id;
if (x->id.daddr.a4 == 0)
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
index b392bee..213d92d 100644
--- a/net/ipv6/xfrm6_state.c
+++ b/net/ipv6/xfrm6_state.c
@@ -21,20 +21,43 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo;
static void
__xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
+ struct xfrm_tmpl *tmpl, struct xfrm_policy *pol,
xfrm_address_t *daddr, xfrm_address_t *saddr)
{
/* Initialize temporary selector matching only
* to current session. */
- ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
- ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
- x->sel.dport = xfrm_flowi_dport(fl);
- x->sel.dport_mask = htons(0xffff);
- x->sel.sport = xfrm_flowi_sport(fl);
- x->sel.sport_mask = htons(0xffff);
- x->sel.prefixlen_d = 128;
- x->sel.prefixlen_s = 128;
- x->sel.proto = fl->proto;
+ if (pol->flags & XFRM_POLICY_PFP_DADDR) {
+ ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
+ x->sel.prefixlen_d = 128;
+ } else {
+ ipv6_addr_copy((struct in6_addr *)&x->sel.daddr,
+ (struct in6_addr *)&pol->selector.daddr);
+ x->sel.prefixlen_d = pol->selector.prefixlen_d;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_SADDR) {
+ ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
+ x->sel.prefixlen_s = 128;
+ } else {
+ ipv6_addr_copy((struct in6_addr *)&x->sel.saddr,
+ (struct in6_addr *)&pol->selector.saddr);
+ x->sel.prefixlen_s = pol->selector.prefixlen_s;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_DPORT) {
+ x->sel.dport = xfrm_flowi_dport(fl);
+ x->sel.dport_mask = htons(0xffff);
+ } else {
+ x->sel.dport = pol->selector.dport;
+ x->sel.dport_mask = pol->selector.dport_mask;
+ }
+ if (pol->flags & XFRM_POLICY_PFP_SPORT) {
+ x->sel.sport = xfrm_flowi_sport(fl);
+ x->sel.sport_mask = htons(0xffff);
+ } else {
+ x->sel.sport = pol->selector.sport;
+ x->sel.sport_mask = pol->selector.sport_mask;
+ }
+ x->sel.proto = pol->flags & XFRM_POLICY_PFP_PROTO ?
+ fl->proto : pol->selector.proto;
x->sel.ifindex = fl->oif;
x->id = tmpl->id;
if (ipv6_addr_any((struct in6_addr*)&x->id.daddr))
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 224b44e..2dab50e 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -654,14 +654,14 @@ EXPORT_SYMBOL(xfrm_sad_getinfo);
static int
xfrm_init_tempsel(struct xfrm_state *x, struct flowi *fl,
- struct xfrm_tmpl *tmpl,
+ struct xfrm_tmpl *tmpl, struct xfrm_policy *pol,
xfrm_address_t *daddr, xfrm_address_t *saddr,
unsigned short family)
{
struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
if (!afinfo)
return -1;
- afinfo->init_tempsel(x, fl, tmpl, daddr, saddr);
+ afinfo->init_tempsel(x, fl, tmpl, pol, daddr, saddr);
xfrm_state_put_afinfo(afinfo);
return 0;
}
@@ -824,7 +824,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
}
/* Initialize temporary selector matching only
* to current session. */
- xfrm_init_tempsel(x, fl, tmpl, daddr, saddr, family);
+ xfrm_init_tempsel(x, fl, tmpl, pol, daddr, saddr, family);
error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
if (error) {
--
1.5.3.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] [IPSEC]: Add populate from packet (PFP) support
2007-12-12 3:23 [PATCH] [IPSEC]: Add populate from packet (PFP) support Tyler Hicks
@ 2007-12-12 13:52 ` Herbert Xu
0 siblings, 0 replies; 2+ messages in thread
From: Herbert Xu @ 2007-12-12 13:52 UTC (permalink / raw)
To: Tyler Hicks; +Cc: linux netdev, David Miller, Joy Latten
On Tue, Dec 11, 2007 at 07:23:52PM -0800, Tyler Hicks wrote:
> RFC 4301 requires us to associate each SPD entry with a set of flags to
> determine how to assign the selector values when creating a new SAD entry.
>
> Each selector in the new xfrm_state can either be assigned using the
> corresponding selector in the xfrm_policy or with the corresponding value
> in the flowi. Prior to this patch, the fields in the flowi were always
> used.
>
> Signed-off-by: Tyler Hicks <tyhicks@ou.edu>
Thanks for the patch Tyler!
I think the kernel is fine as it is. What we're doing is generating
the most specific selector possible for the larval SA and which lets
the KM do whatever it wants.
What RFC 4301 is asking for is for the mature SAs to have their
selectors either populated from the policy or the packet.
So for PFP the KM should fill out its SA selector according to its
PFP flags. In other words we don't need PFP flags in the kernel
at all.
> + if (pol->flags & XFRM_POLICY_PFP_SPORT) {
> + x->sel.sport = xfrm_flowi_sport(fl);
> + x->sel.sport_mask = htons(0xffff);
> + } else {
> + x->sel.sport = pol->selector.sport;
> + x->sel.sport = pol->selector.sport_mask;
There's a typo here.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-12-12 13:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-12 3:23 [PATCH] [IPSEC]: Add populate from packet (PFP) support Tyler Hicks
2007-12-12 13:52 ` Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).