X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=af35aba2cc781f93dda07ded49061d6cfc2f3c35;hb=999fba59afd9c8eef30d30a6fd2f490b85c24665;hp=b81bd6b84d08bb3e808bde9d1ee2ff869d560065;hpb=5fcc0d004ae0aa080deed51c842d074a83ec1f67;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index b81bd6b8..af35aba2 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks. * Copyright (c) 2010 Jean Tourrilhes - HP-Labs. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -1478,6 +1478,21 @@ ofproto_get_port(const struct ofproto *ofproto, uint16_t ofp_port) return NULL; } +int +ofproto_port_get_stats(const struct ofport *port, struct netdev_stats *stats) +{ + struct ofproto *ofproto = port->ofproto; + int error; + + if (ofproto->ofproto_class->port_get_stats) { + error = ofproto->ofproto_class->port_get_stats(port, stats); + } else { + error = EOPNOTSUPP; + } + + return error; +} + static void update_port(struct ofproto *ofproto, const char *name) { @@ -1950,7 +1965,7 @@ append_port_stat(struct ofport *port, struct list *replies) /* Intentionally ignore return value, since errors will set * 'stats' to all-1s, which is correct for OpenFlow, and * netdev_get_stats() will log errors. */ - netdev_get_stats(port->netdev, &stats); + ofproto_port_get_stats(port, &stats); ops = ofputil_append_stats_reply(sizeof *ops, replies); ops->port_no = port->opp.port_no; @@ -2066,8 +2081,9 @@ next_matching_table(struct ofproto *ofproto, * Returns 0 on success, otherwise an OpenFlow error code. */ static int collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, - const struct cls_rule *match, uint16_t out_port, - struct list *rules) + const struct cls_rule *match, + ovs_be64 cookie, ovs_be64 cookie_mask, + uint16_t out_port, struct list *rules) { struct classifier *cls; int error; @@ -2087,7 +2103,8 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, if (rule->pending) { return OFPROTO_POSTPONE; } - if (!rule_is_hidden(rule) && rule_has_out_port(rule, out_port)) { + if (!rule_is_hidden(rule) && rule_has_out_port(rule, out_port) + && !((rule->flow_cookie ^ cookie) & cookie_mask)) { list_push_back(rules, &rule->ofproto_node); } } @@ -2108,8 +2125,9 @@ collect_rules_loose(struct ofproto *ofproto, uint8_t table_id, * Returns 0 on success, otherwise an OpenFlow error code. */ static int collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, - const struct cls_rule *match, uint16_t out_port, - struct list *rules) + const struct cls_rule *match, + ovs_be64 cookie, ovs_be64 cookie_mask, + uint16_t out_port, struct list *rules) { struct classifier *cls; int error; @@ -2128,7 +2146,8 @@ collect_rules_strict(struct ofproto *ofproto, uint8_t table_id, if (rule->pending) { return OFPROTO_POSTPONE; } - if (!rule_is_hidden(rule) && rule_has_out_port(rule, out_port)) { + if (!rule_is_hidden(rule) && rule_has_out_port(rule, out_port) + && !((rule->flow_cookie ^ cookie) & cookie_mask)) { list_push_back(rules, &rule->ofproto_node); } } @@ -2153,6 +2172,7 @@ handle_flow_stats_request(struct ofconn *ofconn, } error = collect_rules_loose(ofproto, fsr.table_id, &fsr.match, + fsr.cookie, fsr.cookie_mask, fsr.out_port, &rules); if (error) { return error; @@ -2283,6 +2303,7 @@ handle_aggregate_stats_request(struct ofconn *ofconn, } error = collect_rules_loose(ofproto, request.table_id, &request.match, + request.cookie, request.cookie_mask, request.out_port, &rules); if (error) { return error; @@ -2578,8 +2599,9 @@ modify_flows_loose(struct ofproto *ofproto, struct ofconn *ofconn, struct list rules; int error; - error = collect_rules_loose(ofproto, fm->table_id, &fm->cr, OFPP_NONE, - &rules); + error = collect_rules_loose(ofproto, fm->table_id, &fm->cr, + fm->cookie, fm->cookie_mask, + OFPP_NONE, &rules); return (error ? error : list_is_empty(&rules) ? add_flow(ofproto, ofconn, fm, request) : modify_flows__(ofproto, ofconn, fm, request, &rules)); @@ -2598,8 +2620,9 @@ modify_flow_strict(struct ofproto *ofproto, struct ofconn *ofconn, struct list rules; int error; - error = collect_rules_strict(ofproto, fm->table_id, &fm->cr, OFPP_NONE, - &rules); + error = collect_rules_strict(ofproto, fm->table_id, &fm->cr, + fm->cookie, fm->cookie_mask, + OFPP_NONE, &rules); return (error ? error : list_is_empty(&rules) ? add_flow(ofproto, ofconn, fm, request) : list_is_singleton(&rules) ? modify_flows__(ofproto, ofconn, @@ -2641,8 +2664,9 @@ delete_flows_loose(struct ofproto *ofproto, struct ofconn *ofconn, struct list rules; int error; - error = collect_rules_loose(ofproto, fm->table_id, &fm->cr, fm->out_port, - &rules); + error = collect_rules_loose(ofproto, fm->table_id, &fm->cr, + fm->cookie, fm->cookie_mask, + fm->out_port, &rules); return (error ? error : !list_is_empty(&rules) ? delete_flows__(ofproto, ofconn, request, &rules) @@ -2658,8 +2682,9 @@ delete_flow_strict(struct ofproto *ofproto, struct ofconn *ofconn, struct list rules; int error; - error = collect_rules_strict(ofproto, fm->table_id, &fm->cr, fm->out_port, - &rules); + error = collect_rules_strict(ofproto, fm->table_id, &fm->cr, + fm->cookie, fm->cookie_mask, + fm->out_port, &rules); return (error ? error : list_is_singleton(&rules) ? delete_flows__(ofproto, ofconn, request, &rules) @@ -3166,12 +3191,16 @@ ofoperation_complete(struct ofoperation *op, int error) if (op->victim) { ofproto_rule_destroy__(op->victim); } - if (!(rule->cr.wc.vlan_tci_mask & htons(VLAN_VID_MASK)) - && ofproto->vlan_bitmap) { - uint16_t vid = vlan_tci_to_vid(rule->cr.flow.vlan_tci); - - if (!bitmap_is_set(ofproto->vlan_bitmap, vid)) { - bitmap_set1(ofproto->vlan_bitmap, vid); + if ((rule->cr.wc.vlan_tci_mask & htons(VLAN_VID_MASK)) + == htons(VLAN_VID_MASK)) { + if (ofproto->vlan_bitmap) { + uint16_t vid = vlan_tci_to_vid(rule->cr.flow.vlan_tci); + + if (!bitmap_is_set(ofproto->vlan_bitmap, vid)) { + bitmap_set1(ofproto->vlan_bitmap, vid); + ofproto->vlans_changed = true; + } + } else { ofproto->vlans_changed = true; } } @@ -3262,8 +3291,8 @@ ofproto_lookup(const char *name) } static void -ofproto_unixctl_list(struct unixctl_conn *conn, const char *arg OVS_UNUSED, - void *aux OVS_UNUSED) +ofproto_unixctl_list(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) { struct ofproto *ofproto; struct ds results; @@ -3285,7 +3314,8 @@ ofproto_unixctl_init(void) } registered = true; - unixctl_command_register("ofproto/list", "", ofproto_unixctl_list, NULL); + unixctl_command_register("ofproto/list", "", 0, 0, + ofproto_unixctl_list, NULL); } /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) @@ -3310,7 +3340,8 @@ ofproto_get_vlan_usage(struct ofproto *ofproto, unsigned long int *vlan_bitmap) const struct cls_table *table; HMAP_FOR_EACH (table, hmap_node, &cls->tables) { - if (!(table->wc.vlan_tci_mask & htons(VLAN_VID_MASK))) { + if ((table->wc.vlan_tci_mask & htons(VLAN_VID_MASK)) + == htons(VLAN_VID_MASK)) { const struct cls_rule *rule; HMAP_FOR_EACH (rule, hmap_node, &table->rules) {