On Tue, Apr 9, 2024 at 5:54 PM Numan Siddique <[email protected]> wrote:
> > > On Tue, Apr 9, 2024, 7:46 AM Dumitru Ceara <[email protected]> wrote: > >> On 4/8/24 09:19, Ales Musil wrote: >> > On Fri, Apr 5, 2024 at 10:35 PM Numan Siddique <[email protected]> wrote: >> > >> >> >> >> >> >> On Tue, Apr 2, 2024 at 2:28 AM Ales Musil <[email protected]> wrote: >> >> >> >>> The current packet injection loses ct_state in the process. When >> >>> the ct_state is lost we might commit to DNAT zone and perform >> >>> zero SNAT after the packet injection. This causes the first session >> >>> to be wrong as the reply packets are not unDNATted. >> >>> >> >>> Instead of re-injecting the packet back into the pipeline when >> >>> we get the MAC binding, use paused controller action. The paused >> >>> controller action stores ct_state, which is important for the behavior >> >>> of the resumed packet. >> >>> >> >>> At the same time bump the OvS submodule latest branch-3.3. This is >> >>> mainly for [0], which fixes metering for paused controller actions. >> >>> >> >>> [0] c560f6ca3257 ("ofproto-dpif-xlate: Fix continuations with >> associated >> >>> metering.") >> >>> >> >>> Reported-at: https://issues.redhat.com/browse/FDP-439 >> >>> Signed-off-by: Ales Musil <[email protected]> >> >>> Acked-by: Mark Michelson <[email protected]> >> >>> --- >> >>> v2: Fix the Jira link and add ack from Mark. >> >>> >> >> >> >> Hi Ales, >> >> >> >> I see one problem during upgrades. The packet buffering functionality >> >> would be broken when ovn-controllers are updated to the version >> >> which has your patch but ovn-northd is still yet to. >> >> >> >> In this case, the below logical flow will be present (without the >> outer >> >> "output" action) >> >> >> >> --- >> >> table=21(lr_in_arp_request ), priority=100 , match=(eth.dst == >> >> 00:00:00:00:00:00 && ip4), action=(arp { eth.dst = ff:ff:ff:ff:ff:ff; >> >> arp.spa = reg1; arp.tpa = reg0; arp.op = 1; output; };) >> >> --- >> >> >> >> The updated ovn-controller will now resume the packet after learning >> the >> >> nexthop. But this resumed packet will be dropped because there is no >> >> "next" or "output" action following arp {}. >> >> >> >> Is this behavior acceptable until ovn-northd is also updated/upgraded ? >> >> >> > >> >> Thanks >> >> Numan >> >> >> >> >> > Hi Numan, >> > >> > this is a very good point, thank you for raising this. It probably >> depends >> > how long the upgrade takes, for ovn-kubernetes with ic it is all done >> per >> > node so that should be fine. However it might be more concerning for >> >> I'm afraid with OpenStack upgrade roll outs can take significantly >> longer. That means running with an older version of ovn-northd while >> some of the chassis run newer ovn-controllers. >> >> > OpenStack. In the end we would be losing only a small amount of packets >> (in >> > most cases only 1) for connections without MAC binding, on the other >> hand >> > the scenario it tries to fix is causing the first connection (whole >> > connection) to be completely broken. >> > >> > I've tried to think about a possible solution to avoid this problem and >> I >> > see only one way out of this. That would involve keeping the old arp >> > unchanged, adding new action that would result in the pause instead. I'm >> > not sure if that's worth the effort, it's hard to estimate how big of an >> > impact it might have during the upgrade. One unfortunate thing is that >> we >> > cannot modify the actions of the continuation, if we could there >> wouldn't >> > be any change required in northd. >> > >> > Let me know if you have other ideas on how to avoid this issue, maybe >> the >> > solution might be easier. >> > >> >> I don't have a great alternative. The only thing that seems safe is: >> - add a new action + a feature flag >> - deprecate and keep the old action for a release then remove it >> > > > My suggestion would be > - In ovn-controller, check it's version and the northd version. > - if northd version is lesser than it's version, then don't encode > the arp/ns with pause flag. Otherwise do. > - I think you can add new action types (only for pinctrl.c) for > arp/ns with pause flag set. > > > This way ovn-controller can still have 2 versions of arp/ns with just one > version of OVN actions - arp/ ns which northd uses. > > > > > Thanks > Numan > After some discussion and testing I went with adding an option in northd that will indicate if it's supported, if not the controller will emit implicit output action. To ensure that this works I have added a check into ovn-fake-mutlinode test. Posted in v3. > > > Regards, >> Dumitru >> >> > >> >> --- >> >> >> >>> controller/mac-learn.c | 30 +++++++++---- >> >>> controller/mac-learn.h | 9 ++-- >> >>> controller/pinctrl.c | 64 ++++++++++------------------ >> >>> lib/actions.c | 41 +++++++++++++++++- >> >>> northd/northd.c | 6 +-- >> >>> ovs | 2 +- >> >>> tests/ovn-northd.at | 3 ++ >> >>> tests/ovn.at | 8 ++-- >> >>> tests/system-ovn.at | 95 >> ++++++++++++++++++++++++++++++++++++++++++ >> >>> 9 files changed, 195 insertions(+), 63 deletions(-) >> >>> >> >>> diff --git a/controller/mac-learn.c b/controller/mac-learn.c >> >>> index 071f01b4f..0c3b60c23 100644 >> >>> --- a/controller/mac-learn.c >> >>> +++ b/controller/mac-learn.c >> >>> @@ -199,15 +199,24 @@ ovn_fdb_add(struct hmap *fdbs, uint32_t dp_key, >> >>> struct eth_addr mac, >> >>> /* packet buffering functions */ >> >>> >> >>> struct packet_data * >> >>> -ovn_packet_data_create(struct ofpbuf ofpacts, >> >>> - const struct dp_packet *original_packet) >> >>> +ovn_packet_data_create(const struct ofputil_packet_in *pin, >> >>> + const struct ofpbuf *continuation) >> >>> { >> >>> struct packet_data *pd = xmalloc(sizeof *pd); >> >>> >> >>> - pd->ofpacts = ofpacts; >> >>> - /* clone the packet to send it later with correct L2 address */ >> >>> - pd->p = dp_packet_clone_data(dp_packet_data(original_packet), >> >>> - dp_packet_size(original_packet)); >> >>> + pd->pin = (struct ofputil_packet_in) { >> >>> + .packet = xmemdup(pin->packet, pin->packet_len), >> >>> + .packet_len = pin->packet_len, >> >>> + .flow_metadata = pin->flow_metadata, >> >>> + .reason = pin->reason, >> >>> + .table_id = pin->table_id, >> >>> + .cookie = pin->cookie, >> >>> + /* Userdata are empty on purpose, >> >>> + * it is not needed for the continuation. */ >> >>> + .userdata = NULL, >> >>> + .userdata_len = 0, >> >>> + }; >> >>> + pd->continuation = ofpbuf_clone(continuation); >> >>> >> >>> return pd; >> >>> } >> >>> @@ -216,8 +225,8 @@ ovn_packet_data_create(struct ofpbuf ofpacts, >> >>> void >> >>> ovn_packet_data_destroy(struct packet_data *pd) >> >>> { >> >>> - dp_packet_delete(pd->p); >> >>> - ofpbuf_uninit(&pd->ofpacts); >> >>> + free(pd->pin.packet); >> >>> + ofpbuf_delete(pd->continuation); >> >>> free(pd); >> >>> } >> >>> >> >>> @@ -307,7 +316,10 @@ ovn_buffered_packets_ctx_run(struct >> >>> buffered_packets_ctx *ctx, >> >>> >> >>> struct packet_data *pd; >> >>> LIST_FOR_EACH_POP (pd, node, &bp->queue) { >> >>> - struct eth_header *eth = dp_packet_data(pd->p); >> >>> + struct dp_packet packet; >> >>> + dp_packet_use_const(&packet, pd->pin.packet, >> >>> pd->pin.packet_len); >> >>> + >> >>> + struct eth_header *eth = dp_packet_data(&packet); >> >>> eth->eth_dst = mac; >> >>> >> >>> ovs_list_push_back(&ctx->ready_packets_data, &pd->node); >> >>> diff --git a/controller/mac-learn.h b/controller/mac-learn.h >> >>> index e0fd6a8d1..20a015e1a 100644 >> >>> --- a/controller/mac-learn.h >> >>> +++ b/controller/mac-learn.h >> >>> @@ -24,6 +24,7 @@ >> >>> #include "openvswitch/hmap.h" >> >>> #include "openvswitch/list.h" >> >>> #include "openvswitch/ofpbuf.h" >> >>> +#include "openvswitch/ofp-packet.h" >> >>> >> >>> struct ovsdb_idl_index; >> >>> >> >>> @@ -91,8 +92,8 @@ struct fdb_entry *ovn_fdb_add(struct hmap *fdbs, >> >>> struct packet_data { >> >>> struct ovs_list node; >> >>> >> >>> - struct ofpbuf ofpacts; >> >>> - struct dp_packet *p; >> >>> + struct ofpbuf *continuation; >> >>> + struct ofputil_packet_in pin; >> >>> }; >> >>> >> >>> struct buffered_packets { >> >>> @@ -120,8 +121,8 @@ struct buffered_packets_ctx { >> >>> }; >> >>> >> >>> struct packet_data * >> >>> -ovn_packet_data_create(struct ofpbuf ofpacts, >> >>> - const struct dp_packet *original_packet); >> >>> +ovn_packet_data_create(const struct ofputil_packet_in *pin, >> >>> + const struct ofpbuf *continuation); >> >>> void ovn_packet_data_destroy(struct packet_data *pd); >> >>> struct buffered_packets * >> >>> ovn_buffered_packets_add(struct buffered_packets_ctx *ctx, uint64_t >> >>> dp_key, >> >>> diff --git a/controller/pinctrl.c b/controller/pinctrl.c >> >>> index 9a4deb80a..2c0ecdb4c 100644 >> >>> --- a/controller/pinctrl.c >> >>> +++ b/controller/pinctrl.c >> >>> @@ -258,9 +258,9 @@ static void pinctrl_handle_put_nd_ra_opts( >> >>> struct ofpbuf *continuation); >> >>> static void pinctrl_handle_nd_ns(struct rconn *swconn, >> >>> const struct flow *ip_flow, >> >>> - struct dp_packet *pkt_in, >> >>> - const struct match *md, >> >>> - struct ofpbuf *userdata); >> >>> + const struct ofputil_packet_in *pin, >> >>> + struct ofpbuf *userdata, >> >>> + const struct ofpbuf *continuation); >> >>> static void pinctrl_handle_put_icmp_frag_mtu(struct rconn *swconn, >> >>> const struct flow >> *in_flow, >> >>> struct dp_packet >> *pkt_in, >> >>> @@ -1534,11 +1534,13 @@ destroy_buffered_packets_ctx(void) >> >>> >> >>> /* Called with in the pinctrl_handler thread context. */ >> >>> static void >> >>> -pinctrl_handle_buffered_packets(struct dp_packet *pkt_in, >> >>> - const struct match *md, bool is_arp) >> >>> +pinctrl_handle_buffered_packets(const struct ofputil_packet_in *pin, >> >>> + const struct ofpbuf *continuation, >> >>> + bool is_arp) >> >>> OVS_REQUIRES(pinctrl_mutex) >> >>> { >> >>> struct in6_addr ip; >> >>> + const struct match *md = &pin->flow_metadata; >> >>> uint64_t dp_key = ntohll(md->flow.metadata); >> >>> uint64_t oport_key = md->flow.regs[MFF_LOG_OUTPORT - MFF_REG0]; >> >>> >> >>> @@ -1556,20 +1558,7 @@ OVS_REQUIRES(pinctrl_mutex) >> >>> return; >> >>> } >> >>> >> >>> - struct ofpbuf ofpacts; >> >>> - ofpbuf_init(&ofpacts, 4096); >> >>> - reload_metadata(&ofpacts, md); >> >>> - /* reload pkt_mark field */ >> >>> - const struct mf_field *pkt_mark_field = mf_from_id(MFF_PKT_MARK); >> >>> - union mf_value pkt_mark_value; >> >>> - mf_get_value(pkt_mark_field, &md->flow, &pkt_mark_value); >> >>> - ofpact_put_set_field(&ofpacts, pkt_mark_field, &pkt_mark_value, >> >>> NULL); >> >>> - >> >>> - struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts); >> >>> - resubmit->in_port = OFPP_CONTROLLER; >> >>> - resubmit->table_id = OFTABLE_OUTPUT_INIT; >> >>> - >> >>> - struct packet_data *pd = ovn_packet_data_create(ofpacts, pkt_in); >> >>> + struct packet_data *pd = ovn_packet_data_create(pin, >> continuation); >> >>> ovn_buffered_packets_packet_data_enqueue(bp, pd); >> >>> >> >>> /* There is a chance that the MAC binding was already created. */ >> >>> @@ -1579,8 +1568,8 @@ OVS_REQUIRES(pinctrl_mutex) >> >>> /* Called with in the pinctrl_handler thread context. */ >> >>> static void >> >>> pinctrl_handle_arp(struct rconn *swconn, const struct flow *ip_flow, >> >>> - struct dp_packet *pkt_in, >> >>> - const struct match *md, struct ofpbuf *userdata) >> >>> + const struct ofputil_packet_in *pin, >> >>> + struct ofpbuf *userdata, const struct ofpbuf >> >>> *continuation) >> >>> { >> >>> /* This action only works for IP packets, and the switch should >> only >> >>> send >> >>> * us IP packets this way, but check here just to be sure. */ >> >>> @@ -1592,7 +1581,7 @@ pinctrl_handle_arp(struct rconn *swconn, const >> >>> struct flow *ip_flow, >> >>> } >> >>> >> >>> ovs_mutex_lock(&pinctrl_mutex); >> >>> - pinctrl_handle_buffered_packets(pkt_in, md, true); >> >>> + pinctrl_handle_buffered_packets(pin, continuation, true); >> >>> ovs_mutex_unlock(&pinctrl_mutex); >> >>> >> >>> /* Compose an ARP packet. */ >> >>> @@ -1617,7 +1606,8 @@ pinctrl_handle_arp(struct rconn *swconn, const >> >>> struct flow *ip_flow, >> >>> ip_flow->vlans[0].tci); >> >>> } >> >>> >> >>> - set_actions_and_enqueue_msg(swconn, &packet, md, userdata); >> >>> + set_actions_and_enqueue_msg(swconn, &packet, >> >>> + &pin->flow_metadata, userdata); >> >>> dp_packet_uninit(&packet); >> >>> } >> >>> >> >>> @@ -3294,8 +3284,7 @@ process_packet_in(struct rconn *swconn, const >> >>> struct ofp_header *msg) >> >>> >> >>> switch (ntohl(ah->opcode)) { >> >>> case ACTION_OPCODE_ARP: >> >>> - pinctrl_handle_arp(swconn, &headers, &packet, >> &pin.flow_metadata, >> >>> - &userdata); >> >>> + pinctrl_handle_arp(swconn, &headers, &pin, &userdata, >> >>> &continuation); >> >>> break; >> >>> case ACTION_OPCODE_IGMP: >> >>> pinctrl_ip_mcast_handle(swconn, &headers, &packet, >> >>> &pin.flow_metadata, >> >>> @@ -3361,8 +3350,7 @@ process_packet_in(struct rconn *swconn, const >> >>> struct ofp_header *msg) >> >>> break; >> >>> >> >>> case ACTION_OPCODE_ND_NS: >> >>> - pinctrl_handle_nd_ns(swconn, &headers, &packet, >> >>> &pin.flow_metadata, >> >>> - &userdata); >> >>> + pinctrl_handle_nd_ns(swconn, &headers, &pin, &userdata, >> >>> &continuation); >> >>> break; >> >>> >> >>> case ACTION_OPCODE_ICMP: >> >>> @@ -4374,16 +4362,8 @@ send_mac_binding_buffered_pkts(struct rconn >> >>> *swconn) >> >>> >> >>> struct packet_data *pd; >> >>> LIST_FOR_EACH_POP (pd, node, >> >>> &buffered_packets_ctx.ready_packets_data) { >> >>> - struct ofputil_packet_out po = { >> >>> - .packet = dp_packet_data(pd->p), >> >>> - .packet_len = dp_packet_size(pd->p), >> >>> - .buffer_id = UINT32_MAX, >> >>> - .ofpacts = pd->ofpacts.data, >> >>> - .ofpacts_len = pd->ofpacts.size, >> >>> - }; >> >>> - match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER); >> >>> - queue_msg(swconn, ofputil_encode_packet_out(&po, proto)); >> >>> - >> >>> + queue_msg(swconn, ofputil_encode_resume(&pd->pin, >> >>> pd->continuation, >> >>> + proto)); >> >>> ovn_packet_data_destroy(pd); >> >>> } >> >>> >> >>> @@ -6317,8 +6297,9 @@ pinctrl_handle_nd_na(struct rconn *swconn, const >> >>> struct flow *ip_flow, >> >>> /* Called with in the pinctrl_handler thread context. */ >> >>> static void >> >>> pinctrl_handle_nd_ns(struct rconn *swconn, const struct flow >> *ip_flow, >> >>> - struct dp_packet *pkt_in, >> >>> - const struct match *md, struct ofpbuf *userdata) >> >>> + const struct ofputil_packet_in *pin, >> >>> + struct ofpbuf *userdata, >> >>> + const struct ofpbuf *continuation) >> >>> { >> >>> /* This action only works for IPv6 packets. */ >> >>> if (get_dl_type(ip_flow) != htons(ETH_TYPE_IPV6)) { >> >>> @@ -6328,7 +6309,7 @@ pinctrl_handle_nd_ns(struct rconn *swconn, const >> >>> struct flow *ip_flow, >> >>> } >> >>> >> >>> ovs_mutex_lock(&pinctrl_mutex); >> >>> - pinctrl_handle_buffered_packets(pkt_in, md, false); >> >>> + pinctrl_handle_buffered_packets(pin, continuation, false); >> >>> ovs_mutex_unlock(&pinctrl_mutex); >> >>> >> >>> uint64_t packet_stub[128 / 8]; >> >>> @@ -6341,7 +6322,8 @@ pinctrl_handle_nd_ns(struct rconn *swconn, const >> >>> struct flow *ip_flow, >> >>> &ip_flow->ipv6_dst); >> >>> >> >>> /* Reload previous packet metadata and set actions from >> userdata. */ >> >>> - set_actions_and_enqueue_msg(swconn, &packet, md, userdata); >> >>> + set_actions_and_enqueue_msg(swconn, &packet, >> >>> + &pin->flow_metadata, userdata); >> >>> dp_packet_uninit(&packet); >> >>> } >> >>> >> >>> diff --git a/lib/actions.c b/lib/actions.c >> >>> index 71615fc53..004b77a89 100644 >> >>> --- a/lib/actions.c >> >>> +++ b/lib/actions.c >> >>> @@ -1977,6 +1977,44 @@ format_REJECT(const struct ovnact_nest *nest, >> >>> struct ds *s) >> >>> format_nested_action(nest, "reject", s); >> >>> } >> >>> >> >>> +static bool >> >>> +is_paused_nested_action(enum action_opcode opcode) >> >>> +{ >> >>> + switch (opcode) { >> >>> + case ACTION_OPCODE_ARP: >> >>> + case ACTION_OPCODE_ND_NS: >> >>> + return true; >> >>> + case ACTION_OPCODE_IGMP: >> >>> + case ACTION_OPCODE_PUT_ARP: >> >>> + case ACTION_OPCODE_PUT_DHCP_OPTS: >> >>> + case ACTION_OPCODE_ND_NA: >> >>> + case ACTION_OPCODE_ND_NA_ROUTER: >> >>> + case ACTION_OPCODE_PUT_ND: >> >>> + case ACTION_OPCODE_PUT_FDB: >> >>> + case ACTION_OPCODE_PUT_DHCPV6_OPTS: >> >>> + case ACTION_OPCODE_DNS_LOOKUP: >> >>> + case ACTION_OPCODE_LOG: >> >>> + case ACTION_OPCODE_PUT_ND_RA_OPTS: >> >>> + case ACTION_OPCODE_ICMP: >> >>> + case ACTION_OPCODE_ICMP4_ERROR: >> >>> + case ACTION_OPCODE_ICMP6_ERROR: >> >>> + case ACTION_OPCODE_TCP_RESET: >> >>> + case ACTION_OPCODE_SCTP_ABORT: >> >>> + case ACTION_OPCODE_REJECT: >> >>> + case ACTION_OPCODE_PUT_ICMP4_FRAG_MTU: >> >>> + case ACTION_OPCODE_PUT_ICMP6_FRAG_MTU: >> >>> + case ACTION_OPCODE_EVENT: >> >>> + case ACTION_OPCODE_BIND_VPORT: >> >>> + case ACTION_OPCODE_DHCP6_SERVER: >> >>> + case ACTION_OPCODE_HANDLE_SVC_CHECK: >> >>> + case ACTION_OPCODE_BFD_MSG: >> >>> + case ACTION_OPCODE_ACTIVATION_STRATEGY_RARP: >> >>> + case ACTION_OPCODE_MG_SPLIT_BUF: >> >>> + default: >> >>> + return false; >> >>> + } >> >>> +} >> >>> + >> >>> static void >> >>> encode_nested_actions(const struct ovnact_nest *on, >> >>> const struct ovnact_encode_params *ep, >> >>> @@ -1992,7 +2030,8 @@ encode_nested_actions(const struct ovnact_nest >> *on, >> >>> * converted to OpenFlow, as its userdata. ovn-controller will >> >>> convert the >> >>> * packet to ARP or NA and then send the packet and actions back >> to >> >>> the >> >>> * switch inside an OFPT_PACKET_OUT message. */ >> >>> - size_t oc_offset = encode_start_controller_op(opcode, false, >> >>> + bool pause = is_paused_nested_action(opcode); >> >>> + size_t oc_offset = encode_start_controller_op(opcode, pause, >> >>> ep->ctrl_meter_id, >> >>> ofpacts); >> >>> ofpacts_put_openflow_actions(inner_ofpacts.data, >> inner_ofpacts.size, >> >>> ofpacts, OFP15_VERSION); >> >>> diff --git a/northd/northd.c b/northd/northd.c >> >>> index c568f6360..f65f0d1d9 100644 >> >>> --- a/northd/northd.c >> >>> +++ b/northd/northd.c >> >>> @@ -13427,7 +13427,7 @@ build_arp_request_flows_for_lrouter( >> >>> "ip6.dst = %s; " >> >>> "nd.target = %s; " >> >>> "output; " >> >>> - "};", ETH_ADDR_ARGS(eth_dst), sn_addr_s, >> >>> + "}; output;", ETH_ADDR_ARGS(eth_dst), >> sn_addr_s, >> >>> route->nexthop); >> >>> >> >>> ovn_lflow_add_with_hint__(lflows, od, >> S_ROUTER_IN_ARP_REQUEST, >> >>> 200, >> >>> @@ -13447,7 +13447,7 @@ build_arp_request_flows_for_lrouter( >> >>> "arp.tpa = " REG_NEXT_HOP_IPV4 "; " >> >>> "arp.op = 1; " /* ARP request */ >> >>> "output; " >> >>> - "};", >> >>> + "}; output;", >> >>> copp_meter_get(COPP_ARP_RESOLVE, od->nbr->copp, >> >>> meter_groups), >> >>> lflow_ref); >> >>> @@ -13456,7 +13456,7 @@ build_arp_request_flows_for_lrouter( >> >>> "nd_ns { " >> >>> "nd.target = " REG_NEXT_HOP_IPV6 "; " >> >>> "output; " >> >>> - "};", >> >>> + "}; output;", >> >>> copp_meter_get(COPP_ND_NS_RESOLVE, >> od->nbr->copp, >> >>> meter_groups), >> >>> lflow_ref); >> >>> diff --git a/ovs b/ovs >> >>> index fe55ce37a..43db93787 160000 >> >>> --- a/ovs >> >>> +++ b/ovs >> >>> @@ -1 +1 @@ >> >>> -Subproject commit fe55ce37a7b090d09dee5c01ae0797320ad678f6 >> >>> +Subproject commit 43db937876fcec57947634d6e642429673d1ec06 >> >>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at >> >>> index cd53755b2..b3f8bd158 100644 >> >>> --- a/tests/ovn-northd.at >> >>> +++ b/tests/ovn-northd.at >> >>> @@ -6947,6 +6947,9 @@ ct_dnat /* assuming no un-dnat entry, so no >> change >> >>> */ { >> >>> arp.op = 1; >> >>> output("rtr-ls"); >> >>> }; >> >>> + ct_dnat /* assuming no un-dnat entry, so no change */ { >> >>> + output("rtr-ls"); >> >>> + }; >> >>> }; >> >>> }; >> >>> ]) >> >>> diff --git a/tests/ovn.at b/tests/ovn.at >> >>> index dd2ebce98..471cafcf9 100644 >> >>> --- a/tests/ovn.at >> >>> +++ b/tests/ovn.at >> >>> @@ -1540,11 +1540,11 @@ clone { ip4.dst = 255.255.255.255; output; }; >> >>> next; >> >>> >> >>> # arp >> >>> arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output; >> >>> - encodes as >> >>> >> controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00),resubmit(,OFTABLE_SAVE_INPORT) >> >>> + encodes as >> >>> >> controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00,pause),resubmit(,OFTABLE_SAVE_INPORT) >> >>> has prereqs ip4 >> >>> arp { }; >> >>> formats as arp { drop; }; >> >>> - encodes as controller(userdata=00.00.00.00.00.00.00.00) >> >>> + encodes as controller(userdata=00.00.00.00.00.00.00.00,pause) >> >>> has prereqs ip4 >> >>> >> >>> # get_arp >> >>> @@ -1674,12 +1674,12 @@ reg1[[0]] = put_dhcp_opts(offerip=1.2.3.4, >> >>> domain_search_list=1.2.3.4); >> >>> >> >>> # nd_ns >> >>> nd_ns { nd.target = xxreg0; output; }; >> >>> - encodes as >> >>> controller(userdata=00.00.00.09.00.00.00.00.00.1c.00.18.00. >> >>> 80.00.00.00.00.00.00.00.01.de >> >>> >> .10.80.00.3e.10.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00) >> >>> + encodes as >> >>> controller(userdata=00.00.00.09.00.00.00.00.00.1c.00.18.00. >> >>> 80.00.00.00.00.00.00.00.01.de >> >>> >> .10.80.00.3e.10.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00,pause) >> >>> has prereqs ip6 >> >>> >> >>> nd_ns { }; >> >>> formats as nd_ns { drop; }; >> >>> - encodes as controller(userdata=00.00.00.09.00.00.00.00) >> >>> + encodes as controller(userdata=00.00.00.09.00.00.00.00,pause) >> >>> has prereqs ip6 >> >>> >> >>> # nd_na >> >>> diff --git a/tests/system-ovn.at b/tests/system-ovn.at >> >>> index fc69facb9..c69e649a6 100644 >> >>> --- a/tests/system-ovn.at >> >>> +++ b/tests/system-ovn.at >> >>> @@ -12298,3 +12298,98 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query >> >>> port patch-.*/d >> >>> /connection dropped.*/d"]) >> >>> AT_CLEANUP >> >>> ]) >> >>> + >> >>> +OVN_FOR_EACH_NORTHD([ >> >>> +AT_SETUP([LB with first packet buffered]) >> >>> +AT_KEYWORDS([ovnlb]) >> >>> + >> >>> +CHECK_CONNTRACK() >> >>> +CHECK_CONNTRACK_NAT() >> >>> + >> >>> +ovn_start >> >>> +OVS_TRAFFIC_VSWITCHD_START() >> >>> +ADD_BR([br-int]) >> >>> +ADD_BR([br-ext]) >> >>> + >> >>> +check ovs-ofctl add-flow br-ext action=normal >> >>> +# Set external-ids in br-int needed for ovn-controller >> >>> +check ovs-vsctl \ >> >>> + -- set Open_vSwitch . external-ids:system-id=hv1 \ >> >>> + -- set Open_vSwitch . >> >>> external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ >> >>> + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ >> >>> + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ >> >>> + -- set bridge br-int fail-mode=secure >> >>> other-config:disable-in-band=true \ >> >>> + -- set Open_vSwitch . >> >>> external-ids:ovn-bridge-mappings=phynet:br-ext >> >>> + >> >>> +# Start ovn-controller >> >>> +start_daemon ovn-controller >> >>> + >> >>> +check ovn-nbctl lr-add lr >> >>> +check ovn-nbctl ls-add internal >> >>> +check ovn-nbctl ls-add public >> >>> + >> >>> +check ovn-nbctl lrp-add lr lr-pub 00:00:01:01:02:03 192.168.100.1/24 >> >>> 1000::1/64 >> >>> +check ovn-nbctl lsp-add public pub-lr -- set Logical_Switch_Port >> pub-lr >> >>> \ >> >>> + type=router options:router-port=lr-pub >> >>> addresses=\"00:00:01:01:02:03\" >> >>> + >> >>> +check ovn-nbctl lrp-add lr lr-internal 00:00:01:01:02:04 >> >>> 192.168.200.1/24 2000::1/64 >> >>> +check ovn-nbctl lsp-add internal internal-lr -- set >> Logical_Switch_Port >> >>> internal-lr \ >> >>> + type=router options:router-port=lr-internal >> >>> addresses=\"00:00:01:01:02:04\" >> >>> + >> >>> +check ovn-nbctl lsp-add internal server -- lsp-set-addresses server >> >>> "unknown" >> >>> + >> >>> +ovn-nbctl lsp-add public ln_port \ >> >>> + -- lsp-set-addresses ln_port unknown \ >> >>> + -- lsp-set-type ln_port localnet \ >> >>> + -- lsp-set-options ln_port network_name=phynet >> >>> + >> >>> +check ovn-nbctl set logical_router lr options:chassis=hv1 >> >>> + >> >>> +check ovn-nbctl lb-add lb1 192.168.100.20 192.168.200.10 >> >>> +check ovn-nbctl lb-add lb2 1000::20 2000::10 >> >>> +check ovn-nbctl lr-lb-add lr lb1 >> >>> +check ovn-nbctl lr-lb-add lr lb2 >> >>> +check ovn-nbctl --wait=hv sync >> >>> + >> >>> +ADD_NAMESPACES(client) >> >>> +ADD_VETH(client, client, br-ext, "1000::10/64", "f0:00:00:01:02:03", >> \ >> >>> + "1000::1", "nodad", "192.168.100.10/24", "192.168.100.1") >> >>> + >> >>> +ADD_NAMESPACES(server) >> >>> +ADD_VETH(server, server, br-int, "2000::10/64", "f0:00:0f:01:02:03", >> \ >> >>> + "2000::1", "nodad", "192.168.200.10/24", "192.168.200.1") >> >>> + >> >>> +NETNS_DAEMONIZE([server], [nc -l -u 192.168.200.10 4242 > /dev/null], >> >>> [serverv4.pid]) >> >>> +NETNS_DAEMONIZE([server], [nc -l -u 2000::10 4243 > /dev/null], >> >>> [serverv6.pid]) >> >>> + >> >>> +NETNS_START_TCPDUMP([client], [-l -U -i client -vnne udp], [client]) >> >>> +NETNS_START_TCPDUMP([server], [-l -U -i server -vnne udp], [server]) >> >>> + >> >>> +check ovs-appctl dpctl/flush-conntrack >> >>> + >> >>> +NS_CHECK_EXEC([client], [nc -z -u 192.168.100.20 4242], [ignore], >> >>> [ignore], [ignore]) >> >>> +OVS_WAIT_UNTIL([grep -q "192.168.200.10" server.tcpdump]) >> >>> + >> >>> +NS_CHECK_EXEC([client], [nc -z -u 1000::20 4243]) >> >>> +OVS_WAIT_UNTIL([grep -q "2000::10" server.tcpdump]) >> >>> + >> >>> +zone_id=$(ovn-appctl -t ovn-controller ct-zone-list | grep lr_dnat | >> cut >> >>> -d ' ' -f2) >> >>> +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep -c "zone=$zone_id"], >> >>> [0], [2 >> >>> +]) >> >>> + >> >>> +OVS_APP_EXIT_AND_WAIT([ovn-controller]) >> >>> + >> >>> +as ovn-sb >> >>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) >> >>> + >> >>> +as ovn-nb >> >>> +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) >> >>> + >> >>> +as northd >> >>> +OVS_APP_EXIT_AND_WAIT([ovn-northd]) >> >>> + >> >>> +as >> >>> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d >> >>> +/connection dropped.*/d"]) >> >>> +AT_CLEANUP >> >>> +]) >> >>> -- >> >>> 2.44.0 >> >>> >> >>> _______________________________________________ >> >>> dev mailing list >> >>> [email protected] >> >>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >> >>> >> >>> >> > Thanks, >> > Ales >> > >> >> _______________________________________________ >> dev mailing list >> [email protected] >> https://mail.openvswitch.org/mailman/listinfo/ovs-dev >> > Thanks, Ales -- Ales Musil Senior Software Engineer - OVN Core Red Hat EMEA <https://www.redhat.com> [email protected] <https://red.ht/sig> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
