Friday, July 19, 2013

[TRILL] The keypoint for Appointed VLAN-x Forwarder

If you study a lot of TRILL related documents and still are not able to figure out what Appointed VLAN-x Forwarder is and what purpose it is for, please refer to the following excerpts about it.


Whether they run STP or not, the RBridges have to ensure there’s a single point of contact between a VLAN in the STP domain and the backbone, otherwise all the flooded packets would enter the backbone through multiple entry points, resulting in duplicate packets received by the remote hosts (which might break some odd fainthearted protocols running directly on top of L2). One of the RBridges therefore becomes an appointed forwarder for an edge VLAN.
The right-hand part of the figure illustrates the appointed forwarder concept: the RBridges don’t participate in the STP, none of their edge ports are blocked, but only one of the RBridges acts as a forwarder between the edge STP domain and the TRILL backbone (marked with A), all other RBridges ignore packets received through that VLAN (marked with B).

Having multiple RBridges active on a LAN segment could be an issue if they all start forwarding traffic over the TRILL network, as this would cause both traffic duplication and also confusion in terms of the appropriate return path with which to populate the MAC mapping tables. Consequently, RBridges on a VLAN see each other and elect a Designated RBridge (DRB) for the segment, which in turn normally becomes the Appointed Forwarder that is exclusively responsible for sending/receiving frames on that shared segment while all other RBridges effectively are in a kind of standby mode. Technically (i.e. in the protocol specifications) it is possible for a DRB to make other RBridges Appointed Forwarders, but I am not aware of this being implemented yet, and the likelihood is that the DRB will do the AF job itself.

If there are multiple RBridges on the same link, together with end nodes, it is important that only one of them encapsulate a packet from an end node. As illustrated in Figure 9, if both R1 and R2 were to encapsulate a unicast packet from S, two copies would be delivered to the destination. However, if S were to transmit a multidestination packet (such as a multicast, or an unknown destination), then the copy that R1 encapsulates would be forwarded through the campus, received by R2 (which likely would not know that the packet originated on its port to R1), and R2 would decapsulate it. Then R1 would see a native packet from S, exactly as the first copy, and again encapsulate it and send it into the campus.
The hop count in the TRILL header would not solve this loop, because the hop count does not exist while the packet is not encapsulated with a TRILL header.
IS-IS has an election protocol in which one of the RBridges is elected as the Designated RBridge (DRB). In order to allow load-splitting the task of encapsulating and decapsulating traffic, the DRB may delegate the job of encapsulation/decapsulation based on VLAN. In other words, if R1 is DRB, R1 can delegate to R2 the task of encapsulating/decapsulating traffic for a set of VLANs, say VLANs x, y, and z, and delegate to R3 a different set of VLANs, and R1 might handle the rest.
http://www.cisco.com/web/about/ac123/ac147/archived_issues/ipj_14-3/143_trill.html


By the way, in this blog the author mentions the concept of Designated VLANs. I excerpt from it as follows:
Some background points that will help to explain things:
1) When RBridges see other RBridges on a multi-access link, they will determine between them which is to be the Designated RBridge (DRB). I should note that this on Point-to-Point (P2P) links, no DRB is elected.
2) When an RBridge receives a native (i.e. non-TRILL) frame that it’s going to forward as TRILL-encapsulated, it first adds a 802.1q header to the frame so that the origin VLAN will be known when the frame is decapsulated at the egress RBridge. Thus when the frame format shows the “original Ethernet frame”, it’s really the original frame plus an 802.1q header. You could, if you wanted to make the Shortest Path Bridging folks laugh quietly, liken this a little to QinQ – you’re sending TRILL-encapsulated frames sourced from multiple VLANS over a single VLAN, and inside the TRILL data frame the 802.1q header in the “original” packet means it can be ‘demuxed’ correctly at the other end. Ugh, horrible analogy :)
3) The reality is that links between RBridges are unlikely to be carrying a single VLAN, but rather they’re likely to be 802.1q trunk links with many VLANs on them. You don’t want to send out TRILL-IS-IS Hellos and run an instance of IS-IS on every VLAN, as that wouldn’t be scalable. It would also be pointless, as TRILL encapsulated frames are not forwarded on the VLAN on which the frame ingressed; rather the TRILL data frames are forwarded on a common VLAN – the Designated VLAN.
So, if we put all that together:
- On any given link, there must be a single VLAN that the RBridges agree to use for the exchange of TRILL-IS-IS and TRILL data.
- On a multi-access link, the DRB dictates what the Designated VLAN will be; other (non-DRB) RBridges on that link MUST use whatever VLAN the DRB dictates.
- On a point-to-point link, the RBridges use tie-break mechanisms to determine whose Designated VLAN should reign supreme (since there’s no DRB)
- The best design obviously would be that you configure all RBridges to prefer the SAME Designated VLAN, so that if the DRB changes, you don’t change Designated VLAN as well.
- You also need to ensure that all RBridges on a link have connectivity to that Designated VLAN. Common sense, really.
So in summary, the Designated VLAN is the VLAN where TRILL-IS-IS really runs, and over which TRILL data forwarding between RBridges occurs. Make sure all RBridges on a link have the same preferred Designated VLAN configured, and ensure they all have connectivity to that VLAN.
 http://lamejournal.com/2011/05/16/layer-2-routing-sort-of-and-trill/




