Monday, November 5, 2012

[OpenFlow] What's new with OpenFlow v1.3

Big Switch Netwoks give a brief introduction about the new with OpenFlow v1.2 as the following URL:
What is new with OpenFlow v1.2?

I also paste the summary from that and aslo add a few comments by my point of view.

OpenFlow 1.0:  Dec 2010
  • First “official” release
  • Basic QoS – minimum bandwidth guarantees
  • Flow Cookies – store metadata in flow table
  • Broadly implemented
OpenFlow 1.1:  Feb 2011
  • Multiple tables
  • Group table – ECMP, fast failover, Multicast
  • MPLS/QinQ support
  • Few implementaKon, less deployment
Openflow 1.2:   Dec 2011
  • More flexible packet matching
    • Makes specification easier to extend
    • Allows third-parties to define their own match types
  • Basic IPv6 support
    •  Match on src/dst IPv6 address + flow label
    •  No support for matching IPv6 extensions
  • Improved controller failover mechanism
    • Enables “active-­active” fast-failover
      • It needs switch to co-operate with controller.
  • v1.2 is inherent from most of the features from v1.1 
  • v1.1 and v1.2 are not compatible with v1.0
    • The flow table is different from v1.0. In v1.2, it has "Match Fields", "Counters", and "Instructions" instead of "Actions"
Openflow 1.3 Apr 2012:
  • introduces per flow meters, IPv6 extension header 
    • handling, flexible table miss support, enhanced/refactored 
    • capability negotiation, multipart requests, MPLS BoS matching, 
    • push/pop for PBB, tunnel-ID meta-data, cookies for packet_in 
    • messages, augmented flow table entry (adds cookie), among others 
  • Configuration Protocol under co-development


Monday, October 29, 2012

[VirtualBox] Daily Operation in Linux VM ( VDI file ) with tip and trick

