Skip to content

Commit 1e23897

Browse files
VR/server: configure default gateway and RA/S2S VPN on the IP/interface with minimum network_id (apache#43)
* server: fix NPE when deploy vm on isolated network * vpn: fix s2s vpn status is not updated Prior to this fix ``` java.lang.IllegalArgumentException: Class com.cloud.agent.api.CheckS2SVpnConnectionsAnswer declares multiple JSON fields named 'details'; conflict is caused by fields com.cloud.agent.api.CheckS2SVpnConnectionsAnswer#details and com.cloud.agent.api.Answer#details at com.cloud.agent.transport.ResponseTest.testCheckS2SVpnConnectionsAnswer(ResponseTest.java:42) ``` * test: fix test_01_vpn_usage as now it is only possible to create VPN on Source NAT if it uses VR * VR: fix unable to create remote access VPN on regular isolated network the error is ``` File "/opt/cloud/bin/configure.py", line 1242, in process self.remoteaccessvpn_iptables(self.dbag['public_interface'], public_ip, self.dbag[public_ip]) ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^ KeyError: 'public_interface' ``` * VR/server: configure default gateway and RA/S2S VPN on the IP/interface with minimum network_id
1 parent d9dd2f2 commit 1e23897

File tree

8 files changed

+79
-18
lines changed

8 files changed

+79
-18
lines changed

core/src/main/java/com/cloud/agent/api/SetupGuestNetworkCommand.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class SetupGuestNetworkCommand extends NetworkElementCommand {
3636
String routerIpv6Gateway = null;
3737
String routerIpv6Cidr = null;
3838
boolean isVrGuestGateway = false;
39+
long networkId;
3940

4041
public NicTO getNic() {
4142
return nic;
@@ -123,4 +124,12 @@ public boolean isVrGuestGateway() {
123124
public void setVrGuestGateway(boolean vrGuestGateway) {
124125
isVrGuestGateway = vrGuestGateway;
125126
}
127+
128+
public long getNetworkId() {
129+
return networkId;
130+
}
131+
132+
public void setNetworkId(long networkId) {
133+
this.networkId = networkId;
134+
}
126135
}

core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetGuestNetworkConfigItem.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
7676
guestNetwork.setRouterIp6Gateway(command.getRouterIpv6Gateway());
7777
guestNetwork.setRouterIp6Cidr(command.getRouterIpv6Cidr());
7878
guestNetwork.setVrGuestGateway(command.isVrGuestGateway());
79+
guestNetwork.setNetworkId(command.getNetworkId());
7980

8081
return generateConfigItems(guestNetwork);
8182
}

core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/GuestNetwork.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class GuestNetwork extends ConfigBase {
3838
private String routerIp6Gateway;
3939
private String routerIp6Cidr;
4040
private boolean isVrGuestGateway;
41+
long networkId;
4142

4243
private Integer mtu;
4344

@@ -211,4 +212,12 @@ public boolean isVrGuestGateway() {
211212
public void setVrGuestGateway(boolean vrGuestGateway) {
212213
isVrGuestGateway = vrGuestGateway;
213214
}
215+
216+
public long getNetworkId() {
217+
return networkId;
218+
}
219+
220+
public void setNetworkId(long networkId) {
221+
this.networkId = networkId;
222+
}
214223
}

server/src/main/java/com/cloud/network/router/CommandSetupHelper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,7 @@ public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRoute
12211221

12221222
boolean isVrGuestGateway = _networkModel.isAnyServiceSupportedInNetwork(network.getId(), Provider.VPCVirtualRouter, Service.SourceNat, Service.Gateway);
12231223
setupCmd.setVrGuestGateway(isVrGuestGateway);
1224+
setupCmd.setNetworkId(network.getId());
12241225

12251226
NicVO publicNic = _nicDao.findDefaultNicForVM(router.getId());
12261227
if (publicNic != null) {

systemvm/debian/opt/cloud/bin/configure.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,11 +1022,10 @@ def process(self):
10221022
dev = CsHelper.get_device(local_ip)
10231023

10241024
if not self.config.has_public_network():
1025-
for interface in self.config.address().get_interfaces():
1026-
if interface.is_guest() and interface.is_added():
1027-
dev = interface.get_device()
1028-
local_ip = interface.get_ip()
1029-
break
1025+
interface = self.config.address().get_guest_if_by_network_id()
1026+
if interface:
1027+
dev = interface.get_device()
1028+
local_ip = interface.get_ip()
10301029

10311030
if dev == "":
10321031
logging.error("Request for ipsec to %s not possible because ip is not configured", local_ip)
@@ -1232,11 +1231,10 @@ def process(self):
12321231

12331232
logging.debug("Remote accessvpn data bag %s", self.dbag)
12341233
if not self.config.has_public_network():
1235-
for interface in self.config.address().get_interfaces():
1236-
if interface.is_guest() and interface.is_added():
1237-
self.configure_l2tpIpsec(interface.get_ip(), self.dbag[public_ip])
1238-
self.remoteaccessvpn_iptables(interface.get_device(), interface.get_ip(), self.dbag[public_ip])
1239-
break
1234+
interface = self.config.address().get_guest_if_by_network_id()
1235+
if interface:
1236+
self.configure_l2tpIpsec(interface.get_ip(), self.dbag[public_ip])
1237+
self.remoteaccessvpn_iptables(interface.get_device(), interface.get_ip(), self.dbag[public_ip])
12401238
else:
12411239
self.configure_l2tpIpsec(public_ip, self.dbag[public_ip])
12421240
self.remoteaccessvpn_iptables(self.dbag[public_ip]['public_interface'], public_ip, self.dbag[public_ip])

systemvm/debian/opt/cloud/bin/cs/CsAddress.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ def get_interfaces(self):
4444
interfaces.append(CsInterface(ip, self.config))
4545
return interfaces
4646

47+
def get_guest_if_by_network_id(self):
48+
guest_interface = None
49+
lowest_network_id = 1000
50+
for interface in self.get_interfaces():
51+
if interface.is_guest() and interface.is_added():
52+
if not self.config.is_vpc():
53+
return interface
54+
network_id = self.config.guestnetwork().get_network_id(interface.get_device())
55+
if network_id and network_id < lowest_network_id:
56+
lowest_network_id = network_id
57+
guest_interface = interface
58+
return guest_interface
59+
4760
def get_guest_if(self):
4861
"""
4962
Return CsInterface object for the lowest in use guest interface
@@ -261,12 +274,15 @@ def __init__(self, dev, config):
261274
self.fw = config.get_fw()
262275
self.cl = config.cmdline()
263276

264-
def configure_rp(self):
277+
def configure_rp(self, enable=True):
265278
"""
266279
Configure Reverse Path Filtering
267280
"""
268281
filename = "/proc/sys/net/ipv4/conf/%s/rp_filter" % self.dev
269-
CsHelper.updatefile(filename, "1\n", "w")
282+
if enable:
283+
CsHelper.updatefile(filename, "1\n", "w")
284+
else:
285+
CsHelper.updatefile(filename, "0\n", "w")
270286

271287
def buildlist(self):
272288
"""
@@ -361,12 +377,11 @@ def post_configure(self, address):
361377
# VPC routers in a different manner. Please do not remove this block otherwise
362378
# The VPC default route will be broken.
363379
if not self.config.has_public_network():
364-
for interface in self.config.address().get_interfaces():
365-
if interface.is_guest() and interface.is_added() and interface.get_device() == self.dev:
366-
gateway = interface.get_gateway()
367-
route.add_defaultroute(gateway)
368-
CsHelper.execute("sudo echo 0 > /proc/sys/net/ipv4/conf/%s/rp_filter" % interface.get_device())
369-
break
380+
interface = self.config.address().get_guest_if_by_network_id()
381+
if interface:
382+
gateway = interface.get_gateway()
383+
route.add_or_change_defaultroute(gateway)
384+
CsDevice(self.dev, self.config).configure_rp(False)
370385
elif self.get_type() in ["public"] and address["device"] == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
371386
gateway = str(address["gateway"])
372387
route.add_defaultroute(gateway)

systemvm/debian/opt/cloud/bin/cs/CsDatabag.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,10 @@ def get_router_ip6gateway(self, devname=None):
257257
if ip6gateway:
258258
return ip6gateway
259259
return False
260+
261+
def get_network_id(self, devname):
262+
nw = self.get_dev_data(devname)
263+
networkidkey = "network_id"
264+
if networkidkey not in nw:
265+
return False
266+
return nw[networkidkey]

systemvm/debian/opt/cloud/bin/cs/CsRoute.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ def set_route(self, cmd, method="add"):
8585
if not found and method == "add":
8686
logging.info("Add " + cmd)
8787
cmd = "ip route add " + cmd
88+
elif not found and method == "change":
89+
logging.info("Change " + cmd)
90+
cmd = "ip route change " + cmd
8891
elif found and method == "delete":
8992
logging.info("Delete " + cmd)
9093
cmd = "ip route delete " + cmd
@@ -122,6 +125,24 @@ def defaultroute_exists(self):
122125
logging.warn("No default route found!")
123126
return False
124127

128+
def add_or_change_defaultroute(self, gateway):
129+
""" Add a default route if not found, or change the default route if found
130+
:param str gateway
131+
:return: bool
132+
"""
133+
if not gateway:
134+
raise Exception("Gateway cannot be None.")
135+
136+
cmd = "default via " + gateway
137+
if self.defaultroute_exists():
138+
logging.info("Changing default route")
139+
self.set_route(cmd, method="change")
140+
return True
141+
else:
142+
logging.info("Adding default route")
143+
self.set_route(cmd)
144+
return True
145+
125146
def findRule(self, rule):
126147
for i in CsHelper.execute("ip rule show"):
127148
if rule in i.strip():

0 commit comments

Comments
 (0)