天天看點

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援

1.建立ovs接口連接配接兩個namespace組成二層網絡

br0
            +--------------------------------------+
            +--+                                +--+
        +---+  | tap1                       tap2|  +---+
        |   +--+                                +--+   |
        |   |                                      |   |
        |   +--------------------------------------+   |
        |                                              |
        |                                              |
        |                                              |
        |                                              |
+------------------+                      +-------------------+
|      tap1        |                      |           tap2    |
|192.168.1.102/24  |                      | 192.168.1.102/24  |
|                  |                      |                   |
|                  |                      |                   |
|                  |                      |                   |
|  namespace ns1   |                      |    namespace ns1  |
|                  |                      |                   |
+------------------+                      +-------------------+      
ip netns add ns1
 ip netns add ns2
 ovs-vsctl add-br br0
 ovs-vsctl add-port br0 tap1 -- set Interface tap1 type=internal
 ip link set tap1 netns ns1
 ip netns exec ns1 ip link set dev tap1 up
 ovs-vsctl add-port br0 tap2 -- set Interface tap2 type=internal
 ip link set tap2 netns ns2
 ip netns exec ns2 ip link set dev tap2 up
 ip netns exec ns1 ip addr add 192.168.1.102/24 dev tap1
 ip netns exec ns2 ip addr add 192.168.1.101/24 dev tap2
 ip netns exec ns1 ip link set lo up
 ip netns exec ns2 ip link set lo up

 ip netns exec ns1 ping -c 4 192.168.1.101
 ip netns exec ns1 ping -c 4 192.168.1.102
           

驗證結果:OK

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援

 2 vlan二層網絡

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援
ip netns add ns1
ip netns add ns2

ovs-vsctl add-br br0
ovs-vsctl add-port br0 tap1 -- set Interface tap1 type=internal

ovs-vsctl set Port tap1  tag=10

ip link set tap1 netns ns1
ip netns exec ns1 ip link set dev tap1 up

ovs-vsctl add-port br0 tap2 -- set Interface tap2 type=internal
ovs-vsctl set Port tap2  tag=11

ip link set tap2 netns ns2
ip netns exec ns2 ip link set dev tap2 up

ip netns exec ns1 ip addr add 192.168.1.101/24 dev tap1
ip netns exec ns2 ip addr add 192.168.1.102/24 dev tap2

ip netns exec ns1 ip link set lo up
ip netns exec ns2 ip link set lo up
-------------------------------------------------------------------------------
以上是第一個測試配置内容
-------------------------------------------------------------------------------
把兩個tap加入不同的vlan中
ovs-vsctl set Port tap1  tag=10
ovs-vsctl set Port tap2  tag=11

--------------------------------------------------------------------------------
再次進行測試
ip netns exec ns1 ping -c 4 192.168.1.102 發現不通,符合預期,因為兩個口屬于不同vlan
           
新增br1,然後建立namesapce ns3,并在裡面建立tap3,vlan屬于tag10
ovs-vsctl add-br br1
ovs-vsctl add-port br1 tap3 -- set Interface tap3 type=internal

ovs-vsctl add-port br0 trunk_br0 trunks=10,11  -- set Interface trunk_br0 type=patch options:peer=trunk_br1
ovs-vsctl add-port br1 trunk_br1 trunks=10,11 -- set Interface trunk_br1 type=patch options:peer=trunk_br0

ip netns add ns3
ip link set tap3 netns ns3
ip netns exec ns3 ip addr add 192.168.1.103/24 dev tap3
ip netns exec ns3 ip link set dev tap3 up
ovs-vsctl set Port tap3 tag=10
---------------------------------------------------------------------------------
發現跟tap1口能通,跟tap2口不通
符合預期
---------------------------------------------------------------------------------
           

3 測試vlan 原理

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援

結論:

1. second_br和thrid_br之間互通

2.first_br與tap1之間互通

3.port 1 和port 4屬于turnk口,預設加入所有vlan中

4.建立的interal類型的端口,預設加入vlan 0中

[[email protected] weiyanhua]# ovs-appctl fdb/show br0

 port  VLAN  MAC                Age

    1    10  de:6a:2a:72:9c:a1  230

    4    10  fa:dd:15:95:04:d8  158

    4     0  3a:a8:43:c2:1e:88   12

    2     0  66:ae:6a:f5:56:8e   12

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# ovs-appctl fdb/show br1

 port  VLAN  MAC                Age

    1    10  de:6a:2a:72:9c:a1  232

    2    10  fa:dd:15:95:04:d8  160

    3     0  3a:a8:43:c2:1e:88   14

    1     0  66:ae:6a:f5:56:8e   14

[[email protected] weiyanhua]# ovs-ofctl dump-ports-desc br0
OFPST_PORT_DESC reply (xid=0x2):
 1(first_br): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 2(second_br): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 4(trunk_br0): addr:9a:ff:ff:71:5e:ab
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br0): addr:6e:e4:dd:55:1a:4b
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
[[email protected] weiyanhua]# 
[[email protected] weiyanhua]# ovs-ofctl dump-ports-desc br1
OFPST_PORT_DESC reply (xid=0x2):
 1(trunk_br1): addr:b6:bf:f7:6b:15:67
     config:     0
     state:      0
     speed: 0 Mbps now, 0 Mbps max
 2(tap1): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 3(third_br): addr:00:00:00:00:00:00
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br1): addr:16:64:c6:1c:e0:4b
     config:     PORT_DOWN
     state:      LINK_DOWN
     speed: 0 Mbps now, 0 Mbps max
[[email protected] weiyanhua]# 
           

 4 ovs bonding鍊路備援

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援
ovs-vsctl add-br br0
ovs-vsctl add-br br1
ip link add br0_tap0 type veth peer name br1_tap0
ip link add br0_tap1 type veth peer name br1_tap1
ip link set br0_tap0 up
ip link set br0_tap1 up
ip link set br1_tap0 up
ip link set br1_tap1 up

ovs-vsctl add-bond br0 bond0 br0_tap0 br0_tap1 
ovs-vsctl add-bond br1 bond1 br1_tap0 br1_tap1


ip netns add ns1
ip netns add ns2
ovs-vsctl add-port br0 tap1 -- set Interface tap1 type=internal
ip link set tap1 netns ns1
ip netns exec ns1 ip link set dev tap1 up
ip netns exec ns1 ip addr add 192.168.1.101/24 dev tap1


ovs-vsctl add-port br1 tap2 -- set Interface tap2 type=internal
ip link set tap2 netns ns2
ip netns exec ns2 ip link set dev tap2 up
ip netns exec ns2 ip addr add 192.168.1.102/24 dev tap2
           
openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援

 [[email protected] weiyanhua]# ovs-appctl bond/show

---- bond1 ----

bond_mode: active-backup

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

lacp_status: off

lacp_fallback_ab: false

active slave mac: 12:da:b4:4f:d3:aa(br1_tap0)

slave br1_tap0: enabled

  active slave

  may_enable: true

slave br1_tap1: enabled

  may_enable: true

---- bond0 ----

bond_mode: active-backup

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

lacp_status: off

lacp_fallback_ab: false

active slave mac: f6:ab:b8:a1:4d:c2(br0_tap0)

slave br0_tap0: enabled

  active slave

  may_enable: true

slave br0_tap1: enabled

  may_enable: true

[[email protected] weiyanhua]# 

預設建立的bond為主備模式(bond_mode: active-backup)

br1_tap0和br0_tap0 流量走這對口

開啟lacp

[[email protected] weiyanhua]# ovs-appctl bond/show

---- bond1 ----

bond_mode: active-backup

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

lacp_status: negotiated

lacp_fallback_ab: false

active slave mac: 12:da:b4:4f:d3:aa(br1_tap0)

slave br1_tap0: enabled

  active slave

  may_enable: true

slave br1_tap1: enabled

  may_enable: true

---- bond0 ----

bond_mode: active-backup

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

lacp_status: negotiated

lacp_fallback_ab: false

active slave mac: f6:ab:b8:a1:4d:c2(br0_tap0)

slave br0_tap0: enabled

  active slave

  may_enable: true

slave br0_tap1: enabled

  may_enable: true

[[email protected] weiyanhua]# 

 能抓到lacp封包:

openvswitch vlan網絡實踐 2 vlan二層網絡3 測試vlan 原理 4 ovs bonding鍊路備援

檢視lacp資訊 

[[email protected] weiyanhua]# ovs-appctl lacp/show

---- bond0 ----

  status: active negotiated

  sys_id: 2e:70:0d:3f:10:4f

  sys_priority: 65534

  aggregation key: 1

  lacp_time: slow

slave: br0_tap0: current attached

  port_id: 2

  port_priority: 65535

  may_enable: true

  actor sys_id: 2e:70:0d:3f:10:4f

  actor sys_priority: 65534

  actor port_id: 2

  actor port_priority: 65535

  actor key: 1

  actor state: activity aggregation synchronized collecting distributing

  partner sys_id: 06:ca:c4:5c:ce:47

  partner sys_priority: 65534

  partner port_id: 1

  partner port_priority: 65535

  partner key: 1

  partner state: activity aggregation synchronized collecting distributing

slave: br0_tap1: current attached

  port_id: 1

  port_priority: 65535

  may_enable: true

  actor sys_id: 2e:70:0d:3f:10:4f

  actor sys_priority: 65534

  actor port_id: 1

  actor port_priority: 65535

  actor key: 1

  actor state: activity aggregation synchronized collecting distributing

  partner sys_id: 06:ca:c4:5c:ce:47

  partner sys_priority: 65534

  partner port_id: 2

  partner port_priority: 65535

  partner key: 1

  partner state: activity aggregation synchronized collecting distributing

---- bond1 ----

  status: active negotiated

  sys_id: 06:ca:c4:5c:ce:47

  sys_priority: 65534

  aggregation key: 1

  lacp_time: slow

slave: br1_tap0: current attached

  port_id: 1

  port_priority: 65535

  may_enable: true

  actor sys_id: 06:ca:c4:5c:ce:47

  actor sys_priority: 65534

  actor port_id: 1

  actor port_priority: 65535

  actor key: 1

  actor state: activity aggregation synchronized collecting distributing

  partner sys_id: 2e:70:0d:3f:10:4f

  partner sys_priority: 65534

  partner port_id: 2

  partner port_priority: 65535

  partner key: 1

  partner state: activity aggregation synchronized collecting distributing

slave: br1_tap1: current attached

  port_id: 2

  port_priority: 65535

  may_enable: true

  actor sys_id: 06:ca:c4:5c:ce:47

  actor sys_priority: 65534

  actor port_id: 2

  actor port_priority: 65535

  actor key: 1

  actor state: activity aggregation synchronized collecting distributing

  partner sys_id: 2e:70:0d:3f:10:4f

  partner sys_priority: 65534

  partner port_id: 1

  partner port_priority: 65535

  partner key: 1

  partner state: activity aggregation synchronized collecting distributing

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# 

  • active-backup 主-備 無法提升吞吐
  • balance-slb, 根據包的 source MAC + vlan tag來均衡流量
  • banlnce-tcp, 根據包的 L2/L3/L4 header來均衡流量
    banlance-tcp必須讓硬體交換機設定802.3ad,balance-slb則設不設均可,設了流量提高比較大。
  • ovs-vsctl set Port bond0 bond_mode=balance-slb
  • 觀察流量指令 cat /proc/net/dev

修改hash模式

[[email protected] weiyanhua]# ovs-vsctl set Port bond0 bond_mode=balance-slb

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# ovs-vsctl set Port bond1 bond_mode=balance-slb

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# 

[[email protected] weiyanhua]# ovs-appctl bond/show

---- bond1 ----

bond_mode: balance-slb

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

next rebalance: 1024 ms

lacp_status: negotiated

lacp_fallback_ab: false

active slave mac: 12:da:b4:4f:d3:aa(br1_tap0)

slave br1_tap0: enabled

  active slave

  may_enable: true

slave br1_tap1: enabled

  may_enable: true

---- bond0 ----

bond_mode: balance-slb

bond may use recirculation: no, Recirc-ID : -1

bond-hash-basis: 0

updelay: 0 ms

downdelay: 0 ms

next rebalance: 7531 ms

lacp_status: negotiated

lacp_fallback_ab: false

active slave mac: f6:ab:b8:a1:4d:c2(br0_tap0)

slave br0_tap0: enabled

  active slave

  may_enable: true

slave br0_tap1: enabled

  may_enable: true

[[email protected] weiyanhua]# 

 配置層顯示interface和port

 [[email protected] weiyanhua]# ovs-vsctl show

1015cc09-a996-41e6-9c77-b2259e969a49

    Bridge "br0"

        Port "tap1"

            Interface "tap1"

                type: internal

        Port "br0"

            Interface "br0"

                type: internal

        Port "bond0"

            Interface "br0_tap1"

            Interface "br0_tap0"

    Bridge "br1"

        Port "tap2"

            Interface "tap2"

                type: internal

        Port "br1"

            Interface "br1"

                type: internal

        Port "bond1"

            Interface "br1_tap0"

            Interface "br1_tap1"

    ovs_version: "2.11.0"

[[email protected] weiyanhua]# 

 openflow層隻顯示interface 不會顯示port

[[email protected] weiyanhua]# ovs-ofctl show br0

OFPT_FEATURES_REPLY (xid=0x2): dpid:00002e700d3f104f

n_tables:254, n_buffers:0

capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP

actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst

 1(br0_tap1): addr:3a:66:82:56:6a:68

     config:     0

     state:      0

     current:    10GB-FD COPPER

     speed: 10000 Mbps now, 0 Mbps max

 2(br0_tap0): addr:f6:ab:b8:a1:4d:c2

     config:     0

     state:      0

     current:    10GB-FD COPPER

     speed: 10000 Mbps now, 0 Mbps max

 4(tap1): addr:00:00:00:00:00:00

     config:     PORT_DOWN

     state:      LINK_DOWN

     speed: 0 Mbps now, 0 Mbps max

 LOCAL(br0): addr:2e:70:0d:3f:10:4f

     config:     PORT_DOWN

     state:      LINK_DOWN

     speed: 0 Mbps now, 0 Mbps max

OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0

[[email protected] weiyanhua]#  

 datapath層也隻顯示interface,不顯示port

 [[email protected] weiyanhua]# ovs-dpctl show

2021-09-10T01:23:10Z|00001|dpif_netlink|INFO|The kernel module does not support meters.

[email protected]:

  lookups: hit:42 missed:12002 lost:0

  flows: 0

  masks: hit:10098 total:0 hit/pkt:0.84

  port 0: ovs-system (internal)

  port 1: br0 (internal)

  port 2: br1 (internal)

  port 3: br0_tap1

  port 4: br0_tap0

  port 5: br1_tap0

  port 6: br1_tap1

  port 7: tap1 (internal)

  port 8: tap2 (internal)

[[email protected] weiyanhua]# 

ovs代碼結構中,大概分為如下三個層面:配置層,openflow層和轉換層 

配置層      openflow層                          xlate轉換層
bridge   -> ofproto                          -> xbridge
port     -> ofproto_dpif->bundles: ofbundle  -> xbundle
iface    -> ofproto->ports: ofport           -> xport
           

a. 通過ovs-vsctl配置的網橋,端口和接口等資訊都認為是在配置層,可以使用ovs-vsctl show檢視所有的配置。

b. 在bridge_reconfigure函數中,會将配置層資訊傳遞到openflow層,每個iface配置設定openflow端口号,可以使用ovs-ofctl show br1檢視。

c. 在type_run函數中,将openflow層資訊轉換到xlate層。

需要注意的是,在openflow層和datapath層隻能看到iface,看不到port資訊。是以對于bond口,在添加流表資訊時,隻能指定出端口為slave口。

展示下datapatch下封包路徑,經過的port口

[[email protected] weiyanhua]# ovs-dpctl show 
2021-09-10T01:44:29Z|00001|dpif_netlink|INFO|The kernel module does not support meters.
[email protected]:
  lookups: hit:1085 missed:12395 lost:0
  flows: 12
  masks: hit:12776 total:2 hit/pkt:0.95
  port 0: ovs-system (internal)
  port 1: br0 (internal)
  port 2: br1 (internal)
  port 3: br0_tap1
  port 4: br0_tap0
  port 5: br1_tap0
  port 6: br1_tap1
  port 7: tap1 (internal)
  port 8: tap2 (internal)
