mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-18 18:43:59 +08:00
fib: Add fib rule match on tunnel id
This add the ability to select a routing table based on the tunnel id which allows to maintain separate routing tables for each virtual tunnel network. ip rule add from all tunnel-id 100 lookup 100 ip rule add from all tunnel-id 200 lookup 200 A new static key controls the collection of metadata at tunnel level upon demand. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3093fbe7ff
commit
e7030878fc
@ -143,7 +143,8 @@ static struct workqueue_struct *vxlan_wq;
|
|||||||
|
|
||||||
static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
|
static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
|
||||||
{
|
{
|
||||||
return vs->flags & VXLAN_F_COLLECT_METADATA;
|
return vs->flags & VXLAN_F_COLLECT_METADATA ||
|
||||||
|
ip_tunnel_collect_metadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_IPV6)
|
#if IS_ENABLED(CONFIG_IPV6)
|
||||||
|
@ -19,6 +19,7 @@ struct fib_rule {
|
|||||||
u8 action;
|
u8 action;
|
||||||
/* 3 bytes hole, try to use */
|
/* 3 bytes hole, try to use */
|
||||||
u32 target;
|
u32 target;
|
||||||
|
__be64 tun_id;
|
||||||
struct fib_rule __rcu *ctarget;
|
struct fib_rule __rcu *ctarget;
|
||||||
struct net *fr_net;
|
struct net *fr_net;
|
||||||
|
|
||||||
|
@ -303,6 +303,17 @@ static inline struct ip_tunnel_info *lwt_tun_info(struct lwtunnel_state *lwtstat
|
|||||||
return (struct ip_tunnel_info *)lwtstate->data;
|
return (struct ip_tunnel_info *)lwtstate->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct static_key ip_tunnel_metadata_cnt;
|
||||||
|
|
||||||
|
/* Returns > 0 if metadata should be collected */
|
||||||
|
static inline int ip_tunnel_collect_metadata(void)
|
||||||
|
{
|
||||||
|
return static_key_false(&ip_tunnel_metadata_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_tunnel_need_metadata(void);
|
||||||
|
void ip_tunnel_unneed_metadata(void);
|
||||||
|
|
||||||
#endif /* CONFIG_INET */
|
#endif /* CONFIG_INET */
|
||||||
|
|
||||||
#endif /* __NET_IP_TUNNELS_H */
|
#endif /* __NET_IP_TUNNELS_H */
|
||||||
|
@ -43,7 +43,7 @@ enum {
|
|||||||
FRA_UNUSED5,
|
FRA_UNUSED5,
|
||||||
FRA_FWMARK, /* mark */
|
FRA_FWMARK, /* mark */
|
||||||
FRA_FLOW, /* flow/class id */
|
FRA_FLOW, /* flow/class id */
|
||||||
FRA_UNUSED6,
|
FRA_TUN_ID,
|
||||||
FRA_SUPPRESS_IFGROUP,
|
FRA_SUPPRESS_IFGROUP,
|
||||||
FRA_SUPPRESS_PREFIXLEN,
|
FRA_SUPPRESS_PREFIXLEN,
|
||||||
FRA_TABLE, /* Extended table id */
|
FRA_TABLE, /* Extended table id */
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <net/net_namespace.h>
|
#include <net/net_namespace.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
#include <net/fib_rules.h>
|
#include <net/fib_rules.h>
|
||||||
|
#include <net/ip_tunnels.h>
|
||||||
|
|
||||||
int fib_default_rule_add(struct fib_rules_ops *ops,
|
int fib_default_rule_add(struct fib_rules_ops *ops,
|
||||||
u32 pref, u32 table, u32 flags)
|
u32 pref, u32 table, u32 flags)
|
||||||
@ -186,6 +187,9 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
|
|||||||
if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
|
if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (rule->tun_id && (rule->tun_id != fl->flowi_tun_key.tun_id))
|
||||||
|
goto out;
|
||||||
|
|
||||||
ret = ops->match(rule, fl, flags);
|
ret = ops->match(rule, fl, flags);
|
||||||
out:
|
out:
|
||||||
return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
|
return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
|
||||||
@ -330,6 +334,9 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh)
|
|||||||
if (tb[FRA_FWMASK])
|
if (tb[FRA_FWMASK])
|
||||||
rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
|
rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
|
||||||
|
|
||||||
|
if (tb[FRA_TUN_ID])
|
||||||
|
rule->tun_id = nla_get_be64(tb[FRA_TUN_ID]);
|
||||||
|
|
||||||
rule->action = frh->action;
|
rule->action = frh->action;
|
||||||
rule->flags = frh->flags;
|
rule->flags = frh->flags;
|
||||||
rule->table = frh_get_table(frh, tb);
|
rule->table = frh_get_table(frh, tb);
|
||||||
@ -407,6 +414,9 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh)
|
|||||||
if (unresolved)
|
if (unresolved)
|
||||||
ops->unresolved_rules++;
|
ops->unresolved_rules++;
|
||||||
|
|
||||||
|
if (rule->tun_id)
|
||||||
|
ip_tunnel_need_metadata();
|
||||||
|
|
||||||
notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid);
|
notify_rule_change(RTM_NEWRULE, rule, ops, nlh, NETLINK_CB(skb).portid);
|
||||||
flush_route_cache(ops);
|
flush_route_cache(ops);
|
||||||
rules_ops_put(ops);
|
rules_ops_put(ops);
|
||||||
@ -473,6 +483,10 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
|
|||||||
(rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
|
(rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (tb[FRA_TUN_ID] &&
|
||||||
|
(rule->tun_id != nla_get_be64(tb[FRA_TUN_ID])))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!ops->compare(rule, frh, tb))
|
if (!ops->compare(rule, frh, tb))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -487,6 +501,9 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rule->tun_id)
|
||||||
|
ip_tunnel_unneed_metadata();
|
||||||
|
|
||||||
list_del_rcu(&rule->list);
|
list_del_rcu(&rule->list);
|
||||||
|
|
||||||
if (rule->action == FR_ACT_GOTO) {
|
if (rule->action == FR_ACT_GOTO) {
|
||||||
@ -535,7 +552,8 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
|
|||||||
+ nla_total_size(4) /* FRA_SUPPRESS_PREFIXLEN */
|
+ nla_total_size(4) /* FRA_SUPPRESS_PREFIXLEN */
|
||||||
+ nla_total_size(4) /* FRA_SUPPRESS_IFGROUP */
|
+ nla_total_size(4) /* FRA_SUPPRESS_IFGROUP */
|
||||||
+ nla_total_size(4) /* FRA_FWMARK */
|
+ nla_total_size(4) /* FRA_FWMARK */
|
||||||
+ nla_total_size(4); /* FRA_FWMASK */
|
+ nla_total_size(4) /* FRA_FWMASK */
|
||||||
|
+ nla_total_size(8); /* FRA_TUN_ID */
|
||||||
|
|
||||||
if (ops->nlmsg_payload)
|
if (ops->nlmsg_payload)
|
||||||
payload += ops->nlmsg_payload(rule);
|
payload += ops->nlmsg_payload(rule);
|
||||||
@ -591,7 +609,9 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
|
|||||||
((rule->mark_mask || rule->mark) &&
|
((rule->mark_mask || rule->mark) &&
|
||||||
nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) ||
|
nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) ||
|
||||||
(rule->target &&
|
(rule->target &&
|
||||||
nla_put_u32(skb, FRA_GOTO, rule->target)))
|
nla_put_u32(skb, FRA_GOTO, rule->target)) ||
|
||||||
|
(rule->tun_id &&
|
||||||
|
nla_put_be64(skb, FRA_TUN_ID, rule->tun_id)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
if (rule->suppress_ifgroup != -1) {
|
if (rule->suppress_ifgroup != -1) {
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
|
#include <linux/static_key.h>
|
||||||
|
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/icmp.h>
|
#include <net/icmp.h>
|
||||||
@ -304,3 +305,18 @@ static void __exit ip_tunnel_core_exit(void)
|
|||||||
lwtunnel_encap_del_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP);
|
lwtunnel_encap_del_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP);
|
||||||
}
|
}
|
||||||
module_exit(ip_tunnel_core_exit);
|
module_exit(ip_tunnel_core_exit);
|
||||||
|
|
||||||
|
struct static_key ip_tunnel_metadata_cnt = STATIC_KEY_INIT_FALSE;
|
||||||
|
EXPORT_SYMBOL(ip_tunnel_metadata_cnt);
|
||||||
|
|
||||||
|
void ip_tunnel_need_metadata(void)
|
||||||
|
{
|
||||||
|
static_key_slow_inc(&ip_tunnel_metadata_cnt);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ip_tunnel_need_metadata);
|
||||||
|
|
||||||
|
void ip_tunnel_unneed_metadata(void)
|
||||||
|
{
|
||||||
|
static_key_slow_dec(&ip_tunnel_metadata_cnt);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(ip_tunnel_unneed_metadata);
|
||||||
|
Loading…
Reference in New Issue
Block a user