Ejemplo n.º 1
0
static void stt_tnl_destroy(struct vport *vport)
{
	struct stt_port *stt_port = stt_vport(vport);

	stt_sock_release(stt_port->stt_sock);
	ovs_vport_deferred_free(vport);
}
Ejemplo n.º 2
0
static int stt_get_options(const struct vport *vport,
			      struct sk_buff *skb)
{
	struct stt_port *stt_port = stt_vport(vport);

	if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, stt_port->port_no))
		return -EMSGSIZE;
	return 0;
}
Ejemplo n.º 3
0
static int stt_tnl_get_options(const struct vport *vport,
			       struct sk_buff *skb)
{
	struct stt_port *stt_port = stt_vport(vport);
	struct inet_sock *sk = inet_sk(stt_port->stt_sock->sock->sk);

	if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, ntohs(sk->inet_sport)))
		return -EMSGSIZE;
	return 0;
}
Ejemplo n.º 4
0
static int stt_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
				   struct ovs_tunnel_info *egress_tun_info)
{
	struct stt_port *stt_port = stt_vport(vport);
	struct net *net = ovs_dp_get_net(vport->dp);
	__be16 dport = inet_sk(stt_port->stt_sock->sock->sk)->inet_sport;
	__be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);

	/* Get tp_src and tp_dst, refert to stt_build_header().
	 */
	return ovs_tunnel_get_egress_info(egress_tun_info,
					  ovs_dp_get_net(vport->dp),
					  OVS_CB(skb)->egress_tun_info,
					  IPPROTO_TCP, skb->mark, sport, dport);
}
Ejemplo n.º 5
0
static struct vport *stt_tnl_create(const struct vport_parms *parms)
{
	struct net *net = ovs_dp_get_net(parms->dp);
	struct nlattr *options = parms->options;
	struct stt_port *stt_port;
	struct net_device *dev;
	struct vport *vport;
	struct nlattr *a;
	u16 dst_port;
	int err;

	if (!options) {
		err = -EINVAL;
		goto error;
	}

	a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
	if (a && nla_len(a) == sizeof(u16)) {
		dst_port = nla_get_u16(a);
	} else {
		/* Require destination port from userspace. */
		err = -EINVAL;
		goto error;
	}

	vport = ovs_vport_alloc(sizeof(struct stt_port),
				&ovs_stt_vport_ops, parms);
	if (IS_ERR(vport))
		return vport;

	stt_port = stt_vport(vport);
	stt_port->port_no = dst_port;

	rtnl_lock();
	dev = stt_dev_create_fb(net, parms->name, NET_NAME_USER, dst_port);
	if (IS_ERR(dev)) {
		rtnl_unlock();
		ovs_vport_free(vport);
		return ERR_CAST(dev);
	}

	dev_change_flags(dev, dev->flags | IFF_UP);
	rtnl_unlock();
	return vport;
error:
	return ERR_PTR(err);
}
Ejemplo n.º 6
0
static struct vport *stt_tnl_create(const struct vport_parms *parms)
{
	struct net *net = ovs_dp_get_net(parms->dp);
	struct nlattr *options = parms->options;
	struct stt_port *stt_port;
	struct stt_sock *stt_sock;
	struct vport *vport;
	struct nlattr *a;
	int err;
	u16 dst_port;

	if (!options) {
		err = -EINVAL;
		goto error;
	}

	a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
	if (a && nla_len(a) == sizeof(u16)) {
		dst_port = nla_get_u16(a);
	} else {
		/* Require destination port from userspace. */
		err = -EINVAL;
		goto error;
	}

	vport = ovs_vport_alloc(sizeof(struct stt_port),
				&ovs_stt_vport_ops, parms);
	if (IS_ERR(vport))
		return vport;

	stt_port = stt_vport(vport);
	strncpy(stt_port->name, parms->name, IFNAMSIZ);

	stt_sock = stt_sock_add(net, htons(dst_port), stt_rcv, vport);
	if (IS_ERR(stt_sock)) {
		ovs_vport_free(vport);
		return ERR_CAST(stt_sock);
	}
	stt_port->stt_sock = stt_sock;

	return vport;
error:
	return ERR_PTR(err);
}
Ejemplo n.º 7
0
static int stt_tnl_send(struct vport *vport, struct sk_buff *skb)
{
	struct net *net = ovs_dp_get_net(vport->dp);
	struct stt_port *stt_port = stt_vport(vport);
	__be16 dport = inet_sk(stt_port->stt_sock->sock->sk)->inet_sport;
	const struct ovs_key_ipv4_tunnel *tun_key;
	const struct ovs_tunnel_info *tun_info;
	struct rtable *rt;
	__be16 sport;
	__be32 saddr;
	__be16 df;
	int err;

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

	tun_key = &tun_info->tunnel;
	/* Route lookup */
	saddr = tun_key->ipv4_src;
	rt = find_route(ovs_dp_get_net(vport->dp),
			&saddr, tun_key->ipv4_dst,
			IPPROTO_TCP, tun_key->ipv4_tos,
			skb->mark);

	if (IS_ERR(rt)) {
		err = PTR_ERR(rt);
		goto error;
	}

	df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
	sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
	skb->ignore_df = 1;

	return stt_xmit_skb(skb, rt, saddr, tun_key->ipv4_dst,
			    tun_key->ipv4_tos, tun_key->ipv4_ttl,
			    df, sport, dport, tun_key->tun_id);
error:
	kfree_skb(skb);
	return err;
}
Ejemplo n.º 8
0
static const char *stt_tnl_get_name(const struct vport *vport)
{
	return stt_vport(vport)->name;
}