If you use VirtulBox on Windows for your virtual machine environment, you will encounter some daily operation issues that are kind of tedious. Here I want to provide some useful commands for quickly solving some common operation in Linux VM.

  • When you want to duplicate original VDI file to use in other VirtualBox environment, you need to execute this: 
    • > "C:\Program Files\Oracle\VirtualBox\VBoxManage" clonevdi source.vdi output.vdi
  • To clean up the empty space in your VDI file ( it could reduce the size of your VDI file ), there are 2 steps:
    • On Linux VM
    • > dd if=/dev/zero of=fillfile bs=1M ( running on
    • > rm fillfile
    • On VirtualBox Host ( Windows )
    • "C:\Program Files\Oracle\VirtualBox\VBoxManage" modifyhd your_VDI.vdi --compact
  • To change the size of your VirtualBox VDI file
    • "C:\Program Files\Oracle\VirtualBox\VBoxManage"--resize SIZE_IN_MB
      YOUR_HARD_DISK.vdi

Tuesday, October 9, 2012

[Trema] How to sync threads using ZeroMQ in Trema

If someone is familiar with Trema, then he/she knows that the socket mode in Trema is non-blocking, which means there is no waiting when sending the request message. But, here is an question. If we want to use ZeroMQ ( in different thread ) to receive the flow stats request from outside world and how do we sync threads and get flow stats info from OFSwitch?

My approach uses "pthread mutex". The key point is in the red box as following picture. When Zmq_Responder receives flow stats request, it will run a callback function, lock the mutex variable, and send flow stats request to OF Switch ( it is non-blocking socket mode ). After sending, Zmq_Responder will be locked and will wait for OF Switch to reply flow stats message. Once it replies, Routing Switch in the main thread will produce the reply message and unlock the mutex variable and let Zmq_Responder to reply to outside world.

The approach can sync these two threads in the sequence, but also has some kind of dead-lock risk. If some one has a better solution, let me know if you are willing.


Tuesday, October 2, 2012

[Trema] Try the cucumber scenarios in Trema

When you install Trema ready, you can try this in Trema path:
trema> sudo cucumber -r features

And then you will get a lot of log and info on screen. For instance, this is what I got:

Failing Scenarios:
cucumber features/example.message.echo_reply.feature:8 # Scenario: Send echo reply x 10
cucumber features/example.message.echo_reply.feature:18 # Scenario: Send echo reply x 10 in Ruby
cucumber features/example.message.echo_request.feature:8 # Scenario: Send echo request x 10
cucumber features/example.message.echo_request.feature:18 # Scenario: Send echo request x 10 in Ruby
cucumber features/example.message.features_request.feature:8 # Scenario: Send a features request
cucumber features/example.message.features_request.feature:48 # Scenario: Send a features request in Ruby
cucumber features/example.message.hello.feature:8 # Scenario: Hello trema
cucumber features/example.message.hello.feature:18 # Scenario: Hello trema in Ruby
cucumber features/example.message.set_config.feature:8 # Scenario: set config x 10
cucumber features/example.message.set_config.feature:19 # Scenario: set config x 10 in Ruby
cucumber features/example.packetin_filter_config.feature:8 # Scenario: add filter
cucumber features/example.packetin_filter_config.feature:23 # Scenario: dump filter
cucumber features/example.packetin_filter_config.feature:40 # Scenario: dump filter strict
cucumber features/example.packetin_filter_config.feature:62 # Scenario: delete filter strict
cucumber features/example.packetin_filter_config.feature:83 # Scenario: delete filter
cucumber features/packetin_filter.feature:8 # Scenario: packetin_filter --help
cucumber features/packetin_filter.feature:33 # Scenario: packetin_filter -h
cucumber features/switch_manager.feature:8 # Scenario: switch_manager --help
cucumber features/switch_manager.feature:26 # Scenario: switch_manager -h

84 scenarios (19 failed, 65 passed)

417 steps (19 failed, 47 skipped, 351 passed)

7m0.821s


Or if you want to further test Trema/Apps, for instance, sliceable_switch app, you can do this:
trema> sudo cucumber -r features -r ../apps/sliceable_switch/features /home/liudanny/SourceCode/apps/sliceable_switch/features/port_binding.feature
But, I am not sure it is correct way or not and will figure it out.


[Cucumber] how to use cucumber with a simple example

As my early post  [Cucumber] An brief introduction, Cucumber is an amazing testing tool and it is about Behaviour-Driven Development instead of Test-Driven Development. 
The book "The Cucumber Book" gives a very good explanation and useful of examles to illustrate the usages and functionalities in depths.

Based on that book's a good simple example, the following picture give the dictionary structure (left hand side ) and 3 of important files ( right hand side ) as follows:
"adding.feature" is file contained scenario ( test case )
"calc.rb" provides the calculation function for calculator_steps.rb
" calculator_steps.rb" provide the functions mapping to feature's script based on the key words: Given, When, and Then

Under the path, we run "cucumber" and then get the information as below:

Feature: Adding

  Scenario Outline: Add two numbers      # features/adding.feature:3
    Given the input "<input>"            # features/step_definitions/calculator_steps.rb:9
    When the calculator is run           # features/step_definitions/calculator_steps.rb:13
    Then the output should be "<output>" # features/step_definitions/calculator_steps.rb:18

    Examples:
      | input | output |
      | 2+2    | 4          |
      | 98+1  | 99        |

2 scenarios (2 passed)
6 steps (6 passed)
0m0.012s






Wednesday, September 26, 2012

[JSON] How to use jansson lib to generate JSON data in C

This exmple method will generate the result string below:

{ "command":"link_status",
  "result":["AAABBBCCC"] }


char* generate_json_data() { char *ret_strings = NULL; char *ret_string = "AAABBBCCC"; json_t *root = json_object(); json_t *result_json_arr = json_array(); json_object_set_new( root, "command", json_string( "link_status" ) ); json_object_set_new( root, "result", result_json_arr ); ... json_array_append( result_json_arr, json_string( ret_string ) ); free( ret_string ); ret_strings = json_dumps( root, 0 ); json_decref( root ); return ret_strings; }

For more example in details: 
#include <stdio.h> #include <jansson.h> void add_2array_to_json( json_t* obj, const char* name, const int* marr, size_t dim1, size_t dim2 ) { size_t i, j; json_t* jarr1 = json_array(); for( i=0; i<dim1; ++i ) { json_t* jarr2 = json_array(); for( j=0; j<dim2; ++j ) { int val = marr[ i*dim2 + j ]; json_t* jval = json_integer( val ); json_array_append_new( jarr2, jval ); } json_array_append_new( jarr1, jarr2 ); } json_object_set_new( obj, name, jarr1 ); return; } int main() { json_t* jdata; char* s; int arr1[2][3] = { {1,2,3}, {4,5,6} }; int arr2[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }; jdata = json_object(); add_2array_to_json( jdata, "arr1", &arr1[0][0], 2, 3 ); add_2array_to_json( jdata, "arr2", &arr2[0][0], 4, 4 ); s = json_dumps( jdata, 0 ); puts( s ); free( s ); json_decref( jdata ); return 0; } When run it outputs: {"arr1": [[1, 2, 3], [4, 5, 6]], "arr2": [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]}




Another example:

#include "jansson.h" ... json_error_t error; json_t *root = json_loads( reply->data.buffer, 0, &error ); if( root ) { json_t *jsonData = json_object_get( root, "data" ); if( json_is_array( jsonData ) ) { const uint length = json_array_size( jsonData ); for( uint i=0; i<length; ++i ) // Iterates over the sequence elements. { json_t *jsonObject = json_array_get( jsonData, i ); json_t *jsonID = json_object_get( jsonObject, "id" ); const char *jsonStringID = json_string_value( jsonID ); json_t *jsonName = json_object_get( jsonObject, "name" ); const char *jsonStringName = json_string_value( jsonName ); // We can now do something with our Name and ID } } json_decref( root ); }

[epoll] How to use epoll in socket program?

When we do socket program, the most popular way is of PPC/TPC mode ( Process Per Connection / Thread Per Connection ). But the mode has some drawbacks, for instance, it will consum too much memory and CPU for context switch when creating more than hundreds of connections. epoll is good solution to deal with that.

The following URL is a good explaintion about epoll.
How to use epoll? A complete example in C

And here is a complete examle of using epoll in socket program.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/wait.h>
#define SERVPORT 9527 /* Server Port Number */
#define BACKLOG 10 /* The Max of Client Number */

void setnonblocking(int sock)
{
    int opts;
    opts = fcntl(sock,F_GETFL);
    if(opts<0)
    {
        perror("fcntl(sock,GETFL)");
        exit(1);
    }
    opts = opts|O_NONBLOCK;
    if(fcntl(sock,F_SETFL,opts)<0)
    {
        perror("fcntl(sock,SETFL,opts)");
        exit(1);
    }  
}

void do_use_fd(int client_fd)
{
    const char str[] = "God bless you!\n";
    if (send(client_fd,  str,  sizeof(str),  0) == -1)
        perror("send");
    close(client_fd);
}

int main()
{
    int sockfd;
    struct sockaddr_in my_addr;
    struct sockaddr_in remote_addr;
    if ((sockfd = socket(AF_INET,  SOCK_STREAM,  0)) == -1) {
        perror("socket");
        exit(1);
    }
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(SERVPORT);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero), 8);
    if (bind(sockfd,  (struct sockaddr *)&my_addr,  sizeof(struct sockaddr)) == -1) {
        perror("bind");
        exit(1);
    }
    printf("bind ok\n");
    if (listen(sockfd,  BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }
    printf("listen ok\b");
    size_t sin_size = sizeof(struct sockaddr_in);

#define MAX_EVENTS 10
    struct epoll_event ev, events[MAX_EVENTS];
    int conn_sock, nfds, epollfd;

    epollfd = epoll_create(10);
    if (epollfd == -1) {
        perror("epoll_create");
        exit(EXIT_FAILURE);
    }
    printf("epoll_create\n");

    ev.events = EPOLLIN;
    ev.data.fd = sockfd;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
        perror("epoll_ctl: sockfd");
        exit(EXIT_FAILURE);
    }
    printf("epoll_ctl ok\n");

    for (;;) {
        printf("start epoll_wait\n");
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_pwait");
            exit(EXIT_FAILURE);
        }
        printf("epoll_wait returns, nfds = %d\n", nfds);

        for (int n = 0; n < nfds; ++n) {
            if (events[n].data.fd == sockfd) {
                conn_sock = accept(sockfd,
                        (struct sockaddr *) &remote_addr, &sin_size);
                if (conn_sock == -1) {
                    perror("accept");
                    exit(EXIT_FAILURE);
                }
                setnonblocking(conn_sock);
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = conn_sock;
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                            &ev) == -1) {
                    perror("epoll_ctl: conn_sock");
                    exit(EXIT_FAILURE);
                }
            } else {
                do_use_fd(events[n].data.fd);
            }
        }
    }
}

