def create_gre_tunnel( self, node: CoreNetwork, server: DistributedServer, mtu: int, start: bool ) -> Tuple[GreTap, GreTap]: """ Create gre tunnel using a pair of gre taps between the local and remote server. :param node: node to create gre tunnel for :param server: server to create tunnel for :param mtu: mtu for gre taps :param start: True to start gre taps, False otherwise :return: local and remote gre taps created for tunnel """ host = server.host key = self.tunnel_key(node.id, netaddr.IPAddress(host).value) tunnel = self.tunnels.get(key) if tunnel is not None: return tunnel # local to server logger.info("local tunnel node(%s) to remote(%s) key(%s)", node.name, host, key) local_tap = GreTap(self.session, host, key=key, mtu=mtu) if start: local_tap.startup() local_tap.net_client.set_iface_master(node.brname, local_tap.localname) # server to local logger.info( "remote tunnel node(%s) to local(%s) key(%s)", node.name, self.address, key ) remote_tap = GreTap(self.session, self.address, key=key, server=server, mtu=mtu) if start: remote_tap.startup() remote_tap.net_client.set_iface_master(node.brname, remote_tap.localname) # save tunnels for shutdown tunnel = (local_tap, remote_tap) self.tunnels[key] = tunnel return tunnel
class GreTapBridge(CoreNetwork): """ A network consisting of a bridge with a gretap device for tunneling to another system. """ def __init__( self, session: "Session", remoteip: str = None, _id: int = None, name: str = None, policy: NetworkPolicy = NetworkPolicy.ACCEPT, localip: str = None, ttl: int = 255, key: int = None, server: "DistributedServer" = None, ) -> None: """ Create a GreTapBridge instance. :param session: core session instance :param remoteip: remote address :param _id: object id :param name: object name :param policy: network policy :param localip: local address :param ttl: ttl value :param key: gre tap key :param server: remote server node will run on, default is None for localhost """ CoreNetwork.__init__(self, session, _id, name, server, policy) if key is None: key = self.session.id ^ self.id self.grekey: int = key self.localnum: Optional[int] = None self.remotenum: Optional[int] = None self.remoteip: Optional[str] = remoteip self.localip: Optional[str] = localip self.ttl: int = ttl self.gretap: Optional[GreTap] = None if self.remoteip is not None: self.gretap = GreTap( session, remoteip, key=self.grekey, node=self, localip=localip, ttl=ttl, mtu=self.mtu, ) def startup(self) -> None: """ Creates a bridge and adds the gretap device to it. :return: nothing """ super().startup() if self.gretap: self.gretap.startup() self.attach(self.gretap) def shutdown(self) -> None: """ Detach the gretap device and remove the bridge. :return: nothing """ if self.gretap: self.detach(self.gretap) self.gretap.shutdown() self.gretap = None super().shutdown() def add_ips(self, ips: List[str]) -> None: """ Set the remote tunnel endpoint. This is a one-time method for creating the GreTap device, which requires the remoteip at startup. The 1st address in the provided list is remoteip, 2nd optionally specifies localip. :param ips: address list :return: nothing """ if self.gretap: raise CoreError(f"gretap already exists for {self.name}") remoteip = ips[0].split("/")[0] localip = None if len(ips) > 1: localip = ips[1].split("/")[0] self.gretap = GreTap( self.session, remoteip, key=self.grekey, localip=localip, ttl=self.ttl, mtu=self.mtu, ) self.startup() self.attach(self.gretap) def setkey(self, key: int, iface_data: InterfaceData) -> None: """ Set the GRE key used for the GreTap device. This needs to be set prior to instantiating the GreTap device (before addrconfig). :param key: gre key :param iface_data: interface data for setting up tunnel key :return: nothing """ self.grekey = key ips = iface_data.get_ips() if ips: self.add_ips(ips)