一种基于openflow的虚拟化层软件flowvisor的API测试

一种基于openflow的虚拟化层软件flowvisor的API测试

注明:本文并不对openflow进行分析,本人也是略略知道这个概念,对flowvisor也只是对其API有所测试,更深的源码并未涉及,只是希望该文能对以后的flowvisor研究者提供些许帮助。如果本文排版有问题,请看http://www.cnblogs.com/hyd-desert-camel/p/3891515.html

一:flowvisor简介  

flowvisor是基于openflow的一个中间代理层,其目的在于对物理资源的抽象和分片,从而使得每个控制器下的slice相互隔离,从而做到网络的虚拟化。现有的openflow机制中,主要提供了虚拟交换机如open vswitch,还有控制器如POX,floodlight等,但没有一个很好地资源抽象来实现多用户隔离和分片,flowvisor就是希望完成这个目标。  

flowvisor中有几个比较关键的概念。  

      1.flow:这个其实是对应着openflow报文的10个field的,每一个精确地flow就是这10个filed的一个精确匹配。换言之,由于这10个field总计占256bit,所以这是一个256维的空间,每一个flow就是这个256维空间中的一个点.  

      2.flowspace:上文提到整个openflow报文在匹配(match)时是一个256维空间中的一个点,那么对于整个网络而言,其flowspace就是256维空间。正如论文中所说的那样,flowspace是他们对匹配头的一个称呼。比如slice1下控制有一个所有协议使用TCP/IP的报文的流,那么这所有符合这个匹配条件的流就是这一个slice所对应的子空间,也就是改slice所拥有的一个flowspace。不同的slice可以对同一个flowspace有权限,但其权限应该不同.此概念不易理解,可以直接参考论文进行理解。  

       3.slice:网络虚拟化的目的,就是希望不同的用户看到完全隔离的不同的物理网络,但实际网络并非用户看到的那样,所以slice就是一个对物理网络的抽象和划分,就是资源的分割,权限的分配。每一个slice本质上就是一个配置文件,其中对slice的参数进行的描述。在flowvisor中,其存储在数据库中。  

flowvisor是基于RPC机制的,目前其使用的是JSON-RPC机制,其大致机制如下:


二:API测试测试环境:ubuntu12.04 LTS节点拓扑结构:


 flowspace match字段:

 all or any is used to specify a flow that matches all packets.    

  in_port=port_no             

 Matches  physical  port  port_no.   Switch ports are numbered as              displayed by fvctl getDeviceInfo DPID.       

 dl_vlan=vlan              