Thursday, September 20, 2012

[Socket] How to use he function fcntl()

When server is running to accept() and no client connection request comes, what it happens? When the server stops waiting for the arrival of the connection request on accept(). Similarly, when the program is running to receive(), ifno data can be read, the program will also stop receiving statements. This situation is called blocking. 
If you want to only pay attention to check whether there are customers waiting for a connection server to accept connection, otherwise the program continues to do other things, through the Socket set for non-blocking way: non-blocking socket when no customers waiting for accept calls return immediately.
 

# include <unistd.h>
# include <fcntl.h>
....
sockfd = socket (AF_INET, SOCK_STREAM, 0);
fcntl (sockfd, F_SETFL, O_NONBLOCK);
....
 

Set socket to non-blocking mode, "polling" the Socket. When no data is waiting to be processed from a non-blocking Socket ( for read data ), the function will return immediately, and the return value is set to -1 and errno set of EWOULDBLOCK
But this "polling" causes the CPU is busy waiting mode, thereby reducing performance.


P.S:
There is another way to deal with non-blocking socket.
ioctl(sockfd, FIONBIO, 0); // 0 is about non-blocking mode

Friday, September 14, 2012

[Storage] Some articles of NoSQL and Object Storage ( S3 and Swift )


Severl months ago, I saw the first article "LINE Starage" and didn't pay too much attention on it. Recently Someone discussed storage with me and let me remember it. So I found it again ( took me a bunch of time to look for ) and also took some pretty nice related articles here as well.

