Skip to content

Commit ac9562a

Browse files
committed
Merge remote-tracking branch 'origin/4.11'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2 parents 5d7b33a + 29b8a9d commit ac9562a

4 files changed

Lines changed: 129 additions & 27 deletions

File tree

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/BridgeVifDriver.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ private static boolean isInterface(final String fname) {
206206
return fname.matches(commonPattern.toString());
207207
}
208208

209+
protected boolean isBroadcastTypeVlanOrVxlan(final NicTO nic) {
210+
return nic != null && (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan
211+
|| nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan);
212+
}
213+
214+
protected boolean isValidProtocolAndVnetId(final String vNetId, final String protocol) {
215+
return vNetId != null && protocol != null && !vNetId.equalsIgnoreCase("untagged");
216+
}
217+
209218
@Override
210219
public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicAdapter, Map<String, String> extraConfig) throws InternalErrorException, LibvirtException {
211220

@@ -220,7 +229,7 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA
220229

221230
String vNetId = null;
222231
String protocol = null;
223-
if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan || nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan) {
232+
if (isBroadcastTypeVlanOrVxlan(nic)) {
224233
vNetId = Networks.BroadcastDomainType.getValue(nic.getBroadcastUri());
225234
protocol = Networks.BroadcastDomainType.getSchemeValue(nic.getBroadcastUri()).scheme();
226235
} else if (nic.getBroadcastType() == Networks.BroadcastDomainType.Lswitch) {
@@ -233,8 +242,7 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA
233242
}
234243

235244
if (nic.getType() == Networks.TrafficType.Guest) {
236-
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) ||
237-
(nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) {
245+
if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
238246
if (trafficLabel != null && !trafficLabel.isEmpty()) {
239247
s_logger.debug("creating a vNet dev and bridge for guest traffic per traffic label " + trafficLabel);
240248
String brName = createVnetBr(vNetId, trafficLabel, protocol);
@@ -257,8 +265,7 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA
257265
createControlNetwork();
258266
intf.defBridgeNet(_bridges.get("linklocal"), null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
259267
} else if (nic.getType() == Networks.TrafficType.Public) {
260-
if ((nic.getBroadcastType() == Networks.BroadcastDomainType.Vlan) && (vNetId != null) && (protocol != null) && (!vNetId.equalsIgnoreCase("untagged")) ||
261-
(nic.getBroadcastType() == Networks.BroadcastDomainType.Vxlan)) {
268+
if (isBroadcastTypeVlanOrVxlan(nic) && isValidProtocolAndVnetId(vNetId, protocol)) {
262269
if (trafficLabel != null && !trafficLabel.isEmpty()) {
263270
s_logger.debug("creating a vNet dev and bridge for public traffic per traffic label " + trafficLabel);
264271
String brName = createVnetBr(vNetId, trafficLabel, protocol);
@@ -276,7 +283,7 @@ public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType, String nicA
276283
String storageBrName = nic.getName() == null ? _bridges.get("private") : nic.getName();
277284
intf.defBridgeNet(storageBrName, null, nic.getMac(), getGuestNicModel(guestOsType, nicAdapter));
278285
}
279-
if (nic.getPxeDisable() == true) {
286+
if (nic.getPxeDisable()) {
280287
intf.setPxeDisable(true);
281288
}
282289

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package com.cloud.hypervisor.kvm.resource;
18+
19+
import org.junit.Assert;
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
23+
import com.cloud.agent.api.to.NicTO;
24+
import com.cloud.network.Networks;
25+
26+
public class BridgeVifDriverTest {
27+
28+
private BridgeVifDriver driver;
29+
30+
@Before
31+
public void setUp() throws Exception {
32+
driver = new BridgeVifDriver();
33+
}
34+
35+
@Test
36+
public void isBroadcastTypeVlanOrVxlan() {
37+
final NicTO nic = new NicTO();
38+
nic.setBroadcastType(Networks.BroadcastDomainType.Native);
39+
Assert.assertFalse(driver.isBroadcastTypeVlanOrVxlan(null));
40+
Assert.assertFalse(driver.isBroadcastTypeVlanOrVxlan(nic));
41+
// Test VLAN
42+
nic.setBroadcastType(Networks.BroadcastDomainType.Vlan);
43+
Assert.assertTrue(driver.isBroadcastTypeVlanOrVxlan(nic));
44+
// Test VXLAN
45+
nic.setBroadcastType(Networks.BroadcastDomainType.Vxlan);
46+
Assert.assertTrue(driver.isBroadcastTypeVlanOrVxlan(nic));
47+
}
48+
49+
@Test
50+
public void isValidProtocolAndVnetId() {
51+
Assert.assertFalse(driver.isValidProtocolAndVnetId(null, null));
52+
Assert.assertFalse(driver.isValidProtocolAndVnetId("123", null));
53+
Assert.assertFalse(driver.isValidProtocolAndVnetId(null, "vlan"));
54+
Assert.assertFalse(driver.isValidProtocolAndVnetId("untagged", "vxlan"));
55+
Assert.assertTrue(driver.isValidProtocolAndVnetId("123", "vlan"));
56+
Assert.assertTrue(driver.isValidProtocolAndVnetId("456", "vxlan"));
57+
}
58+
}

scripts/vm/network/security_group.py

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,21 @@ def ipv6_link_local_addr(mac=None):
167167
return IPAddress('fe80::' + ':'.join(re.findall(r'.{4}', eui64)))
168168

169169

170+
def split_ips_by_family(ips):
171+
if type(ips) is str:
172+
ips = [ip for ip in ips.split(';') if ip != '']
173+
174+
ip4s = []
175+
ip6s = []
176+
for ip in ips:
177+
version = IPNetwork(ip).version
178+
if version == 4:
179+
ip4s.append(ip)
180+
elif version == 6:
181+
ip6s.append(ip)
182+
return ip4s, ip6s
183+
184+
170185
def destroy_network_rules_for_vm(vm_name, vif=None):
171186
vmchain = iptables_chain_name(vm_name)
172187
vmchain_egress = egress_chain_name(vm_name)
@@ -405,10 +420,17 @@ def network_rules_vmSecondaryIp(vm_name, ip_secondary, action):
405420
domid = getvmId(vm_name)
406421

407422
vmchain = vm_name
408-
add_to_ipset(vmchain, [ip_secondary], action)
423+
vmchain6 = vmchain + '-6'
424+
425+
ip4s, ip6s = split_ips_by_family(ip_secondary)
426+
427+
add_to_ipset(vmchain, ip4s, action)
428+
429+
#add ebtables rules for the secondary ips
430+
ebtables_rules_vmip(vm_name, ip4s, action)
409431

410-
#add ebtables rules for the secondary ip
411-
ebtables_rules_vmip(vm_name, [ip_secondary], action)
432+
#add ipv6 addresses to ipv6 ipset
433+
add_to_ipset(vmchain6, ip6s, action)
412434

413435
return True
414436

@@ -460,6 +482,8 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
460482

461483
action = "-A"
462484
vmipsetName = ipset_chain_name(vm_name)
485+
vmipsetName6 = vmipsetName + '-6'
486+
463487
#create ipset and add vm ips to that ip set
464488
if not create_ipset_forvm(vmipsetName):
465489
logging.debug(" failed to create ipset for rule " + str(tokens))
@@ -474,13 +498,19 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
474498
secIpSet = "1"
475499
ips = sec_ips.split(';')
476500
ips.pop()
477-
if ips[0] == "0":
501+
502+
if len(ips) == 0 or ips[0] == "0":
478503
secIpSet = "0"
504+
ip4s = []
505+
ip6s = []
479506

480507
if secIpSet == "1":
481-
logging.debug("Adding ipset for secondary ips")
482-
add_to_ipset(vmipsetName, ips, action)
483-
if not write_secip_log_for_vm(vm_name, sec_ips, vm_id):
508+
logging.debug("Adding ipset for secondary ipv4 addresses")
509+
ip4s, ip6s = split_ips_by_family(ips)
510+
511+
add_to_ipset(vmipsetName, ip4s, action)
512+
513+
if write_secip_log_for_vm(vm_name, sec_ips, vm_id) == False:
484514
logging.debug("Failed to log default network rules, ignoring")
485515

486516
try:
@@ -505,15 +535,13 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
505535

506536
default_ebtables_rules(vm_name, vm_ip, vm_mac, vif)
507537
#default ebtables rules for vm secondary ips
508-
ebtables_rules_vmip(vm_name, ips, "-I")
538+
ebtables_rules_vmip(vm_name, ip4s, "-I")
509539

510540
if vm_ip:
511541
if not write_rule_log_for_vm(vmName, vm_id, vm_ip, domID, '_initial_', '-1'):
512542
logging.debug("Failed to log default network rules, ignoring")
513543

514-
vm_ip6_set_name = vm_name + '-6'
515-
516-
if not create_ipset_forvm(vm_ip6_set_name, family='inet6', type='hash:net'):
544+
if not create_ipset_forvm(vmipsetName6, family='inet6', type='hash:net'):
517545
logging.debug(" failed to create ivp6 ipset for rule " + str(tokens))
518546
return False
519547

@@ -525,7 +553,10 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
525553
except AddrFormatError:
526554
pass
527555

528-
add_to_ipset(vm_ip6_set_name, vm_ip6_addr, action)
556+
add_to_ipset(vmipsetName6, vm_ip6_addr, action)
557+
if secIpSet == "1":
558+
logging.debug("Adding ipset for secondary ipv6 addresses")
559+
add_to_ipset(vmipsetName6, ip6s, action)
529560

530561
try:
531562
execute('ip6tables -A ' + brfw + '-OUT' + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -j ' + vmchain_default)
@@ -540,20 +571,20 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
540571
# Allow neighbor solicitations and advertisements
541572
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j RETURN')
542573
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT')
543-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type neighbor-advertisement -m set --match-set ' + vm_ip6_set_name + ' src -m hl --hl-eq 255 -j RETURN')
574+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type neighbor-advertisement -m set --match-set ' + vmipsetName6 + ' src -m hl --hl-eq 255 -j RETURN')
544575
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT')
545576

546577
# Packets to allow as per RFC4890
547-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type packet-too-big -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
578+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type packet-too-big -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
548579
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT')
549580

550-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type destination-unreachable -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
581+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type destination-unreachable -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
551582
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT')
552583

553-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type time-exceeded -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
584+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type time-exceeded -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
554585
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT')
555586

556-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type parameter-problem -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
587+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p icmpv6 --icmpv6-type parameter-problem -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
557588
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -p icmpv6 --icmpv6-type parameter-problem -j ACCEPT')
558589

559590
# MLDv2 discovery packets
@@ -565,14 +596,14 @@ def default_network_rules(vm_name, vm_id, vm_ip, vm_ip6, vm_mac, vif, brname, se
565596
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p udp --sport 547 ! --dst fe80::/64 -j DROP')
566597

567598
# Always allow outbound DNS over UDP and TCP
568-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p udp --dport 53 -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
569-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p tcp --dport 53 -m set --match-set ' + vm_ip6_set_name + ' src -j RETURN')
599+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p udp --dport 53 -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
600+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -p tcp --dport 53 -m set --match-set ' + vmipsetName6 + ' src -j RETURN')
570601

571602
# Prevent source address spoofing
572-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -m set ! --match-set ' + vm_ip6_set_name + ' src -j DROP')
603+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -m set ! --match-set ' + vmipsetName6 + ' src -j DROP')
573604

574605
# Send proper traffic to the egress chain of the Instance
575-
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -m set --match-set ' + vm_ip6_set_name + ' src -j ' + vmchain_egress)
606+
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-in ' + vif + ' -m set --match-set ' + vmipsetName6 + ' src -j ' + vmchain_egress)
576607

577608
execute('ip6tables -A ' + vmchain_default + ' -m physdev --physdev-is-bridged --physdev-out ' + vif + ' -j ' + vmchain)
578609

tools/marvin/marvin/config/test_data.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,12 @@
473473
"supportedservices":
474474
"Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL"
475475
},
476+
"vpc_offering_reduced": {
477+
"name": "VPC reduced off",
478+
"displaytext": "VPC reduced off",
479+
"supportedservices":
480+
"Dhcp,Dns,SourceNat,UserData,StaticNat,NetworkACL"
481+
},
476482
"vpc_offering_multi_lb": {
477483
"name": "VPC offering with multiple Lb service providers",
478484
"displaytext": "VPC offering with multiple Lb service providers",

0 commit comments

Comments
 (0)