gre: add sequence number for collect md mode.
Currently GRE sequence number can only be used in native tunnel mode. This patch adds sequence number support for gre collect metadata mode. RFC2890 defines GRE sequence number to be specific to the traffic flow identified by the key. However, this patch does not implement per-key seqno. The sequence number is shared in the same tunnel device. That is, different tunnel keys using the same collect_md tunnel share single sequence number. Signed-off-by: William Tu <u9012063@gmail.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
a56cd508e7
Коммит
77a5196a80
|
@ -800,6 +800,7 @@ enum bpf_func_id {
|
||||||
/* BPF_FUNC_skb_set_tunnel_key flags. */
|
/* BPF_FUNC_skb_set_tunnel_key flags. */
|
||||||
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
|
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
|
||||||
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
|
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
|
||||||
|
#define BPF_F_SEQ_NUMBER (1ULL << 3)
|
||||||
|
|
||||||
/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
|
/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
|
||||||
* BPF_FUNC_perf_event_read_value flags.
|
* BPF_FUNC_perf_event_read_value flags.
|
||||||
|
|
|
@ -2991,7 +2991,7 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
|
||||||
struct ip_tunnel_info *info;
|
struct ip_tunnel_info *info;
|
||||||
|
|
||||||
if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
|
if (unlikely(flags & ~(BPF_F_TUNINFO_IPV6 | BPF_F_ZERO_CSUM_TX |
|
||||||
BPF_F_DONT_FRAGMENT)))
|
BPF_F_DONT_FRAGMENT | BPF_F_SEQ_NUMBER)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
|
if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
|
@ -3025,6 +3025,8 @@ BPF_CALL_4(bpf_skb_set_tunnel_key, struct sk_buff *, skb,
|
||||||
info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
|
info->key.tun_flags |= TUNNEL_DONT_FRAGMENT;
|
||||||
if (flags & BPF_F_ZERO_CSUM_TX)
|
if (flags & BPF_F_ZERO_CSUM_TX)
|
||||||
info->key.tun_flags &= ~TUNNEL_CSUM;
|
info->key.tun_flags &= ~TUNNEL_CSUM;
|
||||||
|
if (flags & BPF_F_SEQ_NUMBER)
|
||||||
|
info->key.tun_flags |= TUNNEL_SEQ;
|
||||||
|
|
||||||
info->key.tun_id = cpu_to_be64(from->tunnel_id);
|
info->key.tun_id = cpu_to_be64(from->tunnel_id);
|
||||||
info->key.tos = from->tunnel_tos;
|
info->key.tos = from->tunnel_tos;
|
||||||
|
|
|
@ -522,6 +522,7 @@ err_free_skb:
|
||||||
static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
|
static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
__be16 proto)
|
__be16 proto)
|
||||||
{
|
{
|
||||||
|
struct ip_tunnel *tunnel = netdev_priv(dev);
|
||||||
struct ip_tunnel_info *tun_info;
|
struct ip_tunnel_info *tun_info;
|
||||||
const struct ip_tunnel_key *key;
|
const struct ip_tunnel_key *key;
|
||||||
struct rtable *rt = NULL;
|
struct rtable *rt = NULL;
|
||||||
|
@ -545,9 +546,11 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
|
if (gre_handle_offloads(skb, !!(tun_info->key.tun_flags & TUNNEL_CSUM)))
|
||||||
goto err_free_rt;
|
goto err_free_rt;
|
||||||
|
|
||||||
flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
|
flags = tun_info->key.tun_flags &
|
||||||
|
(TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
|
||||||
gre_build_header(skb, tunnel_hlen, flags, proto,
|
gre_build_header(skb, tunnel_hlen, flags, proto,
|
||||||
tunnel_id_to_key32(tun_info->key.tun_id), 0);
|
tunnel_id_to_key32(tun_info->key.tun_id),
|
||||||
|
(flags | TUNNEL_SEQ) ? htonl(tunnel->o_seqno++) : 0);
|
||||||
|
|
||||||
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
||||||
|
|
||||||
|
|
|
@ -695,9 +695,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
|
||||||
else
|
else
|
||||||
fl6->daddr = tunnel->parms.raddr;
|
fl6->daddr = tunnel->parms.raddr;
|
||||||
|
|
||||||
if (tunnel->parms.o_flags & TUNNEL_SEQ)
|
|
||||||
tunnel->o_seqno++;
|
|
||||||
|
|
||||||
/* Push GRE header. */
|
/* Push GRE header. */
|
||||||
protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
|
protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
|
||||||
|
|
||||||
|
@ -720,14 +717,20 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
|
||||||
fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
||||||
|
|
||||||
dsfield = key->tos;
|
dsfield = key->tos;
|
||||||
flags = key->tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
|
flags = key->tun_flags &
|
||||||
|
(TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
|
||||||
tunnel->tun_hlen = gre_calc_hlen(flags);
|
tunnel->tun_hlen = gre_calc_hlen(flags);
|
||||||
|
|
||||||
gre_build_header(skb, tunnel->tun_hlen,
|
gre_build_header(skb, tunnel->tun_hlen,
|
||||||
flags, protocol,
|
flags, protocol,
|
||||||
tunnel_id_to_key32(tun_info->key.tun_id), 0);
|
tunnel_id_to_key32(tun_info->key.tun_id),
|
||||||
|
(flags | TUNNEL_SEQ) ? htonl(tunnel->o_seqno++)
|
||||||
|
: 0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (tunnel->parms.o_flags & TUNNEL_SEQ)
|
||||||
|
tunnel->o_seqno++;
|
||||||
|
|
||||||
gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
|
gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
|
||||||
protocol, tunnel->parms.o_key,
|
protocol, tunnel->parms.o_key,
|
||||||
htonl(tunnel->o_seqno));
|
htonl(tunnel->o_seqno));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче