From: Numan Siddique <[email protected]> This patch adds the logical flows to do mac learning for the logical ports whose port security is disabled with 'unknown' addresses set.
Until now, OVN delivers the unknown destination packets to all the logical ports with 'unknown' addresses set. With this mac learning feature, such flooding of packets is avoided once OVN has learnt the port-to-mac bindings. Note that we don't learn macs seen on the localnet logical ports. Signed-off-by: Numan Siddique <[email protected]> --- controller/lflow.c | 5 + controller/lflow.h | 9 +- lib/ovn-util.h | 3 + northd/ovn-northd.8.xml | 162 +++++++++++-- northd/ovn-northd.c | 96 ++++++-- ovn-sb.ovsschema | 6 +- tests/ovn-northd.at | 32 +-- tests/ovn.at | 517 ++++++++++++++++++++++++++++++++++++---- utilities/ovn-trace.c | 7 +- 9 files changed, 722 insertions(+), 115 deletions(-) diff --git a/controller/lflow.c b/controller/lflow.c index 6c74fe9c85..544b47b41b 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -88,6 +88,11 @@ static void lflow_resource_destroy_lflow(struct lflow_resource_ref *, static bool lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp) { + if (!strcmp(port_name, "none")) { + *portp = 0; + return true; + } + const struct lookup_port_aux *aux = aux_; const struct sbrec_port_binding *pb diff --git a/controller/lflow.h b/controller/lflow.h index 9f8bed4938..2eb2cb1121 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -60,9 +60,9 @@ struct uuid; * you make any changes. */ #define OFTABLE_PHY_TO_LOG 0 #define OFTABLE_LOG_INGRESS_PIPELINE 8 /* First of LOG_PIPELINE_LEN tables. */ -#define OFTABLE_REMOTE_OUTPUT 32 -#define OFTABLE_LOCAL_OUTPUT 33 -#define OFTABLE_CHECK_LOOPBACK 34 +#define OFTABLE_REMOTE_OUTPUT 37 +#define OFTABLE_LOCAL_OUTPUT 38 +#define OFTABLE_CHECK_LOOPBACK 39 #define OFTABLE_LOG_EGRESS_PIPELINE 40 /* First of LOG_PIPELINE_LEN tables. */ #define OFTABLE_SAVE_INPORT 64 #define OFTABLE_LOG_TO_PHY 65 @@ -74,9 +74,6 @@ struct uuid; #define OFTABLE_GET_FDB 71 #define OFTABLE_LOOKUP_FDB 72 -/* The number of tables for the ingress and egress pipelines. */ -#define LOG_PIPELINE_LEN 24 - enum ref_type { REF_TYPE_ADDRSET, REF_TYPE_PORTGROUP, diff --git a/lib/ovn-util.h b/lib/ovn-util.h index 0823461183..df4b0bc989 100644 --- a/lib/ovn-util.h +++ b/lib/ovn-util.h @@ -261,4 +261,7 @@ BUILD_ASSERT_DECL(SCTP_INIT_CHUNK_LEN == sizeof(struct sctp_init_chunk)); /* See RFC 4960 Sections 3.3.7 and 8.5.1 for information on this flag. */ #define SCTP_ABORT_CHUNK_FLAG_T (1 << 0) +/* The number of tables for the ingress and egress pipelines. */ +#define LOG_PIPELINE_LEN 29 + #endif diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 70065a36d9..0251a89dc0 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -307,7 +307,73 @@ </li> </ul> - <h3>Ingress Table 3: <code>from-lport</code> Pre-ACLs</h3> + <h3>Ingress Table 3: Lookup MAC address learning table</h3> + + <p> + This table looks up the MAC learning table of the logical switch + datapath to check if the <code>port-mac</code> pair is present + or not. MAC is learnt only for logical switch VIF ports whose + port security is disabled and 'unknown' address set. + </p> + + <ul> + <li> + <p> + For each such logical port <var>p</var> whose port security + is disabled and 'unknown' address set following flow + is added. + </p> + + <ul> + <li> + Priority 100 flow with the match + <code>inport == <var>p</var></code> and action + <code>reg0[11] = lookup_fdb(inport, eth.src); next;</code> + </li> + </ul> + </li> + + <li> + One priority-0 fallback flow that matches all packets and advances to + the next table. + </li> + </ul> + + <h3>Ingress Table 4: Learn MAC of 'unknown' ports.</h3> + + <p> + This table learns the MAC addresses seen on the logical ports + whose port security is disabled and 'unknown' address set + if the <code>lookup_fdb</code> action returned false in the + previous table. + </p> + + <ul> + <li> + <p> + For each such logical port <var>p</var> whose port security + is disabled and 'unknown' address set following flow + is added. + </p> + + <ul> + <li> + Priority 100 flow with the match + <code>inport == <var>p</var> && reg0[11] == 0</code> and + action <code>put_fdb(inport, eth.src); next;</code> which stores + the <code>port-mac</code> in the mac learning table of the + logical switch datapath and advances the packet to the next table. + </li> + </ul> + </li> + + <li> + One priority-0 fallback flow that matches all packets and advances to + the next table. + </li> + </ul> + + <h3>Ingress Table 5: <code>from-lport</code> Pre-ACLs</h3> <p> This table prepares flows for possible stateful ACL processing in @@ -332,7 +398,7 @@ db="OVN_Northbound"/> table. </p> - <h3>Ingress Table 4: Pre-LB</h3> + <h3>Ingress Table 6: Pre-LB</h3> <p> This table prepares flows for possible stateful load balancing processing @@ -399,7 +465,7 @@ logical router datapath to logical switch datapath. </p> - <h3>Ingress Table 5: Pre-stateful</h3> + <h3>Ingress Table 7: Pre-stateful</h3> <p> This table prepares flows for all possible stateful processing @@ -410,7 +476,7 @@ <code>ct_next;</code> action. </p> - <h3>Ingress Table 6: <code>from-lport</code> ACL hints</h3> + <h3>Ingress Table 8: <code>from-lport</code> ACL hints</h3> <p> This table consists of logical flows that set hints @@ -489,7 +555,7 @@ </li> </ul> - <h3>Ingress table 7: <code>from-lport</code> ACLs</h3> + <h3>Ingress table 9: <code>from-lport</code> ACLs</h3> <p> Logical flows in this table closely reproduce those in the @@ -598,7 +664,7 @@ </li> </ul> - <h3>Ingress Table 8: <code>from-lport</code> QoS Marking</h3> + <h3>Ingress Table 10: <code>from-lport</code> QoS Marking</h3> <p> Logical flows in this table closely reproduce those in the @@ -620,7 +686,7 @@ </li> </ul> - <h3>Ingress Table 9: <code>from-lport</code> QoS Meter</h3> + <h3>Ingress Table 11: <code>from-lport</code> QoS Meter</h3> <p> Logical flows in this table closely reproduce those in the @@ -642,7 +708,7 @@ </li> </ul> - <h3>Ingress Table 10: LB</h3> + <h3>Ingress Table 12: LB</h3> <p> It contains a priority-0 flow that simply moves traffic to the next @@ -668,7 +734,7 @@ connection.) </p> - <h3>Ingress Table 11: Stateful</h3> + <h3>Ingress Table 13: Stateful</h3> <ul> <li> @@ -726,7 +792,7 @@ </li> </ul> - <h3>Ingress Table 12: Pre-Hairpin</h3> + <h3>Ingress Table 14: Pre-Hairpin</h3> <ul> <li> If the logical switch has load balancer(s) configured, then a @@ -751,7 +817,7 @@ </li> </ul> - <h3>Ingress Table 13: Nat-Hairpin</h3> + <h3>Ingress Table 15: Nat-Hairpin</h3> <ul> <li> If the logical switch has load balancer(s) configured, then a @@ -777,7 +843,7 @@ </li> </ul> - <h3>Ingress Table 14: Hairpin</h3> + <h3>Ingress Table 16: Hairpin</h3> <ul> <li> A priority-1 flow that hairpins traffic matched by non-default @@ -790,7 +856,7 @@ </li> </ul> - <h3>Ingress Table 15: ARP/ND responder</h3> + <h3>Ingress Table 17: ARP/ND responder</h3> <p> This table implements ARP/ND responder in a logical switch for known @@ -1080,7 +1146,7 @@ output; </li> </ul> - <h3>Ingress Table 16: DHCP option processing</h3> + <h3>Ingress Table 18: DHCP option processing</h3> <p> This table adds the DHCPv4 options to a DHCPv4 packet from the @@ -1141,7 +1207,7 @@ next; </li> </ul> - <h3>Ingress Table 17: DHCP responses</h3> + <h3>Ingress Table 19: DHCP responses</h3> <p> This table implements DHCP responder for the DHCP replies generated by @@ -1222,7 +1288,7 @@ output; </li> </ul> - <h3>Ingress Table 18 DNS Lookup</h3> + <h3>Ingress Table 20 DNS Lookup</h3> <p> This table looks up and resolves the DNS names to the corresponding @@ -1251,7 +1317,7 @@ reg0[4] = dns_lookup(); next; </li> </ul> - <h3>Ingress Table 19 DNS Responses</h3> + <h3>Ingress Table 21 DNS Responses</h3> <p> This table implements DNS responder for the DNS replies generated by @@ -1286,7 +1352,7 @@ output; </li> </ul> - <h3>Ingress table 20 External ports</h3> + <h3>Ingress table 22 External ports</h3> <p> Traffic from the <code>external</code> logical ports enter the ingress @@ -1329,7 +1395,7 @@ output; </li> </ul> - <h3>Ingress Table 21 Destination Lookup</h3> + <h3>Ingress Table 23 Destination Lookup</h3> <p> This table implements switching behavior. It contains these logical @@ -1492,12 +1558,58 @@ output; </li> <li> - One priority-0 fallback flow that matches all packets and outputs them - to the <code>MC_UNKNOWN</code> multicast group, which - <code>ovn-northd</code> populates with all enabled logical ports that - accept unknown destination packets. As a small optimization, if no - logical ports accept unknown destination packets, - <code>ovn-northd</code> omits this multicast group and logical flow. + One priority-0 fallback flow that matches all packets with the + action <code>outport = get_fdb(eth.dst); next;</code>. The action + <code>get_fdb</code> gets the port for the <code>eth.dst</code> + in the MAC learning table of the logical switch datapath. If there + is no entry for <code>eth.dst</code> in the MAC learning table, + then it stores <code>none</code> in the <code>outport</code>. + </li> + </ul> + + <h3>Ingress Table 23 Destination unknown</h3> + + <p> + This table handles the packets whose destination was not found or + and looked up in the MAC learning table of the logical switch + datapath. It contains the following flows. + </p> + + <ul> + <li> + <p> + If the logical switch has logical ports with 'unknown' addresses set, + then the below logical flow is added + </p> + + <ul> + <li> + Priority 50 flow with the match <code>outport == none</code> then + outputs them to the <code>MC_UNKNOWN</code> multicast group, which + <code>ovn-northd</code> populates with all enabled logical ports + that accept unknown destination packets. As a small optimization, + if no logical ports accept unknown destination packets, + <code>ovn-northd</code> omits this multicast group and logical + flow. + </li> + </ul> + + <p> + If the logical switch has no logical ports with 'unknown' address + set, then the below logical flow is added + </p> + + <ul> + <li> + Priority 50 flow with the match <code>outport == none</code> + and drops the packets. + </li> + </ul> + </li> + + <li> + One priority-0 fallback flow that outputs the packet to the egress + stage with the outport learnt from <code>get_fdb</code> action. </li> </ul> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 12a24a694f..23c26de36f 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -138,25 +138,28 @@ enum ovn_stage { PIPELINE_STAGE(SWITCH, IN, PORT_SEC_L2, 0, "ls_in_port_sec_l2") \ PIPELINE_STAGE(SWITCH, IN, PORT_SEC_IP, 1, "ls_in_port_sec_ip") \ PIPELINE_STAGE(SWITCH, IN, PORT_SEC_ND, 2, "ls_in_port_sec_nd") \ - PIPELINE_STAGE(SWITCH, IN, PRE_ACL, 3, "ls_in_pre_acl") \ - PIPELINE_STAGE(SWITCH, IN, PRE_LB, 4, "ls_in_pre_lb") \ - PIPELINE_STAGE(SWITCH, IN, PRE_STATEFUL, 5, "ls_in_pre_stateful") \ - PIPELINE_STAGE(SWITCH, IN, ACL_HINT, 6, "ls_in_acl_hint") \ - PIPELINE_STAGE(SWITCH, IN, ACL, 7, "ls_in_acl") \ - PIPELINE_STAGE(SWITCH, IN, QOS_MARK, 8, "ls_in_qos_mark") \ - PIPELINE_STAGE(SWITCH, IN, QOS_METER, 9, "ls_in_qos_meter") \ - PIPELINE_STAGE(SWITCH, IN, LB, 10, "ls_in_lb") \ - PIPELINE_STAGE(SWITCH, IN, STATEFUL, 11, "ls_in_stateful") \ - PIPELINE_STAGE(SWITCH, IN, PRE_HAIRPIN, 12, "ls_in_pre_hairpin") \ - PIPELINE_STAGE(SWITCH, IN, NAT_HAIRPIN, 13, "ls_in_nat_hairpin") \ - PIPELINE_STAGE(SWITCH, IN, HAIRPIN, 14, "ls_in_hairpin") \ - PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 15, "ls_in_arp_rsp") \ - PIPELINE_STAGE(SWITCH, IN, DHCP_OPTIONS, 16, "ls_in_dhcp_options") \ - PIPELINE_STAGE(SWITCH, IN, DHCP_RESPONSE, 17, "ls_in_dhcp_response") \ - PIPELINE_STAGE(SWITCH, IN, DNS_LOOKUP, 18, "ls_in_dns_lookup") \ - PIPELINE_STAGE(SWITCH, IN, DNS_RESPONSE, 19, "ls_in_dns_response") \ - PIPELINE_STAGE(SWITCH, IN, EXTERNAL_PORT, 20, "ls_in_external_port") \ - PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 21, "ls_in_l2_lkup") \ + PIPELINE_STAGE(SWITCH, IN, LOOKUP_FDB , 3, "ls_in_lookup_fdb") \ + PIPELINE_STAGE(SWITCH, IN, PUT_FDB, 4, "ls_in_put_fdb") \ + PIPELINE_STAGE(SWITCH, IN, PRE_ACL, 5, "ls_in_pre_acl") \ + PIPELINE_STAGE(SWITCH, IN, PRE_LB, 6, "ls_in_pre_lb") \ + PIPELINE_STAGE(SWITCH, IN, PRE_STATEFUL, 7, "ls_in_pre_stateful") \ + PIPELINE_STAGE(SWITCH, IN, ACL_HINT, 8, "ls_in_acl_hint") \ + PIPELINE_STAGE(SWITCH, IN, ACL, 9, "ls_in_acl") \ + PIPELINE_STAGE(SWITCH, IN, QOS_MARK, 10, "ls_in_qos_mark") \ + PIPELINE_STAGE(SWITCH, IN, QOS_METER, 11, "ls_in_qos_meter") \ + PIPELINE_STAGE(SWITCH, IN, LB, 12, "ls_in_lb") \ + PIPELINE_STAGE(SWITCH, IN, STATEFUL, 13, "ls_in_stateful") \ + PIPELINE_STAGE(SWITCH, IN, PRE_HAIRPIN, 14, "ls_in_pre_hairpin") \ + PIPELINE_STAGE(SWITCH, IN, NAT_HAIRPIN, 15, "ls_in_nat_hairpin") \ + PIPELINE_STAGE(SWITCH, IN, HAIRPIN, 16, "ls_in_hairpin") \ + PIPELINE_STAGE(SWITCH, IN, ARP_ND_RSP, 17, "ls_in_arp_rsp") \ + PIPELINE_STAGE(SWITCH, IN, DHCP_OPTIONS, 18, "ls_in_dhcp_options") \ + PIPELINE_STAGE(SWITCH, IN, DHCP_RESPONSE, 19, "ls_in_dhcp_response") \ + PIPELINE_STAGE(SWITCH, IN, DNS_LOOKUP, 20, "ls_in_dns_lookup") \ + PIPELINE_STAGE(SWITCH, IN, DNS_RESPONSE, 21, "ls_in_dns_response") \ + PIPELINE_STAGE(SWITCH, IN, EXTERNAL_PORT, 22, "ls_in_external_port") \ + PIPELINE_STAGE(SWITCH, IN, L2_LKUP, 23, "ls_in_l2_lkup") \ + PIPELINE_STAGE(SWITCH, IN, L2_UNKNOWN, 24, "ls_in_l2_unknown") \ \ /* Logical switch egress stages. */ \ PIPELINE_STAGE(SWITCH, OUT, PRE_LB, 0, "ls_out_pre_lb") \ @@ -223,6 +226,7 @@ enum ovn_stage { #define REGBIT_ACL_HINT_ALLOW "reg0[8]" #define REGBIT_ACL_HINT_DROP "reg0[9]" #define REGBIT_ACL_HINT_BLOCK "reg0[10]" +#define REGBIT_LKUP_FDB "reg0[11]" /* Register definitions for switches and routers. */ @@ -4717,6 +4721,42 @@ build_lswitch_input_port_sec_od( } } +static void +build_lswitch_learn_fdb_op( + struct ovn_port *op, struct hmap *lflows, + struct ds *actions, struct ds *match) +{ + if (op->nbsp && !op->n_ps_addrs && !strcmp(op->nbsp->type, "") && + op->has_unknown) { + ds_clear(match); + ds_clear(actions); + ds_put_format(match, "inport == %s", op->json_key); + ds_put_format(actions, REGBIT_LKUP_FDB + " = lookup_fdb(inport, eth.src); next;"); + ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_LOOKUP_FDB, 100, + ds_cstr(match), ds_cstr(actions), + &op->nbsp->header_); + + ds_put_cstr(match, " && "REGBIT_LKUP_FDB" == 0"); + ds_clear(actions); + ds_put_cstr(actions, "put_fdb(inport, eth.src); next;"); + ovn_lflow_add_with_hint(lflows, op->od, S_SWITCH_IN_PUT_FDB, 100, + ds_cstr(match), ds_cstr(actions), + &op->nbsp->header_); + } +} + +static void +build_lswitch_learn_fdb_od( + struct ovn_datapath *od, struct hmap *lflows) +{ + + if (od->nbs) { + ovn_lflow_add(lflows, od, S_SWITCH_IN_LOOKUP_FDB, 0, "1", "next;"); + ovn_lflow_add(lflows, od, S_SWITCH_IN_PUT_FDB, 0, "1", "next;"); + } +} + /* Egress table 8: Egress port security - IP (priorities 90 and 80) * if port security enabled. * @@ -6572,16 +6612,25 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *lflows) struct ds actions = DS_EMPTY_INITIALIZER; struct ovn_datapath *od; - /* Ingress table 19: Destination lookup for unknown MACs (priority 0). */ + /* Ingress table 24: Destination lookup for unknown MACs (priority 0). */ HMAP_FOR_EACH (od, key_node, datapaths) { if (!od->nbs) { continue; } + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 0, "1", + "outport = get_fdb(eth.dst); next;"); + if (od->has_unknown) { - ovn_lflow_add_unique(lflows, od, S_SWITCH_IN_L2_LKUP, 0, "1", - "outport = \""MC_UNKNOWN"\"; output;"); + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_UNKNOWN, 50, + "outport == \"none\"", + "outport = \""MC_UNKNOWN"\"; output;"); + } else { + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_UNKNOWN, 50, + "outport == \"none\"", "drop;"); } + ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_UNKNOWN, 0, "1", + "output;"); } ds_destroy(&match); @@ -11421,6 +11470,7 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od, build_fwd_group_lflows(od, lsi->lflows); build_lswitch_lflows_admission_control(od, lsi->lflows); build_lswitch_input_port_sec_od(od, lsi->lflows); + build_lswitch_learn_fdb_od(od, lsi->lflows); build_lswitch_arp_nd_responder_default(od, lsi->lflows); build_lswitch_dns_lookup_and_response(od, lsi->lflows); build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows); @@ -11460,6 +11510,8 @@ build_lswitch_and_lrouter_iterate_by_op(struct ovn_port *op, /* Build Logical Switch Flows. */ build_lswitch_input_port_sec_op(op, lsi->lflows, &lsi->actions, &lsi->match); + build_lswitch_learn_fdb_op(op, lsi->lflows, &lsi->actions, + &lsi->match); build_lswitch_arp_nd_responder_skip_local(op, lsi->lflows, &lsi->match); build_lswitch_arp_nd_responder_known_ips(op, lsi->lflows, diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema index 246e3908a0..b5d3338f46 100644 --- a/ovn-sb.ovsschema +++ b/ovn-sb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Southbound", - "version": "20.16.0", - "cksum": "1219580357 26536", + "version": "20.16.1", + "cksum": "4243908307 26536", "tables": { "SB_Global": { "columns": { @@ -103,7 +103,7 @@ "egress"]]}}}, "table_id": {"type": {"key": {"type": "integer", "minInteger": 0, - "maxInteger": 23}}}, + "maxInteger": 32}}}, "priority": {"type": {"key": {"type": "integer", "minInteger": 0, "maxInteger": 65535}}}, diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 7240e22baf..1b4160cfa0 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -1753,10 +1753,10 @@ AT_CAPTURE_FILE([sw1flows]) AT_CHECK( [grep -E 'ls_(in|out)_acl' sw0flows sw1flows | grep pg0 | sort], [0], [dnl -sw0flows: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw0flows: table=7 (ls_in_acl ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };) -sw1flows: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows: table=7 (ls_in_acl ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };) +sw0flows: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw0flows: table=9 (ls_in_acl ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };) +sw1flows: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows: table=9 (ls_in_acl ), priority=2002 , match=(inport == @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=egress,table=6); };) ]) AS_BOX([2]) @@ -1769,10 +1769,10 @@ ovn-sbctl dump-flows sw1 > sw1flows2 AT_CAPTURE_FILE([sw1flows2]) AT_CHECK([grep "ls_out_acl" sw0flows2 sw1flows2 | grep pg0 | sort], [0], [dnl -sw0flows2: table=5 (ls_out_acl ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw0flows2: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows2: table=5 (ls_out_acl ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows2: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) +sw0flows2: table=5 (ls_out_acl ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw0flows2: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows2: table=5 (ls_out_acl ), priority=2002 , match=(outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows2: table=5 (ls_out_acl ), priority=2003 , match=(outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) ]) AS_BOX([3]) @@ -1787,16 +1787,16 @@ AT_CAPTURE_FILE([sw1flows3]) AT_CHECK([grep "ls_out_acl" sw0flows3 sw1flows3 | grep pg0 | sort], [0], [dnl sw0flows3: table=5 (ls_out_acl ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) sw0flows3: table=5 (ls_out_acl ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) -sw0flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw0flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw0flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw0flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) +sw0flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw0flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw0flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw0flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) sw1flows3: table=5 (ls_out_acl ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) sw1flows3: table=5 (ls_out_acl ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) -sw1flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) -sw1flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=21); };) +sw1flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows3: table=5 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) +sw1flows3: table=5 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=23); };) ]) AT_CLEANUP diff --git a/tests/ovn.at b/tests/ovn.at index 8dbd3bf932..eee77a5dc4 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -8247,18 +8247,18 @@ as hv1 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1]) # On hv1, check that there are no flows outputting bcast to tunnel -OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0]) +OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=37 | ofctl_strip | grep output | wc -l` -eq 0]) # On hv2, check that no flow outputs bcast to tunnel to hv1. as hv2 -OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0]) +OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=37 | ofctl_strip | grep output | wc -l` -eq 0]) # Now bind vif2 on hv2. AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2]) # At this point, the broadcast flow on vif2 should be deleted. -# because, there is now a localnet vif bound (table=32 programming logic) -OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0]) +# because, there is now a localnet vif bound (table=37 programming logic) +OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=37 | ofctl_strip | grep output | wc -l` -eq 0]) # Verify that the local net patch port exists on hv2. OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1]) @@ -10388,12 +10388,12 @@ AT_CAPTURE_FILE([hv2flows]) AT_CHECK( [# Check that redirect mapping is programmed only on hv2 - grep table=33 hv1flows | grep =0x3,metadata=0x1 | wc -l - grep table=33 hv2flows | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l + grep table=38 hv1flows | grep =0x3,metadata=0x1 | wc -l + grep table=38 hv2flows | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l # Check that hv1 sends chassisredirect port traffic to hv2 - grep table=32 hv1flows | grep =0x3,metadata=0x1 | grep output | wc -l - grep table=32 hv2flows | grep =0x3,metadata=0x1 | wc -l + grep table=37 hv1flows | grep =0x3,metadata=0x1 | grep output | wc -l + grep table=37 hv2flows | grep =0x3,metadata=0x1 | wc -l # Check that arp reply on distributed gateway port is only programmed on hv2 grep arp hv1flows | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l @@ -10943,8 +10943,8 @@ as hv3 reset_pcap_file hv3-vif1 hv3/vif1 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet sleep 2 -# On hv1, table 32 check that no packet goes via the tunnel port -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \ +# On hv1, table 37 check that no packet goes via the tunnel port +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=37 \ | grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0 ]]) @@ -11634,20 +11634,20 @@ echo $hv2_gw1_ofport echo $hv2_gw2_ofport echo "--- hv1 ---" -as hv1 ovs-ofctl dump-flows br-int table=32 +as hv1 ovs-ofctl dump-flows br-int table=37 echo "--- hv2 ---" -as hv2 ovs-ofctl dump-flows br-int table=32 +as hv2 ovs-ofctl dump-flows br-int table=37 gw1_chassis=$(fetch_column Chassis _uuid name=gw1) gw2_chassis=$(fetch_column Chassis _uuid name=gw2) -OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \ | wc -l], [0], [1 ]) -OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \ | wc -l], [0], [1 ]) @@ -11688,12 +11688,12 @@ wait_for_ports_up check ovn-nbctl --wait=hv sync # we make sure that the hypervisors noticed, and inverted the slave ports -OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \ | wc -l], [0], [1 ]) -OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \ | wc -l], [0], [1 ]) @@ -11846,12 +11846,12 @@ ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid wait_row_count HA_Chassis_Group 1 wait_row_count HA_Chassis 2 -OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \ | wc -l], [0], [1 ]) -OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \ | wc -l], [0], [1 ]) @@ -11903,12 +11903,12 @@ wait_column "$exp_ref_ch_list" HA_Chassis_Group ref_chassis # Increase the priority of gw2 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40 -OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \ | wc -l], [0], [1 ]) -OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \ +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=37 | \ grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \ | wc -l], [0], [1 ]) @@ -15352,7 +15352,7 @@ wait_for_ports_up ls1-lp_ext1 # There should be a flow in hv2 to drop traffic from ls1-lp_ext1 destined # to router mac. AT_CHECK([as hv2 ovs-ofctl dump-flows br-int \ -table=28,dl_src=f0:00:00:00:00:03,dl_dst=a0:10:00:00:00:01 | \ +table=30,dl_src=f0:00:00:00:00:03,dl_dst=a0:10:00:00:00:01 | \ grep -c "actions=drop"], [0], [1 ]) @@ -15950,6 +15950,7 @@ ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \ ovn-nbctl lsp-add sw0 sw0-p0 \ -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2" + ovn-nbctl lsp-add sw0 sw0-p1 \ -- lsp-set-addresses sw0-p1 "f0:00:00:11:02:03 192.168.1.3 2001::3" @@ -16015,7 +16016,7 @@ policy=$(fetch_column nb:Logical_Router_Policy _uuid priority=2000) check ovn-nbctl set logical_router_policy $policy options:pkt_mark=100 as hv2 # add a flow in egress pipeline to check pkt marking -ovs-ofctl --protocols=OpenFlow13 add-flow br-int "table=32,priority=200,ip,nw_src=172.16.1.2,pkt_mark=0x64 actions=resubmit(,33)" +ovs-ofctl --protocols=OpenFlow13 add-flow br-int "table=37,priority=200,ip,nw_src=172.16.1.2,pkt_mark=0x64 actions=resubmit(,38)" dst_ip=$(ip_to_hex 172 16 2 10) fip_ip=$(ip_to_hex 172 16 1 2) @@ -16027,7 +16028,7 @@ echo $(get_arp_req f00000010204 $fip_ip $gw_router_ip) >> expected send_arp_reply 2 1 $gw_router_mac f00000010204 $gw_router_ip $fip_ip echo "${gw_router_mac}f0000001020408004500001c00004000fe0121b4${fip_ip}${dst_ip}${data}" >> expected -AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep pkt_mark=0x64 | grep -q n_packets=1],[0]) +AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=37 | grep pkt_mark=0x64 | grep -q n_packets=1],[0]) OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) @@ -19016,7 +19017,7 @@ m4_define([DVR_N_S_PING], OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv4/vif-north-tx.pcap], [vif-north.expected]) # Confirm that packets did not go out via tunnel port. - AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=33 | grep NXM_NX_TUN_METADATA0 | grep n_packets=0 | wc -l], [0], [[0 + AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=38 | grep NXM_NX_TUN_METADATA0 | grep n_packets=0 | wc -l], [0], [[0 ]]) # Confirm that packet went out via localnet port @@ -19146,7 +19147,8 @@ list mac_binding], [0], [lr0-sw0 50:54:00:00:00:03 ]) -AT_CHECK([test 1 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +AT_CHECK([test 1 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) AT_CHECK([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=10 | grep arp | \ grep controller | grep -v n_packets=0 | wc -l`]) @@ -19163,7 +19165,8 @@ OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=67 | grep n_p # The packet should not be sent to ovn-controller. The packet # count should be 1 only. -AT_CHECK([test 1 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +AT_CHECK([test 1 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) AT_CHECK([test 1 = `as hv1 ovs-ofctl dump-flows br-int table=10 | grep arp | \ grep controller | grep -v n_packets=0 | wc -l`]) @@ -19176,7 +19179,8 @@ send_garp 1 1 $eth_src $eth_dst $spa $tpa # The garp packet should be sent to ovn-controller and the mac_binding entry # should be updated. -OVS_WAIT_UNTIL([test 2 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +OVS_WAIT_UNTIL([test 2 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) check_row_count MAC_Binding 1 @@ -19201,7 +19205,8 @@ send_garp 1 1 $eth_src $eth_dst $spa $tpa # The garp packet should be sent to ovn-controller and the mac_binding entry # should be updated. -OVS_WAIT_UNTIL([test 3 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +OVS_WAIT_UNTIL([test 3 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) OVS_WAIT_UNTIL( [test 1 = `as hv1 ovs-ofctl dump-flows br-int table=67 | grep dl_src=50:54:00:00:00:33 \ @@ -19222,7 +19227,8 @@ OVS_WAIT_UNTIL( | grep n_packets=1 | wc -l`] ) -AT_CHECK([test 3 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +AT_CHECK([test 3 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) # Now send ARP reply packet with IP - 10.0.0.40 and mac 505400000023 eth_src=505400000023 @@ -19239,7 +19245,8 @@ send_arp_reply 1 1 $eth_src $eth_dst $spa $tpa # The garp packet should be sent to ovn-controller and the mac_binding entry # should be updated. -OVS_WAIT_UNTIL([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +OVS_WAIT_UNTIL([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) # Wait for an entry in table=67 for the learnt mac_binding entry. @@ -19255,7 +19262,8 @@ OVS_WAIT_UNTIL( | grep n_packets=1 | wc -l`] ) -AT_CHECK([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +AT_CHECK([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) send_arp_reply 1 1 $eth_src $eth_dst $spa $tpa OVS_WAIT_UNTIL( @@ -19263,7 +19271,8 @@ OVS_WAIT_UNTIL( | grep n_packets=2 | wc -l`] ) -AT_CHECK([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | wc -l`]) +AT_CHECK([test 4 = `cat hv1/ovn-controller.log | grep NXT_PACKET_IN2 | \ +grep table_id=10 | wc -l`]) OVN_CLEANUP([hv1], [hv2]) AT_CLEANUP @@ -21882,22 +21891,22 @@ AT_CHECK([test ! -z $p1_zoneid]) p2_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-sw0-p2 | sed 's/"//g') AT_CHECK([test ! -z $p2_zoneid]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep REG13 | wc -l) -eq 1]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep "load:0x${p1_zoneid}->NXM_NX_REG13" | wc -l) -eq 1]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw1_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw1_dpkey},\ reg15=0x${p2_dpkey} | grep REG13 | wc -l) -eq 1]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw1_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw1_dpkey},\ reg15=0x${p2_dpkey} | grep "load:0x${p2_zoneid}->NXM_NX_REG13" | wc -l) -eq 1]) ovs-vsctl set interface hv1-vif1 external_ids:iface-id=foo OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p1) = xdown]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep REG13 | wc -l) -eq 0]) p1_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-sw0-p1 | sed 's/"//g') @@ -21909,16 +21918,16 @@ OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p1) = xup]) p1_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-sw0-p1 | sed 's/"//g') AT_CHECK([test ! -z $p1_zoneid]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep REG13 | wc -l) -eq 1]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep "load:0x${p1_zoneid}->NXM_NX_REG13" | wc -l) -eq 1]) ovs-vsctl del-port hv1-vif2 OVS_WAIT_UNTIL([test x$(ovn-nbctl lsp-get-up sw0-p2) = xdown]) -AT_CHECK([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +AT_CHECK([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p2_dpkey} | grep REG13 | wc -l) -eq 0]) p2_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-sw0-p2 | sed 's/"//g') @@ -21926,7 +21935,7 @@ AT_CHECK([test -z $p2_zoneid]) ovn-nbctl lsp-del sw0-p1 -OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=33,metadata=${sw0_dpkey},\ +OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=38,metadata=${sw0_dpkey},\ reg15=0x${p1_dpkey} | grep REG13 | wc -l) -eq 0]) p1_zoneid=$(as hv1 ovs-vsctl get bridge br-int external_ids:ct-zone-sw0-p1 | sed 's/"//g') @@ -22510,7 +22519,8 @@ ovn-nbctl lsp-add s1 lsp-s1-r1 -- set Logical_Switch_Port lsp-s1-r1 type=router # Create logical port p1 in s1 ovn-nbctl lsp-add s1 p1 \ --- lsp-set-addresses p1 "f0:00:00:00:01:02 10.0.1.2" +-- lsp-set-addresses p1 "f0:00:00:00:01:02 10.0.1.2" \ +-- lsp-set-port-security p1 "f0:00:00:00:01:02 10.0.1.2" # Create two hypervisor and create OVS ports corresponding to logical ports. net_add n1 @@ -24003,3 +24013,426 @@ wait_column "true" nb:Logical_Switch_Port up name=lsp1 OVN_CLEANUP([hv1]) AT_CLEANUP + +AT_SETUP([ovn -- OVN FDB (MAC learning) - 2 HVs, 2 LS, 1 LR ]) +ovn_start + +# Create the first logical switch with one port +check ovn-nbctl ls-add sw0 +check ovn-nbctl lsp-add sw0 sw0-p1 +check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3" unknown + +check ovn-nbctl lsp-add sw0 sw0-p2 +check ovn-nbctl lsp-set-addresses sw0-p2 "50:54:00:00:00:04 10.0.0.4" +# Port security is set for sw0-p2 +check ovn-nbctl lsp-set-port-security sw0-p2 "50:54:00:00:00:04 10.0.0.4" + +# sw0-p1 and sw0-p3 have unknown address and no port security. +# FDB should be enabled for these lports. +check ovn-nbctl lsp-add sw0 sw0-p3 +check ovn-nbctl lsp-set-addresses sw0-p3 unknown + +# Create the second logical switch with one port +check ovn-nbctl ls-add sw1 +check ovn-nbctl lsp-add sw1 sw1-p1 +check ovn-nbctl lsp-set-addresses sw1-p1 "40:54:00:00:00:03 11.0.0.3" unknown + +check ovn-nbctl lsp-add sw1 sw1-p2 +check ovn-nbctl lsp-set-addresses sw1-p2 "40:54:00:00:00:04 11.0.0.4" +check ovn-nbctl lsp-set-port-security sw1-p2 "40:54:00:00:00:04 11.0.0.4" + +# Create a logical router and attach both logical switches +check ovn-nbctl lr-add lr0 +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 +check ovn-nbctl lsp-add sw0 sw0-lr0 +check ovn-nbctl lsp-set-type sw0-lr0 router +check ovn-nbctl lsp-set-addresses sw0-lr0 router +check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0 + +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 11.0.0.1/24 +check ovn-nbctl lsp-add sw1 sw1-lr0 +check ovn-nbctl lsp-set-type sw1-lr0 router +check ovn-nbctl lsp-set-addresses sw1-lr0 router +check ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1 +ovn-nbctl --wait=hv sync + +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=sw0-p1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 +ovs-vsctl -- add-port br-int hv1-vif2 -- \ + set interface hv1-vif2 external-ids:iface-id=sw1-p2 \ + options:tx_pcap=hv1/vif2-tx.pcap \ + options:rxq_pcap=hv1/vif2-rx.pcap \ + ofport-request=2 +ovs-vsctl -- add-port br-int hv1-vif3 -- \ + set interface hv1-vif3 external-ids:iface-id=sw0-p3 \ + options:tx_pcap=hv1/vif3-tx.pcap \ + options:rxq_pcap=hv1/vif3-rx.pcap \ + ofport-request=3 + +sim_add hv2 +as hv2 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.2 +ovs-vsctl -- add-port br-int hv2-vif1 -- \ + set interface hv2-vif1 external-ids:iface-id=sw0-p2 \ + options:tx_pcap=hv2/vif1-tx.pcap \ + options:rxq_pcap=hv2/vif1-rx.pcap \ + ofport-request=1 +ovs-vsctl -- add-port br-int hv2-vif2 -- \ + set interface hv2-vif2 external-ids:iface-id=sw1-p1 \ + options:tx_pcap=hv2/vif2-tx.pcap \ + options:rxq_pcap=hv2/vif2-rx.pcap \ + ofport-request=2 + +OVN_POPULATE_ARP + +ip_to_hex() { + printf "%02x%02x%02x%02x" "$@" +} + +send_icmp_packet() { + local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8 + shift 8 + + local ip_ttl=ff + local ip_len=001c + local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data} + echo $packet > expected + as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet +} + +reset_pcap_file() { + local iface=$1 + local pcap_file=$2 + ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \ +options:rxq_pcap=dummy-rx.pcap + rm -f ${pcap_file}*.pcap + ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \ +options:rxq_pcap=${pcap_file}-rx.pcap +} + +trim_zeros() { + sed 's/\(00\)\{1,\}$//' +} + +AS_BOX([Wait for all ports to be up]) +wait_for_ports_up + +# Check that there is put_fdb() flow added by ovn-northd for sw0-p1 +ovn-sbctl dump-flows sw0 > sw0flows +AT_CAPTURE_FILE([sw0flows]) + +AT_CHECK([grep "ls_in_lookup_fdb" sw0flows | sort], [0], [dnl + table=3 (ls_in_lookup_fdb ), priority=0 , dnl +match=(1), action=(next;) + table=3 (ls_in_lookup_fdb ), priority=100 , dnl +match=(inport == "sw0-p1"), action=(reg0[[11]] = lookup_fdb(inport, eth.src); next;) + table=3 (ls_in_lookup_fdb ), priority=100 , dnl +match=(inport == "sw0-p3"), action=(reg0[[11]] = lookup_fdb(inport, eth.src); next;) +]) + +AT_CHECK([grep "ls_in_put_fdb" sw0flows | sort], [0], [dnl + table=4 (ls_in_put_fdb ), priority=0 , dnl +match=(1), action=(next;) + table=4 (ls_in_put_fdb ), priority=100 , dnl +match=(inport == "sw0-p1" && reg0[[11]] == 0), action=(put_fdb(inport, eth.src); next;) + table=4 (ls_in_put_fdb ), priority=100 , dnl +match=(inport == "sw0-p3" && reg0[[11]] == 0), action=(put_fdb(inport, eth.src); next;) +]) + +# Send a packet from sw0-p1 with a different mac not present +# in it's addresses. +AS_BOX([Send a pkt from sw0-p1 with a different mac address]) + +# Use the src mac 50:54:00:00:00:13 instead of 50:54:00:00:00:03 +src_mac=505400000013 +src_ip=$(ip_to_hex 10 0 0 13) + +# send the packet to sw0-p2 +dst_mac=505400000004 +dst_ip=$(ip_to_hex 10 0 0 4) + +data=0800bee4391a0001 +send_icmp_packet 1 1 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +# There should be one row in fdb +AS_BOX([Check that the FDB entry is created]) +wait_row_count FDB 1 + +sw0_dpkey=$(fetch_column datapath_binding tunnel_key external_ids:name=sw0) +sw0p1_dpkey=$(fetch_column port_binding tunnel_key logical_port=sw0-p1) +sw0p3_dpkey=$(fetch_column port_binding tunnel_key logical_port=sw0-p3) + +check_column '50:54:00:00:00:13' fdb mac +check_column $sw0_dpkey fdb dp_key +check_column $sw0p1_dpkey fdb port_key + +# Make sure that OVS tables 71 and 72 are populated on both hv1 and hv2. +AS_BOX([Check that ovn-controller programs the flows for FDB]) +as hv1 ovs-ofctl dump-flows br-int table=71 > hv1_offlows_table71.txt +as hv2 ovs-ofctl dump-flows br-int table=71 > hv2_offlows_table71.txt + +AT_CAPTURE_FILE([hv1_offlows_table71.txt]) +AT_CAPTURE_FILE([hv2_offlows_table71.txt]) +AT_CHECK([cat hv1_offlows_table71.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG15[[]] +]) + +AT_CHECK([cat hv2_offlows_table71.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG15[[]] +]) + +as hv1 ovs-ofctl dump-flows br-int table=72 > hv1_offlows_table72.txt +as hv2 ovs-ofctl dump-flows br-int table=72 > hv2_offlows_table72.txt + +AT_CAPTURE_FILE([hv1_offlows_table72.txt]) +AT_CAPTURE_FILE([hv2_offlows_table72.txt]) +AT_CHECK([cat hv1_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]] +]) + +AT_CHECK([cat hv2_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]] +]) + +# Use the src mac 50:54:00:00:00:14 instead of 50:54:00:00:00:03 +src_mac=505400000014 +src_ip=$(ip_to_hex 10 0 0 14) + +as hv2 reset_pcap_file hv2-vif1 hv2/vif1 + +send_icmp_packet 1 1 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +# There should be two rows in fdb +wait_row_count FDB 2 + +check_column "50:54:00:00:00:13 50:54:00:00:00:14" fdb mac +check_column "$sw0_dpkey $sw0_dpkey" fdb dp_key +check_column "$sw0p1_dpkey $sw0p1_dpkey" fdb port_key + +# Make sure that OVS tables 71 and 72 are populated on both hv1 and hv2. +as hv1 ovs-ofctl dump-flows br-int table=71 > hv1_offlows_table71.txt +as hv2 ovs-ofctl dump-flows br-int table=71 > hv2_offlows_table71.txt + +AT_CAPTURE_FILE([hv1_offlows_table71.txt]) +AT_CAPTURE_FILE([hv2_offlows_table71.txt]) +AT_CHECK([cat hv1_offlows_table71.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG15[[]] +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG15[[]] +]) + +AT_CHECK([cat hv2_offlows_table71.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG15[[]] +priority=100,metadata=0x1,dl_dst=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG15[[]] +]) + +as hv1 ovs-ofctl dump-flows br-int table=72 > hv1_offlows_table72.txt +as hv2 ovs-ofctl dump-flows br-int table=72 > hv2_offlows_table72.txt + +AT_CAPTURE_FILE([hv1_offlows_table72.txt]) +AT_CAPTURE_FILE([hv2_offlows_table72.txt]) +AT_CHECK([cat hv1_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]] +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]] +]) + +AT_CHECK([cat hv2_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]] +priority=100,reg14=0x1,metadata=0x1,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]] +]) + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +as hv2 reset_pcap_file hv2-vif1 hv2/vif1 + +# Send the packet from sw0-p2 to sw0-p1 with the dst mac 50:54:00:00:00:13 +src_mac=505400000004 +src_ip=$(ip_to_hex 10 0 0 4) + +dst_mac=505400000013 +dst_ip=$(ip_to_hex 10 0 0 13) + +send_icmp_packet 1 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +dst_mac=505400000014 +dst_ip=$(ip_to_hex 10 0 0 14) + +send_icmp_packet 1 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +as hv1 reset_pcap_file hv1-vif3 hv1/vif3 + +# Send a packet from sw0-p2 to an unknown mac. Should be received +# by both sw0-p1 and sw0-p3 (as unknown is set). +AS_BOX([Send pkt from sw0-p2 to an unknown mac]) + +src_mac=505400000004 +src_ip=$(ip_to_hex 10 0 0 4) + +dst_mac=505400000023 +dst_ip=$(ip_to_hex 10 0 0 23) + +send_icmp_packet 1 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data + +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) +OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected]) + +AS_BOX([Flip the mac - 50:54:00:00:00:13 from sw0-p1 to sw0-p3]) + +# Use the src mac 50:54:00:00:00:13 +src_mac=505400000013 +src_ip=$(ip_to_hex 10 0 0 23) + +# send the packet to sw0-p2 +dst_mac=505400000004 +dst_ip=$(ip_to_hex 10 0 0 4) + +data=0800bee4391a0001 + +as hv2 reset_pcap_file hv2-vif1 hv2/vif1 +as hv1 reset_pcap_file hv1-vif3 hv1/vif3 + +# Send the pkt from sw0-p3 to sw0-p2. +send_icmp_packet 3 1 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +# fdb row count should be still 2. But the mac 50:54:00:00:00:13 +# should be learnt on sw0-p3. + +wait_row_count FDB 2 + +check_column "50:54:00:00:00:13 50:54:00:00:00:14" fdb mac +check_column "$sw0_dpkey $sw0_dpkey" fdb dp_key +check_column "$sw0p1_dpkey $sw0p3_dpkey" fdb port_key + +check_column "$sw0p3_dpkey" fdb port_key mac="50\:54\:00\:00\:00\:13" + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +as hv1 reset_pcap_file hv1-vif3 hv1/vif3 + +# Send the packet from sw0-p2 to sw0-p3 with the dst mac 50:54:00:00:00:13 +src_mac=505400000004 +src_ip=$(ip_to_hex 10 0 0 4) + +dst_mac=505400000013 +dst_ip=$(ip_to_hex 10 0 0 13) + +send_icmp_packet 1 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data +OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected]) + +# sw0-p1 should not receive the packet. +: > expected +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) + +AS_BOX([Test routing]) + +# Test the routing. +# Send the packet from sw1-p2 (hv1) to sw0-p1 (hv1) with dst ip 10.0.0.14 +# The packet should be delivered to sw0-p1 with dst mac 50:54:00:00:00:14 +# Before sending add mac_binding entry for 10.0.0.14 + +lr0_dp_uuid=$(fetch_column datapath_binding _uuid external_ids:name=lr0) + +ovn-sbctl create mac_binding ip=10.0.0.14 logical_port=lr0-sw0 \ +mac="50\:54\:00\:00\:00\:14" datapath=$lr0_dp_uuid + +# Wait till the mac_binding flows appear in hv1 +OVS_WAIT_UNTIL([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=66 \ +| grep -c reg0=0xa00000e)]) + +src_mac=405400000004 +src_ip=$(ip_to_hex 11 0 0 4) + +dst_mac=00000000ff02 # lr0-sw1 mac +dst_ip=$(ip_to_hex 10 0 0 14) + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +as hv1 reset_pcap_file hv1-vif3 hv1/vif3 + +send_icmp_packet 2 1 $src_mac $dst_mac $src_ip $dst_ip 0000 $data + +exp_packet=50540000001400000000ff0108004500001c00004000fe010100${src_ip}${dst_ip}${data} +echo $exp_packet > expected +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) + +# sw0-p3 should not receive the packet. +: > expected +OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected]) + +# Now the send the packet from sw1-p1 (hv2) to sw0-p1 (hv1) with dst ip 10.0.0.14 +# The acket should be delivered to sw0-p1 with dst mac 50:54:00:00:00:14 + +src_mac=405400000003 +src_ip=$(ip_to_hex 11 0 0 3) + +dst_mac=00000000ff02 # lr0-sw1 mac +dst_ip=$(ip_to_hex 10 0 0 14) + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +send_icmp_packet 2 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data + +exp_packet=50540000001400000000ff0108004500001c00004000fe010100${src_ip}${dst_ip}${data} +echo $exp_packet > expected +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) + +AS_BOX([Clear the FDB rows]) + +# Clear the fdb rows. +check ovn-sbctl --all destroy fdb +ovn-sbctl list fdb + +as hv1 reset_pcap_file hv1-vif1 hv1/vif1 +as hv1 reset_pcap_file hv1-vif3 hv1/vif3 + +# Send the packet from sw0-p2 to sw0-p1 with the dst mac 50:54:00:00:00:14 +# It should be delivered to both sw0-p1 and sw0-p3 since we have cleared the +# FDB table. +src_mac=505400000004 +src_ip=$(ip_to_hex 10 0 0 4) + +dst_mac=505400000014 +dst_ip=$(ip_to_hex 10 0 0 13) + +send_icmp_packet 1 2 $src_mac $dst_mac $src_ip $dst_ip 0000 $data + +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected]) +OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected]) + +# Make sure that OVS tables 71 and 72 are empty. +as hv1 ovs-ofctl dump-flows br-int table=71 > hv1_offlows_table71.txt +as hv2 ovs-ofctl dump-flows br-int table=71 > hv2_offlows_table71.txt + +AT_CAPTURE_FILE([hv1_offlows_table71.txt]) +AT_CAPTURE_FILE([hv2_offlows_table71.txt]) +AT_CHECK([cat hv1_offlows_table71.txt | grep -v NXST], [1], [dnl +]) + +AT_CHECK([cat hv2_offlows_table71.txt | grep -v NXST], [1], [dnl +]) + +as hv1 ovs-ofctl dump-flows br-int table=72 > hv1_offlows_table72.txt +as hv2 ovs-ofctl dump-flows br-int table=72 > hv2_offlows_table72.txt + +AT_CAPTURE_FILE([hv1_offlows_table72.txt]) +AT_CAPTURE_FILE([hv2_offlows_table72.txt]) +AT_CHECK([cat hv1_offlows_table72.txt | grep -v NXST], [1], [dnl +]) + +AT_CHECK([cat hv2_offlows_table72.txt | grep -v NXST], [1], [dnl +]) + +OVN_CLEANUP([hv1], [hv2]) +AT_CLEANUP diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c index fead759b49..6b883886fb 100644 --- a/utilities/ovn-trace.c +++ b/utilities/ovn-trace.c @@ -945,7 +945,7 @@ parse_lflow_for_datapath(const struct sbrec_logical_flow *sblf, .pipeline = (!strcmp(sblf->pipeline, "ingress") ? OVNACT_P_INGRESS : OVNACT_P_EGRESS), - .n_tables = 24, + .n_tables = LOG_PIPELINE_LEN, .cur_ltable = sblf->table_id, }; uint64_t stub[1024 / 8]; @@ -1184,6 +1184,11 @@ ovntrace_lookup_port(const void *dp_, const char *port_name, return true; } + if (!strcmp(port_name, "none")) { + *portp = 0; + return true; + } + const struct ovntrace_port *port = ovntrace_port_lookup_by_name(port_name); if (port) { if (port->dp == dp) { -- 2.29.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
