On Thu, Oct 27, 2011 at 04:38:39PM -0700, Jesse Gross wrote: > On Wed, Oct 26, 2011 at 3:27 PM, Ben Pfaff <b...@nicira.com> wrote: > > diff --git a/datapath/tunnel.c b/datapath/tunnel.c > > index 372d90e..047961f 100644 > > --- a/datapath/tunnel.c > > +++ b/datapath/tunnel.c > > +static int tnl_sock_bind(const struct tnl_ops *tnl_ops, struct > > tnl_mutable_config *mutable) > > +{ > > +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) > > + ?? ?? ?? struct sockaddr_in sin; > > + ?? ?? ?? struct tnl_sock *ts; > > + ?? ?? ?? int err; > > + > > + ?? ?? ?? if (tnl_ops->ipproto != IPPROTO_UDP) > > + ?? ?? ?? ?? ?? ?? ?? return 0; > > + > > + ?? ?? ?? list_for_each_entry (ts, &tnl_socks, list) { > > + ?? ?? ?? ?? ?? ?? ?? if (ts->port == mutable->dst_port) { > > + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? if (udp_sk(ts->socket->sk)->encap_rcv != > > tnl_ops->udp_rcv) > > + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? return -EADDRINUSE; > > When I originally proposed this, I thought that we could directly use > the socket lookup to find the tunnel. I now see that it isn't > possible because of the key (and there is no way to know whether the > key is important until after you do the tunnel lookup). Is there any > benefit to binding the socket more specifically to the tunnel using > the remote and local (if there is one) IPs? The main benefit of this > would be to enable finer grained binding of sockets for different > tunnel types. I don't know whether that is more or less confusing > though. It also makes the UDP socket lookup marginally faster.
If I do that I think I'll need a hash table for the tnl_socks since there's likely to be many of them (one per local/remote IP pair) if someone configures a bunch of tunnels instead of just one (for a given port). I'm willing to do it, your paragraph doesn't make me sure whether you really want it though. > > @@ -1347,29 +1438,57 @@ static int tnl_set_config(struct nlattr *options, > > const struct tnl_ops *tnl_ops, > [...] > > + ?? ?? ?? if (tnl_ops->ipproto == IPPROTO_UDP) { > > + ?? ?? ?? ?? ?? ?? ?? struct nlattr *src_base = > > a[OVS_TUNNEL_ATTR_SRC_PORT_BASE]; > > + ?? ?? ?? ?? ?? ?? ?? struct nlattr *src_hash = > > a[OVS_TUNNEL_ATTR_SRC_PORT_HASH]; > > + ?? ?? ?? ?? ?? ?? ?? struct nlattr *dst = a[OVS_TUNNEL_ATTR_DST_PORT]; > > + > > + ?? ?? ?? ?? ?? ?? ?? if (!src_base || !dst) { > > + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? err = -EINVAL; > > + ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? goto error; > > + ?? ?? ?? ?? ?? ?? ?? } > > I think we should add some validation to check that if ports are > specified then they go with a protocol that has L4 ports. Right now, > I don't think either userspace or kernel will care. OK, fixed in kernel: diff --git a/datapath/tunnel.c b/datapath/tunnel.c index cddae06..0c2a243 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -1436,6 +1436,8 @@ static int tnl_set_config(struct nlattr *options, const struct tnl_ops *tnl_ops, const struct vport *old_vport; const struct tnl_mutable_config *old_mutable; struct nlattr *a[OVS_TUNNEL_ATTR_MAX + 1]; + struct nlattr *src_base, *src_hash; + struct nlattr *dst; int err; if (!options) { @@ -1463,11 +1465,10 @@ static int tnl_set_config(struct nlattr *options, const struct tnl_ops *tnl_ops, mutable->key.saddr = nla_get_be32(a[OVS_TUNNEL_ATTR_SRC_IPV4]); } + src_base = a[OVS_TUNNEL_ATTR_SRC_PORT_BASE]; + src_hash = a[OVS_TUNNEL_ATTR_SRC_PORT_HASH]; + dst = a[OVS_TUNNEL_ATTR_DST_PORT]; if (tnl_ops->ipproto == IPPROTO_UDP) { - struct nlattr *src_base = a[OVS_TUNNEL_ATTR_SRC_PORT_BASE]; - struct nlattr *src_hash = a[OVS_TUNNEL_ATTR_SRC_PORT_HASH]; - struct nlattr *dst = a[OVS_TUNNEL_ATTR_DST_PORT]; - if (!src_base || !dst) { err = -EINVAL; goto error; @@ -1482,6 +1483,9 @@ static int tnl_set_config(struct nlattr *options, const struct tnl_ops *tnl_ops, goto error; } } + } else if (src_base || src_hash || dst) { + err = -EINVAL; + goto error; } if (a[OVS_TUNNEL_ATTR_TOS]) { Userspace already should disallow specifying src_port and dst_port on non-UDP tunnels because the initial values for those will be 0 for such tunnels and there's a check for zero in the parser: } else if (src_port_base && !strcmp(node->name, "src_port")) { ... } else if (dst_port && !strcmp(node->name, "dst_port")) { > > + ?? ?? ?? ?? ?? ?? ?? mutable->src_port_base = > > ntohs(nla_get_be16(src_base)); > > + ?? ?? ?? ?? ?? ?? ?? mutable->dst_port = nla_get_be16(dst); > > Can you add a comment to explain that it is intention that one is byte > swapped and the other is not? When I first saw it, I was sure it was > a bug (although sparse should be good about catching actual bugs). OK, like this? Maybe I should make both __be16 anyway, it's less surprising and ntohs() isn't very expensive. Opinion? diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 0c2a243..61b2795 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -1473,6 +1473,10 @@ static int tnl_set_config(struct nlattr *options, const struct tnl_ops *tnl_ops, err = -EINVAL; goto error; } + + /* src_port_base is u16 because we do arithmetic on it, + * dst_port is __be16 because we just copy it around. + */ mutable->src_port_base = ntohs(nla_get_be16(src_base)); mutable->dst_port = nla_get_be16(dst); _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev