# 基于网络流量的SDN最短路径转发应用

## Forwarding Algorithm

(1) 首先基于跳数计算最优K条路径，然后在这些路径中选择可用带宽最大的路径。

(2) 首先基于跳数计算最优路径，归一化路径的评价分数，然后基于流量计算最优路径，归一化基于带宽的评价；设置跳数和带宽的权重，对基于跳数和带宽的评分求其加权总和；按照加权求和值降序排序，取前K条作为最优评价路径。

## Network Awareness

• 创建继承app_manager.RyuApp的应用network_awareness
• 从topology.switches获取拓扑信息，包括交换机节点信息，链路信息
• 使用Networkx 创建拓扑图的对象，用于存储网络拓扑
• 使用Networkx的函数all_simple_paths(G, source, target, cutoff=None)计算K条最优路径并存储，该函数实现了Yen's algorithm

Note that: 以上的示例代码中，拓扑信息的存储并没有使用networkx，所以读者需要独立完成基于networkx的存储和算法调用部分。

## Forwarding Application

• 获取network awareness和network monitor的数据
• 将network monitor的数据整合到networkx存储的网络拓扑信息中
• 比较最短K条路径中各路径的剩余带宽，选择最优路径，剩余路径为备份路径和逃生路径
• 基于路径信息，安装流表项

```<code>def create_bw_graph(self, graph, link2port, bw_dict):

if src_dpid in bw_dict and dst_dpid in bw_dict:
bw_src = bw_dict[src_dpid][src_port]
bw_dst = bw_dict[dst_dpid][dst_port]
graph[src_dpid][dst_dpid]['bandwidth'] = min(bw_src, bw_dst)
else:
graph[src_dpid][dst_dpid]['bandwidth'] = 0
return graph```

```def k_shortest_paths(graph, src, dst):
path_generator = nx.shortest_simple_paths(graph, source=src,
target=dst, weight='weight')
return path_generator```

```def band_width_compare(graph, paths, best_paths):
capabilities = {}
MAX_CAPACITY = 100000
for src in paths:
for dst in paths[src]:
if src == dst:
best_paths[src][src] = [src]
capabilities.setdefault(src, {src: MAX_CAPACITY})
capabilities[src][src] = MAX_CAPACITY
continue
max_bw_of_paths = 0
best_path = paths[src][dst][0]
for path in paths[src][dst]:
min_bw = MAX_CAPACITY
if min_bw &gt; max_bw_of_paths:
max_bw_of_paths = min_bw
best_path = path</p>
best_paths[src][dst] = best_path
capabilities.setdefault(src, {dst: max_bw_of_paths})
capabilities[src][dst] = max_bw_of_paths
return capabilities, best_paths```
```def best_paths_by_bw(graph, src=None, topo=None):
_graph = copy.deepcopy(graph)
paths = {}
best_paths = {}
# find ksp in graph.
for src in _graph.nodes():
paths.setdefault(src, {src: [src]})
best_paths.setdefault(src, {src: [src]})
for dst in _graph.nodes():
if src == dst:
continue
paths[src].setdefault(dst, [])
best_paths[src].setdefault(dst, [])
path_generator = k_shortest_paths(_graph, src, dst)
k = 2
for path in path_generator:
if k &lt;= 0:
break
paths[src][dst].append(path)
k -= 1
# find best path by comparing bandwidth.
capabilities, best_paths = band_width_compare(_graph, paths, best_paths)
return capabilities, best_paths, paths```

```def install_flow(datapaths, link2port, access_table, path, flow_info, buffer_id, data):
''' path=[dpid1, dpid2, dpid3...]
flow_info=(eth_type, src_ip, dst_ip, in_port)
'''
if path is None or len(path) == 0:
LOG.info("PATH ERROR")
return
in_port = flow_info[3]
first_dp = datapaths[path[0]]
out_port = first_dp.ofproto.OFPP_LOCAL
reverse_flow_info = (flow_info[0], flow_info[2], flow_info[1])
<pre><code>if len(path) &gt; 2:
for i in xrange(1, len(path) - 1):
if port and port_next:
src_port, dst_port = port[1], port_next[0]
datapath = datapaths[path[i]]
send_flow_mod(datapath, flow_info, src_port, dst_port)
send_flow_mod(datapath, reverse_flow_info, dst_port, src_port)
if len(path) &gt; 1:
# the last flow entry: tor -&gt; host
last_dp = datapaths[path[-1]]
if port_pair:
src_port = port_pair[1]
else:
return
dst_port = get_port(flow_info[2], access_table)
send_flow_mod(last_dp, flow_info, src_port, dst_port)
send_flow_mod(last_dp, reverse_flow_info, dst_port, src_port)
# the first flow entry
if port_pair:
out_port = port_pair[0]
else:
return
send_flow_mod(first_dp, flow_info, in_port, out_port)
send_flow_mod(first_dp, reverse_flow_info, out_port, in_port)
send_packet_out(first_dp, buffer_id, in_port, out_port, data)
# ensure the first ping success.
# send_packet_out(last_dp, buffer_id, src_port, dst_port, data)
# src and dst on the same datapath
else:
out_port = get_port(flow_info[2], access_table)
send_flow_mod(first_dp, flow_info, in_port, out_port)
send_flow_mod(first_dp, reverse_flow_info, out_port, in_port)
send_packet_out(first_dp, buffer_id, in_port, out_port, data)```

Note that: 以上的代码均为示例代码，不可直接运行，完整版代码后续将发布。

1632 篇文章99 人订阅

0 条评论

## 相关文章

13520

### Github 项目推荐 | 用于多元时间序列的 Python 模块 —— Seglearn

Seglearn 是一个通过滑动窗口分割的机器学习多元时间序列的 Python 模块。它为特征提取、特征处理和最终估计提供一个集成的 Pipeline。

18220

13720

48760

### 多模型机器学习功能数据库EuclidesDB全新发布

EuclidesDB，一个多模型机器学习功能数据库，发布了0.1版本。EuclidesDB 0.1与PyTorch紧密耦合，为模型特征空间中包含和查询数据提供后...

10010

### TensorFlow从0到1 | 第十八章： 升级手记：TensorFlow 1.3.0

《TensorFlow从0到1》写到现在，TensorFlow的版本也从当时的1.1.0迭代到了8月初发布的1.3.0。可以预见在未来很长一段时间里，它仍会持续...

31270

25050

12920

### TensorFlow 1.8.0正式发布，Bug修复和改进内容都在这里了

【导语】TensorFlow 1.8.0 近日正式发布，新版本主要有以下改进内容，AI科技大本营对其编译如下。 ▌主要特点及改进 可以将 tf.contrib...

42190

### HTML 正文内容提取库 Boilerpipe

Boilerpipe 是一个能从 HTML 中剔除广告和其他附加信息，提取出目标信息（如正文内容、发布时间）的 Java 库。 授权协议：Apache 开发语言...

37360