[[email protected] weiyanhua]# 
[[email protected] weiyanhua]# ovs-dpctl dump-flows
2021-09-10T01:44:36Z|00001|dpif_netlink|INFO|The kernel module does not support meters.
recirc_id(0),in_port(8),eth(src=c6:18:15:7f:86:05,dst=f2:ce:eb:63:45:e4),eth_type(0x0800),ipv4(frag=no), packets:262, bytes:25676, used:0.303s, actions:5
recirc_id(0),in_port(7),eth(src=f2:ce:eb:63:45:e4,dst=c6:18:15:7f:86:05),eth_type(0x0800),ipv4(frag=no), packets:262, bytes:25676, used:0.303s, actions:4
recirc_id(0),in_port(4),eth(src=c6:18:15:7f:86:05,dst=f2:ce:eb:63:45:e4),eth_type(0x0800),ipv4(frag=no), packets:262, bytes:25676, used:0.303s, actions:7
recirc_id(0),in_port(5),eth(src=f2:ce:eb:63:45:e4,dst=c6:18:15:7f:86:05),eth_type(0x0800),ipv4(frag=no), packets:262, bytes:25676, used:0.303s, actions:8
[[email protected] weiyanhua]# 

在流表中顯示port的name,便于觀察
[[email protected] weiyanhua]# ovs-dpctl dump-flows --names
2021-09-10T04:57:47Z|00001|dpif_netlink|INFO|The kernel module does not support meters.
recirc_id(0),in_port(br0_tap0),eth(),eth_type(0x8809), packets:0, bytes:0, used:never, actions:userspace(pid=4294962660,slow_path(lacp))
recirc_id(0),in_port(br1_tap1),eth(),eth_type(0x8809), packets:0, bytes:0, used:never, actions:userspace(pid=4294962660,slow_path(lacp))
recirc_id(0),in_port(tap1),eth(src=f2:ce:eb:63:45:e4,dst=c6:18:15:7f:86:05),eth_type(0x0800),ipv4(frag=no), packets:11853, bytes:1161594, used:0.913s, actions:br0_tap0
recirc_id(0),in_port(br1_tap0),eth(src=f2:ce:eb:63:45:e4,dst=c6:18:15:7f:86:05),eth_type(0x0800),ipv4(frag=no), packets:11853, bytes:1161594, used:0.913s, actions:tap2
recirc_id(0),in_port(tap2),eth(src=c6:18:15:7f:86:05,dst=f2:ce:eb:63:45:e4),eth_type(0x0800),ipv4(frag=no), packets:11853, bytes:1161594, used:0.913s, actions:br1_tap0
recirc_id(0),in_port(br0_tap1),eth(),eth_type(0x8809), packets:0, bytes:0, used:never, actions:userspace(pid=4294962660,slow_path(lacp))
recirc_id(0),in_port(br0_tap0),eth(src=c6:18:15:7f:86:05,dst=f2:ce:eb:63:45:e4),eth_type(0x0800),ipv4(frag=no), packets:11853, bytes:1161594, used:0.913s, actions:tap1
recirc_id(0),in_port(br1_tap0),eth(),eth_type(0x8809), packets:0, bytes:0, used:never, actions:userspace(pid=4294962660,slow_path(lacp))
[[email protected] weiyanhua]# 
           

 4.1 bond實作說明

4.1.1 bond口出方向封包處理

如果出端口為bond的slave口,應該怎麼選擇slave口呢?

分為兩種情況,如果流表直接指定了出端口為slave口,則封包隻會從此slave口發出,另一種情況是流表沒有指定slave口,而是通過normal動作進行轉發,這個情況bond轉發才會生效

static void
output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
              const struct xvlan *xvlan)
{
    uint16_t vid;
    union flow_vlan_hdr old_vlans[FLOW_MAX_VLAN_HEADERS];
    struct xport *xport;
    struct xlate_bond_recirc xr;
    bool use_recirc = false;
    struct xvlan out_xvlan;

    check_and_set_cvlan_mask(ctx->wc, out_xbundle);

    xvlan_output_translate(out_xbundle, xvlan, &out_xvlan);
    if (out_xbundle->use_priority_tags) {
        out_xvlan.v[0].pcp = ntohs(ctx->xin->flow.vlans[0].tci) &
                             VLAN_PCP_MASK;
    }
    vid = out_xvlan.v[0].vid;
    if (ovs_list_is_empty(&out_xbundle->xports)) {
        /* Partially configured bundle with no slaves.  Drop the packet. */
        return;
    } else if (!out_xbundle->bond) {
        xport = CONTAINER_OF(ovs_list_front(&out_xbundle->xports), struct xport,
                             bundle_node);
    } else {
        struct flow_wildcards *wc = ctx->wc;
        struct ofport_dpif *ofport;

        if (ctx->xbridge->support.odp.recirc) {
            /* In case recirculation is not actually in use, 'xr.recirc_id'
             * will be set to '0', since a valid 'recirc_id' can
             * not be zero.  */
            bond_update_post_recirc_rules(out_xbundle->bond,
                                          &xr.recirc_id,
                                          &xr.hash_basis);
            if (xr.recirc_id) {
                /* Use recirculation instead of output. */
                use_recirc = true;
                xr.hash_alg = OVS_HASH_ALG_L4;
                /* Recirculation does not require unmasking hash fields. */
                wc = NULL;
            }
        }

        ofport = bond_choose_output_slave(out_xbundle->bond,
                                          &ctx->xin->flow, wc, vid);
        xport = xport_lookup(ctx->xcfg, ofport);

        if (!xport) {
            /* No slaves enabled, so drop packet. */
            return;
        }

        /* If use_recirc is set, the main thread will handle stats
         * accounting for this bond. */
        if (!use_recirc) {
            if (ctx->xin->resubmit_stats) {
                bond_account(out_xbundle->bond, &ctx->xin->flow, vid,
                             ctx->xin->resubmit_stats->n_bytes);
            }
            if (ctx->xin->xcache) {
                struct xc_entry *entry;
                struct flow *flow;

                flow = &ctx->xin->flow;
                entry = xlate_cache_add_entry(ctx->xin->xcache, XC_BOND);
                entry->bond.bond = bond_ref(out_xbundle->bond);
                entry->bond.flow = xmemdup(flow, sizeof *flow);
                entry->bond.vid = vid;
            }
        }
    }

    memcpy(&old_vlans, &ctx->xin->flow.vlans, sizeof(old_vlans));
    xvlan_put(&ctx->xin->flow, &out_xvlan);

    compose_output_action(ctx, xport->ofp_port, use_recirc ? &xr : NULL,
                          false, false);
    memcpy(&ctx->xin->flow.vlans, &old_vlans, sizeof(old_vlans));
}
           

判斷是bond口,在bond的slave中根據負載算法選擇端口,bond_choose_output_slave

static struct bond_slave *
choose_output_slave(const struct bond *bond, const struct flow *flow,
                    struct flow_wildcards *wc, uint16_t vlan)
{
    struct bond_entry *e;
    int balance;

    balance = bond->balance;
    if (bond->lacp_status == LACP_CONFIGURED) {
        /* LACP has been configured on this bond but negotiations were
         * unsuccussful. If lacp_fallback_ab is enabled use active-
         * backup mode else drop all traffic. */
        if (!bond->lacp_fallback_ab) {
            return NULL;
        }
        balance = BM_AB;
    }

    switch (balance) {
    case BM_AB:
        return bond->active_slave;

    case BM_TCP:
        if (bond->lacp_status != LACP_NEGOTIATED) {
            /* Must have LACP negotiations for TCP balanced bonds. */
            return NULL;
        }
        if (wc) {
            flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP);
        }
        /* Fall Through. */
    case BM_SLB:
        if (wc && balance == BM_SLB) {
            flow_mask_hash_fields(flow, wc, NX_HASH_FIELDS_ETH_SRC);
        }
        e = lookup_bond_entry(bond, flow, vlan);
        if (!e->slave || !e->slave->enabled) {
            e->slave = get_enabled_slave(CONST_CAST(struct bond*, bond));
        }
        return e->slave;

    default:
        OVS_NOT_REACHED();
    }
}
           

4.1.2 bond口入方向封包處理

在active-backup模式下,如果inactive slave收到多點傳播/廣播封包,并且走的是normal流表,就會被drop,代碼流程如下。

do_xlate_actions->xlate_output_action->xlate_normal->is_admissible->bond_check_admissibility

enum bond_verdict
bond_check_admissibility(struct bond *bond, const void *slave_,
                         const struct eth_addr eth_dst)
{
    ...
    /* Drop all multicast packets on inactive slaves. */
    if (eth_addr_is_multicast(eth_dst)) {
        if (bond->active_slave != slave) {
            goto out;
        }
    }
    ...
}
           

繼續閱讀