Wednesday, July 17, 2013

[OpenFlow] OpenFlow 1.3 Spec Summary

Compared with OF1.0, OF1.3 is more tables and complex design than 1.0. Here I try to summarize the main items in OF1.3 spec included the table, message, and so on for me to review it more quick in the future.

OpenFlow Table

Flow Table
+-----------------------------------------------------------------------------------------+
 | Match Fields | Priority | Counters | Instructions | Timeouts | Cookie |
+-----------------------------------------------------------------------------------------+

Group Table
+-----------------------------------------------------------------------------+
 | Group Identifier | Group Type | Counters | Action Buckets |
+-----------------------------------------------------------------------------+
  •   Group Types
    • Required: all: Execute all buckets in the group
    • Optional: select: Execute one bucket in the group.
    • Required: indirect: Execute the one defines bucket in this group.
    • Optional: fast failover: Execute the first live bucket.
Meter Table
+-------------------------------------------------------+
 | Meter Identifier | Meter Bands | Counters |
+-------------------------------------------------------+
  • Meter Bands 
               +--------------------------------------------------------------------------+
                 | Band Type | Rate | Counters | Type specific arguments |
                +-------------------------------------------------------------------------+
    • Band Type
      • Drop
      • Remark DSCP

New Data Structure in Pipeline
+-------------------------------------------------------+
 | media data | packet header | Action Set   |
+-------------------------------------------------------+

 Instructions
Each flow entry contains a set of instructions that are executed when a packet matches the entry.
  • Optional Instruction: Meter meter id: Direct packet to the specified ed meter.
  • Optional Instruction: Apply-Actions action(s): Applies the specified ed action(s) immediately, without any change to the Action Set.
  • Optional Instruction: Clear-Actions: Clears all the actions in the action set immediately.
  • Required Instruction: Write-Actions action(s): Merges the specified ed action(s) into the current action set. 
  • Optional Instruction: Write-Metadata metadata / mask: Writes the masked metadata value into the metadata field. 
  • Required Instruction: Goto-Table next-table-id: Indicates the next table in the processing pipeline.
Action Set
The actions in an action set are applied in the order specifi ed below, regardless of the order that
they were added to the set.
  • copy TTL inwards: apply copy TTL inward actions to the packet
  • pop: apply all tag pop actions to the packet
  • push-MPLS: apply MPLS tag push action to the packet
  • push-PBB: apply PBB tag push action to the packet
  • push-VLAN: apply VLAN tag push action to the packet
  • copy TTL outwards: apply copy TTL outwards action to the packet
  • decrement TTL: apply decrement TTL action to the packet
  • set: apply all set-eld actions to the packet
  • qos: apply all QoS actions, such as set queue to the packet
  • group: if a group action is specied, apply the actions of the relevant group bucket(s) in the order specied by this list
  • output: if no group action is specied, forward the packet on the port specied by the output action
Action List
  • The Apply-Actions instruction and the Packet-out message include an action list.
Actions
  • Required Action: Output. The Output action forwards a packet to a speci ed OpenFlow port
  • Optional Action: Set-Queue. The set-queue action sets the queue id for a packet.
  • Required Action: Drop. There is no explicit action to represent drops.
  • Required Action: Group. Process the packet through the speci ed group.
  • Optional Action: Push-Tag/Pop-Tag. Switches may support the ability to push/pop tags
    • Push / Pop VLAN header
    • Push  / Pop MPLS header
    • Push  / Pop PBB header
  • Optional Action: Set-Field. The various Set-Field actions are identified by their field type and modify the values of respective header fields in the packet.
  • Optional Action: Change-TTL. The various Change-TTL actions modify the values of the IPv4 TTL, IPv6 Hop Limit or MPLS TTL in the packet.
    • Set MPLS TTL
      • 8 bits: New MPLS TTL
    • Decrement MPLS TTL
    • Set IP TTL
      • 8 bits: New IP TTL
    • Decrement IP TTL
    • Copy TTL outwards
    • Copy TTL inwards

