X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-netdev.c;h=e9fb216feff3eb3083b4f837353c095d41e678bd;hb=3ef917b5699874c46131c1d8731fafc5246c0dd1;hp=4ff1a425f227aa8946f6dea93b5c7a5ac9c6430e;hpb=1d87357a1322c2faa290452c08c7f794c0be848b;p=openvswitch diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 4ff1a425..e9fb216f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -1,5 +1,5 @@ /* - * 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. @@ -23,15 +23,11 @@ #include #include #include -#include -#include -#include #include #include #include #include #include -#include #include #include "csum.h" @@ -160,7 +156,7 @@ get_dp_netdev(const struct dpif *dpif) 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; @@ -200,7 +196,7 @@ create_dpif_netdev(struct dp_netdev *dp) dp->open_cnt++; - dpname = xasprintf("netdev:dp%d", dp->dp_idx); + dpname = xasprintf("dp%d", dp->dp_idx); dpif = xmalloc(sizeof *dpif); dpif_init(&dpif->dpif, &dpif_netdev_class, dpname, dp->dp_idx, dp->dp_idx); dpif->dp = dp; @@ -223,7 +219,7 @@ create_dp_netdev(const char *name, int dp_idx, struct dpif **dpifp) } /* Create datapath. */ - dp_netdevs[dp_idx] = dp = xcalloc(1, sizeof *dp); + dp_netdevs[dp_idx] = dp = xzalloc(sizeof *dp); list_push_back(&dp_netdev_list, &dp->node); dp->dp_idx = dp_idx; dp->open_cnt = 0; @@ -241,7 +237,7 @@ create_dp_netdev(const char *name, int dp_idx, struct dpif **dpifp) error = do_add_port(dp, name, ODP_PORT_INTERNAL, ODPP_LOCAL); if (error) { dp_netdev_free(dp); - return error; + return ENODEV; } *dpifp = create_dpif_netdev(dp); @@ -249,20 +245,20 @@ create_dp_netdev(const char *name, int dp_idx, struct dpif **dpifp) } static int -dpif_netdev_open(const char *name UNUSED, char *suffix, bool create, +dpif_netdev_open(const char *name, const char *type UNUSED, bool create, struct dpif **dpifp) { if (create) { - if (find_dp_netdev(suffix)) { + if (find_dp_netdev(name)) { return EEXIST; } else { - int dp_idx = name_to_dp_idx(suffix); + int dp_idx = name_to_dp_idx(name); if (dp_idx >= 0) { - return create_dp_netdev(suffix, dp_idx, dpifp); + return create_dp_netdev(name, dp_idx, dpifp); } else { /* Scan for unused dp_idx number. */ for (dp_idx = 0; dp_idx < N_DP_NETDEVS; dp_idx++) { - int error = create_dp_netdev(suffix, dp_idx, dpifp); + int error = create_dp_netdev(name, dp_idx, dpifp); if (error != EBUSY) { return error; } @@ -273,7 +269,7 @@ dpif_netdev_open(const char *name UNUSED, char *suffix, bool create, } } } else { - struct dp_netdev *dp = find_dp_netdev(suffix); + struct dp_netdev *dp = find_dp_netdev(name); if (dp) { *dpifp = create_dpif_netdev(dp); return 0; @@ -367,6 +363,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, uint16_t flags, { bool internal = (flags & ODP_PORT_INTERNAL) != 0; struct dp_netdev_port *port; + struct netdev_options netdev_options; struct netdev *netdev; int mtu; int error; @@ -374,13 +371,17 @@ do_add_port(struct dp_netdev *dp, const char *devname, uint16_t flags, /* XXX reject devices already in some dp_netdev. */ /* Open and validate network device. */ - if (!internal) { - error = netdev_open(devname, NETDEV_ETH_TYPE_ANY, &netdev); + memset(&netdev_options, 0, sizeof netdev_options); + netdev_options.name = devname; + netdev_options.ethertype = NETDEV_ETH_TYPE_ANY; + netdev_options.may_create = true; + if (internal) { + netdev_options.type = "tap"; } else { - char *tapname = xasprintf("tap:%s", devname); - error = netdev_open(tapname, NETDEV_ETH_TYPE_ANY, &netdev); - free(tapname); + netdev_options.may_open = true; } + + error = netdev_open(&netdev_options, &netdev); if (error) { return error; } @@ -424,7 +425,7 @@ dpif_netdev_port_add(struct dpif *dpif, const char *devname, uint16_t flags, return do_add_port(dp, devname, flags, port_no); } } - return EXFULL; + return EFBIG; } static int @@ -472,6 +473,7 @@ 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); @@ -484,7 +486,10 @@ do_del_port(struct dp_netdev *dp, uint16_t port_no) dp->n_ports--; dp->serial++; + name = xstrdup(netdev_get_name(port->netdev)); netdev_close(port->netdev); + + free(name); free(port); return 0; @@ -669,7 +674,7 @@ dp_netdev_lookup_flow(const struct dp_netdev *dp, const flow_t *key) } 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) { @@ -687,6 +692,11 @@ answer_flow_query(const struct dp_netdev_flow *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; } @@ -700,7 +710,8 @@ dpif_netdev_flow_get(const struct dpif *dpif, struct odp_flow flows[], int n) 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; } @@ -792,7 +803,7 @@ add_flow(struct dpif *dpif, struct odp_flow *odp_flow) struct dp_netdev_flow *flow; int error; - flow = xcalloc(1, sizeof *flow); + flow = xzalloc(sizeof *flow); flow->key = odp_flow->key; flow->key.reserved = 0; @@ -829,7 +840,7 @@ dpif_netdev_flow_put(struct dpif *dpif, struct odp_flow_put *put) if (hmap_count(&dp->flow_table) < MAX_FLOWS) { return add_flow(dpif, &put->flow); } else { - return EXFULL; + return EFBIG; } } else { return ENOENT; @@ -856,7 +867,7 @@ dpif_netdev_flow_del(struct dpif *dpif, struct odp_flow *odp_flow) 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 { @@ -876,7 +887,7 @@ dpif_netdev_flow_list(const struct dpif *dpif, struct odp_flow flows[], int n) if (i >= n) { break; } - answer_flow_query(flow, &flows[i++]); + answer_flow_query(flow, 0, &flows[i++]); } return hmap_count(&dp->flow_table); } @@ -892,7 +903,7 @@ dpif_netdev_execute(struct dpif *dpif, uint16_t in_port, 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; } @@ -990,7 +1001,7 @@ dp_netdev_flow_used(struct dp_netdev_flow *flow, const flow_t *key, 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; @@ -1163,7 +1174,7 @@ static void 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; @@ -1292,7 +1303,6 @@ dp_netdev_execute_actions(struct dp_netdev *dp, } const struct dpif_class dpif_netdev_class = { - "netdev", "netdev", dp_netdev_run, dp_netdev_wait,