On Thu, Mar 20, 2025 at 11:35 AM Dumitru Ceara <[email protected]> wrote:
> On 3/4/25 12:41 PM, Ales Musil wrote: > > The option activation-strategy supported only "rarp", add "garp" and > > "na" to supported protocols. At the same time change to option to > > accept comma separated list, which allows CMS to set any combination > > of the supported protocols for activation. > > > > Reported-at: https://issues.redhat.com/browse/FDP-1042 > > Signed-off-by: Ales Musil <[email protected]> > > --- > > Hi Ales, > > Thanks for the patch! > Hi Dumitru, thank you for the review. > > NEWS | 3 + > > controller/physical.c | 191 ++++++++++++++++++----- > > ovn-nb.xml | 10 +- > > ovn-sb.xml | 17 +- > > tests/ovn.at | 355 ++++++++++++++++++++++-------------------- > > 5 files changed, 364 insertions(+), 212 deletions(-) > > > > diff --git a/NEWS b/NEWS > > index 455fc12b6..1243c47ec 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -1,5 +1,8 @@ > > Post v25.03.0 > > ------------- > > + - Add additional protocol support for options:activation-strategy. > The new > > + supported protocols are gARP and NA. The option now supports comma > > + separated to specify selected group of protocols. > > > > OVN v25.03.0 - xx xxx xxxx > > -------------------------- > > diff --git a/controller/physical.c b/controller/physical.c > > index 69bf05347..6737e812c 100644 > > --- a/controller/physical.c > > +++ b/controller/physical.c > > @@ -1228,33 +1228,124 @@ enum access_type { > > PORT_HA_REMOTE, > > }; > > > > +enum activation_strategy { > > + ACTIVATION_RARP = 1 << 0, > > + ACTIVATION_GARP = 1 << 1, > > + ACTIVATION_NA = 1 << 2, > > + ACTIVATION_IP4 = ACTIVATION_GARP | ACTIVATION_RARP, > > + ACTIVATION_IP6 = ACTIVATION_NA, > > +}; > > + > > static void > > -setup_rarp_activation_strategy(const struct sbrec_port_binding *binding, > > - ofp_port_t ofport, struct zone_ids > *zone_ids, > > - struct ovn_desired_flow_table > *flow_table) > > +setup_arp_activation_strategy(const struct sbrec_port_binding *binding, > > + ofp_port_t ofport, struct zone_ids > *zone_ids, > > + struct ofpbuf *ofpacts, struct eth_addr > mac, > > + ovs_be32 ip, bool arp, > > + struct ovn_desired_flow_table *flow_table) > > { > > struct match match = MATCH_CATCHALL_INITIALIZER; > > - uint64_t stub[1024 / 8]; > > - struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > > > > - /* Unblock the port on ingress RARP. */ > > - match_set_dl_type(&match, htons(ETH_TYPE_RARP)); > > + /* match: arp/rarp, in_port=<OFPORT>, dl_src=<MAC>, arp_sha=<MAC>, > > + * arp_spa=<IP>, arp_tpa=<IP> */ > > + match_set_dl_type(&match, htons(arp ? ETH_TYPE_ARP : > ETH_TYPE_RARP)); > > match_set_in_port(&match, ofport); > > + match_set_dl_src(&match, mac); > > + match_set_arp_sha(&match, mac); > > + match_set_arp_spa_masked(&match, ip, OVS_BE32_MAX); > > + match_set_arp_tpa_masked(&match, ip, OVS_BE32_MAX); > > > > - load_logical_ingress_metadata(binding, zone_ids, 0, NULL, &ofpacts, > true); > > - > > + load_logical_ingress_metadata(binding, zone_ids, 0, NULL, ofpacts, > true); > > + /* Unblock the traffic when it matches specified strategy. */ > > encode_controller_op(ACTION_OPCODE_ACTIVATION_STRATEGY_RARP, > > - NX_CTLR_NO_METER, &ofpacts); > > + NX_CTLR_NO_METER, ofpacts); > > + put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts); > > > > - put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, &ofpacts); > > + ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 1010, > > + binding->header_.uuid.parts[0], > > + &match, ofpacts, &binding->header_.uuid); > > + ofpbuf_clear(ofpacts); > > +} > > + > > +static void > > +setup_nd_na_activation_strategy(const struct sbrec_port_binding > *binding, > > + ofp_port_t ofport, struct zone_ids > *zone_ids, > > + struct ofpbuf *ofpacts, struct eth_addr > mac, > > + const struct in6_addr *ip, > > + struct ovn_desired_flow_table > *flow_table) > > +{ > > + struct match match = MATCH_CATCHALL_INITIALIZER; > > + > > + /* match: icmp6, in_port=<OFPORT>, icmp_type=136, icmp_code=0, > > + * ipv6_src=<IP>, nd_target=<IP>, nd_tll=<MAC> */ > > + match_set_dl_type(&match, htons(ETH_TYPE_IPV6)); > > + match_set_in_port(&match, ofport); > > + match_set_nw_proto(&match, IPPROTO_ICMPV6); > > + match_set_icmp_type(&match, 136); > > + match_set_icmp_code(&match, 0); > > + match_set_ipv6_src(&match, ip); > > + match_set_nd_target(&match, ip); > > + match_set_arp_tha(&match, mac); > > This confused me a bit.. it's because arp_tha and nd_tll are the same > thing in OVS and because there's no match_set_nd_tll(). > > > + > > + load_logical_ingress_metadata(binding, zone_ids, 0, NULL, ofpacts, > true); > > + /* Unblock the traffic when it matches specified strategy. */ > > + encode_controller_op(ACTION_OPCODE_ACTIVATION_STRATEGY_RARP, > > Nit: this looks a bit weird to me, we're setting up an ND_NA activation > strategy but we're using the ACTION_OPCODE_ACTIVATION_STRATEGY_RARP > opcode. I understand why it works but I think I'd just rename: > > /* activation_strategy_rarp() */ > ACTION_OPCODE(ACTIVATION_STRATEGY_RARP) > > to > > /* activation_strategy() */ > ACTION_OPCODE(ACTIVATION_STRATEGY) > > and while at it rename the pinctrl_rarp_activation_strategy_handler() > function to pinctrl_activation_strategy_handler() as it's really > protocol independent; it only reads the logical ingress port and > datapath from the flow. > Yeah, that makes sense. I completely forgot about that action name. > > + NX_CTLR_NO_METER, ofpacts); > > + put_resubmit(OFTABLE_LOG_INGRESS_PIPELINE, ofpacts); > > > > ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 1010, > > binding->header_.uuid.parts[0], > > - &match, &ofpacts, &binding->header_.uuid); > > - ofpbuf_clear(&ofpacts); > > + &match, ofpacts, &binding->header_.uuid); > > + ofpbuf_clear(ofpacts); > > +} > > + > > +static void > > +setup_activation_strategy_flows(const struct sbrec_port_binding > *binding, > > + ofp_port_t ofport, struct zone_ids > *zone_ids, > > + uint32_t activation_strategies, > > + const struct lport_addresses *addresses, > > + struct ovn_desired_flow_table > *flow_table) > > +{ > > + uint64_t stub[1024 / 8]; > > + struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > > + > > + bool ip4_activation = (activation_strategies & ACTIVATION_IP4) != 0; > > + bool ip6_activation = (activation_strategies & ACTIVATION_IP6) != 0; > > + > > + for (size_t i = 0; ip4_activation && i < addresses->n_ipv4_addrs; > i++) { > > + const struct ipv4_netaddr *address = &addresses->ipv4_addrs[i]; > > + if (activation_strategies & ACTIVATION_GARP) { > > + setup_arp_activation_strategy(binding, ofport, zone_ids, > &ofpacts, > > + addresses->ea, address->addr, > true, > > + flow_table); > > + } > > + > > + if (activation_strategies & ACTIVATION_RARP) { > > + setup_arp_activation_strategy(binding, ofport, zone_ids, > &ofpacts, > > + addresses->ea, address->addr, > false, > > + flow_table); > > + } > > I'm afraid this will potentially break live migration with > activation_strategy=rarp for the case when it's used for logical switch > ports that either: > - have "unknown" addresses > - only have a MAC address configured (no IPv4 address). > > We should probably maintain the old behavior, i.e., if > activation-strategy includes "rarp" then activate the port on any RARP > received on the LSP VIF. > Will revert it back for rarp. > > + } > > + > > + /* Always add LLA address activation if there is any IPv6 address. > */ > > + if (ip6_activation && addresses->n_ipv6_addrs) { > > + struct in6_addr lla; > > + in6_generate_lla(addresses->ea, &lla); > > + > > + setup_nd_na_activation_strategy(binding, ofport, zone_ids, > &ofpacts, > > + addresses->ea, &lla, > flow_table); > > + } > > + > > + for (size_t i = 0; ip6_activation && i < addresses->n_ipv6_addrs; > i++) { > > + const struct ipv6_netaddr *address = &addresses->ipv6_addrs[i]; > > + if (activation_strategies & ACTIVATION_NA) { > > + setup_nd_na_activation_strategy(binding, ofport, zone_ids, > > + &ofpacts, addresses->ea, > > + &address->addr, flow_table); > > + } > > + } > > > > /* Block all non-RARP traffic for the port, both directions. */ > > - match_init_catchall(&match); > > + struct match match = MATCH_CATCHALL_INITIALIZER; > > match_set_in_port(&match, ofport); > > > > ofctrl_add_flow(flow_table, OFTABLE_PHY_TO_LOG, 1000, > > @@ -1274,6 +1365,36 @@ setup_rarp_activation_strategy(const struct > sbrec_port_binding *binding, > > ofpbuf_uninit(&ofpacts); > > } > > > > +static uint32_t > > +pb_parse_activation_strategy(const struct sbrec_port_binding *pb) > > +{ > > + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > > + uint32_t strategies = 0; > > + > > + const char *strategy = smap_get(&pb->options, > "activation-strategy"); > > + if (strategy) { > > + char *save_ptr; > > + char *tokstr = xstrdup(strategy); > > + for (const char *name = strtok_r(tokstr, ",", &save_ptr); > > + name != NULL; > > + name = strtok_r(NULL, ",", &save_ptr)) { > > + if (!strcmp(name, "rarp")) { > > + strategies |= ACTIVATION_RARP; > > + } else if (!strcmp(name, "garp")) { > > + strategies |= ACTIVATION_GARP; > > + } else if (!strcmp(name, "na")) { > > + strategies |= ACTIVATION_NA; > > + } else { > > + VLOG_WARN_RL(&rl, "Unknown activation strategy defined > for " > > + "port %s: %s", pb->logical_port, name); > > + } > > + } > > + free(tokstr); > > + } > > + > > + return strategies; > > +} > > + > > static void > > setup_activation_strategy(const struct sbrec_port_binding *binding, > > const struct sbrec_chassis *chassis, > > @@ -1281,28 +1402,28 @@ setup_activation_strategy(const struct > sbrec_port_binding *binding, > > ofp_port_t ofport, struct zone_ids *zone_ids, > > struct ovn_desired_flow_table *flow_table) > > { > > - for (size_t i = 0; i < binding->n_additional_chassis; i++) { > > - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > > - if (binding->additional_chassis[i] == chassis) { > > - const char *strategy = smap_get(&binding->options, > > - "activation-strategy"); > > - if (strategy > > - && > !lport_is_activated_by_activation_strategy(binding, > > - > chassis) > > - && !pinctrl_is_port_activated(dp_key, port_key)) { > > - if (!strcmp(strategy, "rarp")) { > > - setup_rarp_activation_strategy(binding, ofport, > > - zone_ids, > flow_table); > > - } else { > > - VLOG_WARN_RL(&rl, > > - "Unknown activation strategy defined > for " > > - "port %s: %s", > > - binding->logical_port, strategy); > > - return; > > - } > > - } > > - return; > > + if (!is_additional_chassis(binding, chassis)) { > > + return; > > + } > > + > > + if (lport_is_activated_by_activation_strategy(binding, chassis) || > > + pinctrl_is_port_activated(dp_key, port_key)) { > > + return; > > + } > > + > > + uint32_t strategies = pb_parse_activation_strategy(binding); > > + if (!strategies) { > > + return; > > + } > > + > > + for (size_t i = 0; i < binding->n_mac; i++) { > > + struct lport_addresses addresses; > > + if (!extract_lsp_addresses(binding->mac[i], &addresses)) { > > + continue; > > } > > + setup_activation_strategy_flows(binding, ofport, zone_ids, > strategies, > > + &addresses, flow_table); > > + destroy_lport_addresses(&addresses); > > } > > } > > > > diff --git a/ovn-nb.xml b/ovn-nb.xml > > index 3ab514651..48f00632a 100644 > > --- a/ovn-nb.xml > > +++ b/ovn-nb.xml > > @@ -1360,10 +1360,12 @@ > > <ref column="requested-chassis"/>, specifies an activation > strategy > > for all additional chassis. By default, no activation > strategy is > > used, meaning additional port locations are immediately > available for > > - use. When set to "rarp", the port is blocked for ingress and > egress > > - communication until a RARP packet is sent from a new > location. The > > - "rarp" strategy is useful in live migration scenarios for > virtual > > - machines. > > + use. The option supports comma separated list where you can > combine > > Nit: "a comma separated list". > > > + 3 protocols, "rarp", "garp" and "na". When any of the > protocols is > > + set, the port is blocked for ingress and egress communication > until > > + a specified protocol packet is sent from a new location. The > > + activation strategy is useful in live migration scenarios for > > + virtual machines. > > </column> > > > > <column name="options" key="iface-id-ver"> > > diff --git a/ovn-sb.xml b/ovn-sb.xml > > index 39acb81a4..072c88ddb 100644 > > --- a/ovn-sb.xml > > +++ b/ovn-sb.xml > > @@ -3784,13 +3784,16 @@ tcp.flags = RST; > > </column> > > > > <column name="options" key="activation-strategy"> > > - If used with multiple chassis set in <ref > column="requested-chassis"/>, > > - specifies an activation strategy for all additional chassis. By > > - default, no activation strategy is used, meaning additional port > > - locations are immediately available for use. When set to > "rarp", the > > - port is blocked for ingress and egress communication until a > RARP > > - packet is sent from a new location. The "rarp" strategy is > useful > > - in live migration scenarios for virtual machines. > > + If used with multiple chassis set in > > + <ref column="requested-chassis"/>, specifies an activation > strategy > > + for all additional chassis. By default, no activation strategy > is > > + used, meaning additional port locations are immediately > available for > > + use. The option supports comma separated list where you can > combine > > Nit: "a comma separated list". > > > + 3 protocols, "rarp", "garp" and "na". When any of the protocols > is > > + set, the port is blocked for ingress and egress communication > until > > + a specified protocol packet is sent from a new location. The > > + activation strategy is useful in live migration scenarios for > > + virtual machines. > > </column> > > > > <column name="options" key="additional-chassis-activated"> > > diff --git a/tests/ovn.at b/tests/ovn.at > > index ec8ee8de7..ad31d8482 100644 > > --- a/tests/ovn.at > > +++ b/tests/ovn.at > > @@ -5428,7 +5428,7 @@ test_arp() { > > test_na() { > > local inport=$1 sha=$2 spa=$3 src=${4-$3} > > local request=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', > src='${sha}')/ \ > > - IPv6(dst='ff01::1', src='${src}')/ \ > > + IPv6(dst='ff02::1', src='${src}')/ \ > > Is this an accidental change? We don't use test_na() in the activation > strategy tests. Or am I missing something? > That's leftover from testing. I will revert it back. > > ICMPv6ND_NA(tgt='${spa}')/ \ > > ICMPv6NDOptDstLLAddr(lladdr='${sha}')") > > > > @@ -16487,205 +16487,228 @@ MULTICHASSIS_PATH_MTU_DISCOVERY_TEST([ipv6], > [geneve], [1404]) > > MULTICHASSIS_PATH_MTU_DISCOVERY_TEST([ipv4], [vxlan], [1432]) > > MULTICHASSIS_PATH_MTU_DISCOVERY_TEST([ipv6], [vxlan], [1412]) > > > > -OVN_FOR_EACH_NORTHD([ > > -AT_SETUP([options:activation-strategy for logical port]) > > -AT_KEYWORDS([multi-chassis]) > > -AT_KEYWORDS([slowtest]) > > -ovn_start > > - > > -net_add n1 > > - > > -sim_add hv1 > > -as hv1 > > -check ovs-vsctl add-br br-phys > > -ovn_attach n1 br-phys 192.168.0.11 > > - > > -sim_add hv2 > > -as hv2 > > -check ovs-vsctl add-br br-phys > > -ovn_attach n1 br-phys 192.168.0.12 > > - > > -sim_add hv3 > > -as hv3 > > -check ovs-vsctl add-br br-phys > > -ovn_attach n1 br-phys 192.168.0.13 > > - > > -# Disable local ARP responder to pass ARP requests through tunnels > > -check ovn-nbctl ls-add ls0 -- add Logical_Switch ls0 other_config > vlan-passthru=true > > - > > -check ovn-nbctl lsp-add ls0 migrator > > -check ovn-nbctl lsp-set-options migrator requested-chassis=hv1,hv2 \ > > - activation-strategy=rarp > > - > > -check ovn-nbctl lsp-add ls0 first > > -check ovn-nbctl lsp-set-options first requested-chassis=hv1 > > -check ovn-nbctl lsp-add ls0 second > > -check ovn-nbctl lsp-set-options second requested-chassis=hv2 > > -check ovn-nbctl lsp-add ls0 outside > > -check ovn-nbctl lsp-set-options outside requested-chassis=hv3 > > - > > -check ovn-nbctl lsp-set-addresses migrator "00:00:00:00:00:10 10.0.0.10" > > -check ovn-nbctl lsp-set-addresses first "00:00:00:00:00:01 10.0.0.1" > > -check ovn-nbctl lsp-set-addresses second "00:00:00:00:00:02 10.0.0.2" > > -check ovn-nbctl lsp-set-addresses outside "00:00:00:00:00:03 10.0.0.3" > > - > > -for hv in hv1 hv2; do > > - as $hv check ovs-vsctl -- add-port br-int migrator -- \ > > - set Interface migrator external-ids:iface-id=migrator \ > > - options:tx_pcap=$hv/migrator-tx.pcap \ > > - options:rxq_pcap=$hv/migrator-rx.pcap > > -done > > - > > -as hv1 check ovs-vsctl -- add-port br-int first -- \ > > - set Interface first external-ids:iface-id=first > > -as hv2 check ovs-vsctl -- add-port br-int second -- \ > > - set Interface second external-ids:iface-id=second > > -as hv3 check ovs-vsctl -- add-port br-int outside -- \ > > - set Interface outside external-ids:iface-id=outside > > - > > -for hv in hv1 hv2 hv3; do > > - wait_row_count Chassis 1 name=$hv > > -done > > -hv1_uuid=$(fetch_column Chassis _uuid name=hv1) > > -hv2_uuid=$(fetch_column Chassis _uuid name=hv2) > > -hv3_uuid=$(fetch_column Chassis _uuid name=hv3) > > +m4_define([ACTIVATION_STRATEGY_TEST], > > + [OVN_FOR_EACH_NORTHD([ > > + AT_SETUP([options:activation-strategy=$1 for logical port]) > > + AT_KEYWORDS([multi-chassis]) > > + AT_KEYWORDS([slowtest]) > > + AT_SKIP_IF([test $HAVE_SCAPY = no]) > > + ovn_start > > > > -wait_column "$hv1_uuid" Port_Binding chassis logical_port=migrator > > -wait_column "$hv1_uuid" Port_Binding requested_chassis > logical_port=migrator > > -wait_column "$hv2_uuid" Port_Binding additional_chassis > logical_port=migrator > > -wait_column "$hv2_uuid" Port_Binding requested_additional_chassis > logical_port=migrator > > + net_add n1 > > > > -wait_column "$hv1_uuid" Port_Binding chassis logical_port=first > > -wait_column "$hv2_uuid" Port_Binding chassis logical_port=second > > -wait_column "$hv3_uuid" Port_Binding chassis logical_port=outside > > - > > -OVN_POPULATE_ARP > > + sim_add hv1 > > + as hv1 > > + check ovs-vsctl add-br br-phys > > + ovn_attach n1 br-phys 192.168.0.11 > > > > -send_arp() { > > - local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6 > > - local > request=${eth_dst}${eth_src}08060001080006040001${eth_src}${spa}${eth_dst}${tpa} > > - as ${hv} ovs-appctl netdev-dummy/receive $inport $request > > - echo "${request}" > > -} > > + sim_add hv2 > > + as hv2 > > + check ovs-vsctl add-br br-phys > > + ovn_attach n1 br-phys 192.168.0.12 > > > > -send_rarp() { > > - local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6 > > - local > request=${eth_dst}${eth_src}80350001080006040001${eth_src}${spa}${eth_dst}${tpa} > > - as ${hv} ovs-appctl netdev-dummy/receive $inport $request > > - echo "${request}" > > -} > > + sim_add hv3 > > + as hv3 > > + check ovs-vsctl add-br br-phys > > + ovn_attach n1 br-phys 192.168.0.13 > > + > > + # Disable local ARP responder to pass ARP requests through tunnels > > + check ovn-nbctl ls-add ls0 -- add Logical_Switch ls0 other_config > vlan-passthru=true > > + > > + check ovn-nbctl lsp-add ls0 migrator > > + check ovn-nbctl lsp-set-options migrator requested-chassis=hv1,hv2 \ > > + activation-strategy=$1 > > + > > + check ovn-nbctl lsp-add ls0 first > > + check ovn-nbctl lsp-set-options first requested-chassis=hv1 > > + check ovn-nbctl lsp-add ls0 second > > + check ovn-nbctl lsp-set-options second requested-chassis=hv2 > > + check ovn-nbctl lsp-add ls0 outside > > + check ovn-nbctl lsp-set-options outside requested-chassis=hv3 > > + > > + check ovn-nbctl lsp-set-addresses migrator "00:00:00:00:00:10 > 10.0.0.10 fd10::10" > > + check ovn-nbctl lsp-set-addresses first "00:00:00:00:00:01 10.0.0.1" > > + check ovn-nbctl lsp-set-addresses second "00:00:00:00:00:02 > 10.0.0.2" > > + check ovn-nbctl lsp-set-addresses outside "00:00:00:00:00:03 > 10.0.0.3" > > + > > + for hv in hv1 hv2; do > > + as $hv check ovs-vsctl -- add-port br-int migrator -- \ > > + set Interface migrator external-ids:iface-id=migrator \ > > + options:tx_pcap=$hv/migrator-tx.pcap > \ > > + options:rxq_pcap=$hv/migrator-rx.pcap > > + done > > > > -reset_env() { > > - as hv1 reset_pcap_file migrator hv1/migrator > > - as hv2 reset_pcap_file migrator hv2/migrator > > - as hv1 reset_pcap_file first hv1/first > > - as hv2 reset_pcap_file second hv2/second > > - as hv3 reset_pcap_file outside hv3/outside > > + as hv1 check ovs-vsctl -- add-port br-int first -- \ > > + set Interface first external-ids:iface-id=first > > + as hv2 check ovs-vsctl -- add-port br-int second -- \ > > + set Interface second external-ids:iface-id=second > > + as hv3 check ovs-vsctl -- add-port br-int outside -- \ > > + set Interface outside external-ids:iface-id=outside > > > > - for port in hv1/migrator hv2/migrator hv1/first hv2/second > hv3/outside; do > > - : > $port.expected > > + for hv in hv1 hv2 hv3; do > > + wait_row_count Chassis 1 name=$hv > > done > > -} > > + hv1_uuid=$(fetch_column Chassis _uuid name=hv1) > > + hv2_uuid=$(fetch_column Chassis _uuid name=hv2) > > + hv3_uuid=$(fetch_column Chassis _uuid name=hv3) > > + > > + wait_column "$hv1_uuid" Port_Binding chassis logical_port=migrator > > + wait_column "$hv1_uuid" Port_Binding requested_chassis > logical_port=migrator > > + wait_column "$hv2_uuid" Port_Binding additional_chassis > logical_port=migrator > > + wait_column "$hv2_uuid" Port_Binding requested_additional_chassis > logical_port=migrator > > + > > + wait_column "$hv1_uuid" Port_Binding chassis logical_port=first > > + wait_column "$hv2_uuid" Port_Binding chassis logical_port=second > > + wait_column "$hv3_uuid" Port_Binding chassis logical_port=outside > > + > > + OVN_POPULATE_ARP > > + > > + send_arp() { > > + local hv=${1} inport=${2} op=${3} eth_src=${4} eth_dst=${5} > spa=${6} tpa=${7} > > + local request=$(fmt_pkt "Ether(dst='${eth_dst}', > src='${eth_src}')/ \ > > + ARP(op=${op}, hwsrc='${eth_src}', > hwdst='${eth_dst}', \ > > + psrc='${spa}', pdst='${tpa}')") > > + as ${hv} ovs-appctl netdev-dummy/receive $inport $request > > + echo "${request}" > > + } > > + > > + send_rarp() { > > + local hv=${1} inport=${2} eth_src=${3} spa=${4} > > + local request=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', > src='${eth_src}', type=0x8035)/ \ > > + ARP(op=1, hwsrc='${eth_src}', > hwdst='00:00:00:00:00:00', \ > > + psrc='${spa}', pdst='${spa}')") > > + as ${hv} ovs-appctl netdev-dummy/receive $inport $request > > + echo "${request}" > > + } > > + > > + send_na() { > > + local hv=${1} inport=${2} eth_src=${3} spa=${4} > > + local request=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', > src='${eth_src}')/ \ > > + IPv6(dst='ff02::1', src='${spa}')/ \ > > + ICMPv6ND_NA(tgt='${spa}')/ \ > > + > ICMPv6NDOptDstLLAddr(lladdr='${eth_src}')") > > + as ${hv} ovs-appctl netdev-dummy/receive $inport $request > > + echo "${request}" > > + } > > + > > + > > + reset_env() { > > + as hv1 reset_pcap_file migrator hv1/migrator > > + as hv2 reset_pcap_file migrator hv2/migrator > > + as hv1 reset_pcap_file first hv1/first > > + as hv2 reset_pcap_file second hv2/second > > + as hv3 reset_pcap_file outside hv3/outside > > + > > + for port in hv1/migrator hv2/migrator hv1/first hv2/second > hv3/outside; do > > + : > $port.expected > > + done > > + } > > > > -check_packets() { > > - OVN_CHECK_PACKETS([hv1/migrator-tx.pcap], [hv1/migrator.expected]) > > - OVN_CHECK_PACKETS([hv2/migrator-tx.pcap], [hv2/migrator.expected]) > > - OVN_CHECK_PACKETS([hv3/outside-tx.pcap], [hv3/outside.expected]) > > - OVN_CHECK_PACKETS([hv1/first-tx.pcap], [hv1/first.expected]) > > - OVN_CHECK_PACKETS([hv2/second-tx.pcap], [hv2/second.expected]) > > -} > > + check_packets() { > > + OVN_CHECK_PACKETS([hv1/migrator-tx.pcap], > [hv1/migrator.expected]) > > + OVN_CHECK_PACKETS([hv2/migrator-tx.pcap], > [hv2/migrator.expected]) > > + OVN_CHECK_PACKETS([hv3/outside-tx.pcap], [hv3/outside.expected]) > > + OVN_CHECK_PACKETS([hv1/first-tx.pcap], [hv1/first.expected]) > > + OVN_CHECK_PACKETS([hv2/second-tx.pcap], [hv2/second.expected]) > > + } > > > > -migrator_spa=$(ip_to_hex 10 0 0 10) > > -first_spa=$(ip_to_hex 10 0 0 1) > > -second_spa=$(ip_to_hex 10 0 0 2) > > -outside_spa=$(ip_to_hex 10 0 0 3) > > + reset_env > > > > -reset_env > > + # Packet from hv3:Outside arrives to hv1:Migrator > > + # hv3:Outside cannot reach hv2:Migrator because it is blocked by > activation strategy > > + request=$(send_arp hv3 outside 1 "00:00:00:00:00:03" > "00:00:00:00:00:10" "10.0.0.3" "10.0.0.10") > > + echo $request >> hv1/migrator.expected > > > > -# Packet from hv3:Outside arrives to hv1:Migrator > > -# hv3:Outside cannot reach hv2:Migrator because it is blocked by RARP > strategy > > -request=$(send_arp hv3 outside 000000000003 000000000010 $outside_spa > $migrator_spa) > > -echo $request >> hv1/migrator.expected > > + # Packet from hv1:First arrives to hv1:Migrator > > + # hv1:First cannot reach hv2:Migrator because it is blocked by > activation strategy > > + request=$(send_arp hv1 first 1 "00:00:00:00:00:01" > "00:00:00:00:00:10" "10.0.0.1" "10.0.0.10") > > + echo $request >> hv1/migrator.expected > > > > -# Packet from hv1:First arrives to hv1:Migrator > > -# hv1:First cannot reach hv2:Migrator because it is blocked by RARP > strategy > > -request=$(send_arp hv1 first 000000000001 000000000010 $first_spa > $migrator_spa) > > -echo $request >> hv1/migrator.expected > > + # Packet from hv2:Second arrives to hv1:Migrator > > + # hv2:Second cannot reach hv2:Migrator because it is blocked by > activation strategy > > + request=$(send_arp hv2 second 1 "00:00:00:00:00:02" > "00:00:00:00:00:10" "10.0.0.2" "10.0.0.10") > > + echo $request >> hv1/migrator.expected > > > > -# Packet from hv2:Second arrives to hv1:Migrator > > -# hv2:Second cannot reach hv2:Migrator because it is blocked by RARP > strategy > > -request=$(send_arp hv2 second 000000000002 000000000010 $second_spa > $migrator_spa) > > -echo $request >> hv1/migrator.expected > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + # Packet from hv1:Migrator arrives to hv3:Outside > > + request=$(send_arp hv1 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:03" "10.0.0.10" "10.0.0.3") > > + echo $request >> hv3/outside.expected > > > > -# Packet from hv1:Migrator arrives to hv3:Outside > > -request=$(send_arp hv1 migrator 000000000010 000000000003 $migrator_spa > $outside_spa) > > -echo $request >> hv3/outside.expected > > + # Packet from hv1:Migrator arrives to hv1:First > > + request=$(send_arp hv1 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:01" "10.0.0.10" "10.0.0.1") > > + echo $request >> hv1/first.expected > > > > -# Packet from hv1:Migrator arrives to hv1:First > > -request=$(send_arp hv1 migrator 000000000010 000000000001 $migrator_spa > $first_spa) > > -echo $request >> hv1/first.expected > > + # Packet from hv1:Migrator arrives to hv2:Second > > + request=$(send_arp hv1 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:02" "10.0.0.10" "10.0.0.2") > > + echo $request >> hv2/second.expected > > > > -# Packet from hv1:Migrator arrives to hv2:Second > > -request=$(send_arp hv1 migrator 000000000010 000000000002 $migrator_spa > $second_spa) > > -echo $request >> hv2/second.expected > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + # hv2:Migrator cannot reach to hv3:Outside because it is blocked by > activation strategy > > + request=$(send_arp hv2 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:03" "10.0.0.10" "10.0.0.3") > > > > -# hv2:Migrator cannot reach to hv3:Outside because it is blocked by > RARP strategy > > -request=$(send_arp hv2 migrator 000000000010 000000000003 $migrator_spa > $outside_spa) > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + AT_CHECK([ovn-sbctl find port_binding logical_port=migrator | grep > -q additional-chassis-activated], [1]) > > > > -AT_CHECK([ovn-sbctl find port_binding logical_port=migrator | grep -q > additional-chassis-activated], [1]) > > + # Now activate hv2:Migrator location > > + if [[ "$1" == "rarp" ]]; then > > + request=$(send_rarp hv2 migrator "00:00:00:00:00:10" > "10.0.0.10") > > + elif [[ "$1" == "na" ]]; then > > + request=$(send_na hv2 migrator "00:00:00:00:00:10" "fd10::10") > > + echo $request > > + else > > + request=$(send_arp hv2 migrator 1 "00:00:00:00:00:10" > "ff:ff:ff:ff:ff:ff" "10.0.0.10" "10.0.0.10") > > + fi > > > > -# Now activate hv2:Migrator location > > -request=$(send_rarp hv2 migrator 000000000010 ffffffffffff > $migrator_spa $migrator_spa) > > + # Activation packet was reinjected into the pipeline > > + echo $request >> hv3/outside.expected > > + echo $request >> hv1/first.expected > > + echo $request >> hv2/second.expected > > > > -# RARP was reinjected into the pipeline > > -echo $request >> hv3/outside.expected > > -echo $request >> hv1/first.expected > > -echo $request >> hv2/second.expected > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + pb_uuid=$(ovn-sbctl --bare --columns _uuid find Port_Binding > logical_port=migrator) > > + OVS_WAIT_UNTIL([test xhv2 = x$(ovn-sbctl get Port_Binding $pb_uuid > options:additional-chassis-activated | tr -d '""')]) > > > > -pb_uuid=$(ovn-sbctl --bare --columns _uuid find Port_Binding > logical_port=migrator) > > -OVS_WAIT_UNTIL([test xhv2 = x$(ovn-sbctl get Port_Binding $pb_uuid > options:additional-chassis-activated | tr -d '""')]) > > + # Now packet arrives to both locations > > + request=$(send_arp hv3 outside 1 "00:00:00:00:00:03" > "00:00:00:00:00:10" "10.0.0.3" "10.0.0.10") > > + echo $request >> hv1/migrator.expected > > + echo $request >> hv2/migrator.expected > > > > -# Now packet arrives to both locations > > -request=$(send_arp hv3 outside 000000000003 000000000010 $outside_spa > $migrator_spa) > > -echo $request >> hv1/migrator.expected > > -echo $request >> hv2/migrator.expected > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + # Packet from hv1:Migrator still arrives to hv3:Outside > > + request=$(send_arp hv1 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:03" "10.0.0.10" "10.0.0.3") > > + echo $request >> hv3/outside.expected > > > > -# Packet from hv1:Migrator still arrives to hv3:Outside > > -request=$(send_arp hv1 migrator 000000000010 000000000003 $migrator_spa > $outside_spa) > > -echo $request >> hv3/outside.expected > > + check_packets > > + reset_env > > > > -check_packets > > -reset_env > > + # hv2:Migrator can now reach to hv3:Outside because it was activated > > + request=$(send_arp hv2 migrator 1 "00:00:00:00:00:10" > "00:00:00:00:00:03" "10.0.0.10" "10.0.0.3") > > + echo $request >> hv3/outside.expected > > > > -# hv2:Migrator can now reach to hv3:Outside because RARP strategy > activated it > > -request=$(send_arp hv2 migrator 000000000010 000000000003 $migrator_spa > $outside_spa) > > -echo $request >> hv3/outside.expected > > + check_packets > > > > -check_packets > > + # complete port migration and check that -activated flag is reset > > + check ovn-nbctl lsp-set-options migrator requested-chassis=hv2 > > + OVS_WAIT_UNTIL([test x = x$(ovn-sbctl get Port_Binding $pb_uuid > options:additional-chassis-activated)]) > > > > -# complete port migration and check that -activated flag is reset > > -check ovn-nbctl lsp-set-options migrator requested-chassis=hv2 > > -OVS_WAIT_UNTIL([test x = x$(ovn-sbctl get Port_Binding $pb_uuid > options:additional-chassis-activated)]) > > + OVN_CLEANUP([hv1],[hv2],[hv3]) > > > > -OVN_CLEANUP([hv1],[hv2],[hv3]) > > + AT_CLEANUP > > +])]) > > > > -AT_CLEANUP > > -]) > > +ACTIVATION_STRATEGY_TEST([rarp]) > > +ACTIVATION_STRATEGY_TEST([garp]) > > +ACTIVATION_STRATEGY_TEST([na]) > > > > OVN_FOR_EACH_NORTHD([ > > AT_SETUP([options:activation-strategy=rarp is not waiting for > southbound db]) > > Regards, > Dumitru > > > Thanks, Ales _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
