コード例 #1
0
ファイル: vport-vxlan.c プロジェクト: 19Dan01/linux
static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
{
	struct net *net = ovs_dp_get_net(vport->dp);
	struct vxlan_port *vxlan_port = vxlan_vport(vport);
	struct sock *sk = vxlan_port->vs->sock->sk;
	__be16 dst_port = inet_sk(sk)->inet_sport;
	const struct ovs_key_ipv4_tunnel *tun_key;
	struct vxlan_metadata md = {0};
	struct rtable *rt;
	struct flowi4 fl;
	__be16 src_port;
	__be16 df;
	int err;
	u32 vxflags;

	if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
		err = -EINVAL;
		goto error;
	}

	tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
	rt = ovs_tunnel_route_lookup(net, tun_key, skb->mark, &fl, IPPROTO_UDP);
	if (IS_ERR(rt)) {
		err = PTR_ERR(rt);
		goto error;
	}

	df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ?
		htons(IP_DF) : 0;

	skb->ignore_df = 1;

	src_port = udp_flow_src_port(net, skb, 0, 0, true);
	md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
	md.gbp = vxlan_ext_gbp(skb);
	vxflags = vxlan_port->exts |
		      (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);

	err = vxlan_xmit_skb(rt, sk, skb, fl.saddr, tun_key->ipv4_dst,
			     tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
			     src_port, dst_port,
			     &md, false, vxflags);
	if (err < 0)
		ip_rt_put(rt);
	return err;
error:
	kfree_skb(skb);
	return err;
}
コード例 #2
0
ファイル: vport.c プロジェクト: JunoZhu/ovs
int ovs_tunnel_get_egress_info(struct dp_upcall_info *upcall,
			       struct net *net,
			       struct sk_buff *skb,
			       u8 ipproto,
			       __be16 tp_src,
			       __be16 tp_dst)
{
	struct ip_tunnel_info *egress_tun_info = upcall->egress_tun_info;
	struct ip_tunnel_info *tun_info = skb_tunnel_info(skb);
	const struct ip_tunnel_key *tun_key;
	u32 skb_mark = skb->mark;
	struct rtable *rt;
	struct flowi4 fl;

	if (unlikely(!tun_info))
		return -EINVAL;
	if (ip_tunnel_info_af(tun_info) != AF_INET)
		return -EINVAL;

	tun_key = &tun_info->key;

	/* Route lookup to get srouce IP address.
	 * The process may need to be changed if the corresponding process
	 * in vports ops changed.
	 */
	rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
	if (IS_ERR(rt))
		return PTR_ERR(rt);

	ip_rt_put(rt);

	/* Generate egress_tun_info based on tun_info,
	 * saddr, tp_src and tp_dst
	 */
	ip_tunnel_key_init(&egress_tun_info->key,
			   fl.saddr, tun_key->u.ipv4.dst,
			   tun_key->tos,
			   tun_key->ttl,
			   tp_src, tp_dst,
			   tun_key->tun_id,
			   tun_key->tun_flags);
	egress_tun_info->options_len = tun_info->options_len;
	egress_tun_info->mode = tun_info->mode;
	upcall->egress_tun_opts = ip_tunnel_info_opts(tun_info);
	return 0;
}
コード例 #3
0
ファイル: vport.c プロジェクト: 19Dan01/linux
int ovs_tunnel_get_egress_info(struct ovs_tunnel_info *egress_tun_info,
			       struct net *net,
			       const struct ovs_tunnel_info *tun_info,
			       u8 ipproto,
			       u32 skb_mark,
			       __be16 tp_src,
			       __be16 tp_dst)
{
	const struct ovs_key_ipv4_tunnel *tun_key;
	struct rtable *rt;
	struct flowi4 fl;

	if (unlikely(!tun_info))
		return -EINVAL;

	tun_key = &tun_info->tunnel;

	/* Route lookup to get srouce IP address.
	 * The process may need to be changed if the corresponding process
	 * in vports ops changed.
	 */
	rt = ovs_tunnel_route_lookup(net, tun_key, skb_mark, &fl, ipproto);
	if (IS_ERR(rt))
		return PTR_ERR(rt);

	ip_rt_put(rt);

	/* Generate egress_tun_info based on tun_info,
	 * saddr, tp_src and tp_dst
	 */
	__ovs_flow_tun_info_init(egress_tun_info,
				 fl.saddr, tun_key->ipv4_dst,
				 tun_key->ipv4_tos,
				 tun_key->ipv4_ttl,
				 tp_src, tp_dst,
				 tun_key->tun_id,
				 tun_key->tun_flags,
				 tun_info->options,
				 tun_info->options_len);

	return 0;
}