forked from Minki/linux
3e12939a2a
No longer needed. TCP writes metrics, but now in it's own special cache that does not dirty the route metrics. Therefore there is no longer any reason to pre-cow metrics in this way. Signed-off-by: David S. Miller <davem@davemloft.net>
227 lines
5.7 KiB
C
227 lines
5.7 KiB
C
/*
|
|
*
|
|
* Generic internet FLOW.
|
|
*
|
|
*/
|
|
|
|
#ifndef _NET_FLOW_H
|
|
#define _NET_FLOW_H
|
|
|
|
#include <linux/socket.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/atomic.h>
|
|
|
|
struct flowi_common {
|
|
int flowic_oif;
|
|
int flowic_iif;
|
|
__u32 flowic_mark;
|
|
__u8 flowic_tos;
|
|
__u8 flowic_scope;
|
|
__u8 flowic_proto;
|
|
__u8 flowic_flags;
|
|
#define FLOWI_FLAG_ANYSRC 0x01
|
|
#define FLOWI_FLAG_CAN_SLEEP 0x02
|
|
#define FLOWI_FLAG_RT_NOCACHE 0x04
|
|
__u32 flowic_secid;
|
|
};
|
|
|
|
union flowi_uli {
|
|
struct {
|
|
__be16 dport;
|
|
__be16 sport;
|
|
} ports;
|
|
|
|
struct {
|
|
__u8 type;
|
|
__u8 code;
|
|
} icmpt;
|
|
|
|
struct {
|
|
__le16 dport;
|
|
__le16 sport;
|
|
} dnports;
|
|
|
|
__be32 spi;
|
|
__be32 gre_key;
|
|
|
|
struct {
|
|
__u8 type;
|
|
} mht;
|
|
};
|
|
|
|
struct flowi4 {
|
|
struct flowi_common __fl_common;
|
|
#define flowi4_oif __fl_common.flowic_oif
|
|
#define flowi4_iif __fl_common.flowic_iif
|
|
#define flowi4_mark __fl_common.flowic_mark
|
|
#define flowi4_tos __fl_common.flowic_tos
|
|
#define flowi4_scope __fl_common.flowic_scope
|
|
#define flowi4_proto __fl_common.flowic_proto
|
|
#define flowi4_flags __fl_common.flowic_flags
|
|
#define flowi4_secid __fl_common.flowic_secid
|
|
|
|
/* (saddr,daddr) must be grouped, same order as in IP header */
|
|
__be32 saddr;
|
|
__be32 daddr;
|
|
|
|
union flowi_uli uli;
|
|
#define fl4_sport uli.ports.sport
|
|
#define fl4_dport uli.ports.dport
|
|
#define fl4_icmp_type uli.icmpt.type
|
|
#define fl4_icmp_code uli.icmpt.code
|
|
#define fl4_ipsec_spi uli.spi
|
|
#define fl4_mh_type uli.mht.type
|
|
#define fl4_gre_key uli.gre_key
|
|
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
|
|
|
static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
|
|
__u32 mark, __u8 tos, __u8 scope,
|
|
__u8 proto, __u8 flags,
|
|
__be32 daddr, __be32 saddr,
|
|
__be16 dport, __be16 sport)
|
|
{
|
|
fl4->flowi4_oif = oif;
|
|
fl4->flowi4_iif = 0;
|
|
fl4->flowi4_mark = mark;
|
|
fl4->flowi4_tos = tos;
|
|
fl4->flowi4_scope = scope;
|
|
fl4->flowi4_proto = proto;
|
|
fl4->flowi4_flags = flags;
|
|
fl4->flowi4_secid = 0;
|
|
fl4->daddr = daddr;
|
|
fl4->saddr = saddr;
|
|
fl4->fl4_dport = dport;
|
|
fl4->fl4_sport = sport;
|
|
}
|
|
|
|
/* Reset some input parameters after previous lookup */
|
|
static inline void flowi4_update_output(struct flowi4 *fl4, int oif, __u8 tos,
|
|
__be32 daddr, __be32 saddr)
|
|
{
|
|
fl4->flowi4_oif = oif;
|
|
fl4->flowi4_tos = tos;
|
|
fl4->daddr = daddr;
|
|
fl4->saddr = saddr;
|
|
}
|
|
|
|
|
|
struct flowi6 {
|
|
struct flowi_common __fl_common;
|
|
#define flowi6_oif __fl_common.flowic_oif
|
|
#define flowi6_iif __fl_common.flowic_iif
|
|
#define flowi6_mark __fl_common.flowic_mark
|
|
#define flowi6_tos __fl_common.flowic_tos
|
|
#define flowi6_scope __fl_common.flowic_scope
|
|
#define flowi6_proto __fl_common.flowic_proto
|
|
#define flowi6_flags __fl_common.flowic_flags
|
|
#define flowi6_secid __fl_common.flowic_secid
|
|
struct in6_addr daddr;
|
|
struct in6_addr saddr;
|
|
__be32 flowlabel;
|
|
union flowi_uli uli;
|
|
#define fl6_sport uli.ports.sport
|
|
#define fl6_dport uli.ports.dport
|
|
#define fl6_icmp_type uli.icmpt.type
|
|
#define fl6_icmp_code uli.icmpt.code
|
|
#define fl6_ipsec_spi uli.spi
|
|
#define fl6_mh_type uli.mht.type
|
|
#define fl6_gre_key uli.gre_key
|
|
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
|
|
|
struct flowidn {
|
|
struct flowi_common __fl_common;
|
|
#define flowidn_oif __fl_common.flowic_oif
|
|
#define flowidn_iif __fl_common.flowic_iif
|
|
#define flowidn_mark __fl_common.flowic_mark
|
|
#define flowidn_scope __fl_common.flowic_scope
|
|
#define flowidn_proto __fl_common.flowic_proto
|
|
#define flowidn_flags __fl_common.flowic_flags
|
|
__le16 daddr;
|
|
__le16 saddr;
|
|
union flowi_uli uli;
|
|
#define fld_sport uli.ports.sport
|
|
#define fld_dport uli.ports.dport
|
|
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
|
|
|
struct flowi {
|
|
union {
|
|
struct flowi_common __fl_common;
|
|
struct flowi4 ip4;
|
|
struct flowi6 ip6;
|
|
struct flowidn dn;
|
|
} u;
|
|
#define flowi_oif u.__fl_common.flowic_oif
|
|
#define flowi_iif u.__fl_common.flowic_iif
|
|
#define flowi_mark u.__fl_common.flowic_mark
|
|
#define flowi_tos u.__fl_common.flowic_tos
|
|
#define flowi_scope u.__fl_common.flowic_scope
|
|
#define flowi_proto u.__fl_common.flowic_proto
|
|
#define flowi_flags u.__fl_common.flowic_flags
|
|
#define flowi_secid u.__fl_common.flowic_secid
|
|
} __attribute__((__aligned__(BITS_PER_LONG/8)));
|
|
|
|
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
|
|
{
|
|
return container_of(fl4, struct flowi, u.ip4);
|
|
}
|
|
|
|
static inline struct flowi *flowi6_to_flowi(struct flowi6 *fl6)
|
|
{
|
|
return container_of(fl6, struct flowi, u.ip6);
|
|
}
|
|
|
|
static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn)
|
|
{
|
|
return container_of(fldn, struct flowi, u.dn);
|
|
}
|
|
|
|
typedef unsigned long flow_compare_t;
|
|
|
|
static inline size_t flow_key_size(u16 family)
|
|
{
|
|
switch (family) {
|
|
case AF_INET:
|
|
BUILD_BUG_ON(sizeof(struct flowi4) % sizeof(flow_compare_t));
|
|
return sizeof(struct flowi4) / sizeof(flow_compare_t);
|
|
case AF_INET6:
|
|
BUILD_BUG_ON(sizeof(struct flowi6) % sizeof(flow_compare_t));
|
|
return sizeof(struct flowi6) / sizeof(flow_compare_t);
|
|
case AF_DECnet:
|
|
BUILD_BUG_ON(sizeof(struct flowidn) % sizeof(flow_compare_t));
|
|
return sizeof(struct flowidn) / sizeof(flow_compare_t);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#define FLOW_DIR_IN 0
|
|
#define FLOW_DIR_OUT 1
|
|
#define FLOW_DIR_FWD 2
|
|
|
|
struct net;
|
|
struct sock;
|
|
struct flow_cache_ops;
|
|
|
|
struct flow_cache_object {
|
|
const struct flow_cache_ops *ops;
|
|
};
|
|
|
|
struct flow_cache_ops {
|
|
struct flow_cache_object *(*get)(struct flow_cache_object *);
|
|
int (*check)(struct flow_cache_object *);
|
|
void (*delete)(struct flow_cache_object *);
|
|
};
|
|
|
|
typedef struct flow_cache_object *(*flow_resolve_t)(
|
|
struct net *net, const struct flowi *key, u16 family,
|
|
u8 dir, struct flow_cache_object *oldobj, void *ctx);
|
|
|
|
extern struct flow_cache_object *flow_cache_lookup(
|
|
struct net *net, const struct flowi *key, u16 family,
|
|
u8 dir, flow_resolve_t resolver, void *ctx);
|
|
|
|
extern void flow_cache_flush(void);
|
|
extern void flow_cache_flush_deferred(void);
|
|
extern atomic_t flow_cache_genid;
|
|
|
|
#endif
|