Matches IEEE 802.1q virtual LAN tag  vlan.   Specify  0xffff  as              vlan  to  match  packets that are not tagged with a virtual LAN;              otherwise, specify a number between 0 and  4095,  inclusive,  as              the 12-bit VLAN ID to match.        dl_src=mac              Matches  Ethernet  source address mac, which should be specified              as 6 pairs of  hexadecimal  digits  delimited  by  colons,  e.g.              00:0A:E4:25:6B:B0.        dl_dst=mac              Matches Ethernet destination address mac.        dl_type=ethertype              Matches Ethernet protocol type ethertype, which should be speci‐              fied as a integer between 0 and 65535, inclusive, either in dec‐              imal  or  as a hexadecimal number prefixed by 0x, e.g. 0x0806 to              match ARP packets.      nw_src=ip[/netmask]              Matches IPv4 source address ip, which should be specified as  an              IP  address,  e.g.  192.168.1.1.   The  optional  netmask allows              matching only on an IPv4 address prefix.  The netmask is  speci‐              ficed "CIDR-style", i.e., 192.168.1.0/24.        nw_dst=ip[/netmask]              Matches IPv4 destination address ip.        nw_proto=proto              Matches  IP  protocol type proto, which should be specified as a              decimal number between 0 and 255, inclusive, e.g. 6 to match TCP              packets.        nw_tos=tos/dscp              Matches  ToS/DSCP  (only  6-bits, not modify reserved 2-bits for              future use) field of IPv4 header tos/dscp, which should be spec‐              ified as a decimal number between 0 and 255, inclusive.      tp_src=port              Matches transport-layer (e.g., TCP, UDP, ICMP) source port port,              which should be specified as a  decimal  number  between  0  and              65535  (in  the case of TCP or UDP) or between 0 and 255 (in the              case of ICMP), inclusive, e.g. 80 to match  packets  originating              from a HTTP server.        tp_dst=port              Matches transport-layer destination port port. slice权限参数:DELEGATE(1), READ(2), and WRITE(4) API测试:一:add-1.add-slice:命令语法:fvctl add-slice [options] <slicename> <controller-url> <admin-email>   -d DROP, --drop-policy=DROP                        Drop rule type; default='exact'  -l, --recv-lldp       Slice to receive unknown LLDP; default=False  -f FLOW, --flowmod-limit=FLOW                        Slice tcam usage; default is none (-1)  -r RATE, --rate-limit=RATE                        Slice control path rate limit; default is none (-1)  -p PASSWD, --password=PASSWD                        Slice password  --disabled            Disable this slice initially; default=False输入:fvctl -p 8081 add-slice -l s4 tcp:127.0.0.1 hyd@126.com输出:Slice s4 was successfully createdroot@icecamel-virtual-machine:/home/icecamel/nv# fvctl -p 8081 list-slice-info s4Password:{  "admin-contact": "hyd@126.com",  "admin-status": true,  "controller-url": "tcp:127.0.0.1:6633",  "current-flowmod-usage": 0,  "current-rate": 0,  "drop-policy": "exact",  "recv-lldp": true,  "slice-name": "s4"}输入:fvctl -p 8081 add-slice -r 1 s5 tcp:127.0.0.1:6640 hyd@126.com输出:Slice s5 was successfully createdroot@icecamel-virtual-machine:/home/icecamel/nv# fvctl -p 8081 list-slice-info s5Password:{  "admin-contact": "hyd@126.com",  "admin-status": true,  "controller-url": "tcp:127.0.0.1:6640",  "current-flowmod-usage": 0,  "current-rate": 0,  "drop-policy": "exact",  "recv-lldp": false,  "slice-name": "s5"}ps:      1.slice不可同名      2.slice的controller不可相同 2.add-flowspace语法规则: fvctl add-flowspace [options] <flowspace-name> <dpid> <priority> <match> <slice-perm>Options:  -h, --help            show this help message and exit  -q QUEUES, --queues=QUEUES                        Define list of queues permitted on this flowspace.  -f FQUEUE, --forced-queue=FQUEUE                        Force a queue id upon output action.注明:match字段如文档开头描述,在这里用perm1=x1,perm=x2的形式列举希望匹配的字段即可,all或者any可以表示所有资源,slice-perm的规则是slice-name1=num1,slice-name2=num2,其中slice权限参数:DELEGATE(1), READ(2), and WRITE(4)输入:fvctl -p 8081 add-flowspace -f 2 fs3 all 100 all s1=5输出:FlowSpace fs3 was added with request id 4{"force-enqueue": 2, "name": "fs3", "slice-action": [{"slice-name": "s1", "permission": 5}], "queues": [], "priority": 100, "dpid": "all_dpids", "id": 5, "match": {"wildcards": 4194303}}输入:fvctl -p 8081 add-flowspace fs12 all 90 all s2=4输出:{ "dpid": "all_dpids", "force-enqueue": -1, "id": 7, "match": {  "wildcards": 4194303 }, "name": "fs12", "priority": 90, "queues": [], "slice-action": [  {   "permission": 4,   "slice-name": "s2"  } ]}ps:如果执行fvctl -p 8081 add-flowspace all 90 all s1=5,s2=5,会出现两个完全一模一样的flowspace,其ID也是一样的,避免使用。  二:list-1.list-datapaths:Displays the devices输入: fvctl -p 8081 list-datapaths输出:Connected switches:  1 : 00:00:1e:e3:d3:5e:b1:47  2 : 00:00:4a:e6:f6:f2:1e:4c  3 : 00:00:72:cf:98:c4:27:41  4 : 00:00:ee:95:d7:4d:0f:49 2.list-datapath-info:Displays information for a connected device输入:fvctl -p 8081 list-datapath-info 00:00:1e:e3:d3:5e:b1:47 (00:00:1e:e3:d3:5e:b1:47 是dpid)输出:{  "connection": "/127.0.0.1:6633-->/127.0.0.1:58527",  "current-flowmod-usage": {    "fvadmin": 0,    "s1": 0,    "s2": 0  },  "dpid": "00:00:1e:e3:d3:5e:b1:47",  "num-ports": 4,  "port-list": [    3,    2,    65534,    1  ],  "port-names": [    "b2-b3",    "b2-b1",    "b2",    "p2"  ]} 3.list-datapath-stats:Display statistics for a connected device输入:fvctl -p 8081 list-datapath-stats 00:00:1e:e3:d3:5e:b1:47输出:{  "drop": {    "Total": {}  },  "rx": {    "Total": {      "ECHO_REPLY": 426,      "ECHO_REQUEST": 423,      "FEATURES_REPLY": 1,      "HELLO": 1    },    "classifier-dpid=00:00:1e:e3:d3:5e:b1:47": {      "ECHO_REPLY": 426,      "ECHO_REQUEST": 423,      "FEATURES_REPLY": 1,      "HELLO": 1    }  },  "tx": {    "Total": {      "ECHO_REPLY": 423,      "ECHO_REQUEST": 426,      "FEATURES_REQUEST": 1,      "FLOW_MOD": 1,      "HELLO": 1    },    "classifier-dpid=00:00:1e:e3:d3:5e:b1:47": {      "ECHO_REPLY": 423,      "ECHO_REQUEST": 426,      "FEATURES_REQUEST": 1,      "FLOW_MOD": 1,      "HELLO": 1    }  }} 4.list-slices: Displays the configured slices输入:fvctl -p 8081 list-slices输出:fvadmin         --> enableds1              --> enableds2              --> enabled 5.list-slice-info:Displays slice information输入:fvctl -p 8081 list-slice-info s1输出:{  "admin-contact": "hyd@126.com",  "admin-status": true,  "controller-url": "tcp:127.0.0.1:6636",  "current-flowmod-usage": 0,  "current-rate": 0,  "drop-policy": "exact",  "recv-lldp": false,  "slice-name": "s1"} 6.list-slice-stats:Displays statistics about a slice输入:fvctl -p 8081 list-slice-stats s1fvctl -p 8081 list-slice-stats s2fvctl -p 8081 list-slice-stats fvadmin输出:Internal Error -> list-slice-stats: No stats exist for this slice : s1Internal Error -> list-slice-stats: No stats exist for this slice : s2Internal Error -> list-slice-stats: No stats exist for this slice : fvadmin 7.list-flowspace:fvctl list-flowspace [options]        -s SLICE, --slice-name=SLICE Fetch flowspace for specified slice.        -x, --output-hex      Displays relevant fields in hex        -p, --pretty-print    Pretty print output        --show-disabled       Display flowspace for disabled slices输入1:fvctl -p 8081 list-flowspace输出1:{"force-enqueue": -1, "name": "fs1", "slice-action": [{"slice-name": "s1", "permission": 5}], "queues": [], "priority": 100, "dpid": "all_dpids", "id": 1, "match": {"wildcards": 4194263, "nw_proto": 0, "dl_dst": "78:45:c4:2d:72:51"}}输入2:fvctl -p 8081 list-flowspace  -s s1输出:符合结果输入3:fvctl -p 8081 list-flowspace  -x (可输入slice-name)输入3:fvctl -p 8081 list-flowspace -p:以列表形式输出 8.list-datapath-flowdb:Displays the contents of the flow db if flow tracking is enabled(跟踪从slice push到switch的flow)输入:fvctl -p 8081 list-datapath-flowdb 00:00:1e:e3:d3:5e:b1:47输出:Flows seen at FlowVisor: 9. list-datapath-flowrewritedb:Displays the rewrites (or expansions) FlowVisor has applied(当controller把一个flow向flowvisor push的时候,flowvisor可能会扩展该流,次命令查阅该扩展)命令格式:fvctl list-datapath-flowrewritedb slice-name dpid输入:fvctl -p 8081 list-datapath-flowrewritedb s1 00:00:36:f1:bb:00:67:47输出:Rewrites applied by FlowVisor:输入:fvctl -p 8081 list-datapath-flowrewritedb s1 000036f1bb006747输出:同上ps:dpid的格式如果错误,会报错,详情如下:输入:fvctl -p 8081 list-datapath-flowrewritedb s2 0000-3a02-5569-824c输出:HTTP Error 500: Server ErrorRewrites applied by FlowVisor:Traceback (most recent call last):  File "/usr/local/bin/fvctl", line 1103, in <module>    do_func(gopts, opts, args)  File "/usr/local/bin/fvctl", line 702, in do_listrewritedb    for fbe in ret:TypeError: 'NoneType' object is not iterable 10:list-fs-status:命令格式: fvctl list-fs-status <fs-id>命令作用:查看添加flowspace的请求是否被处理或者请求,返回值有UNKNOWN,PENDING,SUCCESS,或者错误信息输入:fvctl -p 8081 list-fs-status 1输出:FlowSpace Request id 1 : SUCCESS输入:   fvctl -p 8081 list-fs-status 10输出:FlowSpace Request id 10 : UNKNOWN 11:list-fv-health:呈现一些参数输入:fvctl -p 8081  list-fv-health输出:{  "average-delay": 0,  "instant-delay": 0} 12:list-links:输入:fvctl -p 8081 list-links输出:[  {    "attributes": "fakeLink=true",    "dstDPID": "00:00:42:49:a6:41:b1:41",    "dstPort": "1",    "srcDPID": "00:00:3a:02:55:69:82:4c",    "srcPort": "0"  },  {    "attributes": "fakeLink=true",    "dstDPID": "00:00:62:0b:89:0d:f5:46",    "dstPort": "1",    "srcDPID": "00:00:42:49:a6:41:b1:41",    "srcPort": "0"  },  {    "attributes": "fakeLink=true",    "dstDPID": "00:00:36:f1:bb:00:67:47",    "dstPort": "1",    "srcDPID": "00:00:62:0b:89:0d:f5:46",    "srcPort": "0"  },  {    "attributes": "fakeLink=true",    "dstDPID": "00:00:3a:02:55:69:82:4c",    "dstPort": "1",    "srcDPID": "00:00:36:f1:bb:00:67:47",    "srcPort": "0"  }] 三:配置1.get-config:fvctl -p 8081 get-config结果:Password:{  "api_jetty_webserver_port": 8081,  "api_webserver_port": 8080,  "checkpointing": false,  "config_name": "default",  "db_version": "2",  "enable-topo-ctrl": false,  "flood-perm": {    "dpid": "all",    "slice-name": "fvadmin"  },  "flow-stats-cache": 30,  "flowmod-limit": {    "fvadmin": {      "00:00:1e:e3:d3:5e:b1:47": -1,      "00:00:4a:e6:f6:f2:1e:4c": -1,      "00:00:72:cf:98:c4:27:41": -1,      "00:00:ee:95:d7:4d:0f:49": -1,      "any": null    },    "s1": {      "00:00:1e:e3:d3:5e:b1:47": -1,      "00:00:4a:e6:f6:f2:1e:4c": -1,      "00:00:72:cf:98:c4:27:41": -1,      "00:00:ee:95:d7:4d:0f:49": -1,      "any": null    },    "s2": {      "00:00:1e:e3:d3:5e:b1:47": -1,      "00:00:4a:e6:f6:f2:1e:4c": -1,      "00:00:72:cf:98:c4:27:41": -1,      "00:00:ee:95:d7:4d:0f:49": -1,      "any": null    }  },  "host": "localhost",  "log_facility": "LOG_LOCAL7",  "log_ident": "flowvisor",  "logging": "NOTE",  "stats-desc": false,  "track-flows": false,  "version": "flowvisor-1.4.0"} 2.set-config:设置flowvisor的参数:For flood permissions, if both the dpid and theslice are given, then that slice is given permission for that dpid. Otherwise,the given slice is set as the slice global flood permissions. For flowmodlimits, the limit is set per slice per dpid. The dpid in case could be 'any'.语法规则:fvctl set-config [options]Options:  -h, --help            show this help message and exit  -f SLICE[,DPID], --flood-perm=SLICE[,DPID]                        Set the floodperm  -l SLICE,DPID,LIMIT, --flowmod-limit=SLICE,DPID,LIMIT                        Set the flowmod limit.  --enable-tracking     Enable flow tracking.  --disable-tracking    Disable flow tracking.  --enable-stats-desc   Enable stats description hijacking.  --disable-stats-desc  Disable stats description hijacking.  --enable-topo-ctrl    Enable topology controller.  --disable-topo-ctrl   Disable topology controller.  -c CACHE, --flow-stats-cache=CACHE                        Set the aging timer for the flow stats cache.输入:fvctl -p 8081 set-config -f s1 -- enable-tracking输出:Configuration has been updated(调用get-config后可以看到的确成功修改)输入:fvctl -p 8081 set-config -l s1,00:00:36:f1:bb:00:67:47,10输出:(修改成功)root@icecamel-virtual-machine:~# fvctl -p 8081 get-config -s s1 -d 00:00:36:f1:bb:00:67:47Password:{  "api_jetty_webserver_port": 8081,  "api_webserver_port": 8080,  "checkpointing": false,  "config_name": "default",  "db_version": "2",  "enable-topo-ctrl": false,  "flood-perm": {    "dpid": "00:00:36:f1:bb:00:67:47",    "slice-name": ""  },  "flow-stats-cache": 30,  "flowmod-limit": {    "s1": {      "00:00:36:f1:bb:00:67:47": 10    }  },  "host": "localhost",  "log_facility": "LOG_LOCAL7",  "log_ident": "flowvisor",  "logging": "NOTE",  "stats-desc": false,  "track-flows": true,  "version": "flowvisor-1.4.0"} 3.save-config:语法规则:fvctl save-config <file>输入: fvctl -p 8081 save-config /home/icecamel/nv/config_test.json输出:Config file written to /home/icecamel/nv/config_test.json.root@icecamel-virtual-machine:/home/icecamel/nv# lsconfig_test.json 四:remove与update1.remove-slice输入:fvctl -p 8081 remove-slice s4输出:(正常删除) 2.remove-flowspace输入:fvctl -p 8081 remove-flowspace fs4输出:(正常删除)ps:之前在add-flowspace时通过命令fvctl -p 8081 add-flowspace all 100 all s1=5,s2=5同时生成的两个一模一样的flowspace通过该命令会被同时删除 3.update-admin-password语法规则:fvctl update-admin-password [options]Update the admin password.Options:  -h, --help            show this help message and exit  -p PASSWD, --password=PASSWD                        New password for admin.输入:fvctl update-admin-password -p 123正常更改输入:fvctl -p 8081 update-admin-password -p 123输出:前面的更改生效且这次也成功更改ps:在修改过后重启,密码修改失效 4.update-flowspace语法规则:fvctl update-flowspace [options] <flowspace-name>Options:  -h, --help            show this help message and exit  -d DPID, --dpid=DPID  Set the dpid for flowspace entry.  -p PRIO, --priority=PRIO                        Set the priority for flowspace entry.  -m MATCH, --match=MATCH                        Set the match for flowspace entry.  -s SACT, --slice-action=SACT                        Set the slice(s) for flowspace entry.  -q QUEUES, --queues=QUEUES                        Define list of queues permitted on this flowspace.  -f FQUEUE, --forced-queue=FQUEUE                        Force a queue id upon output action.输入:fvctl -p 8081 update-flowspace fs6 -m dl_src=0a:a1:f9:da:26:13,nw_proto=0x1输出:Flowspace fs6 was updated with request id 10{ "dpid": "all_dpids", "force-enqueue": -1, "id": 10, "match": {  "dl_src": "0a:a1:f9:da:26:13",  "nw_proto": 1,  "wildcards": 4194267 }, "name": "fs6", "priority": 101, "queues": [  2,  3,  4 ], "slice-action": [  {   "permission": 5,   "slice-name": "s2"  } ]}(成功修改,且无论是添加flowspace还是修改flowspace,均会使id增加,修改id为x的flowspace,其输出结果id=x+n,且该flowspace 的id变为x)输入:fvctl -p 8081 update-flowspace fs6 -s s2=5输出:Flowspace fs6 was updated with request id 11 5.update-slice-password语法规则:fvctl update-slice-password slice-name -p NewPasswd\输入:fvctl update-slice-password s2 -p 123输出:Slice password for s2 has been updated. 6.update-slice语法规则:fvctl update-slice [options] <slicename>输入:fvctl -p 8081 update-slice s1 -n 192.168.1.133输出:Slice s1 has been successfully updated{  "admin-contact": "hyd@126.com",  "admin-status": true,  "controller-url": "tcp:192.168.1.133:6636",  "current-flowmod-usage": 0,  "current-rate": 0,  "drop-policy": "exact",  "recv-lldp": false,  "slice-name": "s1"}输入: fvctl -p 8081 update-slice s1 -d rule输出:Slice s1 has been successfully updatedroot@icecamel-virtual-machine:/home/icecamel/nv# fvctl -p 8081 list-slice-info s1Password:{  "admin-contact": "hyd@126.com",  "admin-status": true,  "controller-url": "tcp:192.168.1.133:6636",  "current-flowmod-usage": 0,  "current-rate": 0,  "drop-policy": "rule",  "recv-lldp": false,  "slice-name": "s1"} 7.register-event-callback:Registers for events from FlowVisor. Possible events are: DEVICE_CONNECTED,SLICE_CONNECTED, SLICE_DISCONNECTED and FLOWTABLE_CALLBACK. ForFLOWTABLE_CALLBACK event type dpid has to be input with -d option. More eventsmay be added later.语法规则:fvctl register-event-callback <url> <methodname> <eventtype> <name>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容