STT reassembly can generate list of packets. But it was
handled as a single skb. Following patch fixes it.
Fixes:
e23775f20 ("datapath: Add support for lwtunnel").
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jesse Gross <jesse@kernel.org>
Acked-by: Joe Stringer <joe@ovn.org>
+static void rcv_list(struct net_device *dev, struct sk_buff *skb,
+ struct metadata_dst *tun_dst)
+{
+ struct sk_buff *next;
+
+ do {
+ next = skb->next;
+ skb->next = NULL;
+ if (next) {
+ ovs_dst_hold((struct dst_entry *)tun_dst);
+ ovs_skb_dst_set(next, (struct dst_entry *)tun_dst);
+ }
+ ovs_ip_tunnel_rcv(dev, skb, tun_dst);
+ } while ((skb = next));
+}
+
#ifndef HAVE_METADATA_DST
#ifndef HAVE_METADATA_DST
-static int __rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
+static int __stt_rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
{
struct metadata_dst tun_dst;
{
struct metadata_dst tun_dst;
tun_dst.u.tun_info.key.tp_src = tcp_hdr(skb)->source;
tun_dst.u.tun_info.key.tp_dst = tcp_hdr(skb)->dest;
tun_dst.u.tun_info.key.tp_src = tcp_hdr(skb)->source;
tun_dst.u.tun_info.key.tp_dst = tcp_hdr(skb)->dest;
- ovs_ip_tunnel_rcv(stt_dev->dev, skb, &tun_dst);
+ rcv_list(stt_dev->dev, skb, &tun_dst);
-static int __rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
+static int __stt_rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
{
struct metadata_dst *tun_dst;
__be16 flags;
{
struct metadata_dst *tun_dst;
__be16 flags;
tun_dst->u.tun_info.key.tp_src = tcp_hdr(skb)->source;
tun_dst->u.tun_info.key.tp_dst = tcp_hdr(skb)->dest;
tun_dst->u.tun_info.key.tp_src = tcp_hdr(skb)->source;
tun_dst->u.tun_info.key.tp_dst = tcp_hdr(skb)->dest;
- ovs_ip_tunnel_rcv(stt_dev->dev, skb, tun_dst);
+ rcv_list(stt_dev->dev, skb, tun_dst);
static void stt_rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
{
int err;
static void stt_rcv(struct stt_dev *stt_dev, struct sk_buff *skb)
{
int err;
if (skb_shinfo(skb)->frag_list && try_to_segment(skb))
goto drop;
if (skb_shinfo(skb)->frag_list && try_to_segment(skb))
goto drop;
- err = __rcv(stt_dev, skb);
+ err = __stt_rcv(stt_dev, skb);
if (err)
goto drop;
return;
if (err)
goto drop;
return;