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

Reply via email to