LINE Storage: Storing billions of rows in Sharded-Redis and HBase per Month

http://tech.naver.jp/blog/?p=1420

NoSQL Data Modeling Techniques

http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/

Cassandra vs MongoDB vs CouchDB vs Redis vs Riak vs HBase vs Membase vs Neo4j comparison

http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis
 

Hadoop + S3

http://wiki.apache.org/hadoop/AmazonS3

Apache Hadoop over OpenStack Swift

http://bigdatacraft.com/archives/349


Wednesday, September 12, 2012

[Sqlite] A simple example of Sqlite in C

Here is a simple example of how to deal with Sqlite Database in C language.


#include <stdio.h> #include <sqlite3.h> static char *createsql = "CREATE TABLE Employee(" "ID INTEGER PRIMARY KEY," "Name VARCHAR(10)," "BadgeID VARCHAR(10));"; static char *insertsql = "INSERT INTO Employee VALUES(NULL, 'Danny', '12345');"; static char *querysql = "SELECT * FROM Employee;"; void main(void) { int rows, cols; sqlite3 *db; char *errMsg = NULL; char **result; /* Open database file */ if (sqlite3_open("my_example.db3", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { return; } /* Build Table */ sqlite3_exec(db, createsql, 0, 0, &errMsg); /* Add a new record */ sqlite3_exec(db, insertsql, 0, 0, &errMsg); /* Get the last insert record's ID */ printf("%d\n", sqlite3_last_insert_rowid(db)); /* Get all records in database */ sqlite3_get_table(db , querysql, &result , &rows, &cols, &errMsg); /* List all the data */ for (i=0;i<rows;i++) { for (j=0;j<cols;j++) { printf("%s\t", result[i*cols+j]); } printf("\n"); } /* Free table */ sqlite3_free_table(result); /* Close database */ sqlite3_close(db); }


When Compiling, just add sqlite's flag  as follows:
gcc -lsqlite3 -o sqlite_exp sqlite_exp.c

Tuesday, September 11, 2012

[tun/tap] An introduction of TUN/TAP


http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/tuntap.txt

TUN/TAP provides packet reception and transmission for user space programs. 
It can be viewed as a simple Point-to-Point or Ethernet device, which 
instead of receiving packets from a physical media, receives them from 
user space program and instead of sending packets via physical media 
writes them to the user space program. 

When a program opens /dev/net/tun, driver creates and registers corresponding
net device tunX or tapX. After a program closed above devices, driver will 
automatically delete tunX or tapX device and all routes corresponding to it.
 
