Skip to content

Commit b175c5d

Browse files
weizhouapachenvazquez
authored andcommitted
VR/server: configure default gateway and RA/S2S VPN on the IP/interface with minimum network_id (#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 f9e48f8 commit b175c5d

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
@@ -1223,6 +1223,7 @@ public SetupGuestNetworkCommand createSetupGuestNetworkCommand(final DomainRoute
12231223

12241224
boolean isVrGuestGateway = _networkModel.isAnyServiceSupportedInNetwork(network.getId(), Provider.VPCVirtualRouter, Service.SourceNat, Service.Gateway);
12251225
setupCmd.setVrGuestGateway(isVrGuestGateway);
1226+
setupCmd.setNetworkId(network.getId());
12261227

12271228
NicVO publicNic = _nicDao.findDefaultNicForVM(router.getId());
12281229
if (publicNic != null) {

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

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

10261026
if not self.config.has_public_network():
1027-
for interface in self.config.address().get_interfaces():
1028-
if interface.is_guest() and interface.is_added():
1029-
dev = interface.get_device()
1030-
local_ip = interface.get_ip()
1031-
break
1027+
interface = self.config.address().get_guest_if_by_network_id()
1028+
if interface:
1029+
dev = interface.get_device()
1030+
local_ip = interface.get_ip()
10321031

10331032
if dev == "":
10341033
logging.error("Request for ipsec to %s not possible because ip is not configured", local_ip)
@@ -1234,11 +1233,10 @@ def process(self):
12341233

12351234
logging.debug("Remote accessvpn data bag %s", self.dbag)
12361235
if not self.config.has_public_network():
1237-
for interface in self.config.address().get_interfaces():
1238-
if interface.is_guest() and interface.is_added():
1239-
self.configure_l2tpIpsec(interface.get_ip(), self.dbag[public_ip])
1240-
self.remoteaccessvpn_iptables(interface.get_device(), interface.get_ip(), self.dbag[public_ip])
1241-
break
1236+
interface = self.config.address().get_guest_if_by_network_id()
1237+
if interface:
1238+
self.configure_l2tpIpsec(interface.get_ip(), self.dbag[public_ip])
1239+
self.remoteaccessvpn_iptables(interface.get_device(), interface.get_ip(), self.dbag[public_ip])
12421240
else:
12431241
self.configure_l2tpIpsec(public_ip, self.dbag[public_ip])
12441242
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
@@ -45,6 +45,19 @@ def get_interfaces(self):
4545
interfaces.append(CsInterface(ip, self.config))
4646
return interfaces
4747

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

265-
def configure_rp(self):
278+
def configure_rp(self, enable=True):
266279
"""
267280
Configure Reverse Path Filtering
268281
"""
269282
filename = "/proc/sys/net/ipv4/conf/%s/rp_filter" % self.dev
270-
CsHelper.updatefile(filename, "1\n", "w")
283+
if enable:
284+
CsHelper.updatefile(filename, "1\n", "w")
285+
else:
286+
CsHelper.updatefile(filename, "0\n", "w")
271287

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