Message ID | 20230710110517.128560-3-amusil@redhat.com |
---|---|
State | Superseded |
Headers | show |
Series | Add MAC binding aging timestamp refresh mechanism | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_ovn-kubernetes | success | github build: passed |
ovsrobot/github-robot-_Build_and_Test | fail | github build: failed |
Hi Ales, Can you please add a test to tests/ovn-controller.at that ensures that flows in table 79 exist when we expect them to and that they are removed when we expect them to be removed? On 7/10/23 07:05, Ales Musil wrote: > Populate and use the MAC cache table. The MAC cache has > the following entries: > ip,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,nw_src=<MB_IP> actions=drop > ipv6,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,ipv6_src=<MB_IP> actions=drop > > The "mac_cache_use" action will resubmit packets from > "lr_in_learn_neighbor" table for MAC bindings that we already > know. > > This is a preparation for the MAC binding refresh mechanism. > > Signed-off-by: Ales Musil <amusil@redhat.com> > --- > controller/lflow.c | 22 ++++++++++++++++++++++ > controller/lflow.h | 1 + > northd/northd.c | 2 +- > tests/ovn-northd.at | 2 +- > tests/ovn.at | 23 ++++++++++++++++++++--- > 5 files changed, 45 insertions(+), 5 deletions(-) > > diff --git a/controller/lflow.c b/controller/lflow.c > index 22faaf013..bc5f73279 100644 > --- a/controller/lflow.c > +++ b/controller/lflow.c > @@ -887,6 +887,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, > .fdb_lookup_ptable = OFTABLE_LOOKUP_FDB, > .in_port_sec_ptable = OFTABLE_CHK_IN_PORT_SEC, > .out_port_sec_ptable = OFTABLE_CHK_OUT_PORT_SEC, > + .mac_cache_use_table = OFTABLE_MAC_CACHE_USE, > .ctrl_meter_id = ctrl_meter_id, > .common_nat_ct_zone = get_common_nat_zone(ldp), > }; > @@ -1337,6 +1338,7 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, > > struct match get_arp_match = MATCH_CATCHALL_INITIALIZER; > struct match lookup_arp_match = MATCH_CATCHALL_INITIALIZER; > + struct match mb_cache_use_match = MATCH_CATCHALL_INITIALIZER; > > if (strchr(ip, '.')) { > ovs_be32 ip_addr; > @@ -1345,9 +1347,14 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, > VLOG_WARN_RL(&rl, "bad 'ip' %s", ip); > return; > } > + > match_set_reg(&get_arp_match, 0, ntohl(ip_addr)); > + > match_set_reg(&lookup_arp_match, 0, ntohl(ip_addr)); > match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_ARP)); > + > + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IP)); > + match_set_nw_src(&mb_cache_use_match, ip_addr); > } else { > struct in6_addr ip6; > if (!ipv6_parse(ip, &ip6)) { > @@ -1363,6 +1370,9 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, > match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_IPV6)); > match_set_nw_proto(&lookup_arp_match, 58); > match_set_icmp_code(&lookup_arp_match, 0); > + > + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IPV6)); > + match_set_ipv6_src(&mb_cache_use_match, &ip6); > } > > match_set_metadata(&get_arp_match, htonll(pb->datapath->tunnel_key)); > @@ -1372,6 +1382,11 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, > match_set_reg(&lookup_arp_match, MFF_LOG_INPORT - MFF_REG0, > pb->tunnel_key); > > + match_set_dl_src(&mb_cache_use_match, mac_addr); > + match_set_reg(&mb_cache_use_match, MFF_LOG_INPORT - MFF_REG0, > + pb->tunnel_key); > + match_set_metadata(&mb_cache_use_match, htonll(pb->datapath->tunnel_key)); > + > uint64_t stub[1024 / 8]; > struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > uint8_t value = 1; > @@ -1392,6 +1407,13 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, > &lookup_arp_match, &ofpacts, > b ? &b->header_.uuid : &smb->header_.uuid); > > + if (b) { > + ofpbuf_clear(&ofpacts); > + ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority, > + b->header_.uuid.parts[0], &mb_cache_use_match, > + &ofpacts, &b->header_.uuid); > + } > + > ofpbuf_uninit(&ofpacts); > } > > diff --git a/controller/lflow.h b/controller/lflow.h > index 2472dec29..5da4385e4 100644 > --- a/controller/lflow.h > +++ b/controller/lflow.h > @@ -93,6 +93,7 @@ struct uuid; > #define OFTABLE_ECMP_NH_MAC 76 > #define OFTABLE_ECMP_NH 77 > #define OFTABLE_CHK_LB_AFFINITY 78 > +#define OFTABLE_MAC_CACHE_USE 79 > > struct lflow_ctx_in { > struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath; > diff --git a/northd/northd.c b/northd/northd.c > index b9605862e..4e3c5d02a 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -12615,7 +12615,7 @@ build_neigh_learning_flows_for_lrouter( > learn_from_arp_request ? "" : > " || "REGBIT_LOOKUP_NEIGHBOR_IP_RESULT" == 0"); > ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 100, > - ds_cstr(match), "next;"); > + ds_cstr(match), "mac_cache_use; next;"); > > ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90, > "arp", "put_arp(inport, arp.spa, arp.sha); next;", > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index 3e06f14c9..6298d4cec 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -7432,7 +7432,7 @@ AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e lr_in_learn_neighbor | > table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_na), action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;) > table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_ns), action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;) > table=2 (lr_in_learn_neighbor), priority=0 , match=(1), action=(drop;) > - table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1), action=(next;) > + table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1), action=(mac_cache_use; next;) > table=2 (lr_in_learn_neighbor), priority=90 , match=(arp), action=(put_arp(inport, arp.spa, arp.sha); next;) > table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_na), action=(put_nd(inport, nd.target, nd.tll); next;) > table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_ns), action=(put_nd(inport, ip6.src, nd.sll); next;) > diff --git a/tests/ovn.at b/tests/ovn.at > index 7fee42acf..7cee8a175 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -34532,12 +34532,23 @@ send_garp() { > mac_byte=$3 > ip_byte=${4-$3} > > - mac="0000000010$mac_byte" > - ip=`ip_to_hex 192 168 10 $ip_byte` > - packet=ffffffffffff${mac}08060001080006040002${mac}${ip}${mac}${ip} > + mac="00:00:00:00:10:${mac_byte}" > + ip="192.168.10.${ip_byte}" > + packet=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${mac}')/ \ > + ARP(op=2, hwsrc='${mac}', hwdst='${mac}', \ > + psrc='${ip}', pdst='${ip}')") > as $hv ovs-appctl netdev-dummy/receive $dev $packet > } > > +send_udp() { > + hv=$1 > + dev=$2 > + byte=$3 > + > + packet=$(fmt_pkt "Ether(dst='00:00:00:00:10:00', src='00:00:00:00:10:${byte}')/ \ > + IP(dst='192.168.20.${byte}', src='192.168.10.${byte}')/UDP()") > + as $hv ovs-appctl netdev-dummy/receive $dev $packet > +} > # Check if the option is not present by default > AT_CHECK([fetch_column nb:logical_router options name="gw" | grep -q mac_binding_age_threshold], [1]) > > @@ -34548,6 +34559,12 @@ send_garp hv2 ext2 20 > OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.10"]) > OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.20"]) > > +send_udp hv1 ext1 10 > +send_udp hv2 ext2 20 > + > +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=79 | grep "192.168.10.10" | grep -q "n_packets=1"]) > +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=79 | grep "192.168.10.20" | grep -q "n_packets=1"]) > + > # Set the MAC binding aging threshold > AT_CHECK([ovn-nbctl set logical_router gw options:mac_binding_age_threshold=1]) > AT_CHECK([fetch_column nb:logical_router options | grep -q mac_binding_age_threshold=1])
On Thu, Jul 20, 2023 at 10:58 PM Mark Michelson <mmichels@redhat.com> wrote: > Hi Ales, > > Can you please add a test to tests/ovn-controller.at that ensures that > flows in table 79 exist when we expect them to and that they are removed > when we expect them to be removed? > Hi Mark, I did adjust in v2 the MAC binding test to also check if the flows are added/removed. > > On 7/10/23 07:05, Ales Musil wrote: > > Populate and use the MAC cache table. The MAC cache has > > the following entries: > > ip,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,nw_src=<MB_IP> > actions=drop > > > ipv6,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,ipv6_src=<MB_IP> > actions=drop > > > > The "mac_cache_use" action will resubmit packets from > > "lr_in_learn_neighbor" table for MAC bindings that we already > > know. > > > > This is a preparation for the MAC binding refresh mechanism. > > > > Signed-off-by: Ales Musil <amusil@redhat.com> > > --- > > controller/lflow.c | 22 ++++++++++++++++++++++ > > controller/lflow.h | 1 + > > northd/northd.c | 2 +- > > tests/ovn-northd.at | 2 +- > > tests/ovn.at | 23 ++++++++++++++++++++--- > > 5 files changed, 45 insertions(+), 5 deletions(-) > > > > diff --git a/controller/lflow.c b/controller/lflow.c > > index 22faaf013..bc5f73279 100644 > > --- a/controller/lflow.c > > +++ b/controller/lflow.c > > @@ -887,6 +887,7 @@ add_matches_to_flow_table(const struct > sbrec_logical_flow *lflow, > > .fdb_lookup_ptable = OFTABLE_LOOKUP_FDB, > > .in_port_sec_ptable = OFTABLE_CHK_IN_PORT_SEC, > > .out_port_sec_ptable = OFTABLE_CHK_OUT_PORT_SEC, > > + .mac_cache_use_table = OFTABLE_MAC_CACHE_USE, > > .ctrl_meter_id = ctrl_meter_id, > > .common_nat_ct_zone = get_common_nat_zone(ldp), > > }; > > @@ -1337,6 +1338,7 @@ consider_neighbor_flow(struct ovsdb_idl_index > *sbrec_port_binding_by_name, > > > > struct match get_arp_match = MATCH_CATCHALL_INITIALIZER; > > struct match lookup_arp_match = MATCH_CATCHALL_INITIALIZER; > > + struct match mb_cache_use_match = MATCH_CATCHALL_INITIALIZER; > > > > if (strchr(ip, '.')) { > > ovs_be32 ip_addr; > > @@ -1345,9 +1347,14 @@ consider_neighbor_flow(struct ovsdb_idl_index > *sbrec_port_binding_by_name, > > VLOG_WARN_RL(&rl, "bad 'ip' %s", ip); > > return; > > } > > + > > match_set_reg(&get_arp_match, 0, ntohl(ip_addr)); > > + > > match_set_reg(&lookup_arp_match, 0, ntohl(ip_addr)); > > match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_ARP)); > > + > > + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IP)); > > + match_set_nw_src(&mb_cache_use_match, ip_addr); > > } else { > > struct in6_addr ip6; > > if (!ipv6_parse(ip, &ip6)) { > > @@ -1363,6 +1370,9 @@ consider_neighbor_flow(struct ovsdb_idl_index > *sbrec_port_binding_by_name, > > match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_IPV6)); > > match_set_nw_proto(&lookup_arp_match, 58); > > match_set_icmp_code(&lookup_arp_match, 0); > > + > > + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IPV6)); > > + match_set_ipv6_src(&mb_cache_use_match, &ip6); > > } > > > > match_set_metadata(&get_arp_match, > htonll(pb->datapath->tunnel_key)); > > @@ -1372,6 +1382,11 @@ consider_neighbor_flow(struct ovsdb_idl_index > *sbrec_port_binding_by_name, > > match_set_reg(&lookup_arp_match, MFF_LOG_INPORT - MFF_REG0, > > pb->tunnel_key); > > > > + match_set_dl_src(&mb_cache_use_match, mac_addr); > > + match_set_reg(&mb_cache_use_match, MFF_LOG_INPORT - MFF_REG0, > > + pb->tunnel_key); > > + match_set_metadata(&mb_cache_use_match, > htonll(pb->datapath->tunnel_key)); > > + > > uint64_t stub[1024 / 8]; > > struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); > > uint8_t value = 1; > > @@ -1392,6 +1407,13 @@ consider_neighbor_flow(struct ovsdb_idl_index > *sbrec_port_binding_by_name, > > &lookup_arp_match, &ofpacts, > > b ? &b->header_.uuid : &smb->header_.uuid); > > > > + if (b) { > > + ofpbuf_clear(&ofpacts); > > + ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority, > > + b->header_.uuid.parts[0], &mb_cache_use_match, > > + &ofpacts, &b->header_.uuid); > > + } > > + > > ofpbuf_uninit(&ofpacts); > > } > > > > diff --git a/controller/lflow.h b/controller/lflow.h > > index 2472dec29..5da4385e4 100644 > > --- a/controller/lflow.h > > +++ b/controller/lflow.h > > @@ -93,6 +93,7 @@ struct uuid; > > #define OFTABLE_ECMP_NH_MAC 76 > > #define OFTABLE_ECMP_NH 77 > > #define OFTABLE_CHK_LB_AFFINITY 78 > > +#define OFTABLE_MAC_CACHE_USE 79 > > > > struct lflow_ctx_in { > > struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath; > > diff --git a/northd/northd.c b/northd/northd.c > > index b9605862e..4e3c5d02a 100644 > > --- a/northd/northd.c > > +++ b/northd/northd.c > > @@ -12615,7 +12615,7 @@ build_neigh_learning_flows_for_lrouter( > > learn_from_arp_request ? "" : > > " || "REGBIT_LOOKUP_NEIGHBOR_IP_RESULT" == 0"); > > ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 100, > > - ds_cstr(match), "next;"); > > + ds_cstr(match), "mac_cache_use; next;"); > > > > ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90, > > "arp", "put_arp(inport, arp.spa, arp.sha); > next;", > > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > > index 3e06f14c9..6298d4cec 100644 > > --- a/tests/ovn-northd.at > > +++ b/tests/ovn-northd.at > > @@ -7432,7 +7432,7 @@ AT_CHECK([cat lrflows | grep -e > lr_in_lookup_neighbor -e lr_in_learn_neighbor | > > table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_na), > action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;) > > table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_ns), > action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;) > > table=2 (lr_in_learn_neighbor), priority=0 , match=(1), > action=(drop;) > > - table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == > 1), action=(next;) > > + table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == > 1), action=(mac_cache_use; next;) > > table=2 (lr_in_learn_neighbor), priority=90 , match=(arp), > action=(put_arp(inport, arp.spa, arp.sha); next;) > > table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_na), > action=(put_nd(inport, nd.target, nd.tll); next;) > > table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_ns), > action=(put_nd(inport, ip6.src, nd.sll); next;) > > diff --git a/tests/ovn.at b/tests/ovn.at > > index 7fee42acf..7cee8a175 100644 > > --- a/tests/ovn.at > > +++ b/tests/ovn.at > > @@ -34532,12 +34532,23 @@ send_garp() { > > mac_byte=$3 > > ip_byte=${4-$3} > > > > - mac="0000000010$mac_byte" > > - ip=`ip_to_hex 192 168 10 $ip_byte` > > - packet=ffffffffffff${mac}08060001080006040002${mac}${ip}${mac}${ip} > > + mac="00:00:00:00:10:${mac_byte}" > > + ip="192.168.10.${ip_byte}" > > + packet=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${mac}')/ \ > > + ARP(op=2, hwsrc='${mac}', hwdst='${mac}', \ > > + psrc='${ip}', pdst='${ip}')") > > as $hv ovs-appctl netdev-dummy/receive $dev $packet > > } > > > > +send_udp() { > > + hv=$1 > > + dev=$2 > > + byte=$3 > > + > > + packet=$(fmt_pkt "Ether(dst='00:00:00:00:10:00', > src='00:00:00:00:10:${byte}')/ \ > > + IP(dst='192.168.20.${byte}', > src='192.168.10.${byte}')/UDP()") > > + as $hv ovs-appctl netdev-dummy/receive $dev $packet > > +} > > # Check if the option is not present by default > > AT_CHECK([fetch_column nb:logical_router options name="gw" | grep -q > mac_binding_age_threshold], [1]) > > > > @@ -34548,6 +34559,12 @@ send_garp hv2 ext2 20 > > OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.10"]) > > OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.20"]) > > > > +send_udp hv1 ext1 10 > > +send_udp hv2 ext2 20 > > + > > +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=79 | grep > "192.168.10.10" | grep -q "n_packets=1"]) > > +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=79 | grep > "192.168.10.20" | grep -q "n_packets=1"]) > > + > > # Set the MAC binding aging threshold > > AT_CHECK([ovn-nbctl set logical_router gw > options:mac_binding_age_threshold=1]) > > AT_CHECK([fetch_column nb:logical_router options | grep -q > mac_binding_age_threshold=1]) > > Thanks, Ales
diff --git a/controller/lflow.c b/controller/lflow.c index 22faaf013..bc5f73279 100644 --- a/controller/lflow.c +++ b/controller/lflow.c @@ -887,6 +887,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, .fdb_lookup_ptable = OFTABLE_LOOKUP_FDB, .in_port_sec_ptable = OFTABLE_CHK_IN_PORT_SEC, .out_port_sec_ptable = OFTABLE_CHK_OUT_PORT_SEC, + .mac_cache_use_table = OFTABLE_MAC_CACHE_USE, .ctrl_meter_id = ctrl_meter_id, .common_nat_ct_zone = get_common_nat_zone(ldp), }; @@ -1337,6 +1338,7 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, struct match get_arp_match = MATCH_CATCHALL_INITIALIZER; struct match lookup_arp_match = MATCH_CATCHALL_INITIALIZER; + struct match mb_cache_use_match = MATCH_CATCHALL_INITIALIZER; if (strchr(ip, '.')) { ovs_be32 ip_addr; @@ -1345,9 +1347,14 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, VLOG_WARN_RL(&rl, "bad 'ip' %s", ip); return; } + match_set_reg(&get_arp_match, 0, ntohl(ip_addr)); + match_set_reg(&lookup_arp_match, 0, ntohl(ip_addr)); match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_ARP)); + + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IP)); + match_set_nw_src(&mb_cache_use_match, ip_addr); } else { struct in6_addr ip6; if (!ipv6_parse(ip, &ip6)) { @@ -1363,6 +1370,9 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_IPV6)); match_set_nw_proto(&lookup_arp_match, 58); match_set_icmp_code(&lookup_arp_match, 0); + + match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IPV6)); + match_set_ipv6_src(&mb_cache_use_match, &ip6); } match_set_metadata(&get_arp_match, htonll(pb->datapath->tunnel_key)); @@ -1372,6 +1382,11 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, match_set_reg(&lookup_arp_match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key); + match_set_dl_src(&mb_cache_use_match, mac_addr); + match_set_reg(&mb_cache_use_match, MFF_LOG_INPORT - MFF_REG0, + pb->tunnel_key); + match_set_metadata(&mb_cache_use_match, htonll(pb->datapath->tunnel_key)); + uint64_t stub[1024 / 8]; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(stub); uint8_t value = 1; @@ -1392,6 +1407,13 @@ consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name, &lookup_arp_match, &ofpacts, b ? &b->header_.uuid : &smb->header_.uuid); + if (b) { + ofpbuf_clear(&ofpacts); + ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority, + b->header_.uuid.parts[0], &mb_cache_use_match, + &ofpacts, &b->header_.uuid); + } + ofpbuf_uninit(&ofpacts); } diff --git a/controller/lflow.h b/controller/lflow.h index 2472dec29..5da4385e4 100644 --- a/controller/lflow.h +++ b/controller/lflow.h @@ -93,6 +93,7 @@ struct uuid; #define OFTABLE_ECMP_NH_MAC 76 #define OFTABLE_ECMP_NH 77 #define OFTABLE_CHK_LB_AFFINITY 78 +#define OFTABLE_MAC_CACHE_USE 79 struct lflow_ctx_in { struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath; diff --git a/northd/northd.c b/northd/northd.c index b9605862e..4e3c5d02a 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -12615,7 +12615,7 @@ build_neigh_learning_flows_for_lrouter( learn_from_arp_request ? "" : " || "REGBIT_LOOKUP_NEIGHBOR_IP_RESULT" == 0"); ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 100, - ds_cstr(match), "next;"); + ds_cstr(match), "mac_cache_use; next;"); ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90, "arp", "put_arp(inport, arp.spa, arp.sha); next;", diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 3e06f14c9..6298d4cec 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -7432,7 +7432,7 @@ AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e lr_in_learn_neighbor | table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_na), action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;) table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_ns), action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;) table=2 (lr_in_learn_neighbor), priority=0 , match=(1), action=(drop;) - table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1), action=(next;) + table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1), action=(mac_cache_use; next;) table=2 (lr_in_learn_neighbor), priority=90 , match=(arp), action=(put_arp(inport, arp.spa, arp.sha); next;) table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_na), action=(put_nd(inport, nd.target, nd.tll); next;) table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_ns), action=(put_nd(inport, ip6.src, nd.sll); next;) diff --git a/tests/ovn.at b/tests/ovn.at index 7fee42acf..7cee8a175 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -34532,12 +34532,23 @@ send_garp() { mac_byte=$3 ip_byte=${4-$3} - mac="0000000010$mac_byte" - ip=`ip_to_hex 192 168 10 $ip_byte` - packet=ffffffffffff${mac}08060001080006040002${mac}${ip}${mac}${ip} + mac="00:00:00:00:10:${mac_byte}" + ip="192.168.10.${ip_byte}" + packet=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${mac}')/ \ + ARP(op=2, hwsrc='${mac}', hwdst='${mac}', \ + psrc='${ip}', pdst='${ip}')") as $hv ovs-appctl netdev-dummy/receive $dev $packet } +send_udp() { + hv=$1 + dev=$2 + byte=$3 + + packet=$(fmt_pkt "Ether(dst='00:00:00:00:10:00', src='00:00:00:00:10:${byte}')/ \ + IP(dst='192.168.20.${byte}', src='192.168.10.${byte}')/UDP()") + as $hv ovs-appctl netdev-dummy/receive $dev $packet +} # Check if the option is not present by default AT_CHECK([fetch_column nb:logical_router options name="gw" | grep -q mac_binding_age_threshold], [1]) @@ -34548,6 +34559,12 @@ send_garp hv2 ext2 20 OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.10"]) OVS_WAIT_UNTIL([ovn-sbctl list mac_binding | grep -q "192.168.10.20"]) +send_udp hv1 ext1 10 +send_udp hv2 ext2 20 + +OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=79 | grep "192.168.10.10" | grep -q "n_packets=1"]) +OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=79 | grep "192.168.10.20" | grep -q "n_packets=1"]) + # Set the MAC binding aging threshold AT_CHECK([ovn-nbctl set logical_router gw options:mac_binding_age_threshold=1]) AT_CHECK([fetch_column nb:logical_router options | grep -q mac_binding_age_threshold=1])
Populate and use the MAC cache table. The MAC cache has the following entries: ip,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,nw_src=<MB_IP> actions=drop ipv6,reg14=<MB_Port>,metadata=<MB_Datapath>,dl_src=<MB_MAC>,ipv6_src=<MB_IP> actions=drop The "mac_cache_use" action will resubmit packets from "lr_in_learn_neighbor" table for MAC bindings that we already know. This is a preparation for the MAC binding refresh mechanism. Signed-off-by: Ales Musil <amusil@redhat.com> --- controller/lflow.c | 22 ++++++++++++++++++++++ controller/lflow.h | 1 + northd/northd.c | 2 +- tests/ovn-northd.at | 2 +- tests/ovn.at | 23 ++++++++++++++++++++--- 5 files changed, 45 insertions(+), 5 deletions(-)