OpenFlow Channel
Controller-to-Switch Message
Handshake:
Features:
Switch-Configuration:

Flow Table Configuration:
Modify-State message:
Multipart message:
Queue-Configuration message:
Read-State:
Packet-out message:
Barrier message:
Role-Request message:
Set-Asynchronous-Configuration message:


Asynchronous Message
Packet-in:
Flow-Removed:
Port-status:
Error:

Symmetric Message
Hello:
Echo Request/Reply:
Experimenter:



Flow Table Modification Messages

Group Table Modification Messages

Meter Modification Messages


Tuesday, July 16, 2013

[TRILL] TRILL Summary for TRILL Test Suite

The following item list is about the key points for each test case in the TRILL Interoperability Test Suite Document.
  • IS-IS
    • For Neighbor Info in Hello Message
      • All RBridges must become adjacent with one another. TRB0 and TRB1 must list each other as neighbors in their TRILL Hellos on link 1. TRB1 and TRB2 must list each other as neighbors in their TRILL Hellos on link 3. TRB0 and TRB2 must list each other as neighbors in their TRILL Hellos on link 2.
  • Designated RBridge Election is based on
    • Priority and MAC Address to solve the tiebreak
  • Incremental Deployment Functionality
    •  
  • Nickname Collision is solved by
    •  Priority, IS-IS System ID
  • Configure TRB1 and TRB2 to have an MTU of 1280 on link 3
    •   The Campus Wide MTU Sz value must be 1280 on all RBridges. The orginatingLSPBufferSize in each RBridge’s LSP must be set to 1280.
  • RBridges perform IP Snooping for multicast data 
    • TES3 sends multicast data for IPv4 multicast group 224.0.6.130 on link 3.
      1. TES0 sends an IGMPv3 to exclude nothing for multicast group 224.0.6.130 on link 0.
        • The multicast data must reach TES0.
      2. TES0 sends an IGMPv3 to include nothing for multicast group 224.0.6.130 on link 0. 
        • The multicast data must not reach TES0.
  •  RBridges receive and transmit BPDUs correctly
    • Inhibits the appointed forwarder for a period of time between zero and 30 seconds on Root Bridge Change
    • Sends Topology Change BPDU on change of Appointed Forwarder
      • When RBridge ceases to be appointed forwarder for noe or more VLANs out a particular port, it SHOULD, as long as it continues to receive spanning tree BPDUs on the port, send topology change BPDUs until it sees the topology change acknowledges in a spanning tree configuration BPDU.
  • Hop Count Handling
    • Transit RBridge must decrease the TRILL hop count of the encapsulated frames
  • RBridge Loss and Link Loss Handling
    • Unicast Pathway RBridge Loss
    • Unicast Pathway Link Loss
    • Distribution Tree Root Loss
    • Distribution Tree Root Link Loss
      • TRB1 must notify TRB0 of the link failure through transmission of an updated IS-IS LSP.
    • Distribution Tree RBridge Loss
      • TRB0 must be the appointed forwarder on link 0, 1 and 2. TRB1 must be the appointed forwarder on link 3.
    • Distribution Tree RBridge Link Loss
      • TRB2 must notify TRB0 of the link failure through transmission of an updated IS-IS LSP.
  • Shortest Path First Calculation
    •  TRILL distribution trees are calculated with the shortest path first algorithm
  • Root Choice
    • RB will be the root  of distribution tree with high priority
    • If equal priority occurs, choose higher IS-IS System Id
    • Distribution Tree Root Priority Max Bound is 0xFFFF
  • Number of Trees to calculate
    • The number of computed distribution tree is not greater than the number of  maximum computed distribution tree
    • Load balancing will use the multiple distribution trees
  • Set of Trees to calculate
    • to advertise a set of root can generate multiple distribution tree root
  • Tie Breaking
    • Nickname could be refer to distribution tree root
  • No Receivers Pruning
    • Distribution tree will be pruned when there is no receivers on the link.
  • VLAN

Saturday, June 8, 2013

[Trema] How to install Trema-edge on Ubuntu10.04

Installing Trema-edge needs to use the version of Ruby that is greater than 1.9. In best situation, version 2.0 is best.

1. Install Ruby 2.0
http://www.jeffduckett.com/blog/18/installing-ruby-2-0-0.html

> wget http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz
> tar zxvf ruby-2.0.0-p0.tar.gz
> cd ruby-2.0.0-p0
> ./configure --prefix=/usr/local
> make
> sudo make install
> sudo apt-get -y install libreadline-ruby libopenssl-ruby
> sudo gem update --system
> gem -v

2. Install Bundler
> sudo gem install bundler

3. Clone Trema-edge source code
> git clone https://github.com/trema/trema-edge

4. Install sqlite3 and sqlite3-dev
> sudo apt-get install sqlite3 libsqlite3-dev

5. Build Trema-edge
(In your trema-edge directory)
> sudo bundle install
> sudo rake

6. Try a sample
> ./trema run src/examples/learning_switch/learning-switch.rb -c src/examples/learning_switch/sample.conf

Friday, April 19, 2013

[SDN] Networking in the cloud: An SDN primer

Ben Cherian, Chief Strategy Officer for Midokura, give a session talk in OpenStack Summit 2013 and the topic is "Networking in the cloud: An SDN primer". I didn't attend this Summit, but someone has summarized the points here:
http://blog.scottlowe.org/2013/04/16/openstack-summit-2013-networking-in-the-cloud-an-sdn-primer/

Furthermore, if you want to know more about what MidoNet truely is, you can check out these:
http://bradhedlund.com/2012/10/06/mind-blowing-l2-l4-network-virtualization-by-midokura-midonet/

















http://blog.ioshints.info/2012/08/midokuras-midonet-layer-2-4-virtual.html




Friday, March 22, 2013

[mininet] A simple example to build your own topology in mininet

Well, first of all I want to thank my colleague to giving me an example to build myself topology. It is very simple. Everyone can modify it and do your own topology with OpenFlow Controller.
Second, due to introducing switch cluster concept in Floodlight Controller, I will provide a simple example to give switch clusters in topology.

my_topology.py


from mininet.topo import Topo class MyTopo( Topo ): "Simple topology example." def __init__( self ): "Create custom topo." # Initialize topology Topo.__init__( self ) h1 = self.addHost( 'h1' ) h2 = self.addHost( 'h2' ) h3 = self.addHost( 'h3' ) h4 = self.addHost( 'h4' ) h5 = self.addHost( 'h5' ) h6 = self.addHost( 'h6' ) s1 = self.addSwitch( 's1' ) s2 = self.addSwitch( 's2' ) s3 = self.addSwitch( 's3' ) s4 = self.addSwitch( 's4' ) s5 = self.addSwitch( 's5' ) s6 = self.addSwitch( 's6' ) s7 = self.addSwitch( 's7' ) self.addLink( s1, s2 ) self.addLink( s1, s3 ) self.addLink( s2, s3 ) self.addLink( s2, s4 ) self.addLink( s2, s5 ) self.addLink( s3, s4 ) self.addLink( s3, s5 ) self.addLink( s4, h1 ) self.addLink( s4, h2 ) self.addLink( s5, s3 ) self.addLink( s5, s4 ) self.addLink( s6, h5 ) self.addLink( s7, h6 ) topos = { 'mytopo': ( lambda: MyTopo() ) }

Testing
Use the REST API in Floodlight Controller to query the related information as follows:

> curl -s http://localhost:8080/wm/topology/switchclusters/json
{
    "00:00:00:00:00:00:00:06": [
        "00:00:00:00:00:00:00:06",
        "00:00:00:00:00:00:00:07"
    ],
    "00:00:00:00:00:00:00:01": [
        "00:00:00:00:00:00:00:05",
        "00:00:00:00:00:00:00:02",
        "00:00:00:00:00:00:00:01",
        "00:00:00:00:00:00:00:03",
        "00:00:00:00:00:00:00:04"
    ]
}

> curl -s http://localhost:8080/wm/topology/links/json
[
    {
        "src-switch": "00:00:00:00:00:00:00:05",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:02",
        "dst-port": 4,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:02",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:01",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:04",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:02",
        "dst-port": 3,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:05",
        "src-port": 2,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:03",
        "dst-port": 4,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:02",
        "src-port": 3,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:04",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:06",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:07",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:07",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:06",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:03",
        "src-port": 3,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:04",
        "dst-port": 2,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:03",
        "src-port": 4,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:05",
        "dst-port": 2,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:03",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:01",
        "dst-port": 2,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:03",
        "src-port": 2,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:02",
        "dst-port": 2,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:02",
        "src-port": 4,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:05",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:04",
        "src-port": 2,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:03",
        "dst-port": 3,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:02",
        "src-port": 2,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:03",
        "dst-port": 2,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:01",
        "src-port": 2,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:03",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    },
    {
        "src-switch": "00:00:00:00:00:00:00:01",
        "src-port": 1,
        "src-port-state": 0,
        "dst-switch": "00:00:00:00:00:00:00:02",
        "dst-port": 1,
        "dst-port-state": 0,
        "type": "internal"
    }
]

> curl -s http://localhost:8080/wm/device/
[
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "82:da:cd:82:03:13"
        ],
        "ipv4": [
            "10.0.0.6"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 2,
                "switchDPID": "00:00:00:00:00:00:00:07",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763792481
    },
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "62:76:b0:43:51:c7"
        ],
        "ipv4": [
            "10.0.0.1"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 3,
                "switchDPID": "00:00:00:00:00:00:00:04",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763762405
    },
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "4a:77:dc:12:86:50"
        ],
        "ipv4": [
            "10.0.0.3"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 3,
                "switchDPID": "00:00:00:00:00:00:00:05",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763762427
    },
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "de:42:94:b1:24:a7"
        ],
        "ipv4": [
            "10.0.0.2"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 4,
                "switchDPID": "00:00:00:00:00:00:00:04",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763762417
    },
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "02:ee:63:f6:65:ea"
        ],
        "ipv4": [
            "10.0.0.4"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 4,
                "switchDPID": "00:00:00:00:00:00:00:05",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763767429
    },
    {
        "entityClass": "DefaultEntityClass",
        "mac": [
            "42:a4:fd:b6:62:b9"
        ],
        "ipv4": [
            "10.0.0.5"
        ],
        "vlan": [],
        "attachmentPoint": [
            {
                "port": 2,
                "switchDPID": "00:00:00:00:00:00:00:06",
                "errorStatus": null
            }
        ],
        "lastSeen": 1363763792493
    }
]


P.S: Here is a more complete example of mininet for you to refer to: http://blog.sflow.com/2013/06/flow-collisions.html
It also contains the setting of sFlow. Awesome!

Wednesday, March 13, 2013

[astyle] A tool to format your source code

This is a good tool to consist your code style in some kind of programming languages, such as C, C++, C#, and Java.
http://astyle.sourceforge.net/astyle.html

Wednesday, February 27, 2013

[sFlow] Use sflowtool to parse sFlow datagram

In order to test and understand sFlow more in details, I prepare the following environment below. Switch 1 and 2 are emulated using Open vSwitch. In the previous sFlow article, there is a sFlow setting on Open vSwitch. Please check it out.

            192.168.12.201           10.3.207.244           192.168.12.202
            +------------+        +-----------------+       +------------+
            |  PC1       |        | sFlow Collector |       |  PC2       |
            |            |        |                 |       |            |
            |            |        |                 |       |            |
            +-----+------+        +---^--------^----+       +-----+------+
                  |                   |        |                  |
                  |                   |        |                  |
                  |                   ^ sFlow  ^                  |
                  +---------+         | Data   |       +----------+
                            |         ^        ^       |
                            |         |        |       |
                            |         ^        ^       |
                            |         |        |       |
                   +--------+---------++      ++-------++---------+
                   |    Switch 1       |      |   Switch 2        |
                   | 10.3.207.142      +------+ 10.3.207.143      |
                   +-------------------+      +-------------------+

sFlowtool is an open source toolkit for us to leverage the functionality of parsing sFlow datagram. In my environment, when I ping PC2 from PC1, then Switch 1 and 2 will send sFlow Counter and Flow Sample datagram to the sFlow collector. Now, I will use sFlowtool to parse  the information that it gets.

> ./sflowtool
Counter Sample:startDatagram =================================
datagramSourceIP 0.0.0.0
datagramSize 144
unixSecondsUTC 1359534209
datagramVersion 5
agentSubId 0
agent 10.3.207.142
packetSequenceNo 403
sysUpTime 947000
samplesInPacket 1
startSample ----------------------
sampleType_tag 0:2
sampleType COUNTERSSAMPLE
sampleSequenceNo 95
sourceId 0:4
counterBlock_tag 0:1
ifIndex 4
networkType 6
ifSpeed 1000000000
ifDirection 1
ifStatus 3
ifInOctets 126361
ifInUcastPkts 1072
ifInMulticastPkts 0
ifInBroadcastPkts 4294967295
ifInDiscards 0
ifInErrors 0
ifInUnknownProtos 4294967295
ifOutOctets 137350
ifOutUcastPkts 1135
ifOutMulticastPkts 4294967295
ifOutBroadcastPkts 4294967295
ifOutDiscards 0
ifOutErrors 0
ifPromiscuousMode 0
endSample   ----------------------
endDatagram   =================================
startDatagram =================================
datagramSourceIP 0.0.0.0
datagramSize 144
unixSecondsUTC 1359534210
datagramVersion 5
agentSubId 0
agent 10.3.207.244
packetSequenceNo 404
sysUpTime 948000
samplesInPacket 1
startSample ----------------------
sampleType_tag 0:2
sampleType COUNTERSSAMPLE
sampleSequenceNo 95
sourceId 0:5
counterBlock_tag 0:1
ifIndex 5
networkType 6
ifSpeed 100000000
ifDirection 2
ifStatus 1
ifInOctets 0
ifInUcastPkts 0
ifInMulticastPkts 0
ifInBroadcastPkts 4294967295
ifInDiscards 0
ifInErrors 0
ifInUnknownProtos 4294967295
ifOutOctets 0
ifOutUcastPkts 0
ifOutMulticastPkts 4294967295
ifOutBroadcastPkts 4294967295
ifOutDiscards 0
ifOutErrors 0
ifPromiscuousMode 0
endSample   ----------------------
endDatagram   =================================

Flow Sample:startDatagram =================================
datagramSourceIP 10.3.207.244
datagramSize 216
unixSecondsUTC 1359597631
datagramVersion 5
agentSubId 0
agent 10.3.207.142
packetSequenceNo 941
sysUpTime 2174000
samplesInPacket 1
startSample ----------------------
sampleType_tag 0:1
sampleType FLOWSAMPLE
sampleSequenceNo 72
sourceId 0:4
meanSkipCount 64
samplePool 4010
dropEvents 0
inputPort 4
outputPort 3
flowBlock_tag 0:1001
extendedType SWITCH
in_vlan 0
in_priority 0
out_vlan 0
out_priority 0
flowBlock_tag 0:1
flowSampleType HEADER
headerProtocol 1
sampledPacketSize 102
strippedBytes 4
headerLen 98
headerBytes 00-AB-77-E3-4B-00-00-AB-71-13-2D-00-08-00-45-00-00-54-00-00-40-00-40-01-9F-C5-C0-A8-0C-CA-C0-A8-0C-C9-08-00-C4-0E-55-06-08-57-28-96-AD-FD-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
dstMAC 00ab77e34b00
srcMAC 00ab71132d00
IPSize 84
ip.tot_len 84
srcIP 192.168.12.202
dstIP 192.168.12.201
IPProtocol 1
IPTOS 0
IPTTL 64
ICMPType 8
ICMPCode 0
endSample   ----------------------
endDatagram   =================================

If you use this, then you will get another format of data:
> ./sflowtool -l
Counter Sample:
CNTR,10.3.207.142,3,6,1000000000,1,3,112616,955,1,4294967295,0,0,4294967295,123043,1012,4294967295,4294967295,0,0,0

Flow Sample:
FLOW,10.3.207.142,4,3,00ab71132d00,00ab77e34b00,0x0800,0,0,192.168.12.202,192.168.12.201,1,0x00,64,0,0,0x00,102,84,64


Monday, February 25, 2013

[C++ STL] Containers

We all know that using data structure well is very important in programming, because it affects the performance, data accuracy, maintenance no matter what kind of the program you write. In C language, we have to provide our data structure by ourselves or by searching for related library and grab it to use. But, if possible ( I mean if your program is able to use g++ compiler and the environment ), you can consider to just use Containers (C++ STL) in your program. It is useful and powerful. For more information, here is the official web site : http://www.cplusplus.com/reference/stl/

Container class templates

Sequence containers:

Container adaptors:

Associative containers:



Friday, January 25, 2013

[Library] The useful libraries for C

Needless to say, C is powerful. But, if you use Java or Python, you will reconize that C lakes a bunch of Libraries(APIs) or a framework for C programmer to do job quicker. Sometimes you have to look for some C libraries to meet your requirement, and then you can avoid from carving the same wheels again and again. This document will record the useful libraries for C language and I will continue to add the new one on it. For those who are a great C programmer, if you know a good library for C, please also let me know that. Thanks in advance.

OGDF - Open Graph Drawing Framework
http://www.ogdf.net/ogdf.php

Curl Lib
the multiprotocol file transfer library
http://curl.haxx.se/libcurl/

mongoose
The lightweight web server in C
http://code.google.com/p/mongoose/

SimCList – A C library for Lists
http://mij.oltrelinux.com/devel/simclist/

JSON Library
http://www.digip.org/jansson/

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts
http://libevent.org/

libev - a high performance full-featured event loop written in C
It is similar with libevent, but is more efficiently
http://doc.dvgu.ru/devel/ev.html

The Better String Library
http://bstring.sourceforge.net/

Unit Test Frameworks
https://github.com/imb/fctx

Exception Handling for C
http://code.google.com/p/exceptions4c/

SSL Library
https://polarssl.org/ssl-library

libssh2 is a client-side C library implementing the SSH2 protocol
http://www.libssh2.org/

MD5
http://256.com/sources/md5/

CIDR Library ( Need to verify )
http://www.over-yonder.net/~fullermd/projects/libcidr 

NETCONF library in C
https://code.google.com/p/libnetconf/

SQLite is a software library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine.
http://www.sqlite.org/

Monday, January 21, 2013

[SDN] The news about Juniper to build its own software-defined networking stack

Software Defined Networking is becoming hotter and hotter topic from last year. Properly networking guys will talk about Software-defined Networking (SDN) everywhere this year. The event that VMware bought Nicira became a catalyst for some related Network Vendors to think about what the strategy and tactic they should have and deal with this wave of SDN. It let me think of this song ( Blondie – The Tide Is High )
  The tide is high but I'm holding on ...
   I'm gonna be your number one ...

   ...

In sum, SDN is important and key to survive this time in the networking world. Here is an example about that Juniper takes an action to provide their SDN approach. I excerpt some paragraph as follows:


Quota from the news:
http://www.theregister.co.uk/2013/01/16/juniper_sdn_strategy/

Juniper's approach to SDN, explained Muglia, will break the monolithic software stack inside of switches and routers – for campuses, branches, and service providers and not just for data centers – into four different planes: management, services, control, and forwarding.

This software will run on a virtualization layer called JunosV App Engine – which sounds a lot like a KVM hypervisor container for an x86 server, but Juniper did not say. This virtualization software will ship later in the first quarter of this year.

Central to that SDN stack is Contrail, a startup that was just getting ready to uncloak last month with its SDN wares when Juniper swept in with $176m in cash and snapped it up. Contrail was founded by a team of networking and software platform experts from Google, Juniper, Cisco, and Aruba Networks, and significantly had former Juniper CTO and chief architect Kireeti Kompella as its CTO. Now Kompella is back at Juniper, and is central to its SDN strategy.

Tuesday, January 8, 2013

[Signal] The examples of using alarm() and sigaction()

In the following URL, it provides a good explanation about signal and signal handling.
https://www.sharcnet.ca/help/index.php/Signal_Handling_and_Checkpointing

Handling signal is a important job when we want to write a great code.
There are several signal functions that we could use often in programming. I will give some examples of how to use alarm() and sigaction() functions as below.
P.S: the URL link is the orginal source code which is from.


The follwing two examples are about how to use alarm() and ualarm().
http://jyhshin.pixnet.net/blog/post/27749178-linux-%E8%A8%88%E6%99%82%E5%99%A8-alarm-signal-%281%29

/* Example of using alarm() */ #include <unistd.h> #include <stdio.h> #include <signal.h> int main(int argc, char *argv[]) { sigset_t block; sigemptyset(&block); sigaddset(&block, SIGALRM); sigprocmask(SIG_BLOCK, &block, NULL); while (1) { alarm(2); printf("%d\n", time(NULL)); sigwaitinfo(&block, NULL); } return 0; }


/* Example of using ualarm() */ #define _XOPEN_SOURCE 500 #include <unistd.h> #include <stdio.h> #include <signal.h> int main(int argc, char *argv[]) { sigset_t block; sigemptyset(&block); sigaddset(&block, SIGALRM); sigprocmask(SIG_BLOCK, &block, NULL); ualarm(500000, 500000); while (1) { printf("%d\n", time(NULL)); sigwaitinfo(&block, NULL); } return 0; }


Actually, sigaction() is widely used in handling signal, for instance, SIGINT (interrupt), SIGCHLD, and so on. Here are the examples to show the usage of sigaction with SIGINT.
http://www.linuxprogrammingblog.com/code-examples/sigaction

/* Example of using sigaction() to setup a signal handler with 3 arguments * including siginfo_t. */ #include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> static void hdl (int sig, siginfo_t *siginfo, void *context) { printf ("Sending PID: %ld, UID: %ld\n", (long)siginfo->si_pid, (long)siginfo->si_uid); } int main (int argc, char *argv[]) { struct sigaction act; memset (&act, '\0', sizeof(act)); /* Use the sa_sigaction field because the handles has two additional parameters */ act.sa_sigaction = &hdl; /* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */ act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &act, NULL) < 0) { perror ("sigaction error"); return 1; } while (1) sleep (10); return 0; }

http://fanqiang.chinaunix.net/a4/b2/20010508/113528_b.html

/* Example of using sigaction() to setup a signal handler * with setting sa_handler */ #include <stdio.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <errno.h> #define PROMPT "Do you want to terminate the process?" char *prompt=PROMPT; void ctrl_c_oper(int signo) { write(STDERR_FILENO,prompt,strlen(prompt)); } int main() { struct sigaction act; act.sa_handler=ctrl_c_oper; sigemptyset(&act.sa_mask); act.sa_flags=0; if(sigaction(SIGINT,&act,NULL)<0) { fprintf(stderr,"Install Signal Action Error:%s\n\a",strerror(errno)); exit(1); } while(1); }

Friday, December 28, 2012

[ZeroMQ] The example of ZeroMQ via C#

Recently I found these two articles that give a very good introduction of ZeroMQ and an useful use case for synchronized PUB-SUB pattern. Although it uses C# as its programming language instead of C, but I still think we can learn some important concept from these.And also, these articles provide very good images to illustrate the communication patterns.

http://www.codeproject.com/Articles/488207/ZeroMQ-via-Csharp-Introduction
  • There are several communication patterns described

http://www.codeproject.com/Articles/514959/ZeroMQ-via-Csharp-Multi-part-messages-JSON-and-Syn
  • Multi-part messages
  • Synchronized Pub-Sub pattern using PUB-SUB + REQ-REP





Thursday, December 13, 2012

[SWIG] How to add C function in Python by using SWIG

Here is a simple example to use SWIG to automatically wrap C function and generate a wrapper and build a shared library for python.

/*** File : example.c ***/
#include 
<time.h>
double My_variable = 3.0;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
int my_mod(int x, int y) {
return (x%y);
}
char *get_time()
{
time_t ltime;
time(&ltime);
return ctime(&ltime);
}
/*************************/


/*** example.i ***/
%module example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
/******************/
Another example:
/* File : example.c */

double  My_variable  = 3.0;

/* Compute factorial of n */
int fact(int n) {
  if (n <= 1)
    return 1;
  else
    return n*fact(n-1);
}

/* Compute n mod m */
int my_mod(int n, int m) {
  return(n % m);
}

/* File : example.i */
%module example
%{
/* Put headers and other declarations here */
extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);
%}

extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);

What if you have some pointer arguments in C ? How to deal with it in Python? 

For example:void add(double a, double b, double *result) {
 *result = a + b;
}
Please refer to this document. It will give you the nametype mapping in SWIG.http://www.swig.org/Doc1.3/Arguments.html





Wednesday, December 12, 2012

[Trema] The L2 isolation mechanism in sliceable switch

If someone has ever seen the documents about sliceable switch as below, he/she will feel headache or sick because of a lot of contents and description.
https://github.com/trema/apps/wiki/sliceable_switch_tutorial
https://github.com/trema/apps/wiki/sliceable_switch_features

Now, I will give a flow control chart of slice function which is summarized from the source code ( slice.c ). That can give you a clear image about L2 isolation mechanism in sliceable switch, specially in Slice function. Check it out as the following chart:

 So, broadly speaking, the slice function will check mac binding first, then port_mac binding, and finally port binding. Meanwhile, some configurations will affect the result, for instance, "restrict hosts on port" enabled will force the slice function to check port_mac binding, otherwise, it won't do that.
Based on this flow chart, you can compare with the test cases in https://github.com/trema/apps/wiki/sliceable_switch_features