On 7/15/16 12:32 AM, deepanshu.saxen...@gmail.com wrote: > From: Deepanshu Saxena <deepanshu.saxe...@tcs.com> > > 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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev