On 7/15/16 12:32 AM, [email protected] wrote:
> From: Deepanshu Saxena <[email protected]>
>
> This commit implements ovs meters in kernel space using the traffic
> control (tc) module of Linux kernel. TC is used to configure Traffic
> Control features like Policing, Shaping etc. Ovs meters are analogous to
> traffic control policing feature. The details from the meter command are
> fetched and mapped to the corresponding fields of tc qdisc,class,filter
> commands.
Great idea. Doesn't TC the TC system only perform actions when a frame
is egresses from an interface. Without additional TC hooks within the
kernel datapath, this metering will not affect traffic send of vswitchd
via upcalls. I would like to see a more universal metering solution
which works with all traffic passing through OVS.
> diff --git a/ofproto/meter_tc.c b/ofproto/meter_tc.c
> new file mode 100644
> index 0000000..fc7fa0b
> --- /dev/null
> +++ b/ofproto/meter_tc.c
> @@ -0,0 +1,74 @@
> +#include <config.h>
> +#include "meter_tc.h"
> +
> +VLOG_DEFINE_THIS_MODULE(meter_tc);
> +
> +enum ofperr flow_mod_to_tc(struct ofproto *ofproto,
> + struct ofputil_flow_mod ofm) {
> + FILE *fp;
> + ovs_be32 nw_src,nw_dst;
> + struct ofpact *a;
> + struct ofpact_meter *m_act;
> + struct ofport *ofport;
> + struct meter *meter;
> + uint32_t id,rate,rate_in_bytesps,burst_size,default_id;
> + char buffer[1024];
> + ofp_port_t port=0;
> + default_id=65535;
> + id=0;
> + struct ds nw_src_string = DS_EMPTY_INITIALIZER;
> + struct ds nw_dst_string = DS_EMPTY_INITIALIZER;
> + nw_src = ofm.match.flow.nw_src;
> + nw_dst = ofm.match.flow.nw_dst;
> + ds_put_format(&nw_src_string, IP_FMT, IP_ARGS(nw_src));
> + ds_put_format(&nw_dst_string, IP_FMT, IP_ARGS(nw_dst));
> + VLOG_INFO("Source IP : %s , Destination IP : %s",nw_src_string.string,
> + nw_dst_string.string);
> + OFPACT_FOR_EACH_FLATTENED (a, ofm.ofpacts, ofm.ofpacts_len) {
> + if (a->type == OFPACT_METER) {
> + m_act=ofpact_get_METER(a);
> + id=m_act->meter_id;
> + }
> + if(a->type == OFPACT_OUTPUT) {
> + port=ofpact_get_OUTPUT(a)->port;
> + }
> + }
> + VLOG_INFO("Output Port Number : %d",port);
> + ofport=ofproto_get_port(ofproto,port);
> + if(ofport==NULL) {
> + VLOG_INFO("The port numbers defined in the flow donot correspond to "
> + "any datapath port. try using ovs-ofctl show <br-name> to "
> + "get the list of ports. Add ports to the bridge first");
> + return OFPERR_OFPBRC_BAD_PORT;
> + }
> + VLOG_INFO("Output Port Name : %s",ofport->pp.name);
> + VLOG_INFO("Meter id : %d",id);
> + meter = ofproto->meters[id];
> + rate=meter->bands->rate;
> + rate_in_bytesps=(uint32_t)((float)(meter->bands->rate/8)*1000);
> + burst_size=meter->bands->burst_size;
> + VLOG_INFO("Rate in kbitsps : %d, burst size in kbits %d",rate,
> + burst_size);
> + snprintf(buffer,sizeof(buffer),"tc qdisc add dev %s root "
> + "handle 1: htb default %x",ofport->pp.name,default_id);
> + fp=popen(buffer,"r");
> + snprintf(buffer,sizeof(buffer),"tc class add dev %s parent 1:0 "
> + "classid 1:%x htb rate 20kbps ceil 100kbps prio 2",
> + ofport->pp.name,default_id);
> + fp = popen(buffer,"r");
> + pclose(fp);
We should check the exit code to ensure the tc command completed
successfully.
> + snprintf(buffer,sizeof(buffer),"tc class add dev %s parent 1:0 classid "
> + "1:%x htb rate %dkbit ceil %dkbit prio 1 mtu %d000 ",
> + ofport->pp.name,id,rate,rate,burst_size);
> + fp = popen(buffer,"r");
> + pclose(fp);
Ditto.
> + snprintf(buffer,sizeof(buffer),"tc filter add dev %s protocol ip parent
> "
> + "1: prio 1 u32 match ip src %s match ip dst %s flowid 1:%x "
> + "police rate %dbps burst %d000 mpu 0 conform-exceed drop/ok",
> + ofport->pp.name,nw_src_string.string,nw_dst_string.string,
> + id,rate_in_bytesps,burst_size);
> + fp = popen(buffer,"r");
> + VLOG_INFO("Meter attached successfully to the flow");
> + pclose(fp);
> + return 0;
> +}
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev