#include "tunnel.h"
#include "vlan.h"
#include "vport.h"
-#include "vport-generic.h"
#include "vport-internal_dev.h"
#define PORT_TABLE_SIZE 1024
if (null_ports) {
lookup.daddr = 0;
lookup.saddr = 0;
+ lookup.in_key = 0;
lookup.tunnel_type = tunnel_type;
vport = port_table_lookup(&lookup, mutable);
if (vport)
const struct rtable *rt, __be16 *frag_offp,
int tunnel_hlen)
{
- bool df_inherit;
bool pmtud;
__be16 frag_off;
int mtu = 0;
unsigned int packet_length = skb->len - ETH_HLEN;
if (OVS_CB(skb)->tun_key->ipv4_dst) {
- df_inherit = false;
pmtud = false;
frag_off = OVS_CB(skb)->tun_key->tun_flags & OVS_TNL_F_DONT_FRAGMENT ?
htons(IP_DF) : 0;
} else {
- df_inherit = mutable->flags & TNL_F_DF_INHERIT;
pmtud = mutable->flags & TNL_F_PMTUD;
frag_off = mutable->flags & TNL_F_DF_DEFAULT ? htons(IP_DF) : 0;
}
if (skb->protocol == htons(ETH_P_IP)) {
struct iphdr *iph = ip_hdr(skb);
- if (df_inherit)
- frag_off = iph->frag_off & htons(IP_DF);
-
if (pmtud && iph->frag_off & htons(IP_DF)) {
mtu = max(mtu, IP_MIN_MTU);
/* IPv6 requires end hosts to do fragmentation
* if the packet is above the minimum MTU.
*/
- if (df_inherit && packet_length > IPV6_MIN_MTU)
+ if (packet_length > IPV6_MIN_MTU)
frag_off = htons(IP_DF);
if (pmtud) {
if (err)
return err;
- if (!a[OVS_TUNNEL_ATTR_FLAGS] || !a[OVS_TUNNEL_ATTR_DST_IPV4])
- return -EINVAL;
+ /* Process attributes possibly useful for null_ports first */
+ if (a[OVS_TUNNEL_ATTR_DST_PORT])
+ mutable->dst_port =
+ htons(nla_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]));
- mutable->flags = nla_get_u32(a[OVS_TUNNEL_ATTR_FLAGS]) & TNL_F_PUBLIC;
- mutable->key.daddr = nla_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+ if (a[OVS_TUNNEL_ATTR_DST_IPV4])
+ mutable->key.daddr = nla_get_be32(a[OVS_TUNNEL_ATTR_DST_IPV4]);
+
+ /* Skip the rest if configuring a null_port */
+ if (!mutable->key.daddr)
+ goto out;
+
+ if (a[OVS_TUNNEL_ATTR_FLAGS])
+ mutable->flags = nla_get_u32(a[OVS_TUNNEL_ATTR_FLAGS])
+ & TNL_F_PUBLIC;
if (a[OVS_TUNNEL_ATTR_SRC_IPV4]) {
if (ipv4_is_multicast(mutable->key.daddr))
if (a[OVS_TUNNEL_ATTR_TTL])
mutable->ttl = nla_get_u8(a[OVS_TUNNEL_ATTR_TTL]);
- if (a[OVS_TUNNEL_ATTR_DST_PORT])
- mutable->dst_port =
- htons(nla_get_u16(a[OVS_TUNNEL_ATTR_DST_PORT]));
-
if (!a[OVS_TUNNEL_ATTR_IN_KEY]) {
mutable->key.tunnel_type |= TNL_T_KEY_MATCH;
mutable->flags |= TNL_F_IN_KEY_MATCH;
const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
const struct tnl_mutable_config *mutable = rcu_dereference_rtnl(tnl_vport->mutable);
- if (nla_put_u32(skb, OVS_TUNNEL_ATTR_FLAGS,
- mutable->flags & TNL_F_PUBLIC) ||
- nla_put_be32(skb, OVS_TUNNEL_ATTR_DST_IPV4, mutable->key.daddr))
+ if (mutable->dst_port && nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT,
+ ntohs(mutable->dst_port)))
goto nla_put_failure;
+ /* Skip the rest for null_ports */
+ if (!mutable->key.daddr)
+ return 0;
+
+ if (nla_put_be32(skb, OVS_TUNNEL_ATTR_DST_IPV4, mutable->key.daddr))
+ goto nla_put_failure;
+ if (nla_put_u32(skb, OVS_TUNNEL_ATTR_FLAGS,
+ mutable->flags & TNL_F_PUBLIC))
+ goto nla_put_failure;
if (!(mutable->flags & TNL_F_IN_KEY_MATCH) &&
nla_put_be64(skb, OVS_TUNNEL_ATTR_IN_KEY, mutable->key.in_key))
goto nla_put_failure;
goto nla_put_failure;
if (mutable->ttl && nla_put_u8(skb, OVS_TUNNEL_ATTR_TTL, mutable->ttl))
goto nla_put_failure;
- if (mutable->dst_port && nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT,
- ntohs(mutable->dst_port)))
- goto nla_put_failure;
return 0;