And also, here is a web site about Universal TUN/TAP device driver Frequently Asked Question.
http://vtun.sourceforge.net/tun/faq.html

The description of Universal TUN/TAP device driver
https://www.kernel.org/doc/Documentation/networking/tuntap.txt

[SLB] Server Load Balancing with DSR



IPVS ( based on LVS) provides 3 kind of ways to do server load balancing:

  1. Virtual Server via Network Address Translation(VS/NAT)
  2. Virtual Server via IP Tunneling(VS/TUN)
  3. Virtual Server via Direct Routing(VS/DR) 
Recently I find another way to do load balancing, and it is Direct Server Return
http://techiess.wordpress.com/2010/09/09/load-balancing-dsr-direct-server-return/
Using DSR, packet is returning directly from the server to client without going through L4 switch.

Wednesday, September 5, 2012

[Virtual Network] Midokura’s MidoNet

Recently I saw the article about Midokura MidoNet as follows:
http://blog.ioshints.info/2012/08/midokuras-midonet-layer-2-4-virtual.html
It is a layer 2-4 virtual network solution and catches my attention and lets me want to know more about.

Meanwhile, Midokura also provide Quantum Plugin for MidoNet to integrate into OpenStack.
https://github.com/midokura/midonet-openstack

On its web site, it provides a lot of features in virtual network solution and is pretty amazing. Due to MidoNet is not an open source project, so we are not able to see how it exactly achieves all of these things.
http://www.midokura.com/midonet/openstack/

MidoNet Key Features

  • Fully virtualized Layer 2 through 7 networking
  • VLAN-less VLANs – Virtual L2 Distributed Level Isolation and Switching with virtually no limitations
  • Fully Distributed Architecture with no single points of failure
  • Virtual L3 Distributed Routing
  • Distributed Load Balancing and Firewall Services
  • NAT
  • VPN
  • Access Control Lists (ACLs)
  • Restful API
  • Web Based Management Control Panel
  • Monitoring and Metering of Networking Services
  • Live Migration
  • Rate Limiting
  • Virtual Tap (Port Monitoring and Mirroring)




[OpenStack] Existing High Availability Options for Networking

 Existing High Availability Options for Networking

    OpenStack offical web site has document to explain the existing HA options for networking. I think most of important item is the option 1: multi-host networking mode. This mode avoids from single point of failure when Nova-Network component is down and also eliminate the potential network bottleneck in single-host networking mode.

For more in details, please see the this:
http://docs.openstack.org/trunk/openstack-compute/admin/content/existing-ha-networking-options.html


Wednesday, August 29, 2012

[Ubuntu] How to build local apt repositories



