/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <fcntl.h>
#include <inttypes.h>
#include <net/if.h>
-#include <linux/rtnetlink.h>
-#include <linux/ethtool.h>
-#include <linux/sockios.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <sys/sysmacros.h>
#include <unistd.h>
#include "csum.h"
static int
name_to_dp_idx(const char *name)
{
- if (!strncmp(name, "dp", 2) && isdigit(name[2])) {
+ if (!strncmp(name, "dp", 2) && isdigit((unsigned char)name[2])) {
int dp_idx = atoi(name + 2);
if (dp_idx >= 0 && dp_idx < N_DP_NETDEVS) {
return dp_idx;
}
static int
-dpif_netdev_open(const char *name UNUSED, char *suffix, bool create,
+dpif_netdev_open(const char *name OVS_UNUSED, char *suffix, bool create,
struct dpif **dpifp)
{
if (create) {
if (!internal) {
error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
} else {
- char *tapname = xasprintf("tap:%s", devname);
- error = netdev_open(tapname, NETDEV_ETH_TYPE_ANY, &netdev);
- free(tapname);
+ error = netdev_create(devname, "tap", NULL);
+ if (!error) {
+ error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev);
+ if (error) {
+ netdev_destroy(devname);
+ }
+ }
}
if (error) {
return error;
return do_add_port(dp, devname, flags, port_no);
}
}
- return EXFULL;
+ return EFBIG;
}
static int
do_del_port(struct dp_netdev *dp, uint16_t port_no)
{
struct dp_netdev_port *port;
+ char *name;
int error;
error = get_port_by_number(dp, port_no, &port);
dp->n_ports--;
dp->serial++;
+ name = xstrdup(netdev_get_name(port->netdev));
netdev_close(port->netdev);
+ if (port->internal) {
+ netdev_destroy(name);
+ }
+ free(name);
free(port);
return 0;
}
static int
-dpif_netdev_port_poll(const struct dpif *dpif_, char **devnamep UNUSED)
+dpif_netdev_port_poll(const struct dpif *dpif_, char **devnamep OVS_UNUSED)
{
struct dpif_netdev *dpif = dpif_netdev_cast(dpif_);
if (dpif->dp_serial != dpif->dp->serial) {
}
static void
-answer_flow_query(const struct dp_netdev_flow *flow,
+answer_flow_query(struct dp_netdev_flow *flow, uint32_t query_flags,
struct odp_flow *odp_flow)
{
if (flow) {
n * sizeof *odp_flow->actions);
odp_flow->n_actions = flow->n_actions;
}
+
+ if (query_flags & ODPFF_ZERO_TCP_FLAGS) {
+ flow->tcp_ctl = 0;
+ }
+
} else {
odp_flow->stats.error = ENOENT;
}
for (i = 0; i < n; i++) {
struct odp_flow *odp_flow = &flows[i];
- answer_flow_query(dp_netdev_lookup_flow(dp, &odp_flow->key), odp_flow);
+ answer_flow_query(dp_netdev_lookup_flow(dp, &odp_flow->key),
+ odp_flow->flags, odp_flow);
}
return 0;
}
if (hmap_count(&dp->flow_table) < MAX_FLOWS) {
return add_flow(dpif, &put->flow);
} else {
- return EXFULL;
+ return EFBIG;
}
} else {
return ENOENT;
flow = dp_netdev_lookup_flow(dp, &odp_flow->key);
if (flow) {
- answer_flow_query(flow, odp_flow);
+ answer_flow_query(flow, 0, odp_flow);
dp_netdev_free_flow(dp, flow);
return 0;
} else {
if (i >= n) {
break;
}
- answer_flow_query(flow, &flows[i++]);
+ answer_flow_query(flow, 0, &flows[i++]);
}
return hmap_count(&dp->flow_table);
}
flow_t flow;
int error;
- if (packet->size < ETH_HLEN || packet->size > UINT16_MAX) {
+ if (packet->size < ETH_HEADER_LEN || packet->size > UINT16_MAX) {
return EINVAL;
}
time_timeval(&flow->used);
flow->packet_count++;
flow->byte_count += packet->size;
- if (key->dl_type == htons(ETH_P_IP)) {
+ if (key->dl_type == htons(ETH_TYPE_IP)) {
struct ip_header *nh = packet->l3;
flow->ip_tos = nh->ip_tos;
dp_netdev_set_tp_port(struct ofpbuf *packet, flow_t *key,
const struct odp_action_tp_port *a)
{
- if (key->dl_type == htons(ETH_P_IP)) {
+ if (key->dl_type == htons(ETH_TYPE_IP)) {
uint16_t *field;
if (key->nw_proto == IPPROTO_TCP) {
struct tcp_header *th = packet->l4;
dpif_netdev_execute,
dpif_netdev_recv_get_mask,
dpif_netdev_recv_set_mask,
+ NULL, /* get_sflow_probability */
+ NULL, /* set_sflow_probability */
dpif_netdev_recv,
dpif_netdev_recv_wait,
};