[ovs-dev] Low-Cost Loans for SMEs & Investment Funding.
Dear My name is Nicholas Toms, an investment portfolio manager with ACLL . We offer the right loan Investment funding with low interest to finance your business or project ranging from US$1M to US$2BIllion. Kindly contact me for more details as I am open to questions. Sincerely, Nicholas Toms ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH] ofp-parse: Support "igmp" keyword in flows.
On 11/3/20 12:28 AM, Ben Pfaff wrote: > match_format() prints out "igmp" for IGMP flows, but > ofp_parse_protocol() didn't accept it, which meant that OVS would print > out a flow that it wouldn't re-parse. This fixes the problem and adds > a test. I'm a bit confused. IIUC, matching on igmp is not supported by any OF version or by any extensions, i.e. we could match by 'ip,nw_proto=2', but there is no special OF header for "igmp" or "igmp_type" or "igmp_code". While it seems easy to add parsing of "igmp" itself, its fields ("igmp_type" and "igmp_code") could appear in the output too and parsing of these fields will, I guess, require a new OF extension. Is it correct? If so, maybe it's better to remove "igmp*" printing code from the match_format() instead? Best regards, Ilya Maximets. > > Signed-off-by: Ben Pfaff > --- > lib/ofp-parse.c| 1 + > tests/ovs-ofctl.at | 2 ++ > 2 files changed, 3 insertions(+) > > diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c > index a90b926efb54..395a519f555f 100644 > --- a/lib/ofp-parse.c > +++ b/lib/ofp-parse.c > @@ -184,6 +184,7 @@ ofp_parse_protocol(const char *name, const struct > ofp_protocol **p_out) > { "ip4", ETH_TYPE_IP, 0 }, > { "arp", ETH_TYPE_ARP, 0 }, > { "icmp", ETH_TYPE_IP, IPPROTO_ICMP }, > +{ "igmp", ETH_TYPE_IP, IPPROTO_IGMP }, > { "tcp", ETH_TYPE_IP, IPPROTO_TCP }, > { "udp", ETH_TYPE_IP, IPPROTO_UDP }, > { "sctp", ETH_TYPE_IP, IPPROTO_SCTP }, > diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at > index b6951f404c45..05ba943d84d6 100644 > --- a/tests/ovs-ofctl.at > +++ b/tests/ovs-ofctl.at > @@ -191,6 +191,7 @@ actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note > ip,actions=set_field:10.4.3.77->ip_src,mod_nw_ecn:2 > sctp actions=drop > sctp actions=drop > +igmp actions=drop > in_port=0 actions=resubmit:0 > > actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) > > actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,ingress) > @@ -225,6 +226,7 @@ OFPT_FLOW_MOD: ADD > actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.0 > OFPT_FLOW_MOD: ADD ip actions=mod_nw_src:10.4.3.77,load:0x2->NXM_NX_IP_ECN[] > OFPT_FLOW_MOD: ADD sctp actions=drop > OFPT_FLOW_MOD: ADD sctp actions=drop > +OFPT_FLOW_MOD: ADD igmp actions=drop > OFPT_FLOW_MOD: ADD in_port=0 actions=resubmit:0 > OFPT_FLOW_MOD: ADD > actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) > OFPT_FLOW_MOD: ADD > actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,ingress) > ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH v1 ovn] northd: Enhance the implementation of ACL log meters.
When multiple ACL rows use the same Meter for log rate-limiting, the 'noisiest' ACL matches may completely consume the Meter and shadow other ACL logs. This patch introduces an option in NB_Global that allows for a Meter to rate-limit each ACL log separately. The change is backward compatible. Based on a well known option, northd will turn a single Meter in the NB into multiple Meters in the SB by appending the ACL uuid to its name. It will also make action in logical flow use the unique Meter name for each affected ACL log. In order to make the Meter behave as described, add this option: ovn-nbctl set nb_global . options:acl_shared_log_meters="${meter_name}" If more than one Meter is wanted, simply use a comma to separate each name. Reported-by: Flavio Fernandes Reported-at: https://mail.openvswitch.org/pipermail/ovs-discuss/2020-October/050769.html Signed-off-by: Flavio Fernandes --- TODO: I do not yet know the implications that this change have on the new ddlog based implementation of northd. Will read up and contact folks on that. northd/ovn-northd.c | 201 ovn-nb.xml | 14 +++ tests/ovn-northd.at | 99 ++ 3 files changed, 262 insertions(+), 52 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 8800a3d3c..721e7be97 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -5378,8 +5378,53 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) } } +static bool +is_a_shared_meter(const struct smap *nb_options, const char *meter_name) +{ +bool is_shared_meter = false; +const char *meters = smap_get(nb_options, "acl_shared_log_meters"); +if (meters && meters[0]) { +char *cur, *next, *start; +next = start = xstrdup(meters); +while ((cur = strsep(, ",")) && *cur) { +if (!strcmp(meter_name, cur)) { +is_shared_meter = true; +break; +} +} +free(start); +} +return is_shared_meter; +} + +static char* +alloc_acl_log_unique_meter_name(const struct nbrec_acl *acl) +{ +return xasprintf("%s__" UUID_FMT, + acl->meter, UUID_ARGS(>header_.uuid)); +} + +static void +build_acl_log_meter(struct ds *actions, const struct nbrec_acl *acl, +const struct smap *nb_options) +{ +if (!acl->meter) { +return; +} + +/* If ACL log meter uses a shared meter, use unique Meter name. */ +if (is_a_shared_meter(nb_options, acl->meter)) { +char *meter_name = alloc_acl_log_unique_meter_name(acl); +ds_put_format(actions, "meter=\"%s\", ", meter_name); +free(meter_name); +} else { +ds_put_format(actions, "meter=\"%s\", ", acl->meter); +} +} + static void -build_acl_log(struct ds *actions, const struct nbrec_acl *acl) +build_acl_log(struct ds *actions, const struct nbrec_acl *acl, + const struct smap *nb_options) { if (!acl->log) { return; @@ -5407,9 +5452,7 @@ build_acl_log(struct ds *actions, const struct nbrec_acl *acl) ds_put_cstr(actions, "verdict=allow, "); } -if (acl->meter) { -ds_put_format(actions, "meter=\"%s\", ", acl->meter); -} +build_acl_log_meter(actions, acl, nb_options); ds_chomp(actions, ' '); ds_chomp(actions, ','); @@ -5420,7 +5463,8 @@ static void build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, enum ovn_stage stage, struct nbrec_acl *acl, struct ds *extra_match, struct ds *extra_actions, - const struct ovsdb_idl_row *stage_hint) + const struct ovsdb_idl_row *stage_hint, + const struct smap *nb_options) { struct ds match = DS_EMPTY_INITIALIZER; struct ds actions = DS_EMPTY_INITIALIZER; @@ -5432,7 +5476,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, ingress ? ovn_stage_get_table(S_SWITCH_OUT_QOS_MARK) : ovn_stage_get_table(S_SWITCH_IN_L2_LKUP)); -build_acl_log(, acl); +build_acl_log(, acl, nb_options); if (extra_match->length > 0) { ds_put_format(, "(%s) && ", extra_match->string); } @@ -5457,7 +5501,8 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, static void consider_acl(struct hmap *lflows, struct ovn_datapath *od, - struct nbrec_acl *acl, bool has_stateful) + struct nbrec_acl *acl, bool has_stateful, + const struct smap *nb_options) { bool ingress = !strcmp(acl->direction, "from-lport") ? true :false; enum ovn_stage stage = ingress ? S_SWITCH_IN_ACL : S_SWITCH_OUT_ACL; @@ -5471,7 +5516,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, * associated conntrack entry and would return "+invalid". */ if (!has_stateful) { struct
Re: [ovs-dev] [PATCH net-next] openvswitch: Use IS_ERR instead of IS_ERR_OR_NULL
On Sat, 31 Oct 2020 14:01:53 +0800 YueHaibing wrote: > Fix smatch warning: > > net/openvswitch/meter.c:427 ovs_meter_cmd_set() warn: passing zero to > 'PTR_ERR' > > dp_meter_create() never returns NULL, use IS_ERR > instead of IS_ERR_OR_NULL to fix this. > > Signed-off-by: YueHaibing Applied, thanks! ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH] ofp-parse: Support "igmp" keyword in flows.
match_format() prints out "igmp" for IGMP flows, but ofp_parse_protocol() didn't accept it, which meant that OVS would print out a flow that it wouldn't re-parse. This fixes the problem and adds a test. Signed-off-by: Ben Pfaff --- lib/ofp-parse.c| 1 + tests/ovs-ofctl.at | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index a90b926efb54..395a519f555f 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -184,6 +184,7 @@ ofp_parse_protocol(const char *name, const struct ofp_protocol **p_out) { "ip4", ETH_TYPE_IP, 0 }, { "arp", ETH_TYPE_ARP, 0 }, { "icmp", ETH_TYPE_IP, IPPROTO_ICMP }, +{ "igmp", ETH_TYPE_IP, IPPROTO_IGMP }, { "tcp", ETH_TYPE_IP, IPPROTO_TCP }, { "udp", ETH_TYPE_IP, IPPROTO_UDP }, { "sctp", ETH_TYPE_IP, IPPROTO_SCTP }, diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index b6951f404c45..05ba943d84d6 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -191,6 +191,7 @@ actions=note:41.42.43,note:00.01.02.03.04.05.06.07,note ip,actions=set_field:10.4.3.77->ip_src,mod_nw_ecn:2 sctp actions=drop sctp actions=drop +igmp actions=drop in_port=0 actions=resubmit:0 actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,ingress) @@ -225,6 +226,7 @@ OFPT_FLOW_MOD: ADD actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.0 OFPT_FLOW_MOD: ADD ip actions=mod_nw_src:10.4.3.77,load:0x2->NXM_NX_IP_ECN[] OFPT_FLOW_MOD: ADD sctp actions=drop OFPT_FLOW_MOD: ADD sctp actions=drop +OFPT_FLOW_MOD: ADD igmp actions=drop OFPT_FLOW_MOD: ADD in_port=0 actions=resubmit:0 OFPT_FLOW_MOD: ADD actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678) OFPT_FLOW_MOD: ADD actions=sample(probability=12345,collector_set_id=23456,obs_domain_id=34567,obs_point_id=45678,ingress) -- 2.26.2 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH] ovsdb-idl: Add comment with program name to ovsdb_idl_loop transactions.
On Wed, Oct 28, 2020 at 10:49:32AM +0100, Dumitru Ceara wrote: > On 10/26/20 6:56 PM, Ben Pfaff wrote: > > This can make it easier to see what daemon is committing transactions. > > Sometimes, in OVN especially, it can be hard to guess. > > > > Signed-off-by: Ben Pfaff > > --- > > lib/ovsdb-idl.c | 3 +++ > > 1 file changed, 3 insertions(+) > > > > diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c > > index d8f221ca6073..fdb9d85f5ccc 100644 > > --- a/lib/ovsdb-idl.c > > +++ b/lib/ovsdb-idl.c > > @@ -5521,6 +5521,9 @@ ovsdb_idl_loop_run(struct ovsdb_idl_loop *loop) > >|| ovsdb_idl_get_seqno(loop->idl) == loop->skip_seqno > >? NULL > >: ovsdb_idl_txn_create(loop->idl)); > > +if (loop->open_txn) { > > +ovsdb_idl_txn_add_comment(loop->open_txn, "%s", program_name); > > +} > > return loop->open_txn; > > } > > > > > > Looks good to me, thanks! > > Once this is applied, we should probably remove the explicit program name we > pass to ovsdb_idl_txn_add_comment() in some places in OVN but that's a > different story I guess. > > Acked-by: Dumitru Ceara Thanks! I applied this to master. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH v11 ovn] Allow to run multiple controllers on the same machine
User stories: 1) NFV: an admin wants to run two separate instances of OVN controller using the same database but configuring ports on different bridges. Some of these bridges may use DPDK while others may not. 2) Parallel OVN instances: an admin wants to run two separate instances of OVN controller using different databases. The instances are completely independent and serve different consumers. For example, the same machine runs both OpenStack and OpenShift stacks, each running its own separate OVN stack. To serve these use cases, several features should be added to ovn-controller: - use different database configuration for multiple controllers; - customize chassis name used by controller. = For each of the following database configuration options, their extended chassis specific counterparts are introduced: external_ids:hostname external_ids:ovn-bridge external_ids:ovn-bridge-datapath-type external_ids:ovn-bridge-mappings external_ids:ovn-chassis-mac-mappings external_ids:ovn-cms-options external_ids:ovn-encap-csum external_ids:ovn-encap-ip external_ids:ovn-encap-type external_ids:ovn-is-interconn external_ids:ovn-monitor-all external_ids:ovn-openflow-probe-interval external_ids:ovn-remote external_ids:ovn-remote-probe-interval For example, external_ids:ovn-bridge -> external_ids:ovn-bridge-= external_ids:ovn-encap-ip -> external_ids:ovn-encap-ip-= external_ids:ovn-remote -> external_ids:ovn-remote-= Priority wise, specific options take precedence. = For system-id, You can now pass intended chassis name via CLI argument: $ ovn-controller ... -n Alternatively, you can configure a chassis name by putting it into the ${ovn_sysconfdir}/system-id-override file before running the controller. The latter option may be more useful in container environment where the same image may be reused for multiple controller instances, where ovs_sysconfigdir/ovn/system-id-override is a volume mounted into this generic image. The override file is read once on startup. If you want to apply a new chassis name to a controller instance, restart it to reread the file. Priority wise, this is the order in which different means to configure the chassis name are used: - ovn-controller ... -n CLI argument. - ${ovs_sysconfdir}/ovn/system-id-override file; - external_ids:system-id= ovsdb option; = Concurrent chassis running on the same host may inadvertantly remove patch ports that belong to their peer chassis. To avoid that, patch ports are now tagged in external-ids:ovn-chassis-id with the appropriate chassis name, and only patch ports that belong to the chassis are touched when cleaning up. Also, now only tunnels on the active integration bridge are being cleaned up. Note that external-ids:ovn-chassis-id key is already used for tunnel ports to identify the remote tunnel endpoint. We can reuse the same key for patch ports because the key usage is not overlapping. Alternatively, we could introduce a new key with a similar but different name. This would simplify code changes needed but would arguably introduce even more confusion. Since the key name is not entirely self-descriptive for tunnel ports (a better name would be e.g. ovn-remote-chassis or ovn-peer-chassis), the ideal scenario would be to rename the key for tunnel endpoints but reuse it for patch ports. This would involve additional migration steps and is probably not worth the hassle. = This patch also expands tunnel port name to allow for long similar chassis names used on the same host. = Note: this patch assumes that each chassis has its own unique IP. Future work may consider adding support to specify custom port numbers for tunneling that would allow to reuse the same IP address for multiple chassis running on the same host. This work is out of scope for this patch. Signed-off-by: Ihar Hrachyshka --- v1: initial implementation. v2: fixed test case to check ports are claimed by proper chassis. v2: added NEWS entry. v2: fixed some compiler warnings. v2: moved file_system_id declaration inside a function that uses it. v2: removed unneeded binding.h #include. v2: docs: better explanation of alternatives to select chassis name. v3: reverted priority order for chassis configuration: first CLI, then system-id file, then ovsdb. v4: introduce helpers to extract external-ids (per-chassis or global). v4: introduce per-chassis config options for all keys. v4: introduce -M (--concurrent) CLI argument to avoid patch ports removed by concurrent chassis. v5: rebased. v6: switched from -M (--concurrent) to external-ids:ovn-is-concurrent. v6: with ovn-is-concurrent=true, also avoid removing unknown tunnel endpoints. v7: don't clean up tunnel endpoints from other bridges. v7: don't clean up patch ports that don't belong to the chassis. v7: remove ovn-is-concurrent that is no longer needed. v7: rebased. v8: rename system-id -> /etc/ovn/system-id-override v8: read the system-id-override file just once on
Re: [ovs-dev] [PATCH ovn 01/16] tests: Drop support for glibc before version 2.11.
On Mon, Nov 02, 2020 at 12:59:18PM +0530, Numan Siddique wrote: > On Fri, Oct 30, 2020 at 5:55 AM Ben Pfaff wrote: > > > > The "ldd" call here didn't work if libtool was involved and would print > > an error message. We could fix that, but the check is only needed for > > glibc earlier than 2.11. glibc 2.11 was released in 2009, so it should > > be safe to expect that testers are running it or a newer version. > > > > Signed-off-by: Ben Pfaff > > Hi Ben, > > Thanks for this series which improves and fixes a lot of test code in OVN. > > For the entire series: > Acked-by: Numan Siddique Thanks a lot! I applied this to ovn master. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH dpdk-latest v4] dpdk: Support running PMD threads on any core.
On Mon, Nov 2, 2020 at 3:40 PM Aaron Conole wrote: > > diff --git a/lib/dpdk.c b/lib/dpdk.c > > index 319540394b..7d3c0637c9 100644 > > --- a/lib/dpdk.c > > +++ b/lib/dpdk.c > > @@ -14,6 +14,10 @@ > > * limitations under the License. > > */ > > > > +#ifndef ALLOW_EXPERIMENTAL_API > > +#define ALLOW_EXPERIMENTAL_API > > +#endif > > + > > We already have a #define for this in netdev-dpdk.c, maybe we should > follow that (and also, possibly combine them). > > Just a quick nit. - In the dpdk-latest branch, there is no trace of ALLOW_EXPERIMENTAL_API since: https://github.com/openvswitch/ovs/commit/0730d7786a40d80a45c8d587ebfdd92ceb4b689d On the why the check on already defined ALLOW_EXPERIMENTAL_API, this is because I added a job with it enabled to catch potential build issues. - About combining (I'd say dpdk.h would be the best location), I am not sure. I like turning this knob on only when needed. -- David Marchand ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH net] net: openvswitch: silence suspicious RCU usage warning
On Mon, 02 Nov 2020 09:52:19 +0100 Eelco Chaudron wrote: > On 30 Oct 2020, at 22:28, Jakub Kicinski wrote: > >> @@ -1695,6 +1695,9 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, > >> struct genl_info *info) > >>if (err) > >>goto err_destroy_ports; > >> > >> + /* So far only local changes have been made, now need the lock. */ > >> + ovs_lock(); > > > > Should we move the lock below assignments to param? > > > > Looks a little strange to protect stack variables with a global lock. > > You are right, I should have moved it down after the assignment. I will > send out a v2. > > > Let's update the name of the label. > > Guess now it is, unlock and destroy meters, so what label are you > looking for? > > err_unlock_and_destroy_meters: which looks a bit long, or just > err_unlock: I feel like I saw some names like err_unlock_and_destroy_meters in OvS code, but can't find them in this file right now. I'd personally go for kist err_unlock, or maybe err_unlock_ovs as is used in other functions in this file. But as long as it starts with err_unlock it's fine by me :) ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] Finiquitos y liquidaciones
Webinar en Vivo: Finiquitos y liquidaciones. Miércoles 11 de Noviembre- Horario de 10:00 a 17:00 Hrs. Desarrollar de una forma dinámica y fácil los aspectos a considerar para el cálculo de los finiquitos y liquidaciones, mediante el estudio del marco jurídico y el desarrollo de casos prácticos. Objetivos Específicos: - Estudiará del marco legal de los finiquitos y liquidaciones. - Proporcionará una guía básica para el cálculo de los finiquitos y las liquidaciones. - Desarrollará de casos prácticos que ejemplifiquen los diferentes escenarios en el calculo de finiquitos y liquidaciones. Este curso va dirigido a los Contadores Públicos, auxiliares contables y cualquier persona que quiera conocer los puntos clave del cálculo de liquidaciones e indemnizaciones. Para mayor información, responder sobre este correo con la palabra Finiquitos + los siguientes datos: NOMBRE: TELÉFONO: EMPRESA: CORREO ALTERNO: Para información inmediata llamar al: (+52) 55 15 54 66 30 - (+52) 55 30 16 70 85 O puede enviarnos un mensaje vía whatsapp Innova Learn México - innovalearn. mx - Mérida, Yucatán, México ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH v4 0/5] XDP offload using flow API provider
On 2020/11/02 18:37, Numan Siddique wrote: On Fri, Oct 30, 2020 at 10:49 AM Toshiaki Makita wrote: Hi all, It's about 3 months since I submitted this patch set. Could someone review this? Or should I resubmit the patch set on the top of current master? Since the patches don't apply cleanly, I think you can rebase and repost them and/or provide the ovs commit id on top of which these patches apply cleanly. Hi Numan, Thank you for the advice! The patches are based on top of commit e8bf77748 ("odp-util: Fix clearing match mask if set action is partially unnecessary."). Actually I provided this information at the bottom of the cover letter. Also you can pull the changes from https://github.com/tmakita/ovs.git (xdp_offload_v4 branch). Thanks, Toshiaki Makita On 2020/08/15 10:54, Toshiaki Makita wrote: Ping. Any feedback is welcome. Thanks, Toshiaki Makita On 2020/07/31 11:55, Toshiaki Makita wrote: This patch adds an XDP-based flow cache using the OVS netdev-offload flow API provider. When an OVS device with XDP offload enabled, packets first are processed in the XDP flow cache (with parse, and table lookup implemented in eBPF) and if hits, the action processing are also done in the context of XDP, which has the minimum overhead. This provider is based on top of William's recently posted patch for custom XDP load. When a custom XDP is loaded, the provider detects if the program supports classifier, and if supported it starts offloading flows to the XDP program. The patches are derived from xdp_flow[1], which is a mechanism similar to this but implemented in kernel. * Motivation While userspace datapath using netdev-afxdp or netdev-dpdk shows good performance, there are use cases where packets better to be processed in kernel, for example, TCP/IP connections, or container to container connections. Current solution is to use tap device or af_packet with extra kernel-to/from-userspace overhead. But with XDP, a better solution is to steer packets earlier in the XDP program, and decides to send to userspace datapath or stay in kernel. One problem with current netdev-afxdp is that it forwards all packets to userspace, The first patch from William (netdev-afxdp: Enable loading XDP program.) only provides the interface to load XDP program, howerver users usually don't know how to write their own XDP program. XDP also supports HW-offload so it may be possible to offload flows to HW through this provider in the future, although not currently. The reason is that map-in-map is required for our program to support classifier with subtables in XDP, but map-in-map is not offloadable. If map-in-map becomes offloadable, HW-offload of our program may also be possible. * How to use 1. Install clang/llvm >= 9, libbpf >= 0.0.6 (included in kernel 5.5), and kernel >= 5.3. 2. make with --enable-afxdp --enable-xdp-offload --enable-bpf will generate XDP program "bpf/flowtable_afxdp.o". Note that the BPF object will not be installed anywhere by "make install" at this point. 3. Load custom XDP program E.g. $ ovs-vsctl add-port ovsbr0 veth0 -- set int veth0 options:xdp-mode=native \ options:xdp-obj="/path/to/ovs/bpf/flowtable_afxdp.o" $ ovs-vsctl add-port ovsbr0 veth1 -- set int veth1 options:xdp-mode=native \ options:xdp-obj="/path/to/ovs/bpf/flowtable_afxdp.o" 4. Enable XDP_REDIRECT If you use veth devices, make sure to load some (possibly dummy) programs on the peers of veth devices. This patch set includes a program which does nothing but returns XDP_PASS. You can use it for the veth peer like this: $ ip link set veth1 xdpdrv object /path/to/ovs/bpf/xdp_noop.o section xdp Some HW NIC drivers require as many queues as cores on its system. Tweak queues using "ethtool -L". 5. Enable hw-offload $ ovs-vsctl set Open_vSwitch . other_config:offload-driver=linux_xdp $ ovs-vsctl set Open_vSwitch . other_config:hw-offload=true This will starts offloading flows to the XDP program. You should be able to see some maps installed, including "debug_stats". $ bpftool map If packets are successfully redirected by the XDP program, debug_stats[2] will be counted. $ bpftool map dump id Currently only very limited keys and output actions are supported. For example NORMAL action entry and IP based matching work with current key support. VLAN actions used by port tag/trunks are also supported. * Performance Tested 2 cases. 1) i40e to veth, 2) i40e to i40e. Test 1 Measured drop rate at veth interface with redirect action from physical interface (i40e 25G NIC, XXV 710) to veth. The CPU is Xeon Silver 4114 (2.20 GHz). XDP_DROP +--+ +---++---+ pktgen -- wire --> | eth0 | -- NORMAL ACTION --> | veth0 || veth2 | +--+ +---++---+ Test 2 uses i40e instead of veth, and measured tx packet rate at output device.
Re: [ovs-dev] [PATCH dpdk-latest v4] dpdk: Support running PMD threads on any core.
David Marchand writes: > DPDK 20.08 introduced a new API that associates a non-EAL thread to a free > lcore. This new API does not change the thread characteristics (like CPU > affinity). > Using this new API, there is no assumption on lcore X running on cpu X > anymore which leaves OVS free from running its PMD thread on any cpu. > > DPDK still limits the number of lcores to RTE_MAX_LCORE (128 on x86_64) > which should be enough for OVS pmd threads (hopefully). > > DPDK lcore/OVS pmd threads mapping are logged at threads creation and > destruction. > A new command is added to help get DPDK point of view of the DPDK lcores: > > $ ovs-appctl dpdk/lcores-list > lcore 0, socket 0, role RTE, cpuset 0 > lcore 1, socket 0, role NON_EAL, cpuset 1 > lcore 2, socket 0, role NON_EAL, cpuset 15 > > Signed-off-by: David Marchand > --- > Changes since v3: > - rebased on current HEAD, > - switched back to simple warning rather than abort when registering a > thread fails, > > Changes since v2: > - introduced a new api in DPDK 20.08 (still being discussed), inbox thread at > > http://inbox.dpdk.org/dev/20200610144506.30505-1-david.march...@redhat.com/T/#t > - this current patch depends on a patch on master I sent: > > https://patchwork.ozlabs.org/project/openvswitch/patch/20200626122738.28163-1-david.march...@redhat.com/ > - dropped 'dpdk-lcore-mask' compat handling, > > Changes since v1: > - rewired existing configuration 'dpdk-lcore-mask' to use --lcores, > - switched to a bitmap to track lcores, > - added a command to dump current mapping (Flavio): used an experimental > API to get DPDK lcores cpuset since it is the most reliable/portable > information, > - used the same code for the logs when starting DPDK/PMD threads, > - addressed Ilya comments, > > --- > lib/dpdk-stub.c | 8 +++- > lib/dpdk.c| 36 ++-- > lib/dpdk.h| 3 ++- > lib/dpif-netdev.c | 3 ++- > 4 files changed, 45 insertions(+), 5 deletions(-) > > diff --git a/lib/dpdk-stub.c b/lib/dpdk-stub.c > index b7d577870d..5bc996b665 100644 > --- a/lib/dpdk-stub.c > +++ b/lib/dpdk-stub.c > @@ -39,7 +39,13 @@ dpdk_init(const struct smap *ovs_other_config) > } > > void > -dpdk_set_lcore_id(unsigned cpu OVS_UNUSED) > +dpdk_init_thread_context(unsigned cpu OVS_UNUSED) > +{ > +/* Nothing */ > +} > + > +void > +dpdk_uninit_thread_context(void) > { > /* Nothing */ > } > diff --git a/lib/dpdk.c b/lib/dpdk.c > index 319540394b..7d3c0637c9 100644 > --- a/lib/dpdk.c > +++ b/lib/dpdk.c > @@ -14,6 +14,10 @@ > * limitations under the License. > */ > > +#ifndef ALLOW_EXPERIMENTAL_API > +#define ALLOW_EXPERIMENTAL_API > +#endif > + We already have a #define for this in netdev-dpdk.c, maybe we should follow that (and also, possibly combine them). Just a quick nit. > #include > #include "dpdk.h" > > @@ -525,6 +529,8 @@ dpdk_init__(const struct smap *ovs_other_config) > dpdk_unixctl_mem_stream, rte_log_dump); > unixctl_command_register("dpdk/log-set", "{level | pattern:level}", 0, > INT_MAX, dpdk_unixctl_log_set, NULL); > +unixctl_command_register("dpdk/lcores-list", "", 0, 0, > + dpdk_unixctl_mem_stream, rte_lcore_dump); > > /* We are called from the main thread here */ > RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID; > @@ -601,11 +607,37 @@ dpdk_available(void) > } > > void > -dpdk_set_lcore_id(unsigned cpu) > +dpdk_init_thread_context(unsigned cpu) > { > /* NON_PMD_CORE_ID is reserved for use by non pmd threads. */ > ovs_assert(cpu != NON_PMD_CORE_ID); > -RTE_PER_LCORE(_lcore_id) = cpu; > + > +if (!dpdk_available()) { > +return; > +} > + > +if (rte_thread_register() < 0) { > +VLOG_WARN("This OVS pmd thread will share resources with the non-pmd > " > + "thread: %s.", rte_strerror(rte_errno)); > +} else { > +VLOG_INFO("PMD thread uses DPDK lcore %u.", rte_lcore_id()); > +} > +} > + > +void > +dpdk_uninit_thread_context(void) > +{ > +unsigned int lcore_id; > + > +if (!dpdk_available()) { > +return; > +} > + > +lcore_id = rte_lcore_id(); > +rte_thread_unregister(); > +if (lcore_id != LCORE_ID_ANY) { > +VLOG_INFO("PMD thread released DPDK lcore %u.", lcore_id); > +} > } > > void > diff --git a/lib/dpdk.h b/lib/dpdk.h > index 445a51d065..1bd16b31db 100644 > --- a/lib/dpdk.h > +++ b/lib/dpdk.h > @@ -36,7 +36,8 @@ struct smap; > struct ovsrec_open_vswitch; > > void dpdk_init(const struct smap *ovs_other_config); > -void dpdk_set_lcore_id(unsigned cpu); > +void dpdk_init_thread_context(unsigned cpu); > +void dpdk_uninit_thread_context(void); > const char *dpdk_get_vhost_sock_dir(void); > bool dpdk_vhost_iommu_enabled(void); > bool dpdk_vhost_postcopy_enabled(void); > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c > index 300861ca59..da9e1e8fcf
[ovs-dev] Ahoj,
Ahoj, ako sa dnes máš? dostali ste moju správu, pretože som stále čakám na vašu odpoveď ďakujem. ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [RFC PATCH ovn v3 3/3] Add ipam unit tests
This adds unit tests for IPAM IPv6 initialization, IPv4 initialization, and IPv4 address retrieval. It also adds testsuite tests corresponding to these unit tests. The IPv6 initialization and IPv4 initialization tests make use of the new unit test framework. They use ovn-appctl to get access to internal functions in northd/ipam.c. They require ENABLE_UNIT_TESTS to be defined, otherwise the internal unit test code will not be compiled in. The IPv4 address retrieval test makes use of the pre-existing ovstest utility. Signed-off-by: Mark Michelson --- northd/ipam.c | 56 ++ northd/ovn-northd.c | 3 + tests/automake.mk | 8 +- tests/ovn-unit-tests.at | 237 tests/testsuite.at | 1 + 5 files changed, 303 insertions(+), 2 deletions(-) create mode 100644 tests/ovn-unit-tests.at diff --git a/northd/ipam.c b/northd/ipam.c index e5383c46f..fb367700b 100644 --- a/northd/ipam.c +++ b/northd/ipam.c @@ -326,3 +326,59 @@ ipam_get_unused_mac(ovs_be32 ip) return mac64; } + +#ifdef ENABLE_UNIT_TESTS + +static void +test_init_ipam_ipv6_prefix(struct ovs_cmdl_context *ctx) +{ +const char *prefix = ctx->argc > 1 ? ctx->argv[1] : NULL; +struct ipam_info ipam; +struct ds *output = ctx->pvt; + +init_ipam_ipv6_prefix(prefix, ); +ds_put_format(output, "ipv6_prefix_set: %s\n", + ipam.ipv6_prefix_set ? "true" : "false"); +if (ipam.ipv6_prefix_set) { +char ipv6[INET6_ADDRSTRLEN]; +inet_ntop(AF_INET6, _prefix, + ipv6, sizeof ipv6); +ds_put_format(output, "ipv6_prefix: %s\n", ipv6); +} +} + +UNIT_TEST_DEFINE(init_ipam_ipv6_prefix, 0, 1, test_init_ipam_ipv6_prefix); + +static void +test_init_ipam_ipv4(struct ovs_cmdl_context *ctx) +{ +const char *subnet = ctx->argv[1]; +const char *exclude_ips = ctx->argc > 2 ? ctx->argv[2] : NULL; +struct ipam_info info; + +init_ipam_ipv4(subnet, exclude_ips, ); +struct ds *output = ctx->pvt; + +ds_put_format(output, "start_ipv4: " IP_FMT "\n", + IP_ARGS(htonl(info.start_ipv4))); +ds_put_format(output, "total_ipv4s: %" PRIuSIZE "\n", info.total_ipv4s); + +ds_put_cstr(output, "allocated_ipv4s: "); +if (info.allocated_ipv4s) { +int start = 0; +int end = info.total_ipv4s; +for (size_t bit = bitmap_scan(info.allocated_ipv4s, true, start, end); + bit != end; + bit = bitmap_scan(info.allocated_ipv4s, true, bit + 1, end)) { +ds_put_format(output, IP_FMT " ", + IP_ARGS((htonl(info.start_ipv4 + bit; +} +} +ds_chomp(output, ' '); +ds_put_char(output, '\n'); +destroy_ipam_info(); +} + +UNIT_TEST_DEFINE(init_ipam_ipv4, 1, 2, test_init_ipam_ipv4); + +#endif /* ENABLE_UNIT_TESTS */ diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 0fb7d0969..41c5df49e 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -36,6 +36,7 @@ #include "lib/ovn-nb-idl.h" #include "lib/ovn-sb-idl.h" #include "lib/ovn-util.h" +#include "lib/unit-test.h" #include "ovn/actions.h" #include "ovn/logical-fields.h" #include "packets.h" @@ -12742,6 +12743,8 @@ main(int argc, char *argv[]) cluster_state_reset_cmd, _ovnnb_idl_min_index); +register_unixctl_unit_test(); + daemonize_complete(); /* We want to detect (almost) all changes to the ovn-nb db. */ diff --git a/tests/automake.mk b/tests/automake.mk index 26b6d11b4..782af79b9 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -30,7 +30,8 @@ TESTSUITE_AT = \ tests/ovn-controller-vtep.at \ tests/ovn-ic.at \ tests/ovn-macros.at \ - tests/ovn-performance.at + tests/ovn-performance.at \ + tests/ovn-unit-tests.at SYSTEM_KMOD_TESTSUITE_AT = \ tests/system-common-macros.at \ @@ -200,7 +201,10 @@ noinst_PROGRAMS += tests/ovstest tests_ovstest_SOURCES = \ tests/ovstest.c \ tests/ovstest.h \ - tests/test-ovn.c + tests/test-ovn.c \ + northd/test-ipam.c \ + northd/ipam.c \ + northd/ipmam.h tests_ovstest_LDADD = $(OVS_LIBDIR)/daemon.lo \ $(OVS_LIBDIR)/libopenvswitch.la lib/libovn.la diff --git a/tests/ovn-unit-tests.at b/tests/ovn-unit-tests.at new file mode 100644 index 0..50fc53745 --- /dev/null +++ b/tests/ovn-unit-tests.at @@ -0,0 +1,237 @@ +AT_BANNER([OVN unit tests]) + +AT_SETUP([ovn -- unit test -- init_ipam_ipv4]) +AT_SKIP_IF([test "$ENABLE_UNIT_TESTS" = no]) +ovn_start + +# Valid subnet, no exclude IPs +AT_CHECK([ovn-appctl -t northd/ovn-northd unit-test init_ipam_ipv4 192.168.0.0/29], [0], [dnl +start_ipv4: 192.168.0.1 +total_ipv4s: 7 +allocated_ipv4s: 192.168.0.1 +]) + +# Valid subnet, single exclude IP +AT_CHECK([ovn-appctl -t northd/ovn-northd unit-test init_ipam_ipv4 192.168.0.0/29 192.168.0.3], [0], [dnl +start_ipv4: 192.168.0.1
[ovs-dev] [RFC PATCH ovn v3 2/3] northd: refactor and split some IPAM functions
This refactor focuses on three efforts: * Break a large function into smaller functions * Pass more specific data types to functions * Isolate these functions in their own code unit Smaller functions have clearer purposes, have fewer chances of unwanted side effects, and are easier to test. The next commit in this series will add some unit tests that exercise the new functions created in this commit. Note that this is not a full refactor of IPAM. Dynamic address assignment is complicated and currently tightly coupled with datapath and port constructs. A refactor of that section of IPAM is difficult enough that it should have its own patch series separate from this one that focuses mostly on unit tests. Signed-off-by: Mark Michelson --- northd/automake.mk | 5 +- northd/ipam.c | 328 northd/ipam.h | 37 + northd/ovn-northd.c | 285 +++--- 4 files changed, 389 insertions(+), 266 deletions(-) create mode 100644 northd/ipam.c create mode 100644 northd/ipam.h diff --git a/northd/automake.mk b/northd/automake.mk index 69657e77e..3340178f5 100644 --- a/northd/automake.mk +++ b/northd/automake.mk @@ -1,6 +1,9 @@ # ovn-northd bin_PROGRAMS += northd/ovn-northd -northd_ovn_northd_SOURCES = northd/ovn-northd.c +northd_ovn_northd_SOURCES = \ + northd/ovn-northd.c \ + northd/ipam.c \ + northd/ipam.h northd_ovn_northd_LDADD = \ lib/libovn.la \ $(OVSDB_LIBDIR)/libovsdb.la \ diff --git a/northd/ipam.c b/northd/ipam.c new file mode 100644 index 0..e5383c46f --- /dev/null +++ b/northd/ipam.c @@ -0,0 +1,328 @@ +#include + +#include +#include +#include +#include + +#include "ipam.h" +#include "lib/unit-test.h" +#include "ovn/lex.h" + +#include "smap.h" +#include "packets.h" +#include "bitmap.h" +#include "openvswitch/vlog.h" + +VLOG_DEFINE_THIS_MODULE(ipam) + +static void +init_ipam_ipv6_prefix(const char *ipv6_prefix, struct ipam_info *info) +{ +info->ipv6_prefix_set = false; +info->ipv6_prefix = in6addr_any; + +if (!ipv6_prefix) { +return; +} + +/* XXX Since we only accept /64 addresses, why do we even bother + * with accepting and trying to analyze a user-provided mask? + */ +if (strchr(ipv6_prefix, '/')) { +/* If a prefix length was specified, it must be 64. */ +struct in6_addr mask; +char *error += ipv6_parse_masked(ipv6_prefix, +>ipv6_prefix, ); +if (error) { +static struct vlog_rate_limit rl += VLOG_RATE_LIMIT_INIT(5, 1); +VLOG_WARN_RL(, "bad 'ipv6_prefix' %s: %s", + ipv6_prefix, error); +free(error); +} else { +if (ipv6_count_cidr_bits() == 64) { +info->ipv6_prefix_set = true; +} else { +static struct vlog_rate_limit rl += VLOG_RATE_LIMIT_INIT(5, 1); +VLOG_WARN_RL(, "bad 'ipv6_prefix' %s: must be /64", + ipv6_prefix); +} +} +} else { +info->ipv6_prefix_set = ipv6_parse( +ipv6_prefix, >ipv6_prefix); +if (!info->ipv6_prefix_set) { +static struct vlog_rate_limit rl += VLOG_RATE_LIMIT_INIT(5, 1); +VLOG_WARN_RL(, "bad 'ipv6_prefix' %s", ipv6_prefix); +} +} + +if (info->ipv6_prefix_set) { +/* Make sure nothing past first 64 bits are set */ +struct in6_addr mask = ipv6_create_mask(64); +info->ipv6_prefix = ipv6_addr_bitand(>ipv6_prefix, ); +} +} + +static void +init_ipam_ipv4(const char *subnet_str, const char *exclude_ip_list, + struct ipam_info *info) +{ +info->start_ipv4 = 0; +info->total_ipv4s = 0; +info->allocated_ipv4s = NULL; + +ovs_be32 subnet, mask; +char *error = ip_parse_masked(subnet_str, , ); +if (error || mask == OVS_BE32_MAX || !ip_is_cidr(mask)) { +static struct vlog_rate_limit rl += VLOG_RATE_LIMIT_INIT(5, 1); +VLOG_WARN_RL(, "bad 'subnet' %s", subnet_str); +free(error); +return; +} + +info->start_ipv4 = ntohl(subnet & mask) + 1; +info->total_ipv4s = ~ntohl(mask); +info->allocated_ipv4s = +bitmap_allocate(info->total_ipv4s); + +/* Mark first IP as taken */ +bitmap_set1(info->allocated_ipv4s, 0); + +if (!exclude_ip_list) { +return; +} + +struct lexer lexer; +lexer_init(, exclude_ip_list); +/* exclude_ip_list could be in the format - +* "10.0.0.4 10.0.0.10 10.0.0.20..10.0.0.50 10.0.0.100..10.0.0.110". +*/ +lexer_get(); +while (lexer.token.type != LEX_T_END) { +if (lexer.token.type != LEX_T_INTEGER) { +lexer_syntax_error(, "expecting address"); +break; +} +uint32_t start = ntohl(lexer.token.value.ipv4); +
[ovs-dev] [RFC PATCH ovn v3 1/3] Add unit test framework.
This creates an API that allows for unit tests to be registered in code by OVN. This change enables the following: * At configure time, "--enable-unit-tests" can be specified to allow for unit tests to be compiled. * This configure-time variable also enables a testsuite variable to be defined, allowing for unit tests to be run from the testsuite. * Testsuite tests are defined using OVS_CONSTRUCTOR, meaning they are automatically registered prior to main() being run in whichever program the unit test is defined in. * Unit tests can be written as standalone programs using the ovstest framework. This works so long as the symbols referenced in the unit test can be found in a header file. Unit tests written in this way don't rely on anything introduced in this commit and have existed in the testsuite via the test-ovn.c file for a while. * Unit tests can also be written within the source of a file and accessed using ovn-appctl. This can be useful for testing private functions within source code. Example: `ovn-appctl -t northd unit-test my-unit-test [args]`. Unit tests written this way require the use of the library introduced in this commit. This commit does not define any unit tests. That is saved for a later commit in this series. Signed-off-by: Mark Michelson --- acinclude.m4 | 12 + configure.ac | 1 + lib/automake.mk | 4 +- lib/unit-test.c | 120 +++ lib/unit-test.h | 34 ++ tests/atlocal.in | 1 + 6 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 lib/unit-test.c create mode 100644 lib/unit-test.h diff --git a/acinclude.m4 b/acinclude.m4 index a797adc82..8b1888075 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -366,3 +366,15 @@ AC_DEFUN([OVN_CHECK_OVS], [ AC_SUBST(OVSVERSION) AC_MSG_RESULT([OVS version is $OVSVERSION]) ]) + +AC_DEFUN([OVN_ENABLE_UNIT_TESTS], + [AC_ARG_ENABLE( + [unit_tests], + [AC_HELP_STRING([--enable-unit-tests], [Enable unit test framework])], + [], [enable_unit_tests=no]) + AC_CONFIG_COMMANDS_PRE( + [if test "X$enable_unit_tests" = Xyes; then +OVS_CFLAGS="$OVS_CFLAGS -DENABLE_UNIT_TESTS" + fi]) + +AC_SUBST([enable_unit_tests])]) diff --git a/configure.ac b/configure.ac index 0b17f05b9..613e2ba3d 100644 --- a/configure.ac +++ b/configure.ac @@ -166,6 +166,7 @@ OVS_CONDITIONAL_CC_OPTION([-Wno-unused], [HAVE_WNO_UNUSED]) OVS_CONDITIONAL_CC_OPTION([-Wno-unused-parameter], [HAVE_WNO_UNUSED_PARAMETER]) OVS_ENABLE_WERROR OVS_ENABLE_SPARSE +OVN_ENABLE_UNIT_TESTS OVS_CHECK_PRAGMA_MESSAGE OVN_CHECK_OVS diff --git a/lib/automake.mk b/lib/automake.mk index f3e9c8818..3e9c2a697 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -23,7 +23,9 @@ lib_libovn_la_SOURCES = \ lib/ovn-util.h \ lib/logical-fields.c \ lib/inc-proc-eng.c \ - lib/inc-proc-eng.h + lib/inc-proc-eng.h \ + lib/unit-test.c \ + lib/unit-test.h nodist_lib_libovn_la_SOURCES = \ lib/ovn-dirs.c \ lib/ovn-nb-idl.c \ diff --git a/lib/unit-test.c b/lib/unit-test.c new file mode 100644 index 0..3a12727c6 --- /dev/null +++ b/lib/unit-test.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2020 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "openvswitch/shash.h" +#include "openvswitch/dynamic-string.h" +#include "util.h" +#include "unixctl.h" +#include "command-line.h" + +#include "lib/unit-test.h" + +#ifdef ENABLE_UNIT_TESTS +static struct shash unit_tests = SHASH_INITIALIZER(_tests); + +struct unit_test_data { +size_t min_args; +size_t max_args; +ovs_cmdl_handler cb; +}; + +void +register_unit_test(const char *name, size_t min_args, size_t max_args, + ovs_cmdl_handler cb) +{ +struct unit_test_data *test_data = xmalloc(sizeof *test_data); +test_data->min_args = min_args; +test_data->max_args = max_args; +test_data->cb = cb; +shash_add_once(_tests, name, test_data); +} + +void +run_unit_test(struct ovs_cmdl_context *ctx) +{ +struct unit_test_data *test_data = shash_find_data(_tests, + ctx->argv[0]); +if (!test_data) { +struct ds *output = ctx->pvt; +ds_put_format(output, "Unable to find unit test %s\n", ctx->argv[0]); +return; +} + +int test_args = ctx->argc - 1; /* Ignore test name */ +if
[ovs-dev] [RFC PATCH ovn v3 0/3] Unit Testing in OVN
OVN has had a test framework for as long as I've been working on the project. The test framework is designed for performing functional tests of OVN. That is, with the entirety of OVN up and running, we can provide configuration and test data and ensure that OVN does with that data what we expect. This is 100% a good thing and has helped us to detect lots of bugs before they can actually be merged in. What's missing, though, are smaller-scale unit tests. As an example, if I wanted to test ovn-northd's IPAM code, I would need to start up ovn-northd, create a logical switch, configure that logical switch to use IPAM, and then create logical switch ports to exercise the IPAM code. This can be overkill if my only goal is to ensure that IPAM's algorithm for selecting the next IP address is correct. This patch series introduces a unit test framework and does some refactoring to make unit testing easier. More refactoring will be required to allow for more unit tests to be written. This is just a starting point. If you want to run the unit tests, you can do so in a couple of ways. 1) Within the testsuite. ./configure --with-ovs-source=/path/to/ovs --enable-unit-tests make check TESTSUITEFLAGS="-k unit" 2) One-off from the command line ./configure --with-ovs-source=/path/to/ovs --enable-unit-tests make sandbox ovn-appctl -t ovn-northd unit-test [test_args] Some notes on this patch series 1) Patch 1 is the most important one in the series. This is an RFC because I'm trying to find out if the unit test framework itself is good. The refactoring in patch 2 and the unit tests added in patch 3 are meant to illustrate examples of the framework. They do not necessarily need to be merged as-is. Feel free to comment on them if you'd like, though. 2) This patch series only adds unit test capabilities to ovn-northd since the subject of the unit testing is IPAM. However, it also is valid to add unit testing for ovn-controller. --- v2 -> v3: * Added missing tests/ovn-unit-tests.at file in patch 3. Patch 1 and 2 are identical to v2. v1 -> v2: * Separated refactored IPAM code into ipam.c and ipam.h in northd/ * Wrote merge-ready unit tests instead of toy examples * Made unit tests work based on command line arguments. Left pass/fail determination to the caller based on test output. * Two new tests use the new unit test framework, and one uses the pre-existing ovstest facility. Mark Michelson (3): Add unit test framework. northd: refactor init_ipam_info_for_datapath northd: Add init_ipam unit tests. acinclude.m4| 12 ++ configure.ac| 1 + lib/automake.mk | 4 +- lib/unit-test.c | 125 +++ lib/unit-test.h | 41 + northd/ovn-northd.c | 362 ++-- tests/atlocal.in| 1 + tests/automake.mk | 3 +- tests/testsuite.at | 1 + 9 files changed, 472 insertions(+), 78 deletions(-) create mode 100644 lib/unit-test.c create mode 100644 lib/unit-test.h -- 2.25.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH dpdk-latest v4] dpdk: Support running PMD threads on any core.
DPDK 20.08 introduced a new API that associates a non-EAL thread to a free lcore. This new API does not change the thread characteristics (like CPU affinity). Using this new API, there is no assumption on lcore X running on cpu X anymore which leaves OVS free from running its PMD thread on any cpu. DPDK still limits the number of lcores to RTE_MAX_LCORE (128 on x86_64) which should be enough for OVS pmd threads (hopefully). DPDK lcore/OVS pmd threads mapping are logged at threads creation and destruction. A new command is added to help get DPDK point of view of the DPDK lcores: $ ovs-appctl dpdk/lcores-list lcore 0, socket 0, role RTE, cpuset 0 lcore 1, socket 0, role NON_EAL, cpuset 1 lcore 2, socket 0, role NON_EAL, cpuset 15 Signed-off-by: David Marchand --- Changes since v3: - rebased on current HEAD, - switched back to simple warning rather than abort when registering a thread fails, Changes since v2: - introduced a new api in DPDK 20.08 (still being discussed), inbox thread at http://inbox.dpdk.org/dev/20200610144506.30505-1-david.march...@redhat.com/T/#t - this current patch depends on a patch on master I sent: https://patchwork.ozlabs.org/project/openvswitch/patch/20200626122738.28163-1-david.march...@redhat.com/ - dropped 'dpdk-lcore-mask' compat handling, Changes since v1: - rewired existing configuration 'dpdk-lcore-mask' to use --lcores, - switched to a bitmap to track lcores, - added a command to dump current mapping (Flavio): used an experimental API to get DPDK lcores cpuset since it is the most reliable/portable information, - used the same code for the logs when starting DPDK/PMD threads, - addressed Ilya comments, --- lib/dpdk-stub.c | 8 +++- lib/dpdk.c| 36 ++-- lib/dpdk.h| 3 ++- lib/dpif-netdev.c | 3 ++- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/dpdk-stub.c b/lib/dpdk-stub.c index b7d577870d..5bc996b665 100644 --- a/lib/dpdk-stub.c +++ b/lib/dpdk-stub.c @@ -39,7 +39,13 @@ dpdk_init(const struct smap *ovs_other_config) } void -dpdk_set_lcore_id(unsigned cpu OVS_UNUSED) +dpdk_init_thread_context(unsigned cpu OVS_UNUSED) +{ +/* Nothing */ +} + +void +dpdk_uninit_thread_context(void) { /* Nothing */ } diff --git a/lib/dpdk.c b/lib/dpdk.c index 319540394b..7d3c0637c9 100644 --- a/lib/dpdk.c +++ b/lib/dpdk.c @@ -14,6 +14,10 @@ * limitations under the License. */ +#ifndef ALLOW_EXPERIMENTAL_API +#define ALLOW_EXPERIMENTAL_API +#endif + #include #include "dpdk.h" @@ -525,6 +529,8 @@ dpdk_init__(const struct smap *ovs_other_config) dpdk_unixctl_mem_stream, rte_log_dump); unixctl_command_register("dpdk/log-set", "{level | pattern:level}", 0, INT_MAX, dpdk_unixctl_log_set, NULL); +unixctl_command_register("dpdk/lcores-list", "", 0, 0, + dpdk_unixctl_mem_stream, rte_lcore_dump); /* We are called from the main thread here */ RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID; @@ -601,11 +607,37 @@ dpdk_available(void) } void -dpdk_set_lcore_id(unsigned cpu) +dpdk_init_thread_context(unsigned cpu) { /* NON_PMD_CORE_ID is reserved for use by non pmd threads. */ ovs_assert(cpu != NON_PMD_CORE_ID); -RTE_PER_LCORE(_lcore_id) = cpu; + +if (!dpdk_available()) { +return; +} + +if (rte_thread_register() < 0) { +VLOG_WARN("This OVS pmd thread will share resources with the non-pmd " + "thread: %s.", rte_strerror(rte_errno)); +} else { +VLOG_INFO("PMD thread uses DPDK lcore %u.", rte_lcore_id()); +} +} + +void +dpdk_uninit_thread_context(void) +{ +unsigned int lcore_id; + +if (!dpdk_available()) { +return; +} + +lcore_id = rte_lcore_id(); +rte_thread_unregister(); +if (lcore_id != LCORE_ID_ANY) { +VLOG_INFO("PMD thread released DPDK lcore %u.", lcore_id); +} } void diff --git a/lib/dpdk.h b/lib/dpdk.h index 445a51d065..1bd16b31db 100644 --- a/lib/dpdk.h +++ b/lib/dpdk.h @@ -36,7 +36,8 @@ struct smap; struct ovsrec_open_vswitch; void dpdk_init(const struct smap *ovs_other_config); -void dpdk_set_lcore_id(unsigned cpu); +void dpdk_init_thread_context(unsigned cpu); +void dpdk_uninit_thread_context(void); const char *dpdk_get_vhost_sock_dir(void); bool dpdk_vhost_iommu_enabled(void); bool dpdk_vhost_postcopy_enabled(void); diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 300861ca59..da9e1e8fcf 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -5926,7 +5926,7 @@ pmd_thread_main(void *f_) /* Stores the pmd thread's 'pmd' to 'per_pmd_key'. */ ovsthread_setspecific(pmd->dp->per_pmd_key, pmd); ovs_numa_thread_setaffinity_core(pmd->core_id); -dpdk_set_lcore_id(pmd->core_id); +dpdk_init_thread_context(pmd->core_id); poll_cnt = pmd_load_queues_and_ports(pmd, _list); dfc_cache_init(>flow_cache);
[ovs-dev] [PATCH] netdev-offload-tc: Use single thread for probing tc features
There is no need for a thread start per probe. Signed-off-by: Roi Dayan Reviewed-by: Paul Blakey --- lib/netdev-offload-tc.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index e828a8683910..53662ef3f0e6 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1988,8 +1988,7 @@ probe_tc_block_support(int ifindex) static int netdev_tc_init_flow_api(struct netdev *netdev) { -static struct ovsthread_once multi_mask_once = OVSTHREAD_ONCE_INITIALIZER; -static struct ovsthread_once block_once = OVSTHREAD_ONCE_INITIALIZER; +static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; enum tc_qdisc_hook hook = get_tc_qdisc_hook(netdev); uint32_t block_id = 0; struct tcf_id id; @@ -2014,16 +2013,12 @@ netdev_tc_init_flow_api(struct netdev *netdev) /* make sure there is no ingress/egress qdisc */ tc_add_del_qdisc(ifindex, false, 0, hook); -if (ovsthread_once_start(_once)) { +if (ovsthread_once_start()) { probe_tc_block_support(ifindex); /* Need to re-fetch block id as it depends on feature availability. */ block_id = get_block_id_from_netdev(netdev); -ovsthread_once_done(_once); -} - -if (ovsthread_once_start(_mask_once)) { probe_multi_mask_per_prio(ifindex); -ovsthread_once_done(_mask_once); +ovsthread_once_done(); } error = tc_add_del_qdisc(ifindex, true, block_id, hook); -- 2.8.4 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH v4 0/5] XDP offload using flow API provider
On Fri, Oct 30, 2020 at 10:49 AM Toshiaki Makita wrote: > > Hi all, > > It's about 3 months since I submitted this patch set. > Could someone review this? > Or should I resubmit the patch set on the top of current master? Since the patches don't apply cleanly, I think you can rebase and repost them and/or provide the ovs commit id on top of which these patches apply cleanly. Thanks Numan > > Thanks, > Toshiaki Makita > > On 2020/08/15 10:54, Toshiaki Makita wrote: > > Ping. > > Any feedback is welcome. > > > > Thanks, > > Toshiaki Makita > > > > On 2020/07/31 11:55, Toshiaki Makita wrote: > >> This patch adds an XDP-based flow cache using the OVS netdev-offload > >> flow API provider. When an OVS device with XDP offload enabled, > >> packets first are processed in the XDP flow cache (with parse, and > >> table lookup implemented in eBPF) and if hits, the action processing > >> are also done in the context of XDP, which has the minimum overhead. > >> > >> This provider is based on top of William's recently posted patch for > >> custom XDP load. When a custom XDP is loaded, the provider detects if > >> the program supports classifier, and if supported it starts offloading > >> flows to the XDP program. > >> > >> The patches are derived from xdp_flow[1], which is a mechanism similar to > >> this but implemented in kernel. > >> > >> > >> * Motivation > >> > >> While userspace datapath using netdev-afxdp or netdev-dpdk shows good > >> performance, there are use cases where packets better to be processed in > >> kernel, for example, TCP/IP connections, or container to container > >> connections. Current solution is to use tap device or af_packet with > >> extra kernel-to/from-userspace overhead. But with XDP, a better solution > >> is to steer packets earlier in the XDP program, and decides to send to > >> userspace datapath or stay in kernel. > >> > >> One problem with current netdev-afxdp is that it forwards all packets to > >> userspace, The first patch from William (netdev-afxdp: Enable loading XDP > >> program.) only provides the interface to load XDP program, howerver users > >> usually don't know how to write their own XDP program. > >> > >> XDP also supports HW-offload so it may be possible to offload flows to > >> HW through this provider in the future, although not currently. > >> The reason is that map-in-map is required for our program to support > >> classifier with subtables in XDP, but map-in-map is not offloadable. > >> If map-in-map becomes offloadable, HW-offload of our program may also > >> be possible. > >> > >> > >> * How to use > >> > >> 1. Install clang/llvm >= 9, libbpf >= 0.0.6 (included in kernel 5.5), and > >> kernel >= 5.3. > >> > >> 2. make with --enable-afxdp --enable-xdp-offload > >> --enable-bpf will generate XDP program "bpf/flowtable_afxdp.o". Note that > >> the BPF object will not be installed anywhere by "make install" at this > >> point. > >> > >> 3. Load custom XDP program > >> E.g. > >> $ ovs-vsctl add-port ovsbr0 veth0 -- set int veth0 options:xdp-mode=native > >> \ > >>options:xdp-obj="/path/to/ovs/bpf/flowtable_afxdp.o" > >> $ ovs-vsctl add-port ovsbr0 veth1 -- set int veth1 options:xdp-mode=native > >> \ > >>options:xdp-obj="/path/to/ovs/bpf/flowtable_afxdp.o" > >> > >> 4. Enable XDP_REDIRECT > >> If you use veth devices, make sure to load some (possibly dummy) programs > >> on the peers of veth devices. This patch set includes a program which > >> does nothing but returns XDP_PASS. You can use it for the veth peer like > >> this: > >> $ ip link set veth1 xdpdrv object /path/to/ovs/bpf/xdp_noop.o section xdp > >> > >> Some HW NIC drivers require as many queues as cores on its system. Tweak > >> queues using "ethtool -L". > >> > >> 5. Enable hw-offload > >> $ ovs-vsctl set Open_vSwitch . other_config:offload-driver=linux_xdp > >> $ ovs-vsctl set Open_vSwitch . other_config:hw-offload=true > >> This will starts offloading flows to the XDP program. > >> > >> You should be able to see some maps installed, including "debug_stats". > >> $ bpftool map > >> > >> If packets are successfully redirected by the XDP program, > >> debug_stats[2] will be counted. > >> $ bpftool map dump id > >> > >> Currently only very limited keys and output actions are supported. > >> For example NORMAL action entry and IP based matching work with current > >> key support. VLAN actions used by port tag/trunks are also supported. > >> > >> > >> * Performance > >> > >> Tested 2 cases. 1) i40e to veth, 2) i40e to i40e. > >> Test 1 Measured drop rate at veth interface with redirect action from > >> physical interface (i40e 25G NIC, XXV 710) to veth. The CPU is Xeon > >> Silver 4114 (2.20 GHz). > >> XDP_DROP > >> +--+ +---++---+ > >> pktgen -- wire --> | eth0 | -- NORMAL ACTION --> | veth0 || veth2 | > >> +--+
Re: [ovs-dev] [PATCH net] net: openvswitch: silence suspicious RCU usage warning
On 30 Oct 2020, at 22:28, Jakub Kicinski wrote: On Thu, 29 Oct 2020 15:53:21 +0100 Eelco Chaudron wrote: Silence suspicious RCU usage warning in ovs_flow_tbl_masks_cache_resize() by replacing rcu_dereference() with rcu_dereference_ovsl(). In addition, when creating a new datapath, make sure it's configured under the ovs_lock. Fixes: 9bf24f594c6a ("net: openvswitch: make masks cache size configurable") Reported-by: syzbot+9a8f8bfcc56e85780...@syzkaller.appspotmail.com Signed-off-by: Eelco Chaudron --- net/openvswitch/datapath.c |8 net/openvswitch/flow_table.c |2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 832f898edb6a..020f8539fede 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1695,6 +1695,9 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) if (err) goto err_destroy_ports; + /* So far only local changes have been made, now need the lock. */ + ovs_lock(); Should we move the lock below assignments to param? Looks a little strange to protect stack variables with a global lock. You are right, I should have moved it down after the assignment. I will send out a v2. /* Set up our datapath device. */ parms.name = nla_data(a[OVS_DP_ATTR_NAME]); parms.type = OVS_VPORT_TYPE_INTERNAL; @@ -1707,9 +1710,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) if (err) goto err_destroy_meters; - /* So far only local changes have been made, now need the lock. */ - ovs_lock(); - vport = new_vport(); if (IS_ERR(vport)) { err = PTR_ERR(vport); @@ -1725,7 +1725,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) ovs_dp_reset_user_features(skb, info); } - ovs_unlock(); goto err_destroy_meters; } @@ -1742,6 +1741,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) return 0; err_destroy_meters: Let's update the name of the label. Guess now it is, unlock and destroy meters, so what label are you looking for? err_unlock_and_destroy_meters: which looks a bit long, or just err_unlock: + ovs_unlock(); ovs_meters_exit(dp); err_destroy_ports: kfree(dp->ports); diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index f3486a37361a..c89c8da99f1a 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c @@ -390,7 +390,7 @@ static struct mask_cache *tbl_mask_cache_alloc(u32 size) } int ovs_flow_tbl_masks_cache_resize(struct flow_table *table, u32 size) { - struct mask_cache *mc = rcu_dereference(table->mask_cache); + struct mask_cache *mc = rcu_dereference_ovsl(table->mask_cache); struct mask_cache *new; if (size == mc->cache_size) ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev