struct netdev netdev;
};
-static int netdev_tunnel_create(const char *name, const char *type,
+static int netdev_tunnel_create(const struct netdev_class *, const char *name,
const struct shash *args, struct netdev_dev **);
static struct netdev_dev_tunnel *
struct tnl_port_config *config)
{
struct shash_node *node;
+ bool ipsec_ip_set = false;
+ bool ipsec_mech_set = false;
memset(config, 0, sizeof *config);
config->flags |= TNL_F_PMTUD;
+ config->flags |= TNL_F_HDR_CACHE;
SHASH_FOR_EACH (node, args) {
if (!strcmp(node->name, "remote_ip")) {
} else {
config->saddr = in_addr.s_addr;
}
- } else if (!strcmp(node->name, "key")) {
+ } else if (!strcmp(node->name, "key") && !strcmp(type, "gre")) {
if (!strcmp(node->data, "flow")) {
config->flags |= TNL_F_IN_KEY_MATCH;
config->flags |= TNL_F_OUT_KEY_ACTION;
} else {
config->out_key = config->in_key = htonl(atoi(node->data));
}
- } else if (!strcmp(node->name, "in_key")) {
+ } else if (!strcmp(node->name, "in_key") && !strcmp(type, "gre")) {
if (!strcmp(node->data, "flow")) {
config->flags |= TNL_F_IN_KEY_MATCH;
} else {
config->in_key = htonl(atoi(node->data));
}
- } else if (!strcmp(node->name, "out_key")) {
+ } else if (!strcmp(node->name, "out_key") && !strcmp(type, "gre")) {
if (!strcmp(node->data, "flow")) {
config->flags |= TNL_F_OUT_KEY_ACTION;
} else {
} else {
config->ttl = atoi(node->data);
}
- } else if (!strcmp(node->name, "csum")) {
+ } else if (!strcmp(node->name, "csum") && !strcmp(type, "gre")) {
if (!strcmp(node->data, "true")) {
config->flags |= TNL_F_CSUM;
}
if (!strcmp(node->data, "false")) {
config->flags &= ~TNL_F_PMTUD;
}
+ } else if (!strcmp(node->name, "header_cache")) {
+ if (!strcmp(node->data, "false")) {
+ config->flags &= ~TNL_F_HDR_CACHE;
+ }
+ } else if (!strcmp(node->name, "ipsec_local_ip")) {
+ ipsec_ip_set = true;
+ } else if (!strcmp(node->name, "ipsec_cert")
+ || !strcmp(node->name, "ipsec_psk")) {
+ ipsec_mech_set = true;
} else {
VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->name);
}
}
+ /* IPsec doesn't work when header caching is enabled. Disable it if
+ * the IPsec local IP address and authentication mechanism have been
+ * defined. */
+ if (ipsec_ip_set && ipsec_mech_set) {
+ VLOG_INFO("%s: header caching disabled due to use of IPsec", name);
+ config->flags &= ~TNL_F_HDR_CACHE;
+ }
+
if (!config->daddr) {
VLOG_WARN("%s: %s type requires valid 'remote_ip' argument", name, type);
return EINVAL;
}
static int
-netdev_tunnel_create(const char *name, const char *type,
+netdev_tunnel_create(const struct netdev_class *class, const char *name,
const struct shash *args, struct netdev_dev **netdev_devp)
{
int err;
struct tnl_port_config port_config;
struct netdev_dev_tunnel *netdev_dev;
- ovs_strlcpy(ova.port_type, type, sizeof ova.port_type);
+ ovs_strlcpy(ova.port_type, class->type, sizeof ova.port_type);
ovs_strlcpy(ova.devname, name, sizeof ova.devname);
ova.config = &port_config;
- err = parse_config(name, type, args, &port_config);
+ err = parse_config(name, class->type, args, &port_config);
if (err) {
return err;
}
}
netdev_dev = xmalloc(sizeof *netdev_dev);
- netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_gre_class);
+ netdev_dev_init(&netdev_dev->netdev_dev, name, class);
*netdev_devp = &netdev_dev->netdev_dev;
return 0;
}
netdev_vport_poll_add,
netdev_vport_poll_remove,
};
+
+const struct netdev_class netdev_capwap_class = {
+ "capwap",
+
+ NULL, /* init */
+ NULL, /* run */
+ NULL, /* wait */
+
+ netdev_tunnel_create,
+ netdev_tunnel_destroy,
+ netdev_tunnel_reconfigure,
+
+ netdev_tunnel_open,
+ netdev_tunnel_close,
+
+ NULL, /* enumerate */
+
+ NULL, /* recv */
+ NULL, /* recv_wait */
+ NULL, /* drain */
+
+ NULL, /* send */
+ NULL, /* send_wait */
+
+ netdev_vport_set_etheraddr,
+ netdev_vport_get_etheraddr,
+ netdev_vport_get_mtu,
+ NULL, /* get_ifindex */
+ netdev_vport_get_carrier,
+ netdev_vport_get_stats,
+ netdev_vport_set_stats,
+
+ NULL, /* get_features */
+ NULL, /* set_advertisements */
+ NULL, /* get_vlan_vid */
+
+ NULL, /* set_policing */
+ NULL, /* get_qos_types */
+ NULL, /* get_qos_capabilities */
+ NULL, /* get_qos */
+ NULL, /* set_qos */
+ NULL, /* get_queue */
+ NULL, /* set_queue */
+ NULL, /* delete_queue */
+ NULL, /* get_queue_stats */
+ NULL, /* dump_queues */
+ NULL, /* dump_queue_stats */
+
+ NULL, /* get_in4 */
+ NULL, /* set_in4 */
+ NULL, /* get_in6 */
+ NULL, /* add_router */
+ NULL, /* get_next_hop */
+ NULL, /* arp_lookup */
+
+ netdev_vport_update_flags,
+
+ netdev_vport_poll_add,
+ netdev_vport_poll_remove,
+};