diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index 3e5136fd4e..dd29a4182d 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -235,7 +235,7 @@ if [ "$TESTSUITE" ]; then configure_ovs export DISTCHECK_CONFIGURE_FLAGS="$OPTS" - if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \ + if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \ TESTSUITEFLAGS=-j4 RECHECK=yes; then # testsuite.log is necessary for debugging. cat */_build/sub/tests/testsuite.log diff --git a/Documentation/topics/dpdk/pmd.rst b/Documentation/topics/dpdk/pmd.rst index caa7d97bef..e481e79414 100644 --- a/Documentation/topics/dpdk/pmd.rst +++ b/Documentation/topics/dpdk/pmd.rst @@ -239,7 +239,9 @@ If not set, the default variance improvement threshold is 25%. PMD Auto Load Balancing doesn't currently work if queues are assigned cross NUMA as actual processing load could get worse after assignment - as compared to what dry run predicts. + as compared to what dry run predicts. The only exception is when all + PMD threads are running on cores from a single NUMA node. In this case + Auto Load Balancing is still possible. The minimum time between 2 consecutive PMD auto load balancing iterations can also be configured by:: diff --git a/Documentation/topics/dpdk/qos.rst b/Documentation/topics/dpdk/qos.rst index 103495415a..a98ec672fc 100644 --- a/Documentation/topics/dpdk/qos.rst +++ b/Documentation/topics/dpdk/qos.rst @@ -69,22 +69,24 @@ to prioritize certain traffic over others at a port level. For example, the following configuration will limit the traffic rate at a port level to a maximum of 2000 packets a second (64 bytes IPv4 packets). -100pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess -Information Rate). High priority traffic is routed to queue 10, which marks +1000pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess +Information Rate). CIR and EIR are measured in bytes without Ethernet header. +As a result, 1000pps means (64-byte - 14-byte) * 1000 = 50,000 in the +configuration below. High priority traffic is routed to queue 10, which marks all traffic as CIR, i.e. Green. All low priority traffic, queue 20, is marked as EIR, i.e. Yellow:: $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \ --id=@myqos create qos type=trtcm-policer \ - other-config:cir=52000 other-config:cbs=2048 \ - other-config:eir=52000 other-config:ebs=2048 \ + other-config:cir=50000 other-config:cbs=2048 \ + other-config:eir=50000 other-config:ebs=2048 \ queues:10=@dpdk1Q10 queues:20=@dpdk1Q20 -- \ --id=@dpdk1Q10 create queue \ - other-config:cir=41600000 other-config:cbs=2048 \ + other-config:cir=100000 other-config:cbs=2048 \ other-config:eir=0 other-config:ebs=0 -- \ --id=@dpdk1Q20 create queue \ other-config:cir=0 other-config:cbs=0 \ - other-config:eir=41600000 other-config:ebs=2048 \ + other-config:eir=50000 other-config:ebs=2048 This configuration accomplishes that the high priority traffic has a guaranteed bandwidth egressing the ports at CIR (1000pps), but it can also diff --git a/NEWS b/NEWS index bc901efdb1..036d4032c4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +v2.15.1 - xx xxx xxxx +--------------------- + - ovs-ctl: + * New option '--no-record-hostname' to disable hostname configuration + in ovsdb on startup. + * New command 'record-hostname-if-not-set' to update hostname in ovsdb. + + v2.15.0 - 15 Feb 2021 --------------------- - OVSDB: diff --git a/configure.ac b/configure.ac index fd82d7d270..9299342960 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ # limitations under the License. AC_PREREQ(2.63) -AC_INIT(openvswitch, 2.15.0, bugs@openvswitch.org) +AC_INIT(openvswitch, 2.15.1, bugs@openvswitch.org) AC_CONFIG_SRCDIR([datapath/datapath.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/debian/changelog b/debian/changelog index 1f2b7a3668..8b5d075840 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openvswitch (2.15.1-1) unstable; urgency=low + [ Open vSwitch team ] + * New upstream version + + -- Open vSwitch team Mon, 15 Feb 2021 17:35:33 +0100 + openvswitch (2.15.0-1) unstable; urgency=low * New upstream version diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 4381c618f1..251788b049 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -279,8 +279,9 @@ static bool dpcls_lookup(struct dpcls *cls, ( 1 << OFPMBT13_DROP ) struct dp_meter_band { - struct ofputil_meter_band up; /* type, prec_level, pad, rate, burst_size */ - uint32_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) */ + uint32_t rate; + uint32_t burst_size; + uint64_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) */ uint64_t packet_count; uint64_t byte_count; }; @@ -3834,6 +3835,15 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put) return error; } + if (match.wc.masks.in_port.odp_port != ODPP_NONE) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + + VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match", + (put->flags & DPIF_FP_CREATE) ? "[create]" + : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]"); + return EINVAL; + } + if (put->ufid) { ufid = *put->ufid; } else { @@ -4878,6 +4888,12 @@ struct rr_numa { bool idx_inc; }; +static size_t +rr_numa_list_count(struct rr_numa_list *rr) +{ + return hmap_count(&rr->numas); +} + static struct rr_numa * rr_numa_list_lookup(struct rr_numa_list *rr, int numa_id) { @@ -5590,10 +5606,17 @@ get_dry_run_variance(struct dp_netdev *dp, uint32_t *core_list, for (int i = 0; i < n_rxqs; i++) { int numa_id = netdev_get_numa_id(rxqs[i]->port->netdev); numa = rr_numa_list_lookup(&rr, numa_id); + /* If there is no available pmd on the local numa but there is only one + * numa for cross-numa polling, we can estimate the dry run. */ + if (!numa && rr_numa_list_count(&rr) == 1) { + numa = rr_numa_list_next(&rr, NULL); + } if (!numa) { - /* Abort if cross NUMA polling. */ - VLOG_DBG("PMD auto lb dry run." - " Aborting due to cross-numa polling."); + VLOG_DBG("PMD auto lb dry run: " + "There's no available (non-isolated) PMD thread on NUMA " + "node %d for port '%s' and there are PMD threads on more " + "than one NUMA node available for cross-NUMA polling. " + "Aborting.", numa_id, netdev_rxq_get_name(rxqs[i]->rx)); goto cleanup; } @@ -6203,12 +6226,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, /* Update all bands and find the one hit with the highest rate for each * packet (if any). */ for (int m = 0; m < meter->n_bands; ++m) { - band = &meter->bands[m]; + uint64_t max_bucket_size; + band = &meter->bands[m]; + max_bucket_size = (band->rate + band->burst_size) * 1000ULL; /* Update band's bucket. */ - band->bucket += delta_t * band->up.rate; - if (band->bucket > band->up.burst_size) { - band->bucket = band->up.burst_size; + band->bucket += (uint64_t) delta_t * band->rate; + if (band->bucket > max_bucket_size) { + band->bucket = max_bucket_size; } /* Drain the bucket for all the packets, if possible. */ @@ -6226,8 +6251,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, * (Only one band will be fired by a packet, and that * can be different for each packet.) */ for (int i = band_exceeded_pkt; i < cnt; i++) { - if (band->up.rate > exceeded_rate[i]) { - exceeded_rate[i] = band->up.rate; + if (band->rate > exceeded_rate[i]) { + exceeded_rate[i] = band->rate; exceeded_band[i] = m; } } @@ -6246,8 +6271,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, /* Update the exceeding band for the exceeding packet. * (Only one band will be fired by a packet, and that * can be different for each packet.) */ - if (band->up.rate > exceeded_rate[i]) { - exceeded_rate[i] = band->up.rate; + if (band->rate > exceeded_rate[i]) { + exceeded_rate[i] = band->rate; exceeded_band[i] = m; } } @@ -6329,16 +6354,15 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id, config->bands[i].burst_size = config->bands[i].rate; } - meter->bands[i].up = config->bands[i]; - /* Convert burst size to the bucket units: */ - /* pkts => 1/1000 packets, kilobits => bits. */ - meter->bands[i].up.burst_size *= 1000; - /* Initialize bucket to empty. */ - meter->bands[i].bucket = 0; + meter->bands[i].rate = config->bands[i].rate; + meter->bands[i].burst_size = config->bands[i].burst_size; + /* Start with a full bucket. */ + meter->bands[i].bucket = + (meter->bands[i].burst_size + meter->bands[i].rate) * 1000ULL; /* Figure out max delta_t that is enough to fill any bucket. */ band_max_delta_t - = meter->bands[i].up.burst_size / meter->bands[i].up.rate; + = meter->bands[i].bucket / meter->bands[i].rate; if (band_max_delta_t > meter->max_delta_t) { meter->max_delta_t = band_max_delta_t; } diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 6be23dbeed..15b25084b3 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -1255,21 +1255,21 @@ netdev_linux_batch_rxq_recv_sock(struct netdev_rxq_linux *rx, int mtu, * aux_buf is allocated so that it can be prepended to TSO buffer. */ std_len = virtio_net_hdr_size + VLAN_ETH_HEADER_LEN + mtu; for (i = 0; i < NETDEV_MAX_BURST; i++) { - buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM); - iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]); - iovs[i][IOV_PACKET].iov_len = std_len; - if (iovlen == IOV_TSO_SIZE) { - iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]); - iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]); - } + buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM); + iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]); + iovs[i][IOV_PACKET].iov_len = std_len; + if (iovlen == IOV_TSO_SIZE) { + iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]); + iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]); + } - mmsgs[i].msg_hdr.msg_name = NULL; - mmsgs[i].msg_hdr.msg_namelen = 0; - mmsgs[i].msg_hdr.msg_iov = iovs[i]; - mmsgs[i].msg_hdr.msg_iovlen = iovlen; - mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i]; - mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i]; - mmsgs[i].msg_hdr.msg_flags = 0; + mmsgs[i].msg_hdr.msg_name = NULL; + mmsgs[i].msg_hdr.msg_namelen = 0; + mmsgs[i].msg_hdr.msg_iov = iovs[i]; + mmsgs[i].msg_hdr.msg_iovlen = iovlen; + mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i]; + mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i]; + mmsgs[i].msg_hdr.msg_flags = 0; } do { diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index e2e829772a..0342a228b7 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -4431,6 +4431,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae, { struct ofpact_encap *encap; const struct ofp_ed_prop_header *ofp_prop; + const size_t encap_ofs = out->size; size_t props_len; uint16_t n_props = 0; int err; @@ -4458,6 +4459,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae, } n_props++; } + encap = ofpbuf_at_assert(out, encap_ofs, sizeof *encap); encap->n_props = n_props; out->header = &encap->ofpact; ofpact_finish_ENCAP(out, &encap); diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c index ff8adaefb5..6f9f912ac4 100644 --- a/lib/ovsdb-cs.c +++ b/lib/ovsdb-cs.c @@ -1367,7 +1367,7 @@ ovsdb_cs_send_transaction(struct ovsdb_cs *cs, struct json *operations) sizeof *cs->txns); } cs->txns[cs->n_txns++] = request_id; - return request_id; + return json_clone(request_id); } /* Makes 'cs' drop its record of transaction 'request_id'. If a reply arrives @@ -1380,6 +1380,7 @@ ovsdb_cs_forget_transaction(struct ovsdb_cs *cs, const struct json *request_id) { for (size_t i = 0; i < cs->n_txns; i++) { if (json_equal(request_id, cs->txns[i])) { + json_destroy(cs->txns[i]); cs->txns[i] = cs->txns[--cs->n_txns]; return true; } diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c index 9c5c633b41..fa8f6cd0e8 100644 --- a/ofproto/connmgr.c +++ b/ofproto/connmgr.c @@ -2140,7 +2140,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule, const struct rule_actions *old_actions) OVS_REQUIRES(ofproto_mutex) { - if (rule_is_hidden(rule)) { + if (!mgr || rule_is_hidden(rule)) { return; } @@ -2244,6 +2244,10 @@ ofmonitor_flush(struct connmgr *mgr) { struct ofconn *ofconn; + if (!mgr) { + return; + } + LIST_FOR_EACH (ofconn, connmgr_node, &mgr->conns) { struct rconn_packet_counter *counter = ofconn->monitor_counter; diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index 5fae46adfc..ccf97266c0 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -491,6 +491,11 @@ udpif_destroy(struct udpif *udpif) dpif_register_upcall_cb(udpif->dpif, NULL, udpif); for (int i = 0; i < N_UMAPS; i++) { + struct udpif_key *ukey; + + CMAP_FOR_EACH (ukey, cmap_node, &udpif->ukeys[i].cmap) { + ukey_delete__(ukey); + } cmap_destroy(&udpif->ukeys[i].cmap); ovs_mutex_destroy(&udpif->ukeys[i].mutex); } diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 72756eb1f2..ba28e36d78 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -1664,14 +1664,15 @@ static void do_needs_conversion(struct jsonrpc *rpc, const char *database_ OVS_UNUSED, int argc OVS_UNUSED, char *argv[]) { + const char *schema_file_name = argv[argc - 1]; struct ovsdb_schema *schema1; - check_ovsdb_error(ovsdb_schema_from_file(argv[0], &schema1)); + check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema1)); char *database = schema1->name; open_rpc(1, NEED_DATABASE, argc, argv, &rpc, &database); if (is_database_clustered(rpc, database)) { - ovsdb_schema_persist_ephemeral_columns(schema1, argv[0]); + ovsdb_schema_persist_ephemeral_columns(schema1, schema_file_name); } struct ovsdb_schema *schema2 = fetch_schema(rpc, schema1->name); diff --git a/ovsdb/raft.c b/ovsdb/raft.c index ea91d1fdba..192f7f0a96 100644 --- a/ovsdb/raft.c +++ b/ovsdb/raft.c @@ -940,6 +940,34 @@ raft_reset_ping_timer(struct raft *raft) raft->ping_timeout = time_msec() + raft->election_timer / 3; } +static void +raft_conn_update_probe_interval(struct raft *raft, struct raft_conn *r_conn) +{ + /* Inactivity probe will be sent if connection will remain idle for the + * time of an election timeout. Connection will be dropped if inactivity + * will last twice that time. + * + * It's not enough to just have heartbeats if connection is still + * established, but no packets received from the other side. Without + * inactivity probe follower will just try to initiate election + * indefinitely staying in 'candidate' role. And the leader will continue + * to send heartbeats to the dead connection thinking that remote server + * is still part of the cluster. */ + int probe_interval = raft->election_timer + ELECTION_RANGE_MSEC; + + jsonrpc_session_set_probe_interval(r_conn->js, probe_interval); +} + +static void +raft_update_probe_intervals(struct raft *raft) +{ + struct raft_conn *r_conn; + + LIST_FOR_EACH (r_conn, list_node, &raft->conns) { + raft_conn_update_probe_interval(raft, r_conn); + } +} + static void raft_add_conn(struct raft *raft, struct jsonrpc_session *js, const struct uuid *sid, bool incoming) @@ -954,7 +982,7 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js, &conn->sid); conn->incoming = incoming; conn->js_seqno = jsonrpc_session_get_seqno(conn->js); - jsonrpc_session_set_probe_interval(js, 0); + raft_conn_update_probe_interval(raft, conn); jsonrpc_session_set_backlog_threshold(js, raft->conn_backlog_max_n_msgs, raft->conn_backlog_max_n_bytes); } @@ -2804,6 +2832,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) raft->election_timer, e->election_timer); raft->election_timer = e->election_timer; raft->election_timer_new = 0; + raft_update_probe_intervals(raft); } if (e->servers) { /* raft_run_reconfigure() can write a new Raft entry, which can @@ -2820,6 +2849,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index) VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64, raft->election_timer, e->election_timer); raft->election_timer = e->election_timer; + raft_update_probe_intervals(raft); } } /* Check if any pending command can be completed, and complete it. @@ -4468,6 +4498,8 @@ raft_unixctl_status(struct unixctl_conn *conn, : raft->leaving ? "leaving cluster" : raft->left ? "left cluster" : raft->failed ? "failed" + : raft->candidate_retrying + ? "disconnected from the cluster (election timeout)" : "cluster member"); if (raft->joining) { ds_put_format(&s, "Remotes for joining:"); diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py index 5850ac7abf..4226d1cb2f 100644 --- a/python/ovs/db/idl.py +++ b/python/ovs/db/idl.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import collections import functools import uuid @@ -39,6 +40,10 @@ OVSDB_UPDATE2 = 1 CLUSTERED = "clustered" +Notice = collections.namedtuple('Notice', ('event', 'row', 'updates')) +Notice.__new__.__defaults__ = (None,) # default updates=None + + class Idl(object): """Open vSwitch Database Interface Definition Language (OVSDB IDL). @@ -614,6 +619,7 @@ class Idl(object): raise error.Error(" is not an object", table_updates) + notices = [] for table_name, table_update in table_updates.items(): table = tables.get(table_name) if not table: @@ -639,7 +645,9 @@ class Idl(object): % (table_name, uuid_string)) if version == OVSDB_UPDATE2: - if self.__process_update2(table, uuid, row_update): + changes = self.__process_update2(table, uuid, row_update) + if changes: + notices.append(changes) self.change_seqno += 1 continue @@ -652,17 +660,20 @@ class Idl(object): raise error.Error(' missing "old" and ' '"new" members', row_update) - if self.__process_update(table, uuid, old, new): + changes = self.__process_update(table, uuid, old, new) + if changes: + notices.append(changes) self.change_seqno += 1 + for notice in notices: + self.notify(*notice) def __process_update2(self, table, uuid, row_update): + """Returns Notice if a column changed, False otherwise.""" row = table.rows.get(uuid) - changed = False if "delete" in row_update: if row: del table.rows[uuid] - self.notify(ROW_DELETE, row) - changed = True + return Notice(ROW_DELETE, row) else: # XXX rate-limit vlog.warn("cannot delete missing row %s from table" @@ -681,29 +692,27 @@ class Idl(object): changed = self.__row_update(table, row, row_update) table.rows[uuid] = row if changed: - self.notify(ROW_CREATE, row) + return Notice(ROW_CREATE, row) elif "modify" in row_update: if not row: raise error.Error('Modify non-existing row') old_row = self.__apply_diff(table, row, row_update['modify']) - self.notify(ROW_UPDATE, row, Row(self, table, uuid, old_row)) - changed = True + return Notice(ROW_UPDATE, row, Row(self, table, uuid, old_row)) else: raise error.Error(' unknown operation', row_update) - return changed + return False def __process_update(self, table, uuid, old, new): - """Returns True if a column changed, False otherwise.""" + """Returns Notice if a column changed, False otherwise.""" row = table.rows.get(uuid) changed = False if not new: # Delete row. if row: del table.rows[uuid] - changed = True - self.notify(ROW_DELETE, row) + return Notice(ROW_DELETE, row) else: # XXX rate-limit vlog.warn("cannot delete missing row %s from table %s" @@ -723,7 +732,7 @@ class Idl(object): if op == ROW_CREATE: table.rows[uuid] = row if changed: - self.notify(ROW_CREATE, row) + return Notice(ROW_CREATE, row) else: op = ROW_UPDATE if not row: @@ -737,8 +746,8 @@ class Idl(object): if op == ROW_CREATE: table.rows[uuid] = row if changed: - self.notify(op, row, Row.from_json(self, table, uuid, old)) - return changed + return Notice(op, row, Row.from_json(self, table, uuid, old)) + return False def __check_server_db(self): """Returns True if this is a valid server database, False otherwise.""" diff --git a/tests/automake.mk b/tests/automake.mk index 677b99a6b4..fc80e027df 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -134,7 +134,8 @@ FUZZ_REGRESSION_TESTS = \ tests/fuzz-regression/ofp_print_fuzzer-5722747668791296 \ tests/fuzz-regression/ofp_print_fuzzer-6285128790704128 \ tests/fuzz-regression/ofp_print_fuzzer-6470117922701312 \ - tests/fuzz-regression/ofp_print_fuzzer-6502620041576448 + tests/fuzz-regression/ofp_print_fuzzer-6502620041576448 \ + tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 $(srcdir)/tests/fuzz-regression-list.at: tests/automake.mk $(AM_V_GEN)for name in $(FUZZ_REGRESSION_TESTS); do \ basename=`echo $$name | sed 's,^.*/,,'`; \ diff --git a/tests/daemon.at b/tests/daemon.at index a7982de381..39d9aa391e 100644 --- a/tests/daemon.at +++ b/tests/daemon.at @@ -218,11 +218,11 @@ OVS_WAIT_UNTIL([test -s ovsdb-server.pid]) OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep RUNNING > /dev/null 2>&1]) AT_CHECK([kill -0 `cat ovsdb-server.pid`], [0], [ignore]) AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs], [0], -[Open_vSwitch +[_Server ]) AT_CHECK([sc stop ovsdb-server], [0], [ignore]) OVS_WAIT_UNTIL([test ! -s ovsdb-server.pid]) -AT_CHECK([sc query ovsdb-server | grep STATE | grep STOPPED], [0], [ignore]) +OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep STOPPED > /dev/null 2>&1]) AT_CHECK([sc delete ovsdb-server], [0], [[[SC]] DeleteService SUCCESS ]) AT_CLEANUP diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at index 2862a3c9b9..d5765a6632 100644 --- a/tests/dpif-netdev.at +++ b/tests/dpif-netdev.at @@ -299,59 +299,61 @@ type=drop rate=1 burst_size=2 ]) ovs-appctl time/warp 5000 -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) +for i in `seq 1 7`; do + AT_CHECK( + [ovs-appctl netdev-dummy/receive p7 \ + 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) +done + +for i in `seq 1 5`; do + AT_CHECK( + [ovs-appctl netdev-dummy/receive p8 \ + 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) +done + sleep 1 # wait for forwarders process packets # Meter 1 is measuring packets, allowing one packet per second with -# bursts of one packet, so 4 out of 5 packets should hit the drop +# bursts of one packet, so 3 out of 5 packets should hit the drop # band. -# Meter 2 is measuring kbps, with burst size 2 (== 2000 bits). 4 packets -# (240 bytes == 1920 bits) pass, but the last packet should hit the drop band. +# Meter 2 is measuring kbps, with burst size 2 (== 3000 bits). 6 packets +# (360 bytes == 2880 bits) pass, but the last packet should hit the drop band. AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | strip_timers], [0], [dnl OFPST_METER reply (OF1.3) (xid=0x2): meter:1 flow_count:1 packet_in_count:5 byte_in_count:300 duration:0.0s bands: -0: packet_count:4 byte_count:240 +0: packet_count:3 byte_count:180 -meter:2 flow_count:1 packet_in_count:5 byte_in_count:300 duration:0.0s bands: +meter:2 flow_count:1 packet_in_count:7 byte_in_count:420 duration:0.0s bands: 0: packet_count:1 byte_count:60 ]) # Advance time by 1/2 second ovs-appctl time/warp 500 -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) -AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) +for i in `seq 1 5`; do + AT_CHECK( + [ovs-appctl netdev-dummy/receive p7 \ + 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) + + AT_CHECK( + [ovs-appctl netdev-dummy/receive p8 \ + 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60]) +done + sleep 1 # wait for forwarders process packets # Meter 1 is measuring packets, allowing one packet per second with # bursts of one packet, so all 5 of the new packets should hit the drop # band. -# Meter 2 is measuring kbps, with burst size 2 (== 2000 bits). After 500ms -# there should be space for 80 + 500 bits, so one new 60 byte (480 bit) packet +# Meter 2 is measuring kbps, with burst size 2 (== 3000 bits). After 500ms +# there should be space for 120 + 500 bits, so one new 60 byte (480 bit) packet # should pass, remaining 4 should hit the drop band. AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | strip_timers], [0], [dnl OFPST_METER reply (OF1.3) (xid=0x2): meter:1 flow_count:1 packet_in_count:10 byte_in_count:600 duration:0.0s bands: -0: packet_count:9 byte_count:540 +0: packet_count:8 byte_count:480 -meter:2 flow_count:1 packet_in_count:10 byte_in_count:600 duration:0.0s bands: +meter:2 flow_count:1 packet_in_count:12 byte_in_count:720 duration:0.0s bands: 0: packet_count:5 byte_count:300 ]) @@ -360,7 +362,7 @@ ovs-appctl time/warp 5000 AT_CHECK([ ovs-appctl coverage/read-counter datapath_drop_meter ], [0], [dnl -14 +13 ]) AT_CHECK([cat ovs-vswitchd.log | filter_flow_install | strip_xout_keep_actions], [0], [dnl @@ -589,3 +591,20 @@ arp,in_port=ANY,dl_vlan=11,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09: DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy]) DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy-pmd]) + +AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match]) +OVS_VSWITCHD_START( + [add-port br0 p1 \ + -- set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock \ + -- set bridge br0 datapath-type=dummy \ + other-config:datapath-id=1234 fail-mode=secure]) + +AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2], +[], [dnl +ovs-vswitchd: updating flow table (Invalid argument) +ovs-appctl: ovs-vswitchd: server returned an error +]) +OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" ovs-vswitchd.log]) +OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d +/failed to put/d"]) +AT_CLEANUP diff --git a/tests/fuzz-regression-list.at b/tests/fuzz-regression-list.at index e3173fb88f..2347c690ef 100644 --- a/tests/fuzz-regression-list.at +++ b/tests/fuzz-regression-list.at @@ -21,3 +21,4 @@ TEST_FUZZ_REGRESSION([ofp_print_fuzzer-5722747668791296]) TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6285128790704128]) TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6470117922701312]) TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6502620041576448]) +TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6540965472632832]) diff --git a/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 b/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 31064ed95e..24bbd884ca 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -2123,7 +2123,7 @@ AT_CHECK([ovs-appctl revalidator/purge]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log]) dnl Add a controller meter. -AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=controller pktps stats bands=type=drop rate=2']) +AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=controller pktps burst stats bands=type=drop rate=1 burst_size=1']) dnl Advance time by 1 second. AT_CHECK([ovs-appctl time/warp 1000], [0], [ignore]) diff --git a/tests/ovsdb-client.at b/tests/ovsdb-client.at index 8d777a0275..5e3b26aea8 100644 --- a/tests/ovsdb-client.at +++ b/tests/ovsdb-client.at @@ -12,6 +12,30 @@ AT_CHECK([ovsdb-client get-schema-cksum unix:socket ordinals], [0], [12345678 9 OVSDB_SERVER_SHUTDOWN AT_CLEANUP +AT_SETUP([ovsdb-client needs-conversion (no conversion needed)]) +AT_KEYWORDS([ovsdb client file positive]) +ordinal_schema > schema +touch .db.~lock~ +AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore]) +AT_CHECK([ovsdb-client needs-conversion unix:socket schema], [0], [no +]) +OVSDB_SERVER_SHUTDOWN +AT_CLEANUP + +AT_SETUP([ovsdb-client needs-conversion (conversion needed)]) +AT_KEYWORDS([ovsdb client file positive]) +ordinal_schema > schema +touch .db.~lock~ +AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore]) +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore]) +sed 's/5\.1\.3/5.1.4/' < schema > schema2 +AT_CHECK([diff schema schema2], [1], [ignore]) +AT_CHECK([ovsdb-client needs-conversion unix:socket schema2], [0], [yes +]) +OVSDB_SERVER_SHUTDOWN +AT_CLEANUP + AT_SETUP([ovsdb-client backup and restore]) AT_KEYWORDS([ovsdb client positive]) diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index 4b4791a7da..e00e67e949 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -1486,6 +1486,28 @@ m4_define([OVSDB_CHECK_IDL_NOTIFY], [OVSDB_CHECK_IDL_PY([$1], [], [$2], [$3], [notify $4], [$5]) OVSDB_CHECK_IDL_SSL_PY([$1], [], [$2], [$3], [notify $4], [$5])]) +OVSDB_CHECK_IDL_NOTIFY([simple link idl verify notify], + [['track-notify' \ + '["idltest", + {"op": "insert", + "table": "link1", + "row": {"i": 1, "k": ["named-uuid", "l1row"], "l2": ["set", [["named-uuid", "l2row"]]]}, + "uuid-name": "l1row"}, + {"op": "insert", + "table": "link2", + "uuid-name": "l2row", + "row": {"i": 2, "l1": ["set", [["named-uuid", "l1row"]]]}}]']], +[[000: empty +000: event:create, row={uuid=<0>}, updates=None +000: event:create, row={uuid=<1>}, updates=None +001: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]} +002: event:create, row={i=1 uuid=<2> l2=[<3>]}, updates=None +002: event:create, row={i=2 uuid=<3> l1=[<2>]}, updates=None +002: i=1 k=1 ka=[] l2=2 uuid=<2> +002: i=2 l1=1 uuid=<3> +003: done +]]) + OVSDB_CHECK_IDL_NOTIFY([simple idl verify notify], [['track-notify' \ '["idltest", diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py index a196802743..9d3228f234 100644 --- a/tests/test-ovsdb.py +++ b/tests/test-ovsdb.py @@ -162,6 +162,8 @@ def get_simple_printable_row_string(row, columns): if isinstance(value, dict): value = sorted((row_to_uuid(k), row_to_uuid(v)) for k, v in value.items()) + if isinstance(value, (list, tuple)): + value = sorted((row_to_uuid(v) for v in value)) s += "%s=%s " % (column, value) s = s.strip() s = re.sub('""|,|u?\'', "", s) @@ -172,9 +174,10 @@ def get_simple_printable_row_string(row, columns): return s -def get_simple_table_printable_row(row): +def get_simple_table_printable_row(row, *additional_columns): simple_columns = ["i", "r", "b", "s", "u", "ia", "ra", "ba", "sa", "ua", "uuid"] + simple_columns.extend(additional_columns) return get_simple_printable_row_string(row, simple_columns) @@ -637,7 +640,8 @@ def do_idl(schema_file, remote, *commands): def mock_notify(event, row, updates=None): output = "%03d: " % step output += "event:" + str(event) + ", row={" - output += get_simple_table_printable_row(row) + "}, updates=" + output += get_simple_table_printable_row(row, + 'l2', 'l1') + "}, updates=" if updates is None: output += "None" else: diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in index d71c34e691..4156da20ef 100644 --- a/utilities/ovs-ctl.in +++ b/utilities/ovs-ctl.in @@ -226,7 +226,9 @@ start_forwarding () { if test X"$OVS_VSWITCHD" = Xyes; then do_start_forwarding || return 1 fi - set_hostname & + if test X"$RECORD_HOSTNAME" = Xyes; then + set_hostname & + fi return 0 } @@ -317,6 +319,7 @@ set_defaults () { SYSTEM_ID= FULL_HOSTNAME=yes + RECORD_HOSTNAME=yes DELETE_BRIDGES=no DELETE_TRANSIENT_PORTS=no @@ -378,19 +381,24 @@ This program is intended to be invoked internally by Open vSwitch startup scripts. System administrators should not normally invoke it directly. Commands: - start start Open vSwitch daemons - stop stop Open vSwitch daemons - restart stop and start Open vSwitch daemons - status check whether Open vSwitch daemons are running - version print versions of Open vSwitch daemons - load-kmod insert modules if not already present - force-reload-kmod save OVS network device state, stop OVS, unload kernel - module, reload kernel module, start OVS, restore state - enable-protocol enable protocol specified in options with iptables - delete-transient-ports delete transient (other_config:transient=true) ports - start-ovs-ipsec start Open vSwitch ipsec daemon - stop-ovs-ipsec stop Open vSwitch ipsec daemon - help display this help message + start start Open vSwitch daemons + stop stop Open vSwitch daemons + restart stop and start Open vSwitch daemons + status check whether Open vSwitch daemons are running + version print versions of Open vSwitch daemons + load-kmod insert modules if not already present + force-reload-kmod save OVS network device state, stop OVS, unload + kernel module, reload kernel module, start OVS, + restore state + enable-protocol enable protocol specified in options with + iptables + delete-transient-ports delete transient (other_config:transient=true) + ports + start-ovs-ipsec start Open vSwitch ipsec daemon + stop-ovs-ipsec stop Open vSwitch ipsec daemon + record-hostname-if-not-set determine the system hostname and record it in + the Open vSwitch database if not already set + help display this help message One of the following options is required for "start", "restart" and "force-reload-kmod": --system-id=UUID set specific ID to uniquely identify this system @@ -411,6 +419,8 @@ Less important options for "start", "restart" and "force-reload-kmod": --ovsdb-server-priority=NICE set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY) --ovs-vswitchd-priority=NICE set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY) --no-full-hostname set short hostname instead of full hostname + --no-record-hostname do not attempt to determine/record system + hostname as part of start command Debugging options for "start", "restart" and "force-reload-kmod": --ovsdb-server-wrapper=WRAPPER @@ -569,6 +579,9 @@ case $command in stop-ovs-ipsec) stop_ovs_ipsec ;; + record-hostname-if-not-set) + set_hostname + ;; help) usage ;; diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index a2ad84edef..4597a215d9 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -4660,7 +4660,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ packets per second the CIR would be set to to to 46000000. This value can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing rate for the number of packets per second and 46 represents the size - of the packet data for a 64 byte ip packet. + of the packet data for a 64 bytes IP packet without 14 bytes Ethernet + and 4 bytes FCS header. The Committed Burst Size (CBS) is measured in bytes and represents a @@ -4681,7 +4682,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \ packets per second the EIR would be set to to to 46000000. This value can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing rate for the number of packets per second and 46 represents the size - of the packet data for a 64 byte ip packet. + of the packet data for a 64 bytes IP packet without 14 bytes Ethernet + and 4 bytes FCS header. The Excess Burst Size (EBS) is measured in bytes and represents a