github.com/vishvananda/netlink@v1.3.1/bridge_linux_test.go (about) 1 package netlink 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "testing" 7 ) 8 9 func TestBridgeVlan(t *testing.T) { 10 minKernelRequired(t, 3, 10) 11 12 tearDown := setUpNetlinkTest(t) 13 defer tearDown() 14 if err := remountSysfs(); err != nil { 15 t.Fatal(err) 16 } 17 bridgeName := "foo" 18 bridge := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeName}} 19 if err := LinkAdd(bridge); err != nil { 20 t.Fatal(err) 21 } 22 if err := ioutil.WriteFile(fmt.Sprintf("/sys/devices/virtual/net/%s/bridge/vlan_filtering", bridgeName), []byte("1"), 0644); err != nil { 23 t.Fatal(err) 24 } 25 if vlanMap, err := BridgeVlanList(); err != nil { 26 t.Fatal(err) 27 } else { 28 if len(vlanMap) != 1 { 29 t.Fatal() 30 } 31 if vInfo, ok := vlanMap[int32(bridge.Index)]; !ok { 32 t.Fatal("vlanMap should include foo port vlan info") 33 } else { 34 if len(vInfo) != 1 { 35 t.Fatal() 36 } else { 37 if !vInfo[0].EngressUntag() || !vInfo[0].PortVID() || vInfo[0].Vid != 1 { 38 t.Fatalf("bridge vlan show get wrong return %s", vInfo[0].String()) 39 } 40 } 41 } 42 } 43 dummy := &Dummy{LinkAttrs: LinkAttrs{Name: "dum1"}} 44 if err := LinkAdd(dummy); err != nil { 45 t.Fatal(err) 46 } 47 if err := LinkSetMaster(dummy, bridge); err != nil { 48 t.Fatal(err) 49 } 50 if err := BridgeVlanAdd(dummy, 2, false, false, false, false); err != nil { 51 t.Fatal(err) 52 } 53 if err := BridgeVlanAdd(dummy, 3, true, true, false, false); err != nil { 54 t.Fatal(err) 55 } 56 if err := BridgeVlanAddRange(dummy, 4, 6, false, false, false, false); err != nil { 57 t.Fatal(err) 58 } 59 if vlanMap, err := BridgeVlanList(); err != nil { 60 t.Fatal(err) 61 } else { 62 if len(vlanMap) != 2 { 63 t.Fatal() 64 } 65 if vInfo, ok := vlanMap[int32(bridge.Index)]; !ok { 66 t.Fatal("vlanMap should include foo port vlan info") 67 } else { 68 if fmt.Sprintf("%v", vInfo) != "[{Flags:6 Vid:1}]" { 69 t.Fatalf("unexpected result %v", vInfo) 70 } 71 } 72 if vInfo, ok := vlanMap[int32(dummy.Index)]; !ok { 73 t.Fatal("vlanMap should include dum1 port vlan info") 74 } else { 75 if fmt.Sprintf("%v", vInfo) != "[{Flags:4 Vid:1} {Flags:0 Vid:2} {Flags:6 Vid:3} {Flags:0 Vid:4} {Flags:0 Vid:5} {Flags:0 Vid:6}]" { 76 t.Fatalf("unexpected result %v", vInfo) 77 } 78 } 79 } 80 } 81 82 func TestBridgeVlanTunnelInfo(t *testing.T) { 83 minKernelRequired(t, 4, 11) 84 tearDown := setUpNetlinkTest(t) 85 defer tearDown() 86 87 if err := remountSysfs(); err != nil { 88 t.Fatal(err) 89 } 90 bridgeName := "br0" 91 vxlanName := "vxlan0" 92 93 // ip link add br0 type bridge 94 bridge := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeName}} 95 if err := LinkAdd(bridge); err != nil { 96 t.Fatal(err) 97 } 98 99 // ip link add vxlan0 type vxlan dstport 4789 nolearning external local 10.0.1.1 100 vxlan := &Vxlan{ 101 // local 102 SrcAddr: []byte("10.0.1.1"), 103 Learning: false, 104 // external 105 FlowBased: true, 106 // dstport 107 Port: 4789, 108 LinkAttrs: LinkAttrs{Name: vxlanName}, 109 } 110 if err := LinkAdd(vxlan); err != nil { 111 t.Fatal(err) 112 } 113 114 // ip link set dev vxlan0 master br0 115 if err := LinkSetMaster(vxlan, bridge); err != nil { 116 t.Fatal(err) 117 } 118 119 // ip link set br0 type bridge vlan_filtering 1 120 if err := BridgeSetVlanFiltering(bridge, true); err != nil { 121 t.Fatal(err) 122 } 123 124 // bridge link set dev vxlan0 vlan_tunnel on 125 if err := LinkSetVlanTunnel(vxlan, true); err != nil { 126 t.Fatal(err) 127 } 128 129 p, err := LinkGetProtinfo(vxlan) 130 if err != nil { 131 t.Fatal(err) 132 } 133 if !p.VlanTunnel { 134 t.Fatal("vlan tunnel should be enabled on vxlan device") 135 } 136 137 // bridge vlan add vid 10 dev vxlan0 138 if err := BridgeVlanAdd(vxlan, 10, false, false, false, false); err != nil { 139 t.Fatal(err) 140 } 141 142 // bridge vlan add vid 11 dev vxlan0 143 if err := BridgeVlanAdd(vxlan, 11, false, false, false, false); err != nil { 144 t.Fatal(err) 145 } 146 147 // bridge vlan add dev vxlan0 vid 10 tunnel_info id 20 148 if err := BridgeVlanAddTunnelInfo(vxlan, 10, 20, false, false); err != nil { 149 t.Fatal(err) 150 } 151 152 tis, err := BridgeVlanTunnelShow() 153 if err != nil { 154 t.Fatal(err) 155 } 156 157 if len(tis) != 1 { 158 t.Fatal("only one tunnel info") 159 } 160 ti := tis[0] 161 if ti.TunId != 20 || ti.Vid != 10 { 162 t.Fatal("unexpected result") 163 } 164 165 // bridge vlan del dev vxlan0 vid 10 tunnel_info id 20 166 if err := BridgeVlanDelTunnelInfo(vxlan, 10, 20, false, false); err != nil { 167 t.Fatal(err) 168 } 169 170 tis, err = BridgeVlanTunnelShow() 171 if err != nil { 172 t.Fatal(err) 173 } 174 175 if len(tis) != 0 { 176 t.Fatal("tunnel info should have been deleted") 177 } 178 179 // bridge vlan add dev vxlan0 vid 10-11 tunnel_info id 20-21 180 if err := BridgeVlanAddRangeTunnelInfoRange(vxlan, 10, 11, 20, 21, false, false); err != nil { 181 t.Fatal(err) 182 } 183 184 tis, err = BridgeVlanTunnelShow() 185 if err != nil { 186 t.Fatal(err) 187 } 188 if len(tis) != 2 { 189 t.Fatal("two tunnel info") 190 } 191 192 // bridge vlan del dev vxlan0 vid 10-11 tunnel_info id 20-21 193 if err := BridgeVlanDelRangeTunnelInfoRange(vxlan, 10, 11, 20, 21, false, false); err != nil { 194 t.Fatal(err) 195 } 196 197 tis, err = BridgeVlanTunnelShow() 198 if err != nil { 199 t.Fatal(err) 200 } 201 202 if len(tis) != 0 { 203 t.Fatal("tunnel info should have been deleted") 204 } 205 } 206 207 func TestBridgeGroupFwdMask(t *testing.T) { 208 minKernelRequired(t, 4, 15) //minimal release for per-port group_fwd_mask 209 tearDown := setUpNetlinkTest(t) 210 defer tearDown() 211 if err := remountSysfs(); err != nil { 212 t.Fatal(err) 213 } 214 bridgeName := "foo" 215 var mask uint16 = 0xfff0 216 bridge := &Bridge{LinkAttrs: LinkAttrs{Name: bridgeName}, GroupFwdMask: &mask} 217 if err := LinkAdd(bridge); err != nil { 218 t.Fatal(err) 219 } 220 brlink, err := LinkByName(bridgeName) 221 if err != nil { 222 t.Fatal(err) 223 } 224 if *(brlink.(*Bridge).GroupFwdMask) != mask { 225 t.Fatalf("created bridge has group_fwd_mask value %x, different from expected %x", 226 *(brlink.(*Bridge).GroupFwdMask), mask) 227 } 228 dummyName := "dm1" 229 dummy := &Dummy{LinkAttrs: LinkAttrs{Name: dummyName, MasterIndex: brlink.Attrs().Index}} 230 if err := LinkAdd(dummy); err != nil { 231 t.Fatal(err) 232 } 233 dmLink, err := LinkByName(dummyName) 234 if err != nil { 235 t.Fatal(err) 236 } 237 if err = LinkSetBRSlaveGroupFwdMask(dmLink, mask); err != nil { 238 t.Fatal(err) 239 } 240 }