Unverified Commit 1cec5deb authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!8300 ipvlan: add ipvlan_route_v6_outbound() helper

parents d2d04cfe 5c87f29d
Loading
Loading
Loading
Loading
+25 −16
Original line number Diff line number Diff line
@@ -412,7 +412,7 @@ struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
	return addr;
}

static int ipvlan_process_v4_outbound(struct sk_buff *skb)
static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb)
{
	const struct iphdr *ip4h = ip_hdr(skb);
	struct net_device *dev = skb->dev;
@@ -454,13 +454,11 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
}

#if IS_ENABLED(CONFIG_IPV6)
static int ipvlan_process_v6_outbound(struct sk_buff *skb)

static noinline_for_stack int
ipvlan_route_v6_outbound(struct net_device *dev, struct sk_buff *skb)
{
	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
	struct net_device *dev = skb->dev;
	struct net *net = dev_net(dev);
	struct dst_entry *dst;
	int err, ret = NET_XMIT_DROP;
	struct flowi6 fl6 = {
		.flowi6_oif = dev->ifindex,
		.daddr = ip6h->daddr,
@@ -470,27 +468,38 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
		.flowi6_mark = skb->mark,
		.flowi6_proto = ip6h->nexthdr,
	};
	struct dst_entry *dst;
	int err;

	dst = ip6_route_output(net, NULL, &fl6);
	if (dst->error) {
		ret = dst->error;
	dst = ip6_route_output(dev_net(dev), NULL, &fl6);
	err = dst->error;
	if (err) {
		dst_release(dst);
		goto err;
		return err;
	}
	skb_dst_set(skb, dst);
	return 0;
}

static int ipvlan_process_v6_outbound(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	int err, ret = NET_XMIT_DROP;

	err = ipvlan_route_v6_outbound(dev, skb);
	if (unlikely(err)) {
		dev->stats.tx_errors++;
		kfree_skb(skb);
		return err;
	}

	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));

	err = ip6_local_out(net, skb->sk, skb);
	err = ip6_local_out(dev_net(dev), skb->sk, skb);
	if (unlikely(net_xmit_eval(err)))
		dev->stats.tx_errors++;
	else
		ret = NET_XMIT_SUCCESS;
	goto out;
err:
	dev->stats.tx_errors++;
	kfree_skb(skb);
out:
	return ret;
}
#else