This commit adds COPP support for DHCPv4 Relay. Acked-by: Naveen Yerramneni <naveen.yerramn...@nutanix.com> Signed-off-by: Aditya Mehakare <aditya.mehak...@nutanix.com> --- lib/copp.c | 1 + lib/copp.h | 1 + northd/northd.c | 20 ++++++--- ovn-nb.xml | 4 ++ tests/ovn-northd.at | 2 +- tests/ovn.at | 102 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 123 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), &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), &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..0ae087c5f 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -40171,6 +40171,108 @@ 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]) + +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 + +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], []) + +# 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], []) + +## 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 + +for i in {1..20} +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 -gt 1 ], [0], []) + +# 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 + +for i in {1..20} +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 +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], []) + OVN_CLEANUP([hv1 /WARN\|DHCP_RELAY/d ]) -- 2.43.5 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev