packet lib: packet_base: add a method which makes '_class_prefixes' easy to use

the variable '_class_prefixes' of stringify.StringifyMixin is used to help the method 'from_jsondict()' to create the class instance.
'_class_prefixes' requires a list of the class names.
some classes have another list of the class names alreadly.
this patch adds a method which makes '_class_prefixes' by using the existing list.

before applying this patch:
(e.g. ryu.lib.packet.ipv6)

    # append the name to another list
    @ipv6.register_header_type(inet.IPPROTO_HOPOPTS)
    class hop_opts(opt_header):
    ...

    @ipv6.register_header_type(inet.IPPROTO_DSTOPTS)
    class dst_opts(opt_header):
    ....

    # append the name again
    ipv6._class_prefixes = ['hop_opts', 'dst_opts', ...]

after applying this patch:
(e.g. ryu.lib.packet.ipv6)

    # append the name to another list
    @ipv6.register_header_type(inet.IPPROTO_HOPOPTS)
    class hop_opts(opt_header):
    ...

    @ipv6.register_header_type(inet.IPPROTO_DSTOPTS)
    class dst_opts(opt_header):
    ....

    # create the new list from another list
    ipv6.set_classes(ipv6._IPV6_EXT_HEADER_TYPE)
packet lib: bgp: fix reversibility about json

although BGP is using internal classes, no class is registered into '_class_prefixes'.
therefore, from_jsondict() does not work correctly.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import bgp
    msg1 = bgp.BGPUpdate(withdrawn_routes=[bgp.BGPWithdrawnRoute(length=0, addr='192.168.0.1')])
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = bgp.BGPUpdate.from_jsondict(jsondict['BGPUpdate'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[],total_path_attribute_len=None,type=2,withdrawn_routes=[BGPWithdrawnRoute(addr='192.168.0.1',length=0)],withdrawn_routes_len=None)
    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[],total_path_attribute_len=None,type=2,withdrawn_routes=[{'BGPWithdrawnRoute': {'length': 0, 'addr': '192.168.0.1'}}],withdrawn_routes_len=None)
    False

after applying this patch:

    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[],total_path_attribute_len=None,type=2,withdrawn_routes=[BGPWithdrawnRoute(addr='192.168.0.1',length=0)],withdrawn_routes_len=None)
    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[],total_path_attribute_len=None,type=2,withdrawn_routes=[BGPWithdrawnRoute(addr='192.168.0.1',length=0)],withdrawn_routes_len=None)
    True
packet lib: bpdu: fix reversibility about json

to_jsondict() JSON-izes public member variables of the object.
from_jsondict() calls the constructor using JSON members as the arguments.
BPDU has the public member that is not required for the constructor, so TypeError occurs in from_jsondict().
this patch suppresses the output of to_jsondict() by changing unnecessary public members into protected members.

examination code:

    from ryu.lib.packet import bpdu
    msg1 = bpdu.RstBPDUs()
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = bpdu.RstBPDUs.from_jsondict(jsondict['RstBPDUs'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    RstBPDUs(bpdu_type=2,bridge_mac_address='00:00:00:00:00:00',bridge_priority=32768,bridge_system_id_extension=0,flags=0,forward_delay=15,hello_time=2,max_age=20,message_age=0,port_number=0,port_priority=128,protocol_id=0,root_mac_address='00:00:00:00:00:00',root_path_cost=0,root_priority=32768,root_system_id_extension=0,version_1_length=0,version_id=2)
    CLS <class 'ryu.lib.packet.bpdu.RstBPDUs'>
    ARG {'max_age': 20, 'bpdu_type': 2, 'bridge_mac_address': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'hello_time': 2, 'protocol_id': 0, 'bridge_priority': 32768, 'message_age': 0, 'version_id': 2, 'port_priority': 128, 'flags': 0, 'root_priority': 32768, 'version_1_length': 0, 'root_path_cost': 0, 'port_number': 0, 'root_mac_address': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'root_system_id_extension': 0, 'forward_delay': 15, 'bridge_system_id_extension': 0}
    KWARG {'max_age': 20, 'bpdu_type': 2, 'bridge_mac_address': '00:00:00:00:00:00', 'hello_time': 2, 'protocol_id': 0, 'bridge_priority': 32768, 'message_age': 0, 'version_id': 2, 'port_priority': 128, 'flags': 0, 'root_priority': 32768, 'version_1_length': 0, 'root_path_cost': 0, 'port_number': 0, 'root_mac_address': '00:00:00:00:00:00', 'root_system_id_extension': 0, 'forward_delay': 15, 'bridge_system_id_extension': 0}
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 293, in from_jsondict
        return cls(**dict(kwargs, **additional_args))
    TypeError: __init__() got an unexpected keyword argument 'bpdu_type'

after applying this patch:

    RstBPDUs(bridge_mac_address='00:00:00:00:00:00',bridge_priority=32768,bridge_system_id_extension=0,flags=0,forward_delay=15,hello_time=2,max_age=20,message_age=0,port_number=0,port_priority=128,root_mac_address='00:00:00:00:00:00',root_path_cost=0,root_priority=32768,root_system_id_extension=0)
    RstBPDUs(bridge_mac_address='00:00:00:00:00:00',bridge_priority=32768,bridge_system_id_extension=0,flags=0,forward_delay=15,hello_time=2,max_age=20,message_age=0,port_number=0,port_priority=128,root_mac_address='00:00:00:00:00:00',root_path_cost=0,root_priority=32768,root_system_id_extension=0)
    True
packet lib: dhcp: fix reversibility about json

although DHCP is using internal classes, no class is registered into '_class_prefixes'.
therefore, from_jsondict() does not work correctly.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import dhcp
    msg1 = dhcp.dhcp(op=dhcp.DHCP_BOOT_REQUEST, chaddr='00:00:00:00:00:00', options=dhcp.options())
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = dhcp.dhcp.from_jsondict(jsondict['dhcp'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    dhcp(boot_file='',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=1,options=options(magic_cookie='99.130.83.99',option_list=[],options_len=0),secs=0,siaddr='0.0.0.0',sname='',xid=2430470794,yiaddr='0.0.0.0')
    dhcp(boot_file='',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=1,options={'options': {'option_list': [], 'magic_cookie': '99.130.83.99', 'options_len': 0}},secs=0,siaddr='0.0.0.0',sname='',xid=2430470794,yiaddr='0.0.0.0')
    False

after applying this patch:

    dhcp(boot_file='',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=1,options=options(magic_cookie='99.130.83.99',option_list=[],options_len=0),secs=0,siaddr='0.0.0.0',sname='',xid=1161619526,yiaddr='0.0.0.0')
    dhcp(boot_file='',chaddr='00:00:00:00:00:00',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=1,options=options(magic_cookie='99.130.83.99',option_list=[],options_len=0),secs=0,siaddr='0.0.0.0',sname='',xid=1161619526,yiaddr='0.0.0.0')
    True
packet lib: icmp: fix reversibility about json

although ICMP is using internal classes, no class is registered into '_class_prefixes'.
therefore, from_jsondict() does not work correctly.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import icmp
    msg1 = icmp.icmp(data=icmp.echo())
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = icmp.icmp.from_jsondict(jsondict['icmp'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:

    icmp(code=0,csum=0,data=echo(data=None,id=0,seq=0),type=8)
    icmp(code=0,csum=0,data={'echo': {'data': None, 'id': 0, 'seq': 0}},type=8)
    False

after applying this patch:

    icmp(code=0,csum=0,data=echo(data=None,id=0,seq=0),type=8)
    icmp(code=0,csum=0,data=echo(data=None,id=0,seq=0),type=8)
    True
packet lib: icmpv6: fix reversibility about json

although ICMPv6 is using internal classes, no class is registered into '_class_prefixes'.
therefore, from_jsondict() does not work correctly.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import icmpv6
    msg1 = icmpv6.icmpv6(data=icmpv6.nd_neighbor())
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:

    icmpv6(code=0,csum=0,data=nd_neighbor(dst='::',option=None,res=0),type_=0)
    icmpv6(code=0,csum=0,data={'nd_neighbor': {'res': 0, 'dst': '::', 'option': None}},type_=0)
    False

after applying this patch:

    icmpv6(code=0,csum=0,data=nd_neighbor(dst='::',option=None,res=0),type_=0)
    icmpv6(code=0,csum=0,data=nd_neighbor(dst='::',option=None,res=0),type_=0)
    True
packet lib: ipv6: fix reversibility about json

although IPv6 is using internal classes, no class is registered into '_class_prefixes'.
therefore, AssertionError occurs in from_jsondict() when the argument 'ext_hdrs' was processed.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import ipv6
    msg1 = ipv6.ipv6(ext_hdrs=[ipv6.hop_opts()])
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = ipv6.ipv6.from_jsondict(jsondict['ipv6'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    ipv6(dst='::',ext_hdrs=[hop_opts(data=None,nxt=6,size=0)],flow_label=0,hop_limit=255,nxt=6,payload_length=0,src='::',traffic_class=0,version=6)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 293, in from_jsondict
        return cls(**dict(kwargs, **additional_args))
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/packet/ipv6.py", line 86, in __init__
        assert isinstance(ext_hdr, header)
    AssertionError

after applying this patch:

    ipv6(dst='::',ext_hdrs=[hop_opts(data=None,nxt=6,size=0)],flow_label=0,hop_limit=255,nxt=6,payload_length=0,src='::',traffic_class=0,version=6)
    ipv6(dst='::',ext_hdrs=[hop_opts(data=None,nxt=6,size=0)],flow_label=0,hop_limit=255,nxt=6,payload_length=0,src='::',traffic_class=0,version=6)
    True
packet lib: llc: fix reversibility about json

although LLDP is using internal classes, no class is registered into '_class_prefixes'.
therefore, AssertionError occurs in from_jsondict() when the argument 'control' was processed.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import llc
    msg1 = llc.llc(dsap_addr=66, ssap_addr=66, control=llc.ControlFormatI())
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = llc.llc.from_jsondict(jsondict['llc'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    llc(control=ControlFormatI(pf_bit=0,receive_sequence_number=0,send_sequence_number=0),dsap_addr=66,ssap_addr=66)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 293, in from_jsondict
        return cls(**dict(kwargs, **additional_args))
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/packet/llc.py", line 140, in __init__
        assert getattr(control, 'TYPE', None) in self._CTR_TYPES
    AssertionError

after applying this patch:

    llc(control=ControlFormatI(pf_bit=0,receive_sequence_number=0,send_sequence_number=0),dsap_addr=66,ssap_addr=66)
    llc(control=ControlFormatI(pf_bit=0,receive_sequence_number=0,send_sequence_number=0),dsap_addr=66,ssap_addr=66)
    True
packet lib: lldp: fix reversibility about json

although LLDP is using internal classes, no class is registered into '_class_prefixes'.
therefore, from_jsondict() does not work correctly.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import lldp
    msg1 = lldp.lldp([lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id='\x00\x00\x00\x00\x00\x00')])
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = lldp.lldp.from_jsondict(jsondict['lldp'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    lldp(tlvs=[ChassisID(chassis_id='\x00\x00\x00\x00\x00\x00',len=7,subtype=4,typelen=519)])
    lldp(tlvs=[{'ChassisID': {'subtype': 4, 'typelen': 519, 'chassis_id': '\x00\x00\x00\x00\x00\x00', 'len': 7}}])
    False

after applying this patch:

    lldp(tlvs=[ChassisID(chassis_id='\x00\x00\x00\x00\x00\x00',len=7,subtype=4,typelen=519)])
    lldp(tlvs=[ChassisID(chassis_id='\x00\x00\x00\x00\x00\x00',len=7,subtype=4,typelen=519)])
    True
packet lib: sctp: fix reversibility about json

although SCTP is using internal classes, no class is registered into '_class_prefixes'.
therefore, AssertionError occurs in from_jsondict() when the argument 'param' was processed.
this patch makes from_jsondict() to work correctly by registering internal classes into '_class_prefixes'.

examination code:

    from ryu.lib.packet import sctp
    msg1 = sctp.sctp(chunks=[sctp.chunk_init(params=[sctp.param_cookie_preserve()])])
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = sctp.sctp.from_jsondict(jsondict['sctp'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:

    sctp(chunks=[chunk_init(a_rwnd=0,flags=0,i_tsn=0,init_tag=0,length=0,mis=0,os=0,params=[param_cookie_preserve(length=0,value=0)])],csum=0,dst_port=0,src_port=0,vtag=0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 291, in from_jsondict
        kwargs = cls._restore_args(_mapdict_kv(decode, dict_))
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 46, in <lambda>
        _mapdict_kv = lambda f, d: dict([(k, f(k, v)) for k, v in d.items()])
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 290, in <lambda>
        decode = lambda k, x: cls._decode_value(k, x, decode_string)
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 234, in _decode_value
        return cls._get_decoder(k, decode_string)(json_value)
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 242, in _decode
        v = map(_decode, json_value)
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 245, in _decode
        v = cls.obj_from_jsondict(json_value)
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 223, in obj_from_jsondict
        return obj_cls.from_jsondict(v)
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 293, in from_jsondict
        return cls(**dict(kwargs, **additional_args))
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/packet/sctp.py", line 273, in __init__
        assert isinstance(one, param)
    AssertionError

after applying this patch:

    sctp(chunks=[chunk_init(a_rwnd=0,flags=0,i_tsn=0,init_tag=0,length=0,mis=0,os=0,params=[param_cookie_preserve(length=0,value=0)])],csum=0,dst_port=0,src_port=0,vtag=0)
    sctp(chunks=[chunk_init(a_rwnd=0,flags=0,i_tsn=0,init_tag=0,length=0,mis=0,os=0,params=[param_cookie_preserve(length=0,value=0)])],csum=0,dst_port=0,src_port=0,vtag=0)
    True
packet lib: slow: fix reversibility about json

to_jsondict() JSON-izes public member variables of the object.
from_jsondict() calls the constructor using JSON members as the arguments.
LACP has the public member that is not required for the constructor, so TypeError occurs in from_jsondict().
this patch suppresses the output of to_jsondict() by changing unnecessary public members into protected members.

examination code:

    from ryu.lib.packet import slow
    msg1 = slow.lacp()
    print msg1
    jsondict = msg1.to_jsondict()
    msg2 = slow.lacp.from_jsondict(jsondict['lacp'])
    print msg2
    print str(msg1) == str(msg2)

before applying this patch:
    lacp(actor_key=0,actor_length=20,actor_port=0,actor_port_priority=0,actor_state=0,actor_state_activity=0,actor_state_aggregation=0,actor_state_collecting=0,actor_state_defaulted=0,actor_state_distributing=0,actor_state_expired=0,actor_state_synchronization=0,actor_state_timeout=0,actor_system='00:00:00:00:00:00',actor_system_priority=0,actor_tag=1,collector_length=16,collector_max_delay=0,collector_tag=3,partner_key=0,partner_length=20,partner_port=0,partner_port_priority=0,partner_state=0,partner_state_activity=0,partner_state_aggregation=0,partner_state_collecting=0,partner_state_defaulted=0,partner_state_distributing=0,partner_state_expired=0,partner_state_synchronization=0,partner_state_timeout=0,partner_system='00:00:00:00:00:00',partner_system_priority=0,partner_tag=2,subtype=1,terminator_length=0,terminator_tag=0,version=1)
    CLS <class 'ryu.lib.packet.slow.lacp'>
    ARG {'actor_state_distributing': 0, 'actor_length': 20, 'actor_system': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'collector_max_delay': 0, 'terminator_length': 0, 'collector_length': 16, 'partner_state_synchronization': 0, 'partner_state_timeout': 0, 'partner_state_distributing': 0, 'partner_state_collecting': 0, 'actor_state_synchronization': 0, 'actor_state_expired': 0, 'actor_state_defaulted': 0, 'partner_state_expired': 0, 'partner_state': 0, 'partner_system_priority': 0, 'actor_state_aggregation': 0, 'version': 1, 'partner_port': 0, 'partner_length': 20, 'collector_tag': 3, 'partner_state_defaulted': 0, 'actor_state_timeout': 0, 'actor_port_priority': 0, 'partner_state_activity': 0, 'actor_state_activity': 0, 'terminator_tag': 0, 'actor_system_priority': 0, 'actor_key': 0, 'partner_system': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'partner_tag': 2, 'actor_state': 0, 'actor_port': 0, 'partner_state_aggregation': 0, 'partner_port_priority': 0, 'actor_tag': 1, 'subtype': 1, 'partner_key': 0, 'actor_state_collecting': 0}
    KWARG {'actor_state_distributing': 0, 'actor_length': 20, 'actor_system': '00:00:00:00:00:00', 'collector_max_delay': 0, 'terminator_length': 0, 'collector_length': 16, 'partner_state_synchronization': 0, 'partner_state_timeout': 0, 'partner_state_distributing': 0, 'partner_state_collecting': 0, 'actor_state_synchronization': 0, 'actor_state_expired': 0, 'actor_state_defaulted': 0, 'partner_state_expired': 0, 'partner_state': 0, 'partner_system_priority': 0, 'actor_state_aggregation': 0, 'version': 1, 'partner_port': 0, 'partner_length': 20, 'collector_tag': 3, 'partner_state_defaulted': 0, 'actor_state_timeout': 0, 'actor_port_priority': 0, 'partner_state_activity': 0, 'actor_state_activity': 0, 'terminator_tag': 0, 'actor_system_priority': 0, 'actor_key': 0, 'partner_system': '00:00:00:00:00:00', 'partner_tag': 2, 'actor_state': 0, 'actor_port': 0, 'partner_state_aggregation': 0, 'partner_port_priority': 0, 'actor_tag': 1, 'subtype': 1, 'partner_key': 0, 'actor_state_collecting': 0}
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/ryu/lib/stringify.py", line 293, in from_jsondict
        return cls(**dict(kwargs, **additional_args))
    TypeError: __init__() got an unexpected keyword argument 'actor_length'

after applying this patch:

    lacp(actor_key=0,actor_port=0,actor_port_priority=0,actor_state_activity=0,actor_state_aggregation=0,actor_state_collecting=0,actor_state_defaulted=0,actor_state_distributing=0,actor_state_expired=0,actor_state_synchronization=0,actor_state_timeout=0,actor_system='00:00:00:00:00:00',actor_system_priority=0,collector_max_delay=0,partner_key=0,partner_port=0,partner_port_priority=0,partner_state_activity=0,partner_state_aggregation=0,partner_state_collecting=0,partner_state_defaulted=0,partner_state_distributing=0,partner_state_expired=0,partner_state_synchronization=0,partner_state_timeout=0,partner_system='00:00:00:00:00:00',partner_system_priority=0,version=1)
    lacp(actor_key=0,actor_port=0,actor_port_priority=0,actor_state_activity=0,actor_state_aggregation=0,actor_state_collecting=0,actor_state_defaulted=0,actor_state_distributing=0,actor_state_expired=0,actor_state_synchronization=0,actor_state_timeout=0,actor_system='00:00:00:00:00:00',actor_system_priority=0,collector_max_delay=0,partner_key=0,partner_port=0,partner_port_priority=0,partner_state_activity=0,partner_state_aggregation=0,partner_state_collecting=0,partner_state_defaulted=0,partner_state_distributing=0,partner_state_expired=0,partner_state_synchronization=0,partner_state_timeout=0,partner_system='00:00:00:00:00:00',partner_system_priority=0,version=1)
    True
packet lib: add unittests for reversibility about json

this patch adds tests that examine reversibility about json for all packet library.
the test codes are written as:

    jsondict = msg1.to_jsondict()
    msg2 = cls.from_jsondict(jsondict['msg'])
    eq_(str(msg1), str(msg2)

TODO: make VRRP reversible.
since VRRP has an unusual construction method, VRRP is not reversible about json.
packet lib: arp: improve readability of JSON

examination code:

    from ryu.lib.packet import arp
    msg = arp.arp()
    print msg
    jsonstr = msg.to_jsondict()
    print jsonstr

before applying this patch:

    arp(dst_ip='0.0.0.0',dst_mac='ff:ff:ff:ff:ff:ff',hlen=6,hwtype=1,opcode=1,plen=4,proto=2048,src_ip='0.0.0.0',src_mac='ff:ff:ff:ff:ff:ff')
    {'arp': {'hlen': 6, 'dst_mac': 'ZmY6ZmY6ZmY6ZmY6ZmY6ZmY=', 'proto': 2048, 'src_ip': 'MC4wLjAuMA==', 'hwtype': 1, 'opcode': 1, 'plen': 4, 'dst_ip': 'MC4wLjAuMA==', 'src_mac': 'ZmY6ZmY6ZmY6ZmY6ZmY6ZmY='}}

after applying this patch:

    arp(dst_ip='0.0.0.0',dst_mac='ff:ff:ff:ff:ff:ff',hlen=6,hwtype=1,opcode=1,plen=4,proto=2048,src_ip='0.0.0.0',src_mac='ff:ff:ff:ff:ff:ff')
    {'arp': {'hlen': 6, 'dst_mac': u'ff:ff:ff:ff:ff:ff', 'proto': 2048, 'src_ip': u'0.0.0.0', 'hwtype': 1, 'opcode': 1, 'plen': 4, 'dst_ip': u'0.0.0.0', 'src_mac': u'ff:ff:ff:ff:ff:ff'}}
packet lib: bgp: improve readability of JSON

examination code:

    from ryu.lib.packet import bgp
    withdrawn_routes = [bgp.BGPWithdrawnRoute(length=0, addr='192.0.2.13')
    ]
    communities = [
        bgp.BGP_COMMUNITY_NO_EXPORT,
        bgp.BGP_COMMUNITY_NO_ADVERTISE,
    ]
    ecommunities = [
        bgp.BGPIPv4AddressSpecificExtendedCommunity(subtype=3,
                                                    ipv4_address='192.0.2.1',
                                                    local_administrator=65432)
    ]
    path_attributes = [
        bgp.BGPPathAttributeNextHop(value='192.0.2.199'),
        bgp.BGPPathAttributeAggregator(as_number=40000, addr='192.0.2.99'),
        bgp.BGPPathAttributeAs4Aggregator(as_number=100040000, addr='192.0.2.99')]
    nlri = [
        bgp.BGPNLRI(length=24, addr='203.0.113.1'),
        bgp.BGPNLRI(length=16, addr='203.0.113.0')
    ]
    msg = bgp.BGPUpdate(withdrawn_routes=withdrawn_routes,
                         path_attributes=path_attributes)
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[BGPPathAttributeNextHop(flags=0,length=None,type=3,value='192.0.2.199'), BGPPathAttributeAggregator(addr='192.0.2.99',as_number=40000,flags=0,length=None,type=7), BGPPathAttributeAs4Aggregator(addr='192.0.2.99',as_number=100040000,flags=0,length=None,type=18)],total_path_attribute_len=None,type=2,withdrawn_routes=[BGPWithdrawnRoute(addr='192.0.2.13',length=0)],withdrawn_routes_len=None)
    {'BGPUpdate': {'path_attributes': [{'BGPPathAttributeNextHop': {'type': 3, 'length': None, 'flags': 0, 'value': 'MTkyLjAuMi4xOTk='}}, {'BGPPathAttributeAggregator': {'as_number': 40000, 'length': None, 'flags': 0, 'addr': 'MTkyLjAuMi45OQ==', 'type': 7}}, {'BGPPathAttributeAs4Aggregator': {'as_number': 100040000, 'length': None, 'flags': 0, 'addr': 'MTkyLjAuMi45OQ==', 'type': 18}}], 'total_path_attribute_len': None, 'withdrawn_routes': [{'BGPWithdrawnRoute': {'length': 0, 'addr': 'MTkyLjAuMi4xMw=='}}], 'nlri': [], 'len': None, 'marker': '/////////////////////w==', 'type': 2, 'withdrawn_routes_len': None}}

after applying this patch:

    BGPUpdate(len=None,marker='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff',nlri=[],path_attributes=[BGPPathAttributeNextHop(flags=0,length=None,type=3,value='192.0.2.199'), BGPPathAttributeAggregator(addr='192.0.2.99',as_number=40000,flags=0,length=None,type=7), BGPPathAttributeAs4Aggregator(addr='192.0.2.99',as_number=100040000,flags=0,length=None,type=18)],total_path_attribute_len=None,type=2,withdrawn_routes=[BGPWithdrawnRoute(addr='192.0.2.13',length=0)],withdrawn_routes_len=None)
    {'BGPUpdate': {'path_attributes': [{'BGPPathAttributeNextHop': {'type': 3, 'length': None, 'flags': 0, 'value': u'192.0.2.199'}}, {'BGPPathAttributeAggregator': {'as_number': 40000, 'length': None, 'flags': 0, 'addr': u'192.0.2.99', 'type': 7}}, {'BGPPathAttributeAs4Aggregator': {'as_number': 100040000, 'length': None, 'flags': 0, 'addr': u'192.0.2.99', 'type': 18}}], 'total_path_attribute_len': None, 'withdrawn_routes': [{'BGPWithdrawnRoute': {'length': 0, 'addr': u'192.0.2.13'}}], 'nlri': [], 'len': None, 'marker': '/////////////////////w==', 'type': 2, 'withdrawn_routes_len': None}}
packet lib: bpdu: improve readability of JSON

examination code:

    from ryu.lib.packet import bpdu
    msg = bpdu.ConfigurationBPDUs()
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    ConfigurationBPDUs(bridge_mac_address='00:00:00:00:00:00',bridge_priority=32768,bridge_system_id_extension=0,flags=0,forward_delay=15,hello_time=2,max_age=20,message_age=0,port_number=0,port_priority=128,root_mac_address='00:00:00:00:00:00',root_path_cost=0,root_priority=32768,root_system_id_extension=0)
    {'ConfigurationBPDUs': {'max_age': 20, 'bridge_mac_address': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'hello_time': 2, 'root_mac_address': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'bridge_priority': 32768, 'message_age': 0, 'port_priority': 128, 'flags': 0, 'root_priority': 32768, 'root_path_cost': 0, 'port_number': 0, 'root_system_id_extension': 0, 'forward_delay': 15, 'bridge_system_id_extension': 0}}

after applying this patch:

    ConfigurationBPDUs(bridge_mac_address='00:00:00:00:00:00',bridge_priority=32768,bridge_system_id_extension=0,flags=0,forward_delay=15,hello_time=2,max_age=20,message_age=0,port_number=0,port_priority=128,root_mac_address='00:00:00:00:00:00',root_path_cost=0,root_priority=32768,root_system_id_extension=0)
    {'ConfigurationBPDUs': {'max_age': 20, 'bridge_mac_address': u'00:00:00:00:00:00', 'hello_time': 2, 'root_mac_address': u'00:00:00:00:00:00', 'bridge_priority': 32768, 'message_age': 0, 'port_priority': 128, 'flags': 0, 'root_priority': 32768, 'root_path_cost': 0, 'port_number': 0, 'root_system_id_extension': 0, 'forward_delay': 15, 'bridge_system_id_extension': 0}}
packet lib: dhcp: improve readability of JSON

examination code:

    from ryu.lib.packet import dhcp
    msg = dhcp.dhcp(op=dhcp.DHCP_BOOT_REPLY, chaddr='11:22:33:44:55:66', options=dhcp.options())
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    dhcp(boot_file='',chaddr='11:22:33:44:55:66',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=2,options=options(magic_cookie='99.130.83.99',option_list=[],options_len=0),secs=0,siaddr='0.0.0.0',sname='',xid=1869372474,yiaddr='0.0.0.0')
    {'dhcp': {'hlen': 17, 'sname': '', 'xid': 1869372474, 'ciaddr': 'MC4wLjAuMA==', 'hops': 0, 'giaddr': 'MC4wLjAuMA==', 'secs': 0, 'yiaddr': 'MC4wLjAuMA==', 'chaddr': 'MTE6MjI6MzM6NDQ6NTU6NjY=', 'flags': 0, 'htype': 1, 'siaddr': 'MC4wLjAuMA==', 'boot_file': '', 'options': {'options': {'option_list': [], 'magic_cookie': 'OTkuMTMwLjgzLjk5', 'options_len': 0}}, 'op': 2}}

after applying this patch:

    dhcp(boot_file='',chaddr='11:22:33:44:55:66',ciaddr='0.0.0.0',flags=0,giaddr='0.0.0.0',hlen=17,hops=0,htype=1,op=2,options=options(magic_cookie='99.130.83.99',option_list=[],options_len=0),secs=0,siaddr='0.0.0.0',sname='',xid=958610391,yiaddr='0.0.0.0')
    {'dhcp': {'hlen': 17, 'sname': u'', 'xid': 958610391, 'ciaddr': u'0.0.0.0', 'hops': 0, 'giaddr': u'0.0.0.0', 'secs': 0, 'yiaddr': u'0.0.0.0', 'chaddr': u'11:22:33:44:55:66', 'flags': 0, 'htype': 1, 'siaddr': u'0.0.0.0', 'boot_file': '', 'options': {'options': {'option_list': [], 'magic_cookie': u'99.130.83.99', 'options_len': 0}}, 'op': 2}}
packet lib: ethernet: improve readability of JSON

examination code:

    from ryu.lib.packet import ethernet
    msg = ethernet.ethernet()
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    ethernet(dst='ff:ff:ff:ff:ff:ff',ethertype=2048,src='00:00:00:00:00:00')
    {'ethernet': {'ethertype': 2048, 'dst': 'ZmY6ZmY6ZmY6ZmY6ZmY6ZmY=', 'src': 'MDA6MDA6MDA6MDA6MDA6MDA='}}

after applying this patch:

    ethernet(dst='ff:ff:ff:ff:ff:ff',ethertype=2048,src='00:00:00:00:00:00')
    {'ethernet': {'ethertype': 2048, 'dst': u'ff:ff:ff:ff:ff:ff', 'src': u'00:00:00:00:00:00'}}
packet lib: icmpv6: improve readability of JSON

examination code:

    from ryu.lib.packet import icmpv6
    msg = icmpv6.icmpv6(
        type_=icmpv6.ND_ROUTER_ADVERT,
        data=icmpv6.nd_router_advert(
            options=[icmpv6.nd_option_sla(), icmpv6.nd_option_pi()]))
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    icmpv6(code=0,csum=0,data=nd_router_advert(ch_l=0,options=[nd_option_sla(data=None,hw_src='00:00:00:00:00:00',length=0), nd_option_pi(length=0,pl=0,pre_l=0,prefix='::',res1=0,res2=0,val_l=0)],rea_t=0,res=0,ret_t=0,rou_l=0),type_=134)
    {'icmpv6': {'csum': 0, 'type': 134, 'code': 0, 'data': {'nd_router_advert': {'rou_l': 0, 'res': 0, 'rea_t': 0, 'ret_t': 0, 'ch_l': 0, 'options': [{'nd_option_sla': {'hw_src': 'MDA6MDA6MDA6MDA6MDA6MDA=', 'data': None, 'length': 0}}, {'nd_option_pi': {'res1': 0, 'res2': 0, 'pre_l': 0, 'prefix': 'Ojo=', 'length': 0, 'val_l': 0, 'pl': 0}}]}}}}

after applying this patch:

    icmpv6(code=0,csum=0,data=nd_router_advert(ch_l=0,options=[nd_option_sla(data=None,hw_src='00:00:00:00:00:00',length=0), nd_option_pi(length=0,pl=0,pre_l=0,prefix='::',res1=0,res2=0,val_l=0)],rea_t=0,res=0,ret_t=0,rou_l=0),type_=134)
    {'icmpv6': {'csum': 0, 'type': 134, 'code': 0, 'data': {'nd_router_advert': {'rou_l': 0, 'res': 0, 'rea_t': 0, 'ret_t': 0, 'ch_l': 0, 'options': [{'nd_option_sla': {'hw_src': u'00:00:00:00:00:00', 'data': None, 'length': 0}}, {'nd_option_pi': {'res1': 0, 'res2': 0, 'pre_l': 0, 'prefix': u'::', 'length': 0, 'val_l': 0, 'pl': 0}}]}}}}
packet lib: igmp: improve readability of JSON

examination code:

    from ryu.lib.packet import igmp
    msg = igmp.igmp()
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    igmp(address='0.0.0.0',csum=0,maxresp=0,msgtype=17)
    {'igmp': {'csum': 0, 'maxresp': 0, 'msgtype': 17, 'address': 'MC4wLjAuMA=='}}

after applying this patch:

    igmp(address='0.0.0.0',csum=0,maxresp=0,msgtype=17)
    {'igmp': {'csum': 0, 'maxresp': 0, 'msgtype': 17, 'address': u'0.0.0.0'}}
packet lib: ipv4: improve readability of JSON

examination code:

    from ryu.lib.packet import ipv4
    msg = ipv4.ipv4()
    print msg
    jsondict = msg.to_jsondict()
    print jsondict

before applying this patch:

    ipv4(csum=0,dst='0.0.0.0',flags=0,header_length=5,identification=0,offset=0,option=None,proto=0,src='0.0.0.0',tos=0,total_length=0,ttl=255,version=4)
    {'ipv4': {'src': 'MC4wLjAuMA==', 'header_length': 5, 'option': None, 'proto': 0, 'tos': 0, 'dst': 'MC4wLjAuMA==', 'ttl': 255, 'total_length': 0, 'version': 4, 'identification': 0, 'offset': 0, 'csum': 0, 'flags': 0}}

after applying this patch:

    ipv4(csum=0,dst='0.0.0.0',flags=0,header_length=5,identification=0,offset=0,option=None,proto=0,src='0.0.0.0',tos=0,total_length=0,ttl=255,version=4)
    {'ipv4': {'src': u'0.0.0.0', 'header_length': 5, 'option': None, 'proto': 0, 'tos': 0, 'dst': u'0.0.0.0', 'ttl': 255, 'total_length': 0, 'version': 4, 'identification': 0, 'offset': 0, 'csum': 0, 'flags': 0}}