Skip to content

Commit 42a7b32

Browse files
David Ahernklassert
authored andcommitted
xfrm: Add oif to dst lookups
Rules can be installed that direct route lookups to specific tables based on oif. Plumb the oif through the xfrm lookups so it gets set in the flow struct and passed to the resolver routines. Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
1 parent df36756 commit 42a7b32

File tree

4 files changed

+29
-20
lines changed

4 files changed

+29
-20
lines changed

include/net/xfrm.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,13 @@ struct xfrm_policy_afinfo {
285285
unsigned short family;
286286
struct dst_ops *dst_ops;
287287
void (*garbage_collect)(struct net *net);
288-
struct dst_entry *(*dst_lookup)(struct net *net, int tos,
288+
struct dst_entry *(*dst_lookup)(struct net *net,
289+
int tos, int oif,
289290
const xfrm_address_t *saddr,
290291
const xfrm_address_t *daddr);
291-
int (*get_saddr)(struct net *net, xfrm_address_t *saddr, xfrm_address_t *daddr);
292+
int (*get_saddr)(struct net *net, int oif,
293+
xfrm_address_t *saddr,
294+
xfrm_address_t *daddr);
292295
void (*decode_session)(struct sk_buff *skb,
293296
struct flowi *fl,
294297
int reverse);

net/ipv4/xfrm4_policy.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
2020

2121
static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
22-
int tos,
22+
int tos, int oif,
2323
const xfrm_address_t *saddr,
2424
const xfrm_address_t *daddr)
2525
{
@@ -28,6 +28,7 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
2828
memset(fl4, 0, sizeof(*fl4));
2929
fl4->daddr = daddr->a4;
3030
fl4->flowi4_tos = tos;
31+
fl4->flowi4_oif = oif;
3132
if (saddr)
3233
fl4->saddr = saddr->a4;
3334

@@ -38,22 +39,22 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
3839
return ERR_CAST(rt);
3940
}
4041

41-
static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos,
42+
static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif,
4243
const xfrm_address_t *saddr,
4344
const xfrm_address_t *daddr)
4445
{
4546
struct flowi4 fl4;
4647

47-
return __xfrm4_dst_lookup(net, &fl4, tos, saddr, daddr);
48+
return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr);
4849
}
4950

50-
static int xfrm4_get_saddr(struct net *net,
51+
static int xfrm4_get_saddr(struct net *net, int oif,
5152
xfrm_address_t *saddr, xfrm_address_t *daddr)
5253
{
5354
struct dst_entry *dst;
5455
struct flowi4 fl4;
5556

56-
dst = __xfrm4_dst_lookup(net, &fl4, 0, NULL, daddr);
57+
dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr);
5758
if (IS_ERR(dst))
5859
return -EHOSTUNREACH;
5960

net/ipv6/xfrm6_policy.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
2828

29-
static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
29+
static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos, int oif,
3030
const xfrm_address_t *saddr,
3131
const xfrm_address_t *daddr)
3232
{
@@ -35,6 +35,7 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
3535
int err;
3636

3737
memset(&fl6, 0, sizeof(fl6));
38+
fl6.flowi6_oif = oif;
3839
memcpy(&fl6.daddr, daddr, sizeof(fl6.daddr));
3940
if (saddr)
4041
memcpy(&fl6.saddr, saddr, sizeof(fl6.saddr));
@@ -50,13 +51,13 @@ static struct dst_entry *xfrm6_dst_lookup(struct net *net, int tos,
5051
return dst;
5152
}
5253

53-
static int xfrm6_get_saddr(struct net *net,
54+
static int xfrm6_get_saddr(struct net *net, int oif,
5455
xfrm_address_t *saddr, xfrm_address_t *daddr)
5556
{
5657
struct dst_entry *dst;
5758
struct net_device *dev;
5859

59-
dst = xfrm6_dst_lookup(net, 0, NULL, daddr);
60+
dst = xfrm6_dst_lookup(net, 0, oif, NULL, daddr);
6061
if (IS_ERR(dst))
6162
return -EHOSTUNREACH;
6263

net/xfrm/xfrm_policy.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
115115
rcu_read_unlock();
116116
}
117117

118-
static inline struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos,
118+
static inline struct dst_entry *__xfrm_dst_lookup(struct net *net,
119+
int tos, int oif,
119120
const xfrm_address_t *saddr,
120121
const xfrm_address_t *daddr,
121122
int family)
@@ -127,14 +128,15 @@ static inline struct dst_entry *__xfrm_dst_lookup(struct net *net, int tos,
127128
if (unlikely(afinfo == NULL))
128129
return ERR_PTR(-EAFNOSUPPORT);
129130

130-
dst = afinfo->dst_lookup(net, tos, saddr, daddr);
131+
dst = afinfo->dst_lookup(net, tos, oif, saddr, daddr);
131132

132133
xfrm_policy_put_afinfo(afinfo);
133134

134135
return dst;
135136
}
136137

137-
static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
138+
static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x,
139+
int tos, int oif,
138140
xfrm_address_t *prev_saddr,
139141
xfrm_address_t *prev_daddr,
140142
int family)
@@ -153,7 +155,7 @@ static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
153155
daddr = x->coaddr;
154156
}
155157

156-
dst = __xfrm_dst_lookup(net, tos, saddr, daddr, family);
158+
dst = __xfrm_dst_lookup(net, tos, oif, saddr, daddr, family);
157159

158160
if (!IS_ERR(dst)) {
159161
if (prev_saddr != saddr)
@@ -1373,15 +1375,15 @@ int __xfrm_sk_clone_policy(struct sock *sk)
13731375
}
13741376

13751377
static int
1376-
xfrm_get_saddr(struct net *net, xfrm_address_t *local, xfrm_address_t *remote,
1377-
unsigned short family)
1378+
xfrm_get_saddr(struct net *net, int oif, xfrm_address_t *local,
1379+
xfrm_address_t *remote, unsigned short family)
13781380
{
13791381
int err;
13801382
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
13811383

13821384
if (unlikely(afinfo == NULL))
13831385
return -EINVAL;
1384-
err = afinfo->get_saddr(net, local, remote);
1386+
err = afinfo->get_saddr(net, oif, local, remote);
13851387
xfrm_policy_put_afinfo(afinfo);
13861388
return err;
13871389
}
@@ -1410,7 +1412,9 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
14101412
remote = &tmpl->id.daddr;
14111413
local = &tmpl->saddr;
14121414
if (xfrm_addr_any(local, tmpl->encap_family)) {
1413-
error = xfrm_get_saddr(net, &tmp, remote, tmpl->encap_family);
1415+
error = xfrm_get_saddr(net, fl->flowi_oif,
1416+
&tmp, remote,
1417+
tmpl->encap_family);
14141418
if (error)
14151419
goto fail;
14161420
local = &tmp;
@@ -1690,8 +1694,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
16901694

16911695
if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
16921696
family = xfrm[i]->props.family;
1693-
dst = xfrm_dst_lookup(xfrm[i], tos, &saddr, &daddr,
1694-
family);
1697+
dst = xfrm_dst_lookup(xfrm[i], tos, fl->flowi_oif,
1698+
&saddr, &daddr, family);
16951699
err = PTR_ERR(dst);
16961700
if (IS_ERR(dst))
16971701
goto put_states;

0 commit comments

Comments
 (0)