aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/include/net/dst_metadata.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/dst_metadata.h')
-rw-r--r--include/net/dst_metadata.h41
1 files changed, 32 insertions, 9 deletions
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index 701fc814d0af..a803129a4849 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -5,10 +5,22 @@
#include <net/ip_tunnels.h>
#include <net/dst.h>
+enum metadata_type {
+ METADATA_IP_TUNNEL,
+ METADATA_HW_PORT_MUX,
+};
+
+struct hw_port_info {
+ struct net_device *lower_dev;
+ u32 port_id;
+};
+
struct metadata_dst {
struct dst_entry dst;
+ enum metadata_type type;
union {
struct ip_tunnel_info tun_info;
+ struct hw_port_info port_info;
} u;
};
@@ -27,7 +39,7 @@ static inline struct ip_tunnel_info *skb_tunnel_info(struct sk_buff *skb)
struct metadata_dst *md_dst = skb_metadata_dst(skb);
struct dst_entry *dst;
- if (md_dst)
+ if (md_dst && md_dst->type == METADATA_IP_TUNNEL)
return &md_dst->u.tun_info;
dst = skb_dst(skb);
@@ -55,22 +67,33 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
a = (const struct metadata_dst *) skb_dst(skb_a);
b = (const struct metadata_dst *) skb_dst(skb_b);
- if (!a != !b || a->u.tun_info.options_len != b->u.tun_info.options_len)
+ if (!a != !b || a->type != b->type)
return 1;
- return memcmp(&a->u.tun_info, &b->u.tun_info,
- sizeof(a->u.tun_info) + a->u.tun_info.options_len);
+ switch (a->type) {
+ case METADATA_HW_PORT_MUX:
+ return memcmp(&a->u.port_info, &b->u.port_info,
+ sizeof(a->u.port_info));
+ case METADATA_IP_TUNNEL:
+ return memcmp(&a->u.tun_info, &b->u.tun_info,
+ sizeof(a->u.tun_info) +
+ a->u.tun_info.options_len);
+ default:
+ return 1;
+ }
}
void metadata_dst_free(struct metadata_dst *);
-struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags);
-struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags);
+struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type,
+ gfp_t flags);
+struct metadata_dst __percpu *
+metadata_dst_alloc_percpu(u8 optslen, enum metadata_type type, gfp_t flags);
static inline struct metadata_dst *tun_rx_dst(int md_size)
{
struct metadata_dst *tun_dst;
- tun_dst = metadata_dst_alloc(md_size, GFP_ATOMIC);
+ tun_dst = metadata_dst_alloc(md_size, METADATA_IP_TUNNEL, GFP_ATOMIC);
if (!tun_dst)
return NULL;
@@ -85,11 +108,11 @@ static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
int md_size;
struct metadata_dst *new_md;
- if (!md_dst)
+ if (!md_dst || md_dst->type != METADATA_IP_TUNNEL)
return ERR_PTR(-EINVAL);
md_size = md_dst->u.tun_info.options_len;
- new_md = metadata_dst_alloc(md_size, GFP_ATOMIC);
+ new_md = metadata_dst_alloc(md_size, METADATA_IP_TUNNEL, GFP_ATOMIC);
if (!new_md)
return ERR_PTR(-ENOMEM);