From: Xin Long <lucien.xin@gmail.com>
To: network dev <netdev@vger.kernel.org>
Cc: davem@davemloft.net, Jiri Benc <jbenc@redhat.com>,
Thomas Graf <tgraf@suug.ch>,
u9012063@gmail.com
Subject: [PATCHv2 net-next 6/6] erspan: make md work without TUNNEL_ERSPAN_OPT set
Date: Tue, 8 Oct 2019 23:16:16 +0800 [thread overview]
Message-ID: <84a19a454d49bdc89692f9af4e89b73636f99edd.1570547676.git.lucien.xin@gmail.com> (raw)
In-Reply-To: <ad3f4008718a8c90e6c779d30723936934dd85c1.1570547676.git.lucien.xin@gmail.com>
In-Reply-To: <cover.1570547676.git.lucien.xin@gmail.com>
Now when a skb comes with ip_tun_info but with no TUNNEL_ERSPAN_OPT to
a md erspan device, it will be dropped.
This patch is to allow this skb to go through this erspan device, and
the options (version, index, hwid, dir, etc.) will be filled with
tunnel's params, which can be configured by users.
This can be verified by:
# ip net a a; ip net a b
# ip -n a l a eth0 type veth peer name eth0 netns b
# ip -n a l s eth0 up; ip -n b link set eth0 up
# ip -n a a a 10.1.0.1/24 dev eth0; ip -n b a a 10.1.0.2/24 dev eth0
# ip -n b l a erspan1 type erspan key 1 seq local 10.1.0.2 remote 10.1.0.1
# ip -n b a a 1.1.1.1/24 dev erspan1; ip -n b l s erspan1 up
# ip -n b r a 2.1.1.0/24 dev erspan1
# ip -n a l a erspan1 type erspan key 1 seq local 10.1.0.1 external
# ip -n a a a 2.1.1.1/24 dev erspan1; ip -n a l s erspan1 up
# ip -n a r a 1.1.1.0/24 encap ip id 1 dst 10.1.0.2 dev erspan1
# ip net exec a ping 1.1.1.1 -c 1
Reported-by: Jianlin Shi <jishi@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv4/ip_gre.c | 31 +++++++++++++------------------
net/ipv6/ip6_gre.c | 35 +++++++++++++++++++----------------
2 files changed, 32 insertions(+), 34 deletions(-)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b5e1f5e..84a445d 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -491,15 +491,12 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev,
static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
+ struct erspan_metadata *md = NULL;
struct ip_tunnel_info *tun_info;
const struct ip_tunnel_key *key;
- struct erspan_metadata *md;
+ int version, nhoff, thoff;
bool truncate = false;
__be16 proto;
- int tunnel_hlen;
- int version;
- int nhoff;
- int thoff;
tun_info = skb_tunnel_info(skb);
if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
@@ -507,15 +504,11 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
goto err_free_skb;
key = &tun_info->key;
- if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
- goto err_free_skb;
- if (sizeof(*md) > tun_info->options_len)
- goto err_free_skb;
- md = ip_tunnel_info_opts(tun_info);
-
- /* ERSPAN has fixed 8 byte GRE header */
- version = md->version;
- tunnel_hlen = 8 + erspan_hdr_len(version);
+ if (key->tun_flags & TUNNEL_ERSPAN_OPT) {
+ if (tun_info->options_len < sizeof(*md))
+ goto err_free_skb;
+ md = ip_tunnel_info_opts(tun_info);
+ }
if (skb_cow_head(skb, dev->needed_headroom))
goto err_free_skb;
@@ -538,15 +531,17 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
(ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff))
truncate = true;
+ version = md ? md->version : tunnel->erspan_ver;
if (version == 1) {
erspan_build_header(skb, ntohl(tunnel_id_to_key32(key->tun_id)),
- ntohl(md->u.index), truncate, true);
+ md ? ntohl(md->u.index) : tunnel->index,
+ truncate, true);
proto = htons(ETH_P_ERSPAN);
} else if (version == 2) {
erspan_build_header_v2(skb,
ntohl(tunnel_id_to_key32(key->tun_id)),
- md->u.md2.dir,
- get_hwid(&md->u.md2),
+ md ? md->u.md2.dir : tunnel->dir,
+ md ? get_hwid(&md->u.md2) : tunnel->hwid,
truncate, true);
proto = htons(ETH_P_ERSPAN2);
} else {
@@ -556,7 +551,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev)
gre_build_header(skb, 8, TUNNEL_SEQ,
proto, 0, htonl(tunnel->o_seqno++));
- ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, tunnel_hlen);
+ ip_md_tunnel_xmit(skb, dev, IPPROTO_GRE, 8 + erspan_hdr_len(version));
return;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 116987d..3b7d213 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -959,10 +959,11 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
* for native mode, call prepare_ip6gre_xmit_{ipv4,ipv6}.
*/
if (t->parms.collect_md) {
+ struct erspan_metadata *md = NULL;
struct ip_tunnel_info *tun_info;
const struct ip_tunnel_key *key;
- struct erspan_metadata *md;
__be32 tun_id;
+ int version;
tun_info = skb_tunnel_info(skb);
if (unlikely(!tun_info ||
@@ -978,23 +979,25 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
dsfield = key->tos;
- if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
- goto tx_err;
- if (sizeof(*md) > tun_info->options_len)
- goto tx_err;
- md = ip_tunnel_info_opts(tun_info);
+ if (key->tun_flags & TUNNEL_ERSPAN_OPT) {
+ if (tun_info->options_len < sizeof(*md))
+ goto tx_err;
+ md = ip_tunnel_info_opts(tun_info);
+ }
tun_id = tunnel_id_to_key32(key->tun_id);
- if (md->version == 1) {
- erspan_build_header(skb,
- ntohl(tun_id),
- ntohl(md->u.index), truncate,
- false);
- } else if (md->version == 2) {
- erspan_build_header_v2(skb,
- ntohl(tun_id),
- md->u.md2.dir,
- get_hwid(&md->u.md2),
+ version = md ? md->version : t->parms.erspan_ver;
+ if (version == 1) {
+ erspan_build_header(skb, ntohl(tun_id),
+ md ? ntohl(md->u.index)
+ : t->parms.index,
+ truncate, false);
+ } else if (version == 2) {
+ erspan_build_header_v2(skb, ntohl(tun_id),
+ md ? md->u.md2.dir
+ : t->parms.dir,
+ md ? get_hwid(&md->u.md2)
+ : t->parms.hwid,
truncate, false);
} else {
goto tx_err;
--
2.1.0
next prev parent reply other threads:[~2019-10-08 15:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-08 15:16 [PATCHv2 net-next 0/6] net: add support for ip_tun_info options setting Xin Long
2019-10-08 15:16 ` [PATCHv2 net-next 1/6] lwtunnel: add options process for arp request Xin Long
2019-10-08 15:16 ` [PATCHv2 net-next 2/6] lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip Xin Long
2019-10-08 15:16 ` [PATCHv2 net-next 3/6] lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6 Xin Long
2019-10-08 15:16 ` [PATCHv2 net-next 4/6] vxlan: check tun_info options_len properly Xin Long
2019-10-08 15:16 ` [PATCHv2 net-next 5/6] erspan: fix the tun_info options_len check Xin Long
2019-10-08 15:16 ` Xin Long [this message]
2019-10-09 7:55 ` [PATCHv2 net-next 2/6] lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip Simon Horman
2019-10-09 9:15 ` Jiri Benc
2019-10-10 9:45 ` Xin Long
2019-10-11 5:31 ` Simon Horman
2019-10-14 11:26 ` Xin Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=84a19a454d49bdc89692f9af4e89b73636f99edd.1570547676.git.lucien.xin@gmail.com \
--to=lucien.xin@gmail.com \
--cc=davem@davemloft.net \
--cc=jbenc@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=tgraf@suug.ch \
--cc=u9012063@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).