On 4/3/25 9:54 AM, Ales Musil via dev wrote:
> On Mon, Mar 24, 2025 at 9:42 AM Aditya Mehakare <[email protected]>
> wrote:
>
>> This commit adds COPP support for DHCPv4 Relay.
>>
>> Acked-by: Naveen Yerramneni <[email protected]>
>> Signed-off-by: Aditya Mehakare <[email protected]>
>> ---
>> v2: Handle intermittent test failure.
>> ---
>>
>
> Hi Aditya,
>
> thank you for the patch, I have some minor comments down below.
>
Hi Aditya, Ales,
> lib/copp.c | 1 +
>> lib/copp.h | 1 +
>> northd/northd.c | 20 +++++---
>> ovn-nb.xml | 4 ++
>> tests/ovn-northd.at | 2 +-
>> tests/ovn.at | 120 ++++++++++++++++++++++++++++++++++++++++++++
>> 6 files changed, 141 insertions(+), 7 deletions(-)
>>
>> diff --git a/lib/copp.c b/lib/copp.c
>> index 11dd9029d..8ba9ab7f4 100644
>> --- a/lib/copp.c
>> +++ b/lib/copp.c
>> @@ -40,6 +40,7 @@ static char *copp_proto_names[COPP_PROTO_MAX] = {
>> [COPP_REJECT] = "reject",
>> [COPP_SVC_MONITOR] = "svc-monitor",
>> [COPP_BFD] = "bfd",
>> + [COPP_DHCPV4_RELAY] = "dhcpv4-relay",
>> };
>>
>> static const char *
>> diff --git a/lib/copp.h b/lib/copp.h
>> index b99737220..3a7d1ccc5 100644
>> --- a/lib/copp.h
>> +++ b/lib/copp.h
>> @@ -38,6 +38,7 @@ enum copp_proto {
>> COPP_BFD,
>> COPP_REJECT,
>> COPP_SVC_MONITOR,
>> + COPP_DHCPV4_RELAY,
>> COPP_PROTO_MAX,
>> COPP_PROTO_INVALID = COPP_PROTO_MAX,
>> };
>> diff --git a/northd/northd.c b/northd/northd.c
>> index 1d3e132d4..19cddd6c6 100644
>> --- a/northd/northd.c
>> +++ b/northd/northd.c
>> @@ -15098,7 +15098,8 @@ static void
>> build_dhcp_relay_flows_for_lrouter_port(struct ovn_port *op,
>> struct lflow_table *lflows,
>> struct ds *match, struct ds
>> *actions,
>> - struct lflow_ref *lflow_ref)
>> + struct lflow_ref *lflow_ref,
>> + const struct shash *meter_groups)
>> {
>> if (!op->nbrp || !op->nbrp->dhcp_relay ||
>> !op->lrp_networks.n_ipv4_addrs) {
>> return;
>> @@ -15147,8 +15148,11 @@ build_dhcp_relay_flows_for_lrouter_port(struct
>> ovn_port *op,
>> "next; /* DHCP_RELAY_REQ */",
>> op->lrp_networks.ipv4_addrs[0].addr_s, server_ip_str);
>>
>> - ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
>> - ds_cstr(match), ds_cstr(actions),
>> + ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
>> + ds_cstr(match), ds_cstr(actions), NULL,
>> + copp_meter_get(COPP_DHCPV4_RELAY,
>> + op->od->nbr->copp,
>> + meter_groups),
>>
>
> nit: The arguments are not properly aligned.
>
> &op->nbrp->header_, lflow_ref);
>>
>> ds_clear(match);
>> @@ -15209,9 +15213,12 @@ build_dhcp_relay_flows_for_lrouter_port(struct
>> ovn_port *op,
>> " = dhcp_relay_resp_chk(%s, %s); next; /* DHCP_RELAY_RESP */",
>> op->lrp_networks.ipv4_addrs[0].addr_s, server_ip_str);
>>
>> - ovn_lflow_add_with_hint(lflows, op->od,
>> S_ROUTER_IN_DHCP_RELAY_RESP_CHK,
>> + ovn_lflow_add_with_hint__(lflows, op->od,
>> S_ROUTER_IN_DHCP_RELAY_RESP_CHK,
>> 100,
>> - ds_cstr(match), ds_cstr(actions),
>> + ds_cstr(match), ds_cstr(actions), NULL,
>> + copp_meter_get(COPP_DHCPV4_RELAY,
>> + op->od->nbr->copp,
>> + meter_groups),
>>
>
> nit: Same here.
>
> &op->nbrp->header_, lflow_ref);
>>
>>
>> @@ -17394,7 +17401,8 @@ build_lswitch_and_lrouter_iterate_by_lrp(struct
>> ovn_port *op,
>> build_dhcpv6_reply_flows_for_lrouter_port(op, lsi->lflows,
>> &lsi->match,
>> op->lflow_ref);
>> build_dhcp_relay_flows_for_lrouter_port(op, lsi->lflows, &lsi->match,
>> - &lsi->actions, op->lflow_ref);
>> + &lsi->actions, op->lflow_ref,
>> + lsi->meter_groups);
>> build_ipv6_input_flows_for_lrouter_port(op, lsi->lflows,
>> &lsi->match, &lsi->actions,
>> lsi->meter_groups,
>> diff --git a/ovn-nb.xml b/ovn-nb.xml
>> index ff5f2f249..b72be9e59 100644
>> --- a/ovn-nb.xml
>> +++ b/ovn-nb.xml
>> @@ -640,6 +640,10 @@
>> Rate limiting meter for packets that are arriving to service
>> monitor MAC address.
>> </column>
>> + <column name="meters" key="dhcpv4-relay">
>> + Rate limiting meter for DHCPv4 relay packets (request/response) when
>> + DHCPv4 Relay functionality is enabled.
>> + </column>
>> <column name="external_ids">
>> See <em>External IDs</em> at the beginning of this document.
>> </column>
>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
>> index 419130aa8..55605c443 100644
>> --- a/tests/ovn-northd.at
>> +++ b/tests/ovn-northd.at
>> @@ -4203,7 +4203,7 @@ AT_CHECK([ovn-sbctl list logical_flow | grep
>> trigger_event -A 2 | grep -q meter0
>>
>> # let's try to add an usupported protocol "dhcp"
>> AT_CHECK([ovn-nbctl --wait=hv copp-add copp5 dhcp meter1],[1],[],[dnl
>> -ovn-nbctl: Invalid control protocol. Allowed values: arp, arp-resolve,
>> dhcpv4-opts, dhcpv6-opts, dns, event-elb, icmp4-error, icmp6-error, igmp,
>> nd-na, nd-ns, nd-ns-resolve, nd-ra-opts, tcp-reset, bfd, reject,
>> svc-monitor.
>> +ovn-nbctl: Invalid control protocol. Allowed values: arp, arp-resolve,
>> dhcpv4-opts, dhcpv6-opts, dns, event-elb, icmp4-error, icmp6-error, igmp,
>> nd-na, nd-ns, nd-ns-resolve, nd-ra-opts, tcp-reset, bfd, reject,
>> svc-monitor, dhcpv4-relay.
>> ])
>>
>> #Let's try to add a valid protocol to an unknown datapath
>> diff --git a/tests/ovn.at b/tests/ovn.at
>> index 714286596..235f324ed 100644
>> --- a/tests/ovn.at
>> +++ b/tests/ovn.at
>> @@ -40171,6 +40171,126 @@ n_packets=3
>>
>> sid=`ip_to_hex 172.16.1.1`
>>
>> +# ====================================================
>> +# Test Copp for DHCP request/response packets
>> +
>> +AT_CHECK([ovn-nbctl --wait=hv meter-add dhcp_relay_meter drop 10 pktps 5])
>> +AT_CHECK([ovn-nbctl --wait=hv copp-add copp_dhcp_relay dhcpv4-relay
>> dhcp_relay_meter])
>> +AT_CHECK([ovn-nbctl --wait=hv lr-copp-add copp_dhcp_relay lr0])
>>
>
> nit: All of those could be replaced with "check".
>
> +
>> +AT_CHECK([as hv1 ovs-appctl -t ovn-controller meter-table-list], [0], [dnl
>> +dhcp_relay_meter: 1
>> +])
>> +
>> +# Print some information that may help debugging.
>> +ovs-ofctl dump-flows br-int > pflows_dhcp_relay_copp
>> +ovn-sbctl find logical_flow controller_meter=dhcp_relay_meter >
>> lflows_dhcp_relay_copp
>> +
>> +## Verify packets within defined limit are not dropped.
>> +
>> +# Send DHCP discovery.
>> +src_mac="505400000010"
>> +src_ip=`ip_to_hex 0.0.0.0`
>> +dst_mac="ffffffffffff"
>> +dst_ip=`ip_to_hex 255.255.255.255`
>> +yiaddr=`ip_to_hex 0.0.0.0`
>> +giaddr=`ip_to_hex 0.0.0.0`
>> +sid=$src_ip
>>
>
> This is a great opportunity to use scapy for the send_dhcp_packet.
>
I agree we should. But let's not block this patch on it. Let's do that
as a follow up. Aditya, will you have time to do that by any chance?
> +
>> +for i in {1..3}
>> +do
>> + send_dhcp_packet $src_mac $src_ip $dst_mac $dst_ip 01 01 $yiaddr
>> $giaddr $sid vif0
>> +done
>> +
>> +echo "Meter stats:"
>> +as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int
>> +meter_stat=$(as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int)
>> +drop_cnt=$(echo $meter_stat | tail -n1 | sed -n
>> 's/.*packet_count:\([[0-9]]\+\).*/\1/p')
>> +AT_CHECK([ test $drop_cnt -eq 0 ], [0], [])
>>
>
> nit: Extra space around the test, also there is no need for the second and
> third argument.
>
> +
>> +# Send DHCP offer.
>> +src_mac="50540000001f"
>> +src_ip=`ip_to_hex 172.16.1.1`
>> +dst_mac="505400000002"
>> +dst_ip=`ip_to_hex 192.168.1.1`
>> +yiaddr=`ip_to_hex 192.168.1.10`
>> +giaddr=`ip_to_hex 192.168.1.1`
>> +sid=$src_ip
>> +
>> +sleep 1
>> +for i in {1..3}
>> +do
>> + send_dhcp_packet $src_mac $src_ip $dst_mac $dst_ip 02 02 $yiaddr
>> $giaddr $sid ext0
>> +done
>> +
>> +echo "Meter stats:"
>> +as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int
>> +meter_stat=$(as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int)
>> +drop_cnt=$(echo $meter_stat | tail -n1 | sed -n
>> 's/.*packet_count:\([[0-9]]\+\).*/\1/p')
>> +AT_CHECK([ test $drop_cnt -eq 0 ], [0], [])
>
>
> nit: Same here.
>
>
>> +
>> +## Verify packets exceeding rate limiting are dropped.
>> +
>> +# Send DHCP discovery.
>> +src_mac="505400000010"
>> +src_ip=`ip_to_hex 0.0.0.0`
>> +dst_mac="ffffffffffff"
>> +dst_ip=`ip_to_hex 255.255.255.255`
>> +yiaddr=`ip_to_hex 0.0.0.0`
>> +giaddr=`ip_to_hex 0.0.0.0`
>> +sid=$src_ip
>> +
>> +sleep 1
>> +start_time=$(date +%s%3N)
>> +for i in {1..15}
>> +do
>> + send_dhcp_packet $src_mac $src_ip $dst_mac $dst_ip 01 01 $yiaddr
>> $giaddr $sid vif0
>> +done
>> +end_time=$(date +%s%3N)
>> +
>> +# On particularly slow or overloaded systems, the transmission rate may
>> +# be lower than the configured meter rate. To prevent false test
>> +# failures, we check the transmission duration, and if it's
>> +# greater than expected time, just skip the test.
>> +d_ms=$(expr $end_time - $start_time)
>> +echo "Discover transmission duration ms: $d_ms"
>> +AT_SKIP_IF([test $d_ms -gt 1000])
>> +
>> +echo "Meter stats:"
>> +as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int
>> +meter_stat=$(as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int)
>> +drop_cnt=$(echo $meter_stat | tail -n1 | sed -n
>> 's/.*packet_count:\([[0-9]]\+\).*/\1/p')
>> +AT_CHECK([ test $drop_cnt -gt 1 ], [0], [])
>>
>
> nit: Same here.
>
>
>> +
>> +# Send DHCP offer.
>> +src_mac="50540000001f"
>> +src_ip=`ip_to_hex 172.16.1.1`
>> +dst_mac="505400000002"
>> +dst_ip=`ip_to_hex 192.168.1.1`
>> +yiaddr=`ip_to_hex 192.168.1.10`
>> +giaddr=`ip_to_hex 192.168.1.1`
>> +sid=$src_ip
>> +
>> +sleep 1
>> +start_time=$(date +%s%3N)
>> +for i in {1..15}
>> +do
>> + send_dhcp_packet $src_mac $src_ip $dst_mac $dst_ip 02 02 $yiaddr
>> $giaddr $sid ext0
>> +done
>> +end_time=$(date +%s%3N)
>> +
>> +d_ms=$(expr $end_time - $start_time)
>> +echo "Offer transmission duration ms: $d_ms"
>> +AT_SKIP_IF([test $d_ms -gt 1000])
>> +
>> +echo "Meter stats:"
>> +as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int
>> +prev_cnt=$drop_cnt
>> +meter_stat=$(as hv1 ovs-ofctl -O OpenFlow15 meter-stats br-int)
>> +drop_cnt=$(echo $meter_stat | tail -n1 | sed -n
>> 's/.*packet_count:\([[0-9]]\+\).*/\1/p')
>> +drop_delta=$(expr $drop_cnt - $prev_cnt)
>> +AT_CHECK([ test $drop_delta -gt 1 ], [0], [])
>>
>
> nit: Same here.
>
>
>
>> +
>> OVN_CLEANUP([hv1
>> /WARN\|DHCP_RELAY/d
>> ])
>> --
>> 2.43.5
>>
>> _______________________________________________
>> dev mailing list
>> [email protected]
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>>
> Thanks,
> Ales
I took care of the small nits, added a NEWS entry and pushed this patch
to main.
I also added Aditya to AUTHORS.rst.
Regards,
Dumitru
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev