X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=af35aba2cc781f93dda07ded49061d6cfc2f3c35;hb=999fba59afd9c8eef30d30a6fd2f490b85c24665;hp=b0a1a66f591bd4fad8e2254e614dd9c08d45c14f;hpb=6527c598eabbd34aaa7284f4b052de667e13be2f;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index b0a1a66f..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"); @@ -2081,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; @@ -2102,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); } } @@ -2123,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; @@ -2143,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); } } @@ -2168,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; @@ -2298,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; @@ -2593,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)); @@ -2613,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, @@ -2656,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) @@ -2673,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) @@ -3181,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; } } @@ -3277,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; @@ -3300,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.) @@ -3325,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) {