xfrm: Add a new lookup key to match xfrm interfaces.
This patch adds the xfrm interface id as a lookup key for xfrm states and policies. With this we can assign states and policies to virtual xfrm interfaces. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Acked-by: Shannon Nelson <shannon.nelson@oracle.com> Acked-by: Benedict Wong <benedictwong@google.com> Tested-by: Benedict Wong <benedictwong@google.com> Tested-by: Antony Antony <antony@phenome.org> Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
This commit is contained in:
@@ -747,6 +747,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
||||
newpos = NULL;
|
||||
hlist_for_each_entry(pol, chain, bydst) {
|
||||
if (pol->type == policy->type &&
|
||||
pol->if_id == policy->if_id &&
|
||||
!selector_cmp(&pol->selector, &policy->selector) &&
|
||||
xfrm_policy_mark_match(policy, pol) &&
|
||||
xfrm_sec_ctx_match(pol->security, policy->security) &&
|
||||
@@ -798,8 +799,9 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_insert);
|
||||
|
||||
struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
|
||||
int dir, struct xfrm_selector *sel,
|
||||
struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u32 if_id,
|
||||
u8 type, int dir,
|
||||
struct xfrm_selector *sel,
|
||||
struct xfrm_sec_ctx *ctx, int delete,
|
||||
int *err)
|
||||
{
|
||||
@@ -812,6 +814,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
|
||||
ret = NULL;
|
||||
hlist_for_each_entry(pol, chain, bydst) {
|
||||
if (pol->type == type &&
|
||||
pol->if_id == if_id &&
|
||||
(mark & pol->mark.m) == pol->mark.v &&
|
||||
!selector_cmp(sel, &pol->selector) &&
|
||||
xfrm_sec_ctx_match(ctx, pol->security)) {
|
||||
@@ -837,8 +840,9 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type,
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
|
||||
|
||||
struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
|
||||
int dir, u32 id, int delete, int *err)
|
||||
struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u32 if_id,
|
||||
u8 type, int dir, u32 id, int delete,
|
||||
int *err)
|
||||
{
|
||||
struct xfrm_policy *pol, *ret;
|
||||
struct hlist_head *chain;
|
||||
@@ -853,6 +857,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type,
|
||||
ret = NULL;
|
||||
hlist_for_each_entry(pol, chain, byidx) {
|
||||
if (pol->type == type && pol->index == id &&
|
||||
pol->if_id == if_id &&
|
||||
(mark & pol->mark.m) == pol->mark.v) {
|
||||
xfrm_pol_hold(pol);
|
||||
if (delete) {
|
||||
@@ -1063,6 +1068,7 @@ static int xfrm_policy_match(const struct xfrm_policy *pol,
|
||||
bool match;
|
||||
|
||||
if (pol->family != family ||
|
||||
pol->if_id != fl->flowi_xfrm.if_id ||
|
||||
(fl->flowi_mark & pol->mark.m) != pol->mark.v ||
|
||||
pol->type != type)
|
||||
return ret;
|
||||
@@ -1177,7 +1183,8 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir,
|
||||
|
||||
match = xfrm_selector_match(&pol->selector, fl, family);
|
||||
if (match) {
|
||||
if ((sk->sk_mark & pol->mark.m) != pol->mark.v) {
|
||||
if ((sk->sk_mark & pol->mark.m) != pol->mark.v ||
|
||||
pol->if_id != fl->flowi_xfrm.if_id) {
|
||||
pol = NULL;
|
||||
goto out;
|
||||
}
|
||||
@@ -1305,6 +1312,7 @@ static struct xfrm_policy *clone_policy(const struct xfrm_policy *old, int dir)
|
||||
newp->lft = old->lft;
|
||||
newp->curlft = old->curlft;
|
||||
newp->mark = old->mark;
|
||||
newp->if_id = old->if_id;
|
||||
newp->action = old->action;
|
||||
newp->flags = old->flags;
|
||||
newp->xfrm_nr = old->xfrm_nr;
|
||||
|
Reference in New Issue
Block a user