route: Extend flow representation with tunnel key
Add a new flowi_tunnel structure which is a subset of ip_tunnel_key to allow routes to match on tunnel metadata. For now, the tunnel id is added to flowi_tunnel which allows for routes to be bound to specific virtual tunnels. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ee122c79d4
commit
1b7179d3ad
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
#define LOOPBACK_IFINDEX 1
|
#define LOOPBACK_IFINDEX 1
|
||||||
|
|
||||||
|
struct flowi_tunnel {
|
||||||
|
__be64 tun_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct flowi_common {
|
struct flowi_common {
|
||||||
int flowic_oif;
|
int flowic_oif;
|
||||||
int flowic_iif;
|
int flowic_iif;
|
||||||
|
@ -30,6 +34,7 @@ struct flowi_common {
|
||||||
#define FLOWI_FLAG_ANYSRC 0x01
|
#define FLOWI_FLAG_ANYSRC 0x01
|
||||||
#define FLOWI_FLAG_KNOWN_NH 0x02
|
#define FLOWI_FLAG_KNOWN_NH 0x02
|
||||||
__u32 flowic_secid;
|
__u32 flowic_secid;
|
||||||
|
struct flowi_tunnel flowic_tun_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
union flowi_uli {
|
union flowi_uli {
|
||||||
|
@ -66,6 +71,7 @@ struct flowi4 {
|
||||||
#define flowi4_proto __fl_common.flowic_proto
|
#define flowi4_proto __fl_common.flowic_proto
|
||||||
#define flowi4_flags __fl_common.flowic_flags
|
#define flowi4_flags __fl_common.flowic_flags
|
||||||
#define flowi4_secid __fl_common.flowic_secid
|
#define flowi4_secid __fl_common.flowic_secid
|
||||||
|
#define flowi4_tun_key __fl_common.flowic_tun_key
|
||||||
|
|
||||||
/* (saddr,daddr) must be grouped, same order as in IP header */
|
/* (saddr,daddr) must be grouped, same order as in IP header */
|
||||||
__be32 saddr;
|
__be32 saddr;
|
||||||
|
@ -95,6 +101,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
|
||||||
fl4->flowi4_proto = proto;
|
fl4->flowi4_proto = proto;
|
||||||
fl4->flowi4_flags = flags;
|
fl4->flowi4_flags = flags;
|
||||||
fl4->flowi4_secid = 0;
|
fl4->flowi4_secid = 0;
|
||||||
|
fl4->flowi4_tun_key.tun_id = 0;
|
||||||
fl4->daddr = daddr;
|
fl4->daddr = daddr;
|
||||||
fl4->saddr = saddr;
|
fl4->saddr = saddr;
|
||||||
fl4->fl4_dport = dport;
|
fl4->fl4_dport = dport;
|
||||||
|
@ -165,6 +172,7 @@ struct flowi {
|
||||||
#define flowi_proto u.__fl_common.flowic_proto
|
#define flowi_proto u.__fl_common.flowic_proto
|
||||||
#define flowi_flags u.__fl_common.flowic_flags
|
#define flowi_flags u.__fl_common.flowic_flags
|
||||||
#define flowi_secid u.__fl_common.flowic_secid
|
#define flowi_secid u.__fl_common.flowic_secid
|
||||||
|
#define flowi_tun_key u.__fl_common.flowic_tun_key
|
||||||
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
||||||
|
|
||||||
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
|
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
|
||||||
|
|
|
@ -280,6 +280,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
|
||||||
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
|
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
|
||||||
fl4.flowi4_scope = scope;
|
fl4.flowi4_scope = scope;
|
||||||
fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
|
fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
|
||||||
|
fl4.flowi4_tun_key.tun_id = 0;
|
||||||
if (!fib_lookup(net, &fl4, &res, 0))
|
if (!fib_lookup(net, &fl4, &res, 0))
|
||||||
return FIB_RES_PREFSRC(net, res);
|
return FIB_RES_PREFSRC(net, res);
|
||||||
} else {
|
} else {
|
||||||
|
@ -313,6 +314,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
|
||||||
fl4.saddr = dst;
|
fl4.saddr = dst;
|
||||||
fl4.flowi4_tos = tos;
|
fl4.flowi4_tos = tos;
|
||||||
fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
|
fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
|
||||||
|
fl4.flowi4_tun_key.tun_id = 0;
|
||||||
|
|
||||||
no_addr = idev->ifa_list == NULL;
|
no_addr = idev->ifa_list == NULL;
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/jhash.h>
|
#include <linux/jhash.h>
|
||||||
#include <net/dst.h>
|
#include <net/dst.h>
|
||||||
|
#include <net/dst_metadata.h>
|
||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <net/protocol.h>
|
#include <net/protocol.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
#include <linux/kmemleak.h>
|
#include <linux/kmemleak.h>
|
||||||
#endif
|
#endif
|
||||||
#include <net/secure_seq.h>
|
#include <net/secure_seq.h>
|
||||||
|
#include <net/ip_tunnels.h>
|
||||||
|
|
||||||
#define RT_FL_TOS(oldflp4) \
|
#define RT_FL_TOS(oldflp4) \
|
||||||
((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
|
((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
|
||||||
|
@ -1673,6 +1675,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
||||||
{
|
{
|
||||||
struct fib_result res;
|
struct fib_result res;
|
||||||
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
struct in_device *in_dev = __in_dev_get_rcu(dev);
|
||||||
|
struct ip_tunnel_info *tun_info;
|
||||||
struct flowi4 fl4;
|
struct flowi4 fl4;
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
u32 itag = 0;
|
u32 itag = 0;
|
||||||
|
@ -1690,6 +1693,11 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
||||||
by fib_lookup.
|
by fib_lookup.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
tun_info = skb_tunnel_info(skb);
|
||||||
|
if (tun_info && tun_info->mode == IP_TUNNEL_INFO_RX)
|
||||||
|
fl4.flowi4_tun_key.tun_id = tun_info->key.tun_id;
|
||||||
|
else
|
||||||
|
fl4.flowi4_tun_key.tun_id = 0;
|
||||||
skb_dst_drop(skb);
|
skb_dst_drop(skb);
|
||||||
|
|
||||||
if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr))
|
if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr))
|
||||||
|
|
Loading…
Reference in New Issue