Summary:
  1. Edit your sources.list file 
  2. Copy your debian packages to the folder where is the packages repository directory  (*.deb folder) 
  3. Change into the packages repository directory  (cd ~/repository) 
  4. Generate a Packages.gz file  (sudo dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz) 
  5. Install the build-essential package  (sudo apt-get install build-essentiall
  6.  Update apt-get server packages list  (sudo apt-get update)


Monday, August 27, 2012

[SDN] HP's SDN solution

http://www.infoworld.com/d/networking/hp-aims-three-part-effort-network-virtualization-200048?source=IFWNLE_nlt_virtualization_2012-08-16

Summary:
HP provides 3 tools (softwares) to deal with network virtualization using SDN
  • EVI (Ethernet Virtual Interconnect)
    • EVI creates a tunnel through the Layer 3 network by encapsulating the packets traveling between the data centers. Rival Cisco already has software that can do this, called OTV (Overlay Transport Virtualization), but it charges extra for that software.
  • MDC (Multitenant Device Context)
    • It allows for segregating the resources of multiple tenants in a virtualized environment without buying separate switches. This secures the data and applications of one department or cloud service customer from other tenants.
  • VSA
    • StoreVirtual VSA, for virtualizing storage management. The software is based on VSA (virtual storage appliance) technology from LeftHand Networks, which HP acquired in 2008.

Tuesday, August 21, 2012

[Trema] The real case to test flow-based ECMP Routing Switch App


The following picture is a topology that used in testing my ECMP Routing Switch App.

After host3 send packets to host1, the app starts making path process and the related log as below. You will see this app picks up 2 paths ( "0xe5->0xe3->0xe4"  and  "0xe5->0xe2->0xe4" ) and choose one of them to setup flow entries.

[pickup_next_candidate] Find a candidate = 0xe5
[update_distance] node = 0xe3, distance = 1
[update_distance] node = 0xe2, distance = 1
[pickup_next_candidate] Find a candidate = 0xe3
[update_distance] node = 0xe1, distance = 2
[update_distance] node = 0xe4, distance = 2
[update_distance] node = 0xe2, distance = 1
[pickup_next_candidate] Find a candidate = 0xe2
[update_distance] node = 0xe1, distance = 2
[update_distance] node = 0xe4, distance = 2
[pickup_next_candidate] Find a candidate = 0xe1
[pickup_next_candidate] Find a candidate = 0xe4
[build_hop_list] build a hop = 0xe4
[build_hop_list] build a hop = 0xe3
[build_hop_list] build a hop = 0xe5
[resolve_path] find a hop list 0
[pickup_next_candidate] Find a candidate = 0xe5
[update_distance] node = 0xe2, distance = 1
[pickup_next_candidate] Find a candidate = 0xe2
[update_distance] node = 0xe1, distance = 2
[update_distance] node = 0xe4, distance = 2
[pickup_next_candidate] Find a candidate = 0xe1
[pickup_next_candidate] Find a candidate = 0xe4
[build_hop_list] build a hop = 0xe4
[build_hop_list] build a hop = 0xe2
[build_hop_list] build a hop = 0xe5
[resolve_path] find a hop list 1
[resolve_path] has 2 paths, pick up the key = 0 from hash_value = 2169503748

[Trema][Concept] How to do flow-based ECMP in Routing Switch App

  As we have known that Routing Switch App uses Dijkstra algorithm to pick up the lowest cost of the path. Only one path will be selected. If we want to do flow-based ECMP, how to do it? I have a simple way to slightly modify the Routing Switch App and then it can become "ECMP Routing Switch" App.

  Here is a topology as follows. If the source is PC1 and destination is PC2, we can know that the source switch is A and destination switch is B. I will base on this to explain my idea.

  First, we setup a number of multi-path , for instance, 8, and let the loop to do Dijkstra algorithm these times.
  Second, we need to add a new chosen flag to record nodes in the path that we have picked up, and get rid of the source and destination node. And also, when Dijkstra algorithm is running, we also need to add a condition to avoid from choosing the node whose chosen flag is true.

For instance, Path 1 is A->B->C->D. We need to add flag on B and C as true.
                        Path 2 is A->E->F->D. We need to add flag on E and F as true.

In this case, Dijkstra algorithm is not able to pick up the third path so that making paths is done.
I have implemented this in Routing Switch App and it works. I will post the real case in the next article.


Wednesday, August 8, 2012

[Trema] Provide a monitoring application to watch port and flow loading

I currently provide a initial version of monitoring application to watch port and flow loading information. Here are some items about the configuration and criteria for sending notification.



The configuration
  • port_percentage_condition
    • the threshold of port loading percentage
  • port_setting_feature_rate
    • the speed rate of port
  • flow_bit_rate_conditon
    • the threshold of flow loading
  • flow_times_condition
    • how many seconds will flow become big flow when being over the threshold of flow loading

The notification criteria of Port Loading
  • Check port loading per 4 seconds
  • Calculate the percentage of port loading
    • port_bit_rate = avg_rx_bytes * 8
    • port_loading_percentage = port_bit_rate * 100 / port_feature_rate
  • If the port loading percentage is higer than port_percentage_condition, then it sends port loading notification
The notification criteria of Flow Loading
  • Check port loading per 4 seconds
  • Calculate the flow loading ( flow_bit_rate )
    • flow_bit_rate = bytes_count * 8 / duration seconds
  • If flow_bit_rate  is bigger than flow_bit_rate_condition, then flow_times adds 1.
  • If flow_times is higher than flow_times_condition, for instance, 3, then it sends flow loading notification

Tuesday, August 7, 2012

[Introduction] ar and ranlib

ar and ranlib
ar this program can do the following actions to the archive (static library)
create, modify, and extract.Following is a list of several commonly used options explained:
  • d: delete
    • Remove files from the archive
  • r: replace
    • Insert archive files to be replaced
  • u: update
    • option 'r' is usually to replace all, but the option u only will be inserted over the files in the archive in
  • v: verbose
    • The implementation, as well as additional information
for example:
   > ar uv mylib.a first.o second.o

These directives is to establish two obj file into a mylib.a, and shows the implementation of the process information

ranlib generates an index to the contents of an archive and stores it in the archive. The index lists each symbol defined by a member of an archive that is a relocatable object file.

You can use nm-s or nm, - print-armap Include to list this index

To run this program is to increase the speed of linking to the library and allows routines in the library can call each other without having to worry about these routines in the archive of the placement order

[Cucumber] An brief introduction

http://cukes.info/
I just saw the "Cucumber" and was amazed by its power of scenario testing with human-readable syntax and sentences. It is so amazing...
If you guys want to do the job for testing, that is a good choice~

For more information in details, please also check it out:
http://andrewvos.com/2011/06/15/writing-better-cucumber-features/
http://grosser.it/2008/12/25/getting-started-with-cucumber-on-ubuntu/
http://jeannotsweblog.blogspot.tw/search?q=cucumber
http://holmwood.id.au/~lindsay/2009/11/09/behaviour-driven-infrastructure-through-cucumber/

How to install Cucumber
sudo apt-get install libxslt1-dev libxml2-dev racc
sudo apt-get install gem
sudo gem install gherkin
sudo gem install cucumber./script/generate cucumber
rake features

[How To] Add ZeroMQ in Trema App

If someone wants to add the mechanism of ZeroMQ to send message from Trema Application, for instance, Routing_Switch, there are several things that need to do and I have tested OK.

Example Trema App: Routing_Switch

1. Install ZeroMQ
2. Modify its Makefile: 
  • add the include folder location of ZeroMQ :
    • CFLAGS = $(shell $(TREMA)/trema-config --cflags) -I/home/liudanny/SourceCode/zeromq2-1/include -I../topology -g -std=gnu99 -D_GNU_SOURCE -fno-strict-aliasing -Werror -Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wfloat-equal -Wpointer-arith
  • add library name of zeroMQ and link it:
    • LDFLAGS = $(shell $(TREMA)/trema-config --libs) -lzmq -L../topology -ltopology
3. Write your ZeroMQ code in Routing_Switch.

Thursday, July 26, 2012

[How to][Trema] Get Flow_Removed message in routing_switch app

I asked an question about how to get Flow_Removed message in routing_switch app. But, soon I realized that I asked a stupid one because the answer is also in OpenFlow Spec v1.0.0.
We should set a "OFPFF_SEND_FLOW_REM" flag into "Flow Mod" message when we want to set a flow. The following list is the discussion message log.

================================================================ 
Hi,


If you want to receive "Flow Removed" message, you have to set
"OFPFF_SEND_FLOW_REM" flag into "Flow Mod" message when you set the flow.


Currently "routing_switch" app does not set this flag, then switches does
not send "Flow Removed" message.

================================================================
Hi,
  I try to get "Flow_Removed" message in routing_switch app, but do not see any one coming in.
The following is what I have done in the app and could someone tell me how to fix or modify it?
Many thanks.


Add it in main():
  set_flow_removed_handler( handle_flow_removed, routing_switch );


Add a method for display:
void handle_flow_removed( uint64_t datapath_id, flow_removed message ) {
  routing_switch *routing_switch = message.user_data;
  info( "[handle_flow_removed] dpid = %#" PRIx64 ", match = %s",
          datapath_id, message.match );
}


Modify routing_switch.conf:
vswitch {
  datapath_id "0xe0"
}
vhost ("host1") {
  ip "192.168.0.1"
  netmask "255.255.0.0"
  mac "00:00:00:01:00:01"
}
vhost ("host2") {
  ip "192.168.0.2"
  netmask "255.255.0.0"
  mac "00:00:00:01:00:02"
}
link "0xe0", "host1"
link "0xe0", "host2"


run {
  path "../apps/topology/topology"
}
run {
  path "../apps/topology/topology_
discovery"
}
run {
  path "../apps/routing_switch/routing_switch"
}


event :port_status => "topology", :packet_in => "filter", :state_notify => "topology", :flow_removed => "routing_switch"
filter :lldp => "topology_discovery", :packet_in